ruby-changes:16870
From: nobu <ko1@a...>
Date: Thu, 5 Aug 2010 16:57:41 +0900 (JST)
Subject: [ruby-changes:16870] Ruby:r28866 (trunk): * dir.c (glob_make_pattern): fold continuous PLAINs to get rid of
nobu 2010-08-05 16:57:26 +0900 (Thu, 05 Aug 2010) New Revision: 28866 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=28866 Log: * dir.c (glob_make_pattern): fold continuous PLAINs to get rid of snail at too deep path. [ruby-dev:41871] Modified files: trunk/ChangeLog trunk/dir.c Index: ChangeLog =================================================================== --- ChangeLog (revision 28865) +++ ChangeLog (revision 28866) @@ -1,3 +1,8 @@ +Thu Aug 5 16:57:20 2010 Nobuyoshi Nakada <nobu@r...> + + * dir.c (glob_make_pattern): fold continuous PLAINs to get rid of + snail at too deep path. [ruby-dev:41871] + Thu Aug 5 16:42:41 2010 Nobuyoshi Nakada <nobu@r...> * string.c (rb_str_set_len): should fail to modify shared string. Index: dir.c =================================================================== --- dir.c (revision 28865) +++ dir.c (revision 28866) @@ -1045,16 +1045,14 @@ /* Return nonzero if S has any special globbing chars in it. */ static int -has_magic(const char *s, int flags, rb_encoding *enc) +has_magic(const char *p, const char *pend, int flags, rb_encoding *enc) { const int escape = !(flags & FNM_NOESCAPE); const int nocase = flags & FNM_CASEFOLD; - register const char *p = s; - register const char *pend = p + strlen(p); register char c; - while ((c = *p++) != 0) { + while (p < pend && (c = *p++) != 0) { switch (c) { case '*': case '?': @@ -1079,12 +1077,10 @@ /* Find separator in globbing pattern. */ static char * -find_dirsep(const char *s, int flags, rb_encoding *enc) +find_dirsep(const char *p, const char *pend, int flags, rb_encoding *enc) { const int escape = !(flags & FNM_NOESCAPE); - register const char *p = s; - register const char *pend = p + strlen(p); register char c; int open = 0; @@ -1151,31 +1147,41 @@ static void glob_free_pattern(struct glob_pattern *list); static struct glob_pattern * -glob_make_pattern(const char *p, int flags, rb_encoding *enc) +glob_make_pattern(const char *p, const char *e, int flags, rb_encoding *enc) { struct glob_pattern *list, *tmp, **tail = &list; int dirsep = 0; /* pattern is terminated with '/' */ - while (*p) { + while (p < e && *p) { tmp = GLOB_ALLOC(struct glob_pattern); if (!tmp) goto error; if (p[0] == '*' && p[1] == '*' && p[2] == '/') { /* fold continuous RECURSIVEs (needed in glob_helper) */ - do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/'); + do { p += 3; while (*p == '/') p++; } while (p[0] == '*' && p[1] == '*' && p[2] == '/'); tmp->type = RECURSIVE; tmp->str = 0; dirsep = 1; } else { - const char *m = find_dirsep(p, flags, enc); - char *buf = GLOB_ALLOC_N(char, m-p+1); + const char *m = find_dirsep(p, e, flags, enc); + int magic = has_magic(p, m, flags, enc); + char *buf; + + if (!magic && *m) { + const char *m2; + while (!has_magic(m+1, m2 = find_dirsep(m+1, e, flags, enc), flags, enc) && + *m2) { + m = m2; + } + } + buf = GLOB_ALLOC_N(char, m-p+1); if (!buf) { GLOB_FREE(tmp); goto error; } memcpy(buf, p, m-p); buf[m-p] = '\0'; - tmp->type = has_magic(buf, flags, enc) ? MAGICAL : PLAIN; + tmp->type = magic ? MAGICAL : PLAIN; tmp->str = buf; if (*m) { dirsep = 1; @@ -1480,7 +1486,7 @@ MEMCPY(buf, start, char, n); buf[n] = '\0'; - list = glob_make_pattern(root, flags, enc); + list = glob_make_pattern(root, root + strlen(root), flags, enc); if (!list) { GLOB_FREE(buf); return -1; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/