[#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:22819] Re: File.fnmatch が "*?" のパターンを正しく処理しない?
山本です。
>File.fnmatch で、* のあとに ? が続く場合のマッチが正しくないようなので、
>修正してみました。
もうひとつ忘れてました。']'もエスケープ対象文字だと思うので、以下のように
修正しました。これは Unix のシェルでもそうなのか自信がありません。
BeOS(bash) では「修正後」のように動作しました。
# 修正前
E:\ruby-cvs\ruby>..\miniruby -Ks -ve "puts File.fnmatch('\[1\]', '[1]')"
ruby 1.9.0 (2004-01-31) [i386-bccwin32]
false
# 修正後
E:\ruby-cvs\ruby>miniruby -Ks -ve "puts File.fnmatch('\[1\]', '[1]')"
ruby 1.9.0 (2004-01-31) [i386-bccwin32]
true
前回同様、fnmatch以外の部分は、コメントや長すぎる行の修正などで、
動作に変更はありません。
cvs diff -u -wb dir.c (in directory E:\ruby-cvs\ruby\)
Index: dir.c
===================================================================
RCS file: /ruby/ruby/dir.c,v
retrieving revision 1.100
diff -u -w -b -r1.100 dir.c
--- dir.c 29 Jan 2004 11:59:55 -0000 1.100
+++ dir.c 7 Feb 2004 02:20:01 -0000
@@ -267,7 +267,7 @@
test = escape && c == '\\' ? pat+1 : pat;
while (*s) {
- if ((c == '[' || Compare(s, test) == 0) &&
+ if ((c == '?' || c == '[' || Compare(s, test) == 0) &&
!fnmatch(pat, s, flags | FNM_DOTMATCH))
return 0;
else if (ISDIRSEP(*s))
@@ -288,7 +288,7 @@
case '\\':
if (escape && pat[1]
#if defined DOSISH
- && strchr("*?[\\", pat[1])
+ && strchr("*?[]\\", pat[1])
#endif
) {
c = *++pat;
@@ -971,7 +971,13 @@
}
/* Globing pattern */
-enum glob_pattern_type { PLAIN, MAGICAL, RECURSIVE, MATCH_ALL, MATCH_DIR };
+enum glob_pattern_type {
+ PLAIN,
+ MAGICAL,
+ RECURSIVE,
+ MATCH_ALL,
+ MATCH_DIR
+};
struct glob_pattern {
char *str;
@@ -985,13 +991,14 @@
int flags;
{
char *buf;
- int dirsep = 0; /* pattern terminates with '/' */
+ int dirsep = 0;
struct glob_pattern *list, *tmp, **tail = &list;
while (*p) {
tmp = ALLOC(struct glob_pattern);
if (p[0] == '*' && p[1] == '*' && p[2] == '/') {
- do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/'); /* fold continuous RECURSIVEs */
+ /* fold continuous recursive patterns */
+ do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/');
tmp->type = RECURSIVE;
tmp->str = 0;
dirsep = 1;
@@ -1060,7 +1067,11 @@
return buf;
}
-enum answer { YES, NO, UNKNOWN };
+enum answer {
+ YES,
+ NO,
+ UNKNOWN
+};
#ifndef S_ISDIR
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
@@ -1111,9 +1122,9 @@
static int
glob_helper(path, dirsep, exist, isdir, beg, end, flags, func, arg)
const char *path;
- int dirsep; /* '/' should be placed before appending child entry's name to 'path'. */
- enum answer exist; /* exist? */
- enum answer isdir; /* a directory or a symlink to a directory? */
+ int dirsep; /* '/' is needed before appending name to 'path' */
+ enum answer exist; /* Does 'path' indicates an existing entry? */
+ enum answer isdir; /* Does 'path' indicates a directory or a symlink to a directory? */
struct glob_pattern **beg;
struct glob_pattern **end;
int flags;
@@ -1121,24 +1132,23 @@
VALUE arg;
{
struct stat st;
- int status = 0;
struct glob_pattern **cur, **new_beg, **new_end;
- int recursive = 0, need_readdir = 0, need_plain = 0, match_all = 0, match_dir = 0;
- const int escape = !(flags & FNM_NOESCAPE);
+ int plain = 0, magical = 0, recursive = 0, match_all = 0, match_dir = 0;
+ int status = 0;
+ int escape = !(flags & FNM_NOESCAPE);
for (cur = beg; cur < end; ++cur) {
struct glob_pattern *p = *cur;
if (p->type == RECURSIVE) {
recursive = 1;
- need_readdir = 1;
p = p->next;
}
switch (p->type) {
case PLAIN:
- need_plain = 1; /* ignored if need_readdir is set */
+ plain = 1;
break;
case MAGICAL:
- need_readdir = 1;
+ magical = 1;
break;
case MATCH_ALL:
match_all = 1;
@@ -1173,29 +1183,25 @@
if (match_all && exist == YES) {
status = glob_call_func(func, path, arg);
+ if (status) return status;
}
if (match_dir && isdir == YES) {
char *buf = join_path(path, dirsep, "");
status = glob_call_func(func, buf, arg);
free(buf);
- }
-
if (status) return status;
+ }
if (exist == NO || isdir == NO) return 0;
- if (need_readdir) {
-
+ if (magical || recursive) {
struct dirent *dp;
-
DIR *dirp = do_opendir(*path ? path : ".");
if (dirp == NULL) return 0;
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
-
char *buf = join_path(path, dirsep, dp->d_name);
-
enum answer new_isdir = UNKNOWN;
if (recursive && strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
@@ -1213,13 +1219,11 @@
for (cur = beg; cur < end; ++cur) {
struct glob_pattern *p = *cur;
-
if (p->type == RECURSIVE) {
if (new_isdir == YES) /* not symlink but real directory */
*new_end++ = p; /* append recursive pattern */
p = p->next; /* 0 times recursion */
}
-
if (p->type == PLAIN || p->type == MAGICAL) {
if (fnmatch(p->str, dp->d_name, flags) == 0)
*new_end++ = p->next;
@@ -1236,8 +1240,7 @@
closedir(dirp);
}
- else if (need_plain) {
-
+ else if (plain) {
struct glob_pattern **copy_beg, **copy_end, **cur2;
copy_beg = copy_end = ALLOC_N(struct glob_pattern *, end - beg);
@@ -1246,11 +1249,8 @@
*copy_end++ = (*cur)->type == PLAIN ? *cur : 0;
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);
@@ -1258,7 +1258,6 @@
new_beg = new_end = ALLOC_N(struct glob_pattern *, end - beg);
*new_end++ = (*cur)->next;
-
for (cur2 = cur + 1; cur2 < copy_end; ++cur2) {
if (*cur2 && fnmatch((*cur2)->str, name, flags) == 0) {
*new_end++ = (*cur2)->next;
@@ -1276,7 +1275,6 @@
if (status) break;
}
-
}
free(copy_beg);