[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]