[#23139] backslash in string — Jun Adachi <adachi@...>
安達@沖データと申します。
8 messages
2004/03/05
[#23148] BSD make(OpenBSD3.4) で make 出来ない — KAWAJI Shinya <kawaji@...>
かわじ、です。
3 messages
2004/03/06
[#23168] File.fnmatch のリファクタリング — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
山本です。
13 messages
2004/03/08
[#23175] Re: File.fnmatch のリファクタリング
— "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
2004/03/08
山本です。
[#23176] Re: File.fnmatch のリファクタリング
— "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
2004/03/08
山本です。
[#23184] Re: File.fnmatch のリファクタリング
— "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
2004/03/11
山本です。
[#23187] Re: File.fnmatch のリファクタリング
— "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
2004/03/12
山本です。
[#23171] Re: File.fnmatch のリファクタリング — kkosako@...
> -----Original Message-----
2 messages
2004/03/08
[#23173] Re: Oniguruma has been merged into ruby CVS — kkosako@...
> -----Original Message-----
4 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
山本です。
[#23267] Re: File.fnmatch とDir.glob の非互換部分
— matz@... (Yukihiro Matsumoto)
2004/03/30
まつもと ゆきひろです
[#23268] Re: File.fnmatch とDir.glob の非互換部分
— "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
2004/03/30
山本です。
[#23269] Re: File.fnmatch とDir.glob の非互換部分
— "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
2004/03/30
山本です。
[#23272] Re: File.fnmatch とDir.glob の非互換部分
— matz@... (Yukihiro Matsumoto)
2004/03/30
まつもと ゆきひろです
[#23273] Re: File.fnmatch とDir.glob の非互換部分
— "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
2004/03/30
山本です。
[#23212] warning: fork terminates thread — Tanaka Akira <akr@...17n.org>
思い出したのですが、thread が動いている時に fork すると、
12 messages
2004/03/23
[#23213] Re: warning: fork terminates thread
— matz@... (Yukihiro Matsumoto)
2004/03/23
まつもと ゆきひろです
[#23214] Re: warning: fork terminates thread
— keiju@... (石塚圭樹)
2004/03/24
けいじゅ@いしつかです.
[#23217] Re: warning: fork terminates thread
— Tietew <tietew-ml-ruby-dev@...>
2004/03/24
[#23221] English alias — nobu.nakada@...
なかだです。
16 messages
2004/03/25
[#23226] [-0xf0000000].pack("U") again — Tanaka Akira <akr@...17n.org>
ふと、[ruby-dev:21577] で書いた
8 messages
2004/03/26
[#23227] (retry; 0).xxx {} dumps core — Tanaka Akira <akr@...17n.org>
ふと気がついたのですが、[ruby-dev:19293] に書いて誰にも反応されなかっ
4 messages
2004/03/26
[#23228] Zlib::GzipWriter.new(nil).close dumps core — Tanaka Akira <akr@...17n.org>
次のように、Zlib::GzipWriter.new(nil).close が core を吐きます。
8 messages
2004/03/26
[#23230] Re: Zlib::GzipWriter.new(nil).close dumps core
— nobu.nakada@...
2004/03/26
なかだです。
[#23231] Re: Zlib::GzipWriter.new(nil).close dumps core
— matz@... (Yukihiro Matsumoto)
2004/03/26
まつもと ゆきひろです
[#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
[#23247] IO#readpartial — Tanaka Akira <akr@...17n.org>
ついに気が向いたので、以前から考えていた、stdio のバッファを考慮する
7 messages
2004/03/28
[#23274] Time.gm(...): gmtime/localtime error (ArgumentError) — MIYAMUKO Katsuyuki <k-miyamuko@...>
みやむこです。
6 messages
2004/03/30
[#23275] Re: Time.gm(...): gmtime/localtime error (ArgumentError)
— Tanaka Akira <akr@...17n.org>
2004/03/30
In article <4069466A.2030008@az.jp.nec.com>,
[#23283] ensure modifier — nobu.nakada@...
なかだです。
11 messages
2004/03/30
[ruby-dev:23187] Re: File.fnmatch のリファクタリング
From:
"H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
Date:
2004-03-12 05:42:34 UTC
List:
ruby-dev #23187
山本です。
File.fnmatch('**/', 'a/.b/', File::FNM_PATHNAME) がマッチしてしまうバグを修正しました。
完全な dir.c を http://www.ccsnet.ne.jp/~ocean/23187/dir.c に置いておきます。
>一通りテストしましたが、念のため明日またテストし、深夜(3/12 24:00)にコミットする予定です。
これは予定通り行うつもりです。問題があれば報告お願いします。
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.111
diff -u -w -b -p -r1.111 dir.c
--- dir.c 8 Mar 2004 12:14:49 -0000 1.111
+++ dir.c 12 Mar 2004 05:20:34 -0000
@@ -164,150 +164,173 @@ CompareImpl(p1, p2, nocase)
}
#endif /* environment */
-#if defined DOSISH
-#define isdirsep(c) ((c) == '/' || (c) == '\\')
-#else
-#define isdirsep(c) ((c) == '/')
-#endif
-
-static const char *
-range(
- const char *p, /* pattern */
- const char *test,
- int flags)
+static char *
+bracket(p, s, flags)
+ const char *p; /* pattern (next to '[') */
+ const char *s; /* string */
+ int flags;
{
- int not = 0, ok = 0;
- const char *t1, *t2;
const int nocase = flags & FNM_CASEFOLD;
const int escape = !(flags & FNM_NOESCAPE);
+ int ok = 0, not = 0;
+
if (*p == '!' || *p == '^') {
not = 1;
p++;
}
- while (*p) {
- if (*p == ']')
- return ok == not ? 0 : p + 1;
- t1 = p;
+ while (*p != ']') {
+ const char *t1 = p;
if (escape && *t1 == '\\')
t1++;
if (!*t1)
- break;
+ return 0;
p = Next(t1);
- if (*p == '-' && p[1] != ']') {
- t2 = p + 1;
+ if (p[0] == '-' && p[1] != ']') {
+ const char *t2 = p + 1;
if (escape && *t2 == '\\')
t2++;
if (!*t2)
- break;
+ return 0;
p = Next(t2);
- if (!ok && Compare(t1, test) <= 0 && Compare(test, t2) <= 0)
+ if (!ok && Compare(t1, s) <= 0 && Compare(s, t2) <= 0)
ok = 1;
}
- else {
- if (!ok && Compare(t1, test) == 0)
+ else
+ if (!ok && Compare(t1, s) == 0)
ok = 1;
}
- }
- return 0;
+ return ok == not ? 0 : (char *)p + 1;
}
-#define ISDIRSEP(c) (pathname && isdirsep(c))
-#define PERIOD_S() (period && *s == '.' && \
- (!s_prev || ISDIRSEP(*s_prev)))
-#define INC_S() (s = Next(s_prev = s))
+/* If FNM_PATHNAME is set, only path element will be matched. (upto '/' or '\0')
+ Otherwise, entire string will be matched.
+ End marker itself won't be compared.
+ And if function succeeds, *pcur points to end marker.
+*/
+#define ISEND(c) (!(c) || (pathname && (c) == '/'))
+#define RETURN(val) return *pcur = p, *scur = s, (val);
+
static int
-fnmatch(pat, string, flags)
- const char *pat;
- const char *string;
+fnmatch_helper(pcur, scur, flags)
+ const char **pcur; /* pattern */
+ const char **scur; /* string */
int flags;
{
- int c;
- const char *test;
- const char *s = string, *s_prev = 0;
- int escape = !(flags & FNM_NOESCAPE);
- int pathname = flags & FNM_PATHNAME;
- int period = !(flags & FNM_DOTMATCH);
- int nocase = flags & FNM_CASEFOLD;
+ const int period = !(flags & FNM_DOTMATCH);
+ const int escape = !(flags & FNM_NOESCAPE);
+ const int nocase = flags & FNM_CASEFOLD;
+ const int pathname = flags & FNM_PATHNAME;
- while (c = *pat) {
- switch (c) {
- case '?':
- if (!*s || ISDIRSEP(*s) || PERIOD_S())
- return FNM_NOMATCH;
- INC_S();
- ++pat;
- break;
-
- case '*':
- while ((c = *++pat) == '*')
- ;
+ const char *ptmp = 0;
+ const char *stmp = 0;
- if (PERIOD_S())
- return FNM_NOMATCH;
+ const char *p = *pcur;
+ const char *s = *scur;
- if (!c) {
- if (pathname && *rb_path_next(s))
- return FNM_NOMATCH;
- else
- return 0;
+ if (period && *s == '.' && *p != '.') /* leading period */
+ RETURN(FNM_NOMATCH);
+
+ while (1) {
+ if (*p == '*') {
+ do { p++; } while (*p == '*');
+ if (ISEND(*p))
+ RETURN(0);
+ ptmp = p;
+ stmp = s;
}
- else if (ISDIRSEP(c)) {
- s = rb_path_next(s);
- if (*s) {
- INC_S();
- ++pat;
- break;
+ if (ISEND(*s)) {
+ RETURN(ISEND(*p) ? 0 : FNM_NOMATCH);
}
- return FNM_NOMATCH;
+ if (ISEND(*p)) {
+ goto failed;
}
+ switch (*p) {
+ case '?':
+ p++;
+ Inc(s);
+ continue;
- test = escape && c == '\\' ? pat+1 : pat;
- while (*s) {
- if ((c == '?' || c == '[' || Compare(s, test) == 0) &&
- !fnmatch(pat, s, flags | FNM_DOTMATCH))
- return 0;
- else if (ISDIRSEP(*s))
- break;
- INC_S();
+ case '[': {
+ const char *t = bracket(p + 1, s, flags);
+ if (t) {
+ p = t;
+ Inc(s);
+ continue;
+ }
+ goto failed;
}
- return FNM_NOMATCH;
-
- case '[':
- if (!*s || ISDIRSEP(*s) || PERIOD_S())
- return FNM_NOMATCH;
- pat = range(pat+1, s, flags);
- if (!pat)
- return FNM_NOMATCH;
- INC_S();
- break;
case '\\':
- if (escape && pat[1]
-#if defined DOSISH
- && strchr("*?[]\\", pat[1])
-#endif
- ) {
- c = *++pat;
- }
- /* FALLTHROUGH */
-
- default:
-#if defined DOSISH
- if (ISDIRSEP(c) && isdirsep(*s))
- ;
- else
-#endif
- if (Compare(pat, s) != 0)
+ if (escape && p[1])
+ p++;
+ break; /* goto ordinary */
+ }
+
+ /* ordinary */
+ if (Compare(p, s) != 0) {
+ goto failed;
+ }
+ Inc(p);
+ Inc(s);
+ continue;
+
+ failed: /* try next '*' position */
+ if (ptmp && stmp) {
+ p = ptmp;
+ Inc(stmp); /* !ISEND(*stmp) */
+ s = stmp;
+ continue;
+ }
+ RETURN(FNM_NOMATCH);
+ }
+}
+
+static int
+fnmatch(p, s, flags)
+ const char *p; /* pattern */
+ const char *s; /* string */
+ int flags;
+{
+ const int period = !(flags & FNM_DOTMATCH);
+ const int pathname = flags & FNM_PATHNAME;
+
+ const char *ptmp = 0;
+ const char *stmp = 0;
+
+ if (pathname) {
+ while (1) {
+ if (p[0] == '*' && p[1] == '*' && p[2] == '/') {
+ do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/');
+ ptmp = p;
+ stmp = s;
+ }
+ if (fnmatch_helper(&p, &s, flags) == 0) {
+ while (*s && *s != '/') Inc(s);
+ if (*p && *s) {
+ p++;
+ s++;
+ continue;
+ }
+ if (!*p && !*s)
+ return 0;
+ }
+ if (ptmp && stmp && !(period && *stmp == '.' && *ptmp != '.')) { /* failed : try next recursion */
+ while (*stmp && *stmp != '/') Inc(stmp);
+ if (*stmp) {
+ p = ptmp;
+ stmp++;
+ s = stmp;
+ continue;
+ }
+ }
return FNM_NOMATCH;
- INC_S();
- Inc(pat);
- break;
}
}
- return !*s ? 0 : FNM_NOMATCH;
+ else
+ return fnmatch_helper(&p, &s, flags);
}
VALUE rb_cDir;