なかだです。

At Tue, 5 Mar 2002 19:04:19 +0900,
Nobuyoshi-Nakada wrote:
> > > なるほど。とりあえず合わせてみますか。ってかなり手抜き。
> 
> ONIGURUMA対応。

メモリリークしてたので[ruby-dev:16219]からの差分です。


--- ruby.c~ Tue Mar 5 18:57:44 2002 +++ ruby.c Thu Mar 7 01:20:31 2002 @@ -384,9 +384,18 @@ Init_modeset _((void)) } -void -ruby_modeset(str, len) +struct modeset_scan_t { + struct re_registers regs; + VALUE name, val; const char *str; int len; +}; + +static VALUE +modeset_scan_i(arg) + struct modeset_scan_t *arg; { + const char *str = arg->str; + int len = arg->len; + struct re_registers *regs = &arg->regs; #define str_copy(_s, _p, _n) ((_s) \ ? (rb_str_resize((_s), (_n)), \ @@ -394,44 +403,58 @@ ruby_modeset(str, len) : ((_s) = rb_str_new((_p), (_n)))) #ifdef ONIGURUMA_VERSION -#define match(_re, _p, _n) (MEMZERO(&regs, struct re_registers, 1), \ - re_match((_re), (_p), (_n), 0, &regs)) +#define match(_re, _p, _n) (re_match((_re), (_p), (_n), 0, regs)) #else -#define match(_re, _p, _n) (MEMZERO(&regs, struct re_registers, 1), \ - re_match(&(_re), (_p), (_n), 0, &regs)) +#define match(_re, _p, _n) (re_match(&(_re), (_p), (_n), 0, regs)) #endif - struct re_registers regs; - VALUE name = 0, val = 0; - if (match(modeset_re, str, len) < 0) return; + if (match(modeset_re, str, len) < 0) return Qnil; - len = regs.end[1] - regs.beg[1]; - str += regs.beg[1]; - re_free_registers(&regs); + str += regs->beg[1]; + len = regs->end[1] - regs->beg[1]; - while (match(modeset_scan_re, str, len) >= 0) { + while (len > 0 && match(modeset_scan_re, str, len) >= 0) { const struct modeset *p = modesets; - int e0 = regs.end[0]; - int n1 = regs.end[1] - regs.beg[1]; - int s2 = regs.beg[2]; - int n2 = regs.end[2] - s2; - re_free_registers(&regs); + int n = regs->end[1] - regs->beg[1]; - str_copy(name, str, n1); - rb_funcall(name, rb_intern("downcase!"), 0); + str_copy(arg->name, str, n); + rb_funcall(arg->name, rb_intern("downcase!"), 0); do { - if (strncmp(p->name, RSTRING(name)->ptr, n1) == 0) { - str_copy(val, str + s2, n2); - (*p->func)(RSTRING(val)->ptr, RSTRING(name)->ptr); + if (strncmp(p->name, RSTRING(arg->name)->ptr, n) == 0) { + int b = regs->beg[2], e = regs->end[2]; + str_copy(arg->val, str + b, e - b); + (*p->func)(RSTRING(arg->val)->ptr, RSTRING(arg->name)->ptr); break; } } while (++p < modesets + sizeof(modesets) / sizeof(*p)); - len -= e0; - str += e0; + n = regs->end[0]; + str += n; + len -= n; } - if (name) rb_gc_force_recycle(name); - if (val) rb_gc_force_recycle(val); + return Qnil; +} + +static VALUE +modeset_ensure(arg) + struct modeset_scan_t *arg; +{ + re_free_registers(&arg->regs); + if (arg->name) rb_gc_force_recycle(arg->name); + if (arg->val) rb_gc_force_recycle(arg->val); + return Qnil; +} + +void +ruby_modeset(str, len) + const char *str; + int len; +{ + struct modeset_scan_t arg; + MEMZERO(&arg, struct modeset_scan_t, 1); + arg.str = str; + arg.len = len; + rb_ensure(modeset_scan_i, (VALUE)&arg, modeset_ensure, (VALUE)&arg); }
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦