[#24395] "a".sum(32) is 0 — Tanaka Akira <akr@...17n.org>
次のように、"a".sum(32) が 0 になるのは変ではないでしょうか。
まつもと ゆきひろです
In article <1096716505.531808.29662.nullmailer@x31.priv.netlab.jp>,
[#24400] IO#read with 1 argument dumps core — Tanaka Akira <akr@...17n.org>
次のようにすると core を吐きます。
[#24405] Auto stack growing on Mac OS X — Mitsuhiro Kondo <miche@...>
近藤と申します。
[#24413] Re: new NKF2拡張ライブラリ — "NARUSE, Yui" <naruse@...>
naruseです。
[#24444] ARGF.read(len) and EOF — Tanaka Akira <akr@...17n.org>
次のように、ARGF.read(len) から読み込もうとしたときに、引数にファイル
In article <1097228154.590547.23205.nullmailer@x31.priv.netlab.jp>,
[#24464] DelegateClass#clone — pegacorn@...
こんにちは。
From: pegacorn@jcom.home.ne.jp
まつもと ゆきひろです
From: Yukihiro Matsumoto <matz@ruby-lang.org>
[#24467] DBM#select: `select': wrong argument type false (expected Data) (TypeError) — Tanaka Akira <akr@...17n.org>
DBM#select を呼び出すと `select': wrong argument type false (expected
[#24481] can't build ruby 1.9.0 on mswin32 — 木村浩一 <kimura.koichi@...>
木村です。
わたなべです。
[#24493] Init_stack prototype — Tanaka Akira <akr@...17n.org>
eval.c 内で Init_stack が
[#24505] File::open and mode 'w+' — sheepman <sheepman@...>
こんにちは、sheepman です。
[#24507] test_truncate_rbuf fails — "URABE Shyouhei aka.mput" <root@...>
mput です。 make test-all で以下のエラーが出ています。
In article <80041A7C-2022-11D9-9FB0-000393735AAE@mput.dip.jp>,
なかだです。
In article <200410172227.i9HMRGnh016104@sharui.nakada.niregi.kanuma.tochigi.jp>,
[#24515] Marshal.load causes core dump — Tanaka Akira <akr@...17n.org>
次のようにすると core を吐きます。
[#24519] raise dumps core — Tanaka Akira <akr@...17n.org>
次のようにすると core を吐きます。
[#24536] 「Rubyの落し方」 v.s. ruby_1_8 — akira yamada / やまだあきら <akira@...>
<URL:http://jp.rubyist.net/magazine/?0002-RubyCore>
なかだです。
まつもと ゆきひろです
2004-10-20 (水) の 21:38 +0900 に Yukihiro Matsumoto さんは書きました:
2004-10-26 (火) の 16:16 +0900 に akira yamada / やまだあきら さんは書きました:
まつもと ゆきひろです
こんにちは、なかむら(う)です。
まつもと ゆきひろです
こんにちは、なかむら(う)です。
まつもと ゆきひろです
こんにちは、なかむら(う)です。
2004-10-27 (水) の 11:48 +0900 に Yukihiro Matsumoto さんは書きました:
2004-10-27 (水) の 12:42 +0900 に akira yamada / やまだあきら さんは書きました:
In article <1098888819.9446.14.camel@rice.p.arika.org>,
2004-10-29 (金) の 11:30 +0900 に Tanaka Akira さんは書きました:
まつもと ゆきひろです
永井@知能.九工大です.
[#24537] No warning when using alias with exsisting method name — SASADA Koichi <ko1@...>
ささだです。
[#24540] IO#readpartial dumps core — Tanaka Akira <akr@...17n.org>
次のようにすると core を吐きます。
まつもと ゆきひろです
[#24594] unpack("p") dumps core — Tanaka Akira <akr@...17n.org>
次のようにすると core を吐きます。
[#24595] NKF(nkf2)をCVS Headに入れます — "NARUSE, Yui" <naruse@...>
naruseです。
[#24621] Zlib::Deflate#flush_next_in causes core dump on 1.8 — Tanaka Akira <akr@...17n.org>
次のようにすると core を吐きます。
[#24647] Re: oniguruma: big regexp dumps core — "K.Kosako" <kosako@...>
> 次のようにすると core を吐きます。
In article <20041030082637.6A78A33BFF@beryllium.ruby-lang.org>,
まつもと ゆきひろです
斉藤です。CVS の変更以来、鬼車はそう急がないだろうと
[ruby-dev:24488] Re: Dir.glob dumps core
なかだです。
At Tue, 12 Oct 2004 23:59:47 +0900,
Tanaka Akira wrote in [ruby-dev:24487]:
> 次のようにすると core を吐きます。
>
> % mkdir -p /tmp/tst/{a,b,c}/{d,e,f}
> % ./ruby -e '
> Dir.glob("/tmp/tst/**/*") {|f| callcc {|k| $k = k } if f == "/tmp/tst/a/f" }
> $k.call'
バッファの類をStringにしてみたらどうかとも思ったんですが、
opendir/closedirの間でyieldしてるんですよねぇ。
もっと簡単な方法はないかな。
Index: dir.c
===================================================================
RCS file: /cvs/ruby/src/ruby/dir.c,v
retrieving revision 1.127
diff -u -2 -p -r1.127 dir.c
--- dir.c 21 Sep 2004 03:08:32 -0000 1.127
+++ dir.c 13 Oct 2004 03:03:05 -0000
@@ -950,11 +950,25 @@ do_lstat(path, pst)
static DIR *
-do_opendir(path)
+do_opendir(path, vdir)
const char *path;
+ volatile VALUE *vdir;
{
DIR *dirp = opendir(path);
- if (dirp == NULL && errno != ENOENT && errno != ENOTDIR)
- rb_sys_warning(path);
+ if (dirp == NULL) {
+ switch (errno) {
+ case EMFILE:
+ case ENFILE:
+ rb_gc();
+ dirp = opendir(path);
+ }
+ if (dirp == NULL) {
+ if (errno != ENOENT && errno != ENOTDIR)
+ rb_sys_warning(path);
+ return 0;
+ }
+ }
+
+ *vdir = Data_Wrap_Struct(rb_cData, 0, closedir, dirp);
return dirp;
}
@@ -1056,23 +1070,42 @@ remove_backslashes(p)
enum glob_pattern_type { PLAIN, MAGICAL, RECURSIVE, MATCH_ALL, MATCH_DIR };
+#define GLOB_PTR(p) ((struct glob_pattern *)DATA_PTR(p))
+
struct glob_pattern {
char *str;
enum glob_pattern_type type;
- struct glob_pattern *next;
+ VALUE next;
};
-static struct glob_pattern *
+static void
+glob_mark_pattern(p)
+ void *p;
+{
+ rb_gc_mark(((struct glob_pattern *)p)->next);
+}
+
+static void
+glob_free_pattern(p)
+ void *p;
+{
+ xfree(((struct glob_pattern *)p)->str);
+ xfree(p);
+}
+
+static VALUE
glob_make_pattern(p, flags)
const char *p;
int flags;
{
- struct glob_pattern *list, *tmp, **tail = &list;
+ VALUE list, *tail = &list;
+ struct glob_pattern *tmp;
int dirsep = 0; /* pattern is terminated with '/' */
while (*p) {
- tmp = ALLOC(struct glob_pattern);
if (p[0] == '*' && p[1] == '*' && p[2] == '/') {
/* fold continuous RECURSIVEs (needed in glob_helper) */
do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/');
+ *tail = Data_Make_Struct(rb_cData, struct glob_pattern,
+ glob_mark_pattern, -1, tmp);
tmp->type = RECURSIVE;
tmp->str = 0;
@@ -1084,4 +1117,6 @@ glob_make_pattern(p, flags)
memcpy(buf, p, m-p);
buf[m-p] = '\0';
+ *tail = Data_Make_Struct(rb_cData, struct glob_pattern,
+ glob_mark_pattern, glob_free_pattern, tmp);
tmp->type = has_magic(buf, flags) ? MAGICAL : PLAIN;
tmp->str = buf;
@@ -1095,12 +1130,11 @@ glob_make_pattern(p, flags)
}
}
- *tail = tmp;
tail = &tmp->next;
}
- tmp = ALLOC(struct glob_pattern);
+ *tail = Data_Make_Struct(rb_cData, struct glob_pattern,
+ glob_mark_pattern, -1, tmp);
tmp->type = dirsep ? MATCH_DIR : MATCH_ALL;
tmp->str = 0;
- *tail = tmp;
tmp->next = 0;
@@ -1108,18 +1142,7 @@ glob_make_pattern(p, flags)
}
-static void
-glob_free_pattern(list)
- struct glob_pattern *list;
-{
- while (list) {
- struct glob_pattern *tmp = list;
- list = list->next;
- if (tmp->str)
- free(tmp->str);
- free(tmp);
- }
-}
+#define HIDDEN_STRING(str) do {OBJ_FREEZE(str); RBASIC(str)->klass = 0;} while (0)
-static char *
+static VALUE
join_path(path, dirsep, name)
const char *path;
@@ -1128,5 +1151,7 @@ join_path(path, dirsep, name)
{
const int len = strlen(path);
- char *buf = ALLOC_N(char, len+1+strlen(name)+1);
+ VALUE str = rb_str_new(0, len+1+strlen(name)+1);
+ char *buf = RSTRING(str)->ptr;
+ HIDDEN_STRING(str);
strcpy(buf, path);
if (dirsep) {
@@ -1137,5 +1162,5 @@ join_path(path, dirsep, name)
strcpy(buf+len, name);
}
- return buf;
+ return str;
}
@@ -1154,39 +1179,5 @@ enum answer { YES, NO, UNKNOWN };
#endif
-struct glob_args {
- void (*func) _((const char*, VALUE));
- const char *c;
- VALUE v;
-};
-
-static VALUE glob_func_caller _((VALUE));
-
-static VALUE
-glob_func_caller(val)
- VALUE val;
-{
- struct glob_args *args = (struct glob_args *)val;
- (*args->func)(args->c, args->v);
- return Qnil;
-}
-
-static int
-glob_call_func(func, path, arg)
- void (*func) _((const char*, VALUE));
- const char *path;
- VALUE arg;
-{
- int status;
- struct glob_args args;
-
- args.func = func;
- args.c = path;
- args.v = arg;
-
- rb_protect(glob_func_caller, (VALUE)&args, &status);
- return status;
-}
-
-static int
+static void
glob_helper(path, dirsep, exist, isdir, beg, end, flags, func, arg)
const char *path;
@@ -1194,6 +1185,6 @@ glob_helper(path, dirsep, exist, isdir,
enum answer exist; /* Does 'path' indicate an existing entry? */
enum answer isdir; /* Does 'path' indicate a directory or a symlink to a directory? */
- struct glob_pattern **beg;
- struct glob_pattern **end;
+ VALUE *beg;
+ VALUE *end;
int flags;
void (*func) _((const char*, VALUE));
@@ -1201,14 +1192,13 @@ glob_helper(path, dirsep, exist, isdir,
{
struct stat st;
- int status = 0;
- struct glob_pattern **cur, **new_beg, **new_end;
+ VALUE *cur, *new_beg, *new_end;
int plain = 0, magical = 0, recursive = 0, match_all = 0, match_dir = 0;
int escape = !(flags & FNM_NOESCAPE);
for (cur = beg; cur < end; ++cur) {
- struct glob_pattern *p = *cur;
+ struct glob_pattern *p = DATA_PTR(*cur);
if (p->type == RECURSIVE) {
recursive = 1;
- p = p->next;
+ p = GLOB_PTR(p->next);
}
switch (p->type) {
@@ -1252,25 +1242,23 @@ glob_helper(path, dirsep, exist, isdir,
if (match_all && exist == YES) {
- status = glob_call_func(func, path, arg);
- if (status) return status;
+ (*func)(path, arg);
}
if (match_dir && isdir == YES) {
- char *buf = join_path(path, dirsep, "");
- status = glob_call_func(func, buf, arg);
- free(buf);
- if (status) return status;
+ VALUE buf = join_path(path, dirsep, "");
+ (*func)(RSTRING(buf)->ptr, arg);
}
}
- if (exist == NO || isdir == NO) return 0;
+ if (exist == NO || isdir == NO) return;
if (magical || recursive) {
+ volatile VALUE vdir, ary;
struct dirent *dp;
- DIR *dirp = do_opendir(*path ? path : ".");
- if (dirp == NULL) return 0;
+ DIR *dirp = do_opendir(*path ? path : ".", &vdir);
+ if (dirp == NULL) return;
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- char *buf = join_path(path, dirsep, dp->d_name);
+ volatile VALUE buf = join_path(path, dirsep, dp->d_name);
enum answer new_isdir = UNKNOWN;
@@ -1278,5 +1266,5 @@ glob_helper(path, dirsep, exist, isdir,
&& fnmatch("*", dp->d_name, flags) == 0) {
#ifndef _WIN32
- if (do_lstat(buf, &st) == 0)
+ if (do_lstat(RSTRING(buf)->ptr, &st) == 0)
new_isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO;
else
@@ -1287,12 +1275,14 @@ glob_helper(path, dirsep, exist, isdir,
}
- new_beg = new_end = ALLOC_N(struct glob_pattern *, (end - beg) * 2);
+ ary = rb_ary_new2((end - beg) * 2);
+ OBJ_FREEZE(ary);
+ new_beg = new_end = RARRAY(ary)->ptr;
for (cur = beg; cur < end; ++cur) {
- struct glob_pattern *p = *cur;
+ struct glob_pattern *p = DATA_PTR(*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 */
+ *new_end++ = *cur; /* append recursive pattern */
+ p = DATA_PTR(p->next); /* 0 times recursion */
}
if (p->type == PLAIN || p->type == MAGICAL) {
@@ -1302,51 +1292,44 @@ glob_helper(path, dirsep, exist, isdir,
}
- status = glob_helper(buf, 1, YES, new_isdir, new_beg, new_end, flags, func, arg);
- free(new_beg);
- free(buf);
- if (status) break;
+ glob_helper(RSTRING(buf)->ptr, 1, YES, new_isdir, new_beg, new_end, flags, func, arg);
}
-
- closedir(dirp);
}
else if (plain) {
- struct glob_pattern **copy_beg, **copy_end, **cur2;
+ VALUE *copy_beg, *copy_end, *cur2;
+ volatile VALUE copy = rb_ary_new2(end - beg);
- copy_beg = copy_end = ALLOC_N(struct glob_pattern *, end - beg);
+ OBJ_FREEZE(copy);
+ copy_beg = copy_end = RARRAY(copy)->ptr;
for (cur = beg; cur < end; ++cur)
- *copy_end++ = (*cur)->type == PLAIN ? *cur : 0;
+ *copy_end++ = GLOB_PTR(*cur)->type == PLAIN ? *cur : 0;
for (cur = copy_beg; cur < copy_end; ++cur) {
- if (*cur) {
- char *name, *buf;
- name = ALLOC_N(char, strlen((*cur)->str) + 1);
- strcpy(name, (*cur)->str);
- if (escape) remove_backslashes(name);
-
- new_beg = new_end = ALLOC_N(struct glob_pattern *, end - beg);
- *new_end++ = (*cur)->next;
+ struct glob_pattern *p = GLOB_PTR(*cur);
+ if (p) {
+ volatile VALUE buf, ary;
+ VALUE name = rb_str_new2(p->str);
+ HIDDEN_STRING(name);
+ buf = name;
+ if (escape) remove_backslashes(RSTRING(name)->ptr);
+
+ ary = rb_ary_new2(end - beg);
+ OBJ_FREEZE(ary);
+ new_beg = new_end = RARRAY(ary)->ptr;
+ *new_end++ = GLOB_PTR(*cur)->next;
for (cur2 = cur + 1; cur2 < copy_end; ++cur2) {
- if (*cur2 && fnmatch((*cur2)->str, name, flags) == 0) {
- *new_end++ = (*cur2)->next;
+ if (*cur2 && fnmatch(GLOB_PTR(*cur2)->str, RSTRING(name)->ptr, flags) == 0) {
+ *new_end++ = GLOB_PTR(*cur2)->next;
*cur2 = 0;
}
}
- buf = join_path(path, dirsep, name);
- status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg, new_end, flags, func, arg);
- free(buf);
- free(new_beg);
- free(name);
- if (status) break;
+ buf = name = join_path(path, dirsep, RSTRING(name)->ptr);
+ glob_helper(RSTRING(name)->ptr, 1, UNKNOWN, UNKNOWN, new_beg, new_end, flags, func, arg);
}
}
-
- free(copy_beg);
}
-
- return status;
}
-static int
+static void
rb_glob2(path, flags, func, arg)
const char *path;
@@ -1355,9 +1338,7 @@ rb_glob2(path, flags, func, arg)
VALUE arg;
{
- struct glob_pattern *list;
+ VALUE list[1];
const char *root = path;
- char *buf;
- int n;
- int status;
+ volatile VALUE buf;
if (flags & FNM_CASEFOLD) {
@@ -1374,16 +1355,10 @@ rb_glob2(path, flags, func, arg)
if (*root == '/') root++;
- n = root - path;
- buf = ALLOC_N(char, n+1);
- memcpy(buf, path, n);
- buf[n] = '\0';
-
- list = glob_make_pattern(root, flags);
- status = glob_helper(buf, 0, UNKNOWN, UNKNOWN, &list, &list + 1, flags, func, arg);
- glob_free_pattern(list);
-
- free(buf);
+ buf = rb_str_new(path, root - path);
+ HIDDEN_STRING(buf);
- return status;
+ list[0] = glob_make_pattern(root, flags);
+ glob_helper(RSTRING(buf)->ptr, 0, UNKNOWN, UNKNOWN,
+ list, list + 1, flags, func, arg);
}
@@ -1394,7 +1369,5 @@ rb_glob(path, func, arg)
VALUE arg;
{
- int status = rb_glob2(path, 0, func, arg);
-
- if (status) rb_jump_tag(status);
+ rb_glob2(path, 0, func, arg);
}
@@ -1414,5 +1387,5 @@ push_pattern(path, ary)
}
-static int
+static void
push_glob(ary, s, flags)
VALUE ary;
@@ -1424,5 +1397,5 @@ push_glob(ary, s, flags)
const char *p = s;
const char *lbrace = 0, *rbrace = 0;
- int nest = 0, status = 0;
+ int nest = 0;
while (*p) {
@@ -1441,6 +1414,7 @@ push_glob(ary, s, flags)
if (lbrace && rbrace) {
- char *buf, *b;
- buf = xmalloc(strlen(s) + 1);
+ volatile VALUE str = rb_str_new(0, strlen(s) + 1);
+ char *buf = RSTRING(str)->ptr, *b;
+ HIDDEN_STRING(str);
memcpy(buf, s, lbrace-s);
b = buf + (lbrace-s);
@@ -1459,14 +1433,10 @@ push_glob(ary, s, flags)
memcpy(b, t, p-t);
strcpy(b+(p-t), rbrace+1);
- status = push_glob(ary, buf, flags);
- if (status) break;
+ push_glob(ary, buf, flags);
}
- free(buf);
}
else if (!lbrace && !rbrace) {
- status = rb_glob2(s, flags, push_pattern, ary);
+ rb_glob2(s, flags, push_pattern, ary);
}
-
- return status;
}
@@ -1486,4 +1456,5 @@ rb_push_glob(str, flags) /* '\0' is deli
FilePathValue(str);
+ *(volatile VALUE *)&str = rb_str_new4(str);
p = RSTRING(str)->ptr;
pend = p + RSTRING(str)->len;
@@ -1491,6 +1462,5 @@ rb_push_glob(str, flags) /* '\0' is deli
while (p < pend) {
if (*p) {
- int status = push_glob(ary, p, flags);
- if (status) rb_jump_tag(status);
+ push_glob(ary, p, flags);
p += strlen(p);
}
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦