From: "H.Yamamoto" Date: 2003-12-14T12:36:16+09:00 Subject: [ruby-dev:22277] Re: Dir.glob と Shjift_JIS について 山本です。 修正できたと思います。Sienaさんのテストスクリプトの結果は、 ? : ー − 表 ?? : 表裏 ??? : ソフト てすと ー : ー ー* : ー − : − −* : − ?\ : ソフト : ソフト でした。[ruby-dev:22270]に対するパッチです。 find_magicにエスケープ削除を組み込もうかと思いましたが、 find_magicが複雑になりすぎる気がして、とりあえず今の形にしました。 リファクタリング前後で速度比較しましたが、あまり違いがなかったです。うーむ・・・ 5992個のファイルがあるドライブに Dir.glob("f:/**/*"){} で、 リファクタリング前で11sec、後で10secでした。 (一度目はハードディスクにアクセスするので、二度目以降) --- dir.c-22270 Sun Dec 14 10:57:46 2003 +++ dir.c Sun Dec 14 11:02:14 2003 @@ -167,7 +167,7 @@ range(pat, test, flags) char *pstart, *pend; + if (*pat == ']') + return ok == not ? 0 : pat+1; + if (escape && pat[1] == '\\') + pat++; pstart = pend = pat; - if (*pstart == ']') - return ok == not ? 0 : ++pat; - else if (escape && *pstart == '\\') - pstart = pend = ++pat; Inc(pat); @@ -680,5 +680,6 @@ do_fnmatch(beg, end, string, flags) -static void -remove_backslashes(p) +static int +remove_backslashes(p, pend) char *p; + char *pend; { @@ -686,4 +687,5 @@ remove_backslashes(p) char *s = p; + int n = 0; - while (*p) { + while (*p && p < pend) { if (*p == '\\') { @@ -691,2 +693,3 @@ remove_backslashes(p) memmove(t, s, p - s); + n++; } @@ -699,5 +702,10 @@ remove_backslashes(p) + while (*p++); + if (t != s) { - memmove(t, s, p - s + 1); /* move '\0' too */ + memmove(t, s, p - s); /* move '\0' too */ + n++; } + + return n; } @@ -764,2 +772,8 @@ glob_helper(path, sub, flags, func, arg) + if (!(flags & FNM_NOESCAPE)) { + int n = remove_backslashes(sub, beg); + beg -= n; + end -= n; + } + if (*beg == '\0') { /* magic not found */ @@ -907,6 +921,4 @@ rb_glob2(path, flags, func, arg) #if defined DOSISH - remove_backslashes(path); status = glob_helper(path, (ISALPHA(path[0]) && path[1] == ':' ? path + 2 : path), flags, func, arg); #else - if (!(flags & FNM_NOESCAPE)) remove_backslashes(path); status = glob_helper(path, path, flags, func, arg);