[#22815] File.fnmatch が "*?" のパターンを正しく処理しない? — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
山本です。
山本です。
山本です。
山本です。補足します。
なかだです。
山本です。
山本です。
まつもと ゆきひろです
[#22816] YAML.load(time) on OpenBSD3.4 — "Kawaji, Shinya" <kawaji@...>
かわじ、です
In article <20040207005319=tuYR!@hoppeta.com>,
かわじ、です。
[#22832] Dir.glob("**/") のバグ — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
山本です。
[#22859] Re: io/nonblock — nobu.nakada@...
なかだです。
[#22862] File.fnmatch と Dir.glob — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
山本です。
まつもと ゆきひろです
山本です。
山本です。誤記がありました。
まつもと ゆきひろです
山本です。
山本です。
まつもと ゆきひろです
山本です。
まつもと ゆきひろです
山本です。
山本です。
まつもと ゆきひろです
山本です。
まつもと ゆきひろです
山本です。
山本です。
まつもと ゆきひろです
山本です。
まつもと ゆきひろです
まつもと ゆきひろです
わたなべです。
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
まつもと ゆきひろです
山本です。
まつもと ゆきひろです
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
まつもと ゆきひろです
山本です。
まつもと ゆきひろです
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
山本です。
まつもと ゆきひろです
山本です。
なかだです。
山本です。
なかだです。
山本です。
なかだです。
山本です。
[#22870] path for RUBY — GOTOU Yuuzou <gotoyuzo@...>
mkmf.rbでMakefileを作ると、$(RUBY)にディレクトリ名が含まれな
[#22877] Process.spawn & IO.popen w/o shell — nobu.nakada@...
なかだです。
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
In message <200402141156.i1EBuYFH018029@sharui.nakada.niregi.kanuma.tochigi.jp>
なかだです。
In message <200402160353.i1G3rGNK007935@sharui.nakada.niregi.kanuma.tochigi.jp>
なかだです。
[#22890] rb_glob(i) & constness — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
山本です。
In article <20040215161805.6541D650.ocean@m2.ccsnet.ne.jp>,
[#22906] bcc32 の makefile — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
山本です。
なかだです。
山本です。
山本です。
[#22911] core dump with /#{Thread.pass}/o — Tanaka Akira <akr@...17n.org>
ついに捕まえたのですが、次のようにすると core を吐きます。
[#22928] [BUG] make distclean が失敗する — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
山本です。
山本です。
山本です。
こんにちは、なかむら(う)です。
山本です。
こんにちは、なかむら(う)です。
山本です。
なかだです。
山本です。
山本です。
こんにちは、なかむら(う)です。
山本です。
山本です。
山本です。
こんにちは、なかむら(う)です。
山本です。
こんにちは、なかむら(う)です。
山本です。
山本です。
こんにちは、なかむら(う)です。
山本です。
山本です。
こんにちは、なかむら(う)です。
山本です。
山本です。
こんにちは、なかむら(う)です。
[#22956] Dir#glob proposal — nobu.nakada@...
なかだです。
まつもと ゆきひろです
なかだです。
山本です。
山本です。
[#23032] Re: [Oniguruma] Version 2.2.0 — kkosako@...
> -----Original Message-----
斉藤です。
まつもと ゆきひろです
[#23035] Re: [ruby-talk:93584] date/format.rb fix — "NAKAMURA, Hiroshi" <nakahiro@...>
なひです。
[#23038] Re: [ruby-cvs] ruby: * eval.c (localjump_destination): lambda should not interfere — nobu.nakada@...
なかだです。
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
なかだです。
[#23039] rss/dublincore.rb: dc:date format — "NAKAMURA, Hiroshi" <nakahiro@...>
なひです。
[ruby-dev:23010] Re: File.fnmatchとDir.glob
山本です。
>こんにちは、なかむら(う)です。
>
>ぜんぜん中身と関係ない話で恐縮ですが、
>
>できれば -p オプションもつけていただけないでしょうか?
>あると格段に追いやすさが違いますので。
つけてみました。
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.107
diff -u -w -b -p -r1.107 dir.c
--- dir.c 16 Feb 2004 01:33:12 -0000 1.107
+++ dir.c 23 Feb 2004 05:38:42 -0000
@@ -68,7 +68,7 @@ char *strchr _((char*,char));
#endif
#define FNM_NOESCAPE 0x01
-#define FNM_PATHNAME 0x02
+#define FNM_SEPMATCH 0x02
#define FNM_DOTMATCH 0x04
#define FNM_CASEFOLD 0x08
@@ -164,143 +164,151 @@ CompareImpl(p1, p2, nocase)
}
#endif /* environment */
-#if defined DOSISH
-#define isdirsep(c) ((c) == '/' || (c) == '\\')
-#else
-#define isdirsep(c) ((c) == '/')
-#endif
-
-static char *
-range(pat, test, flags)
- char *pat;
- char *test;
- int flags;
+static int
+bracket(
+ const char *p,
+ const char *pend,
+ const char *test,
+ int flags)
{
- int not, ok = 0;
+ int ok = 1;
int nocase = flags & FNM_CASEFOLD;
- int escape = !(flags & FNM_NOESCAPE);
- not = *pat == '!' || *pat == '^';
- if (not)
- pat++;
-
- while (*pat) {
- char *pstart, *pend;
- pstart = pend = pat;
- if (*pstart == ']')
- return ok == not ? 0 : ++pat;
- else if (escape && *pstart == '\\')
- pstart = pend = ++pat;
- Inc(pat);
- if (*pat == '-' && pat[1] != ']') {
- if (escape && pat[1] == '\\')
- pat++;
- pend = pat+1;
- if (!*pend)
- return 0;
- pat = Next(pend);
+ if (p < pend && (*p == '!' || *p == '^')) {
+ ok = 0;
+ p++;
}
- if (Compare(pstart, test) <= 0 && Compare(test, pend) <= 0)
- ok = 1;
+
+ while (p < pend) {
+ const char *t1 = p;
+ Inc(p);
+ if (p < pend && *p == '-') {
+ const char *t2 = p + 1;
+ if (t2 < pend) /* range */
+ if (Compare(t1, test) <= 0 && Compare(test, t2) <= 0)
+ return ok;
+ else {
+ p = Next(t2);
+ if (p < pend && *p == '-') /* behavoir is undefined in POSIX.2 */
+ p = t2;
+ continue;
}
- return 0;
+ }
+ if (Compare(t1, test) == 0)
+ return ok;
+ }
+ return !ok;
}
-#define ISDIRSEP(c) (pathname && isdirsep(c))
-#define PERIOD_S() (period && *s == '.' && \
- (!s_prev || ISDIRSEP(*s_prev)))
-#define INC_S() (s = Next(s_prev = s))
static int
-fnmatch(pat, string, flags)
- const char *pat;
- const char *string;
- int flags;
+fnmatch_helper(
+ const char *p, /* pattern */
+ const char *s, /* string */
+ int leading, /* 's' is leading. */
+ 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;
+ int pathname = !(flags & FNM_SEPMATCH);
- while (c = *pat) {
- switch (c) {
+ while (*p) {
+ switch (*p) {
case '?':
- if (!*s || ISDIRSEP(*s) || PERIOD_S())
+ if (period && (leading && *s == '.')) /* leading period */
return FNM_NOMATCH;
- INC_S();
- ++pat;
- break;
+ if (!*s || (pathname && *s == '/'))
+ return FNM_NOMATCH;
+ p++;
+ leading = 0;
+ Inc(s);
+ continue;
case '*':
- while ((c = *++pat) == '*')
- ;
-
- if (PERIOD_S())
+ if (period && (leading && *s == '.')) /* leading period */
return FNM_NOMATCH;
- if (!c) {
- if (pathname && *rb_path_next(s))
- return FNM_NOMATCH;
+ do { p++; } while (*p == '*');
+
+ if (!*p) {
+ if (pathname) {
+ while (*s && *s != '/') Inc(s);
+ return !*s ? 0 : FNM_NOMATCH;
+ }
else
return 0;
}
- else if (ISDIRSEP(c)) {
- s = rb_path_next(s);
- if (*s) {
- INC_S();
- break;
+
+ if (pathname && *p == '/') {
+ while (*s && *s != '/') Inc(s);
+ if (*s == '/') {
+ p++;
+ leading = 1;
+ s++;
+ continue;
}
+ else
return FNM_NOMATCH;
}
- test = escape && c == '\\' ? pat+1 : pat;
- while (*s) {
- if ((c == '?' || c == '[' || Compare(s, test) == 0) &&
- !fnmatch(pat, s, flags | FNM_DOTMATCH))
+ while (*s && !(pathname && *s == '/')) {
+ if (0 == fnmatch_helper(p, s, leading, flags))
return 0;
- else if (ISDIRSEP(*s))
- break;
- INC_S();
+ leading = 0;
+ Inc(s);
}
return FNM_NOMATCH;
- case '[':
- if (!*s || ISDIRSEP(*s) || PERIOD_S())
+ case '[': {
+ const char *pend = ++p;
+ if (period && (leading && *s == '.')) /* leading period */
return FNM_NOMATCH;
- pat = range(pat+1, s, flags);
- if (!pat)
+ if (!*s || (pathname && *s == '/'))
return FNM_NOMATCH;
- INC_S();
- break;
+ if (*pend == ']') /* bracket expression includes ']' */
+ pend++;
+ while (*pend && !(pathname && *pend == '/') && *pend != ']')
+ Inc(pend);
+ if (*pend == ']') { /* bracket expression */
+ if (bracket(p, pend, s, flags)) {
+ p = pend + 1;
+ leading = 0;
+ Inc(s);
+ continue;
+ }
+ else
+ return FNM_NOMATCH;
+ }
+ p--; /* treat '[' as ordinary character */
+ break; /* goto ordinary */
+ }
case '\\':
- if (escape && pat[1]
-#if defined DOSISH
- && strchr("*?[]\\", pat[1])
-#endif
- ) {
- c = *++pat;
+ if (escape && p[1])
+ p++;
+ break; /* goto ordinary */
}
- /* FALLTHROUGH */
- default:
-#if defined DOSISH
- if (ISDIRSEP(c) && isdirsep(*s))
- ;
- else
-#endif
- if (Compare(pat, s) != 0)
+ /* ordinary */
+
+ if (Compare(p, s) != 0)
return FNM_NOMATCH;
- INC_S();
- Inc(pat);
- break;
- }
+ Inc(p);
+ leading = pathname && *s == '/';
+ Inc(s);
}
return !*s ? 0 : FNM_NOMATCH;
}
+static int
+fnmatch(
+ const char *p, /* pattern */
+ const char *s, /* string */
+ int flags)
+{
+ return fnmatch_helper(p, s, 1, flags);
+}
+
VALUE rb_cDir;
struct dir_data {
@@ -919,15 +927,18 @@ has_magic(s, flags)
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 */
+ open = 1; /* brace to match it. Bracket expressions must be */
+ if (*p == ']') /* complete, according to Posix.2 */
+ p++;
+ continue;
+
case ']':
if (open)
return 1;
continue;
case '\\':
- if (escape && !(c = *p++))
+ if (!open && escape && !(c = *p++)) /* escape is disabled inside bracket */
return 0;
continue;
}
@@ -1272,17 +1283,15 @@ rb_glob2(path, flags, func, arg)
int n;
int status;
- if (flags & FNM_CASEFOLD) {
- rb_warn("Dir.glob() ignores File::FNM_CASEFOLD");
- }
+ if (flags & FNM_CASEFOLD)
+ rb_raise(rb_eArgError, "File::FNM_CASEFOLD cannot be used. case sensitivities depends on system.");
+ if (flags & FNM_SEPMATCH)
+ rb_raise(rb_eArgError, "File::FNM_SEPMATCH cannot be used.");
#if defined DOSISH
flags |= FNM_CASEFOLD;
root = rb_path_skip_prefix(root);
-#else
- flags &= ~FNM_CASEFOLD;
#endif
-
if (*root == '/') root++;
n = root - path;
@@ -1652,7 +1661,7 @@ Init_Dir()
rb_define_singleton_method(rb_cFile,"fnmatch?", file_s_fnmatch, -1);
rb_file_const("FNM_NOESCAPE", INT2FIX(FNM_NOESCAPE));
- rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME));
+ rb_file_const("FNM_SEPMATCH", INT2FIX(FNM_SEPMATCH));
rb_file_const("FNM_DOTMATCH", INT2FIX(FNM_DOTMATCH));
rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD));
}