[#23332] to_str再考 — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

15 messages 2004/04/05

[#23380] [SEGV] make test-all (bccwin32 ruby1.9.0) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>

山本です。

17 messages 2004/04/15
[#23400] Re: [SEGV] make test-all (bccwin32 ruby1.9.0) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/04/16

山本です。落ちる場所がわかりました。

[#23402] Re: [SEGV] make test-all (bccwin32 ruby1.9.0) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/04/16

山本です。

[#23403] Re: [SEGV] make test-all (bccwin32 ruby1.9.0) — nobu.nakada@... 2004/04/16

なかだです。

[#23405] Re: [SEGV] make test-all (bccwin32 ruby1.9.0) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/04/16

山本です。

[#23407] Re: [SEGV] make test-all (bccwin32 ruby1.9.0) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/04/16

山本です。

[ruby-dev:23361] Re: File.fnmatch とDir.glob の非互換部分

From: "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
Date: 2004-04-09 03:14:03 UTC
List: ruby-dev #23361
山本です。

[ruby-dev:23291] をパッチにしてみました。あとはスタイルの変更です。

Index: dir.c
===================================================================
RCS file: /ruby/ruby/dir.c,v
retrieving revision 1.115
diff -u -w -b -p -r1.115 dir.c
--- dir.c	7 Apr 2004 06:30:13 -0000	1.115
+++ dir.c	9 Apr 2004 03:11:31 -0000
@@ -210,7 +210,7 @@ bracket(p, s, flags)
    End marker itself won't be compared.
    And if function succeeds, *pcur reaches end marker.
 */
-#define UNESCAPE(p) (escape && *(p) == '\\' && (p)[1] ? (p) + 1 : (p))
+#define UNESCAPE(p) (escape && *(p) == '\\' ? (p) + 1 : (p))
 #define ISEND(p) (!*(p) || (pathname && *(p) == '/'))
 #define RETURN(val) return *pcur = p, *scur = s, (val);
 
@@ -943,35 +943,66 @@ has_magic(s, flags)
      const char *s;
      int flags;
 {
+    const int escape = !(flags & FNM_NOESCAPE);
+
     register const char *p = s;
     register char c;
-    int open = 0;
-    int escape = !(flags & FNM_NOESCAPE);
 
     while (c = *p++) {
 	switch (c) {
-	  case '?':
 	  case '*':
+	  case '?':
+	  case '[':
 	    return 1;
 
-	  case '[':	/* Only accept an open brace if there is a close */
-	    open++;	/* brace to match it.  Bracket expressions must be */
-	    continue;	/* complete, according to Posix.2 */
+	  case '\\':
+	    if (escape && !(c = *p++))
+		return 0;
+	    continue;
+	}
+
+	p = Next(p-1);
+    }
+
+    return 0;
+}
+
+/* Find separator in globbing pattern. */
+static char *
+find_dirsep(s, flags)
+    const char *s;
+    int flags;
+{
+    const int escape = !(flags & FNM_NOESCAPE);
+
+    register const char *p = s;
+    register char c;
+    int open = 0;
+
+    while (c = *p++) {
+	switch (c) {
+	  case '[':
+	    open = 1;
+	    continue;
 	  case ']':
-	    if (open)
-		return 1;
+	    open = 0;
+	    continue;
+
+	  case '/':
+	    if (!open)
+		return (char *)p-1;
 	    continue;
 
 	  case '\\':
 	    if (escape && !(c = *p++))
-		return 0;
+		return (char *)p-1;
 	    continue;
 	}
 
 	p = Next(p-1);
     }
 
-    return 0;
+    return (char *)p-1;
 }
 
 /* Remove escaping baskclashes */
@@ -1013,23 +1044,21 @@ glob_make_pattern(p, flags)
     const char *p;
     int flags;
 {
-    char *buf;
-    int dirsep = 0; /* pattern terminates with '/' */
     struct glob_pattern *list, *tmp, **tail = &list;
+    int dirsep = 0; /* pattern is terminated with '/' */
 
     while (*p) {
 	tmp = ALLOC(struct glob_pattern);
 	if (p[0] == '*' && p[1] == '*' && p[2] == '/') {
-	    /* fold continuous RECURSIVEs */
+	    /* fold continuous RECURSIVEs (needed in glob_helper) */
 	    do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/');
 	    tmp->type = RECURSIVE;
 	    tmp->str = 0;
 	    dirsep = 1;
 	}
 	else {
-	    const char *m;
-	    for (m = p; *m && *m != '/'; Inc(m));
-	    buf = ALLOC_N(char, m-p+1);
+	    const char *m = find_dirsep(p, flags);
+	    char *buf = ALLOC_N(char, m-p+1);
 	    memcpy(buf, p, m-p);
 	    buf[m-p] = '\0';
 	    tmp->type = has_magic(buf, flags) ? MAGICAL : PLAIN;
@@ -1267,7 +1296,7 @@ glob_helper(path, dirsep, exist, isdir, 
 
 	for (cur = copy_beg; cur < copy_end; ++cur) {
 	    if (*cur) {
-		char *buf, *name;
+		char *name, *buf;
 		name = ALLOC_N(char, strlen((*cur)->str) + 1);
 		strcpy(name, (*cur)->str);
 		if (escape) remove_backslashes(name);


In This Thread