[#23168] File.fnmatch のリファクタリング — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>

山本です。

13 messages 2004/03/08

[#23192] File.fnmatch と Dir.glob の非互換部分 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>

山本です。

19 messages 2004/03/13
[#23194] Re: File.fnmatch と Dir.glob の非互換部分 — matz@... (Yukihiro Matsumoto) 2004/03/13

まつもと ゆきひろです

[#23195] Re: File.fnmatch とDir.glob の非互換部分 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/03/14

山本です。

[#23196] Re: File.fnmatch とDir.glob の非互換部分 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/03/14

山本です。

[#23260] Re: File.fnmatch とDir.glob の非互換部分 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/03/30

山本です。

[#23261] Re: File.fnmatch とDir.glob の非互換部分 — matz@... (Yukihiro Matsumoto) 2004/03/30

まつもと ゆきひろです

[#23265] Re: File.fnmatch とDir.glob の非互換部分 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/03/30

山本です。

[#23238] Re: [ruby-cvs] ruby, ruby/lib, ruby/lib/rss, ruby/sample/openssl: * lib/logger.rb: trim tail space of each line. no user visible change. — Kouhei Sutou <kou@...>

須藤です.

10 messages 2004/03/27

[ruby-dev:23199] Re: File.fnmatchのリファクタリング

From: "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
Date: 2004-03-15 07:10:29 UTC
List: ruby-dev #23199
山本です。

動作が変わってしまった部分があったので、修正しました。

  * dir.c (fnmatch_helper): File.fnmatch('\.', '.') should return true.
  * dir.c (fnmatch_helper): File.fnmatch('\/', '/', File::FNM_PATHNAME) should return true.

また、'**/' に関するバグを修正しました。

  * dir.c (fnmatch): File.fnmatch('**/.boo', '.foo/.boo', File::FNM_PATHNAME) should return false.

'**/' については、これでひとつの記号だと思うので、この修正では '**/' != '**\/' としました。
問題があれば、ご指摘ください。今日の深夜か、明日にでもコミット予定です。


cvs diff -u -wb -p dir.c (in directory E:\ruby-cvs\ruby\)
Index: dir.c
===================================================================
RCS file: /ruby/ruby/dir.c,v
retrieving revision 1.112
diff -u -w -b -p -r1.112 dir.c
--- dir.c	12 Mar 2004 15:00:39 -0000	1.112
+++ dir.c	15 Mar 2004 06:43:16 -0000
@@ -210,7 +210,8 @@ bracket(p, s, flags)
    End marker itself won't be compared.
    And if function succeeds, *pcur reaches end marker.
 */
-#define ISEND(c) (!(c) || (pathname && (c) == '/'))
+#define UNESCAPE(p) (escape && *(p) == '\\' && (p)[1] ? (p) + 1 : (p))
+#define ISEND(p) (!*(p) || (pathname && *(p) == '/'))
 #define RETURN(val) return *pcur = p, *scur = s, (val);
 
 static int
@@ -220,9 +221,9 @@ fnmatch_helper(pcur, scur, flags)
     int flags;
 {
     const int period = !(flags & FNM_DOTMATCH);
+    const int pathname = flags & FNM_PATHNAME;
     const int escape = !(flags & FNM_NOESCAPE);
     const int nocase = flags & FNM_CASEFOLD;
-    const int pathname = flags & FNM_PATHNAME;
 
     const char *ptmp = 0;
     const char *stmp = 0;
@@ -230,49 +231,51 @@ fnmatch_helper(pcur, scur, flags)
     const char *p = *pcur;
     const char *s = *scur;
 
-    if (period && *s == '.' && *p != '.') /* leading period */
+    if (period && *s == '.' && *UNESCAPE(p) != '.') /* leading period */
 	RETURN(FNM_NOMATCH);
 
     while (1) {
-	if (*p == '*') {
+	switch (*p) {
+	  case '*':
 	    do { p++; } while (*p == '*');
-	    if (ISEND(*p))
+	    if (ISEND(UNESCAPE(p))) {
+		p = UNESCAPE(p);
 		RETURN(0);
+	    }
+	    if (ISEND(s))
+		RETURN(FNM_NOMATCH);
 	    ptmp = p;
 	    stmp = s;
-	}
-	if (ISEND(*s)) {
-	    RETURN(ISEND(*p) ? 0 : FNM_NOMATCH);
-	}
-	if (ISEND(*p)) {
-	    goto failed;
-	}
-	switch (*p) {
+	    continue;
+
 	  case '?':
+	    if (ISEND(s))
+		RETURN(FNM_NOMATCH);
 	    p++;
 	    Inc(s);
 	    continue;
 
 	  case '[': {
-	    const char *t = bracket(p + 1, s, flags);
-	    if (t) {
+	    const char *t;
+	    if (ISEND(s))
+		RETURN(FNM_NOMATCH);
+	    if (t = bracket(p + 1, s, flags)) {
 		p = t;
 		Inc(s);
 		continue;
 	    }
 	    goto failed;
 	  }
-
-	  case '\\':
-	    if (escape && p[1])
-		p++;
-	    break; /* goto ordinary */
 	}
 
 	/* ordinary */
-	if (Compare(p, s) != 0) {
+	p = UNESCAPE(p);
+	if (ISEND(s))
+	    RETURN(ISEND(p) ? 0 : FNM_NOMATCH);
+	if (ISEND(p))
+	    goto failed;
+	if (Compare(p, s) != 0)
 	    goto failed;
-	}
 	Inc(p);
 	Inc(s);
 	continue;
@@ -318,7 +321,7 @@ fnmatch(p, s, flags)
 		    return 0;
 	    }
 	    /* failed : try next recursion */
-	    if (ptmp && stmp && !(period && *stmp == '.' && *ptmp != '.')) {
+	    if (ptmp && stmp && !(period && *stmp == '.')) {
 		while (*stmp && *stmp != '/') Inc(stmp);
 		if (*stmp) {
 		    p = ptmp;


In This Thread