diff --git a/ChangeLog b/ChangeLog index 1e53ac37dd..09a8912e2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Mon May 29 10:41:10 2000 Nobuyoshi Nakada + + * file.c (rb_file_s_basename): should propagate taintness. + Sun May 28 21:37:13 2000 WATANABE Hirofumi * eval.c: bug fix: DLEXT2. @@ -18,6 +22,20 @@ Wed May 25 22:25:13 2000 WATANABE Hirofumi * lib/mkmf.rb: ditto. +Thu May 25 22:01:32 2000 Katsuyuki Komatsu + + * defines.h: mswin32: remove obsolete USHORT definition. + + * re.h: mswin32: use EXTERN instead of extern. + + * regex.h: mswin32: export re_mbctab properly. + + * win32/win32.def: add ruby_ignorecase and regex.c's exports. + +Thu May 25 21:28:44 JST 2000 Minero Aoki + + * re.c (rb_reg_expr_str): escape un-printable character. + Wed May 24 23:17:50 2000 Katsuyuki Komatsu * win32/Makefile: remove unnecessary mv and rm command call. @@ -34,6 +52,10 @@ Wed May 24 23:49:47 2000 Yukihiro Matsumoto * object.c (rb_mod_initialize): should provide initialize. +Wed May 24 23:17:50 2000 Katsuyuki Komatsu + + * win32/Makefile: remove unnecessary mv and rm command call. + Wed May 24 21:01:04 2000 Katsuyuki Komatsu * ext/pty/pty.c: use "" instead of <> to include ruby.h and rubyio.h diff --git a/ToDo b/ToDo index 89fd0b3a4a..1e65903b6e 100644 --- a/ToDo +++ b/ToDo @@ -24,6 +24,7 @@ Language Spec. * discourage use of symbol variable (e.g. $/, etc.) in manual * discourage use of Perlish features by giving warnings. * `exception' method to be alternative for `$!'. ?? +* non confusing in-block local variable (is it possible?) Hacking Interpreter @@ -63,9 +64,11 @@ Standard Libraries - Struct::new([name,]member,...) - IO#reopen accepts path as well - Kernel#scan -- call initialize for builtin classes too (not yet: Class, Module) +- call initialize for builtin classes too - performance tune for String's non-bang methods. - 'w' template for pack/unpack +- alternative for interator? => block_given? +- regex - /p (make obsolete), /m (new) * String#scanf(?) * Object#fmt(?) * Integer#{bin,oct,hex,heX} @@ -106,8 +109,5 @@ Things To Do Before 1.6 * fix spec. for the following: - * alternative for $! (exception? in? into? =>?) - * alternative for interator? - - regex - /p, /m - * odd? even? + * alternative for $! (exception? in? =>? :?) * mkmf.rb - create_makefile("net/socket") diff --git a/array.c b/array.c index 25de8b150b..d8dc37195c 100644 --- a/array.c +++ b/array.c @@ -1082,6 +1082,13 @@ rb_ary_delete_at(ary, pos) return del; } +VALUE +rb_ary_delete_at_m(ary, pos) + VALUE ary, pos; +{ + return rb_ary_delete_at(ary, NUM2LONG(pos)); +} + static VALUE rb_ary_slice_bang(argc, argv, ary) int argc; @@ -1629,7 +1636,7 @@ Init_Array() rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0); rb_define_method(rb_cArray, "filter", rb_ary_filter, 0); rb_define_method(rb_cArray, "delete", rb_ary_delete, 1); - rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at, -1); + rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1); rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0); rb_define_method(rb_cArray, "reject!", rb_ary_delete_if, 0); rb_define_method(rb_cArray, "replace", rb_ary_replace_m, 1); diff --git a/defines.h b/defines.h index 4f31f880d8..20197ec600 100644 --- a/defines.h +++ b/defines.h @@ -31,9 +31,7 @@ #endif /* NeXT */ #ifdef NT -#define USHORT _USHORT #include "win32/win32.h" -#undef USHORT #endif #if defined __CYGWIN__ diff --git a/eval.c b/eval.c index 9edf9aeb3e..abf4396017 100644 --- a/eval.c +++ b/eval.c @@ -6793,7 +6793,7 @@ rb_thread_schedule() END_FOREACH_FROM(curr, th); /* Do the select if needed */ - if (need_select || !found) { + if (need_select) { /* Convert delay to a timeval */ /* If a thread is runnable, just poll */ if (found) { @@ -7321,7 +7321,7 @@ rb_thread_abort_exc_set(thread, val) #define THREAD_ALLOC(th) do {\ th = ALLOC(struct thread);\ \ - th->status = 0;\ + th->status = THREAD_RUNNABLE;\ th->result = 0;\ th->errinfo = Qnil;\ \ diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index 9ac24cd763..b0b44180c9 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -277,17 +277,17 @@ EOS exit end -case with_config("ipv6-lookup-order", "INET") +case with_config("lookup-order-hack", "UNSPEC") when "INET" - $CFLAGS="-DDEFAULT_LOOKUP_ORDER_INET "+$CFLAGS + $CFLAGS="-DLOOKUP_ORDER_HACK_INET "+$CFLAGS when "INET6" - $CFLAGS="-DDEFAULT_LOOKUP_ORDER_INET6 "+$CFLAGS + $CFLAGS="-DLOOKUP_ORDER_HACK_INET6 "+$CFLAGS when "UNSPEC" - $CFLAGS="-DDEFAULT_LOOKUP_ORDER_UNSPEC "+$CFLAGS + # nothing special else print <ai_family != PF_UNSPEC) { + return getaddrinfo(nodename, servname, hints, res); + } + for (i = 0; i < LOOKUP_ORDERS; i++) { - af = lookup_order_table[lookup_order][i]; + af = lookup_order_table[i]; MEMCPY(&tmp_hints, hints, struct addrinfo, 1); tmp_hints.ai_family = af; error = getaddrinfo(nodename, servname, &tmp_hints, res); @@ -173,20 +147,7 @@ rb_getaddrinfo(nodename, servname, hints, res) return error; } -#else -static VALUE -lookup_order_get(self) - VALUE self; -{ - return INT2FIX(LOOKUP_ORDER_DEFAULT); -} - -static VALUE -lookup_order_set(self, order) - VALUE self, order; -{ - return order; -} +#define getaddrinfo(node,serv,hints,res) rb_getaddrinfo((node),(serv),(hints),(res)) #endif #ifdef NT @@ -641,11 +602,7 @@ ip_addrsetup(host, port) MEMZERO(&hints, struct addrinfo, 1); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; -#ifndef INET6 error = getaddrinfo(hostp, portp, &hints, &res); -#else - error = rb_getaddrinfo(hostp, portp, &hints, &res); -#endif if (error) { if (hostp && hostp[strlen(hostp)-1] == '\n') { rb_raise(rb_eSocket, "newline at the end of hostname"); @@ -839,11 +796,7 @@ open_inet(class, h, serv, type) if (type == INET_SERVER) { hints.ai_flags = AI_PASSIVE; } -#ifndef INET6 error = getaddrinfo(host, portp, &hints, &res0); -#else - error = rb_getaddrinfo(host, portp, &hints, &res0); -#endif if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -1878,11 +1831,9 @@ sock_s_getaddrinfo(argc, argv) if (!NIL_P(family)) { hints.ai_family = NUM2INT(family); } -#ifndef INET6 else { hints.ai_family = PF_UNSPEC; } -#endif if (!NIL_P(socktype)) { hints.ai_socktype = NUM2INT(socktype); } @@ -1892,16 +1843,7 @@ sock_s_getaddrinfo(argc, argv) if (!NIL_P(flags)) { hints.ai_flags = NUM2INT(flags); } -#ifndef INET6 error = getaddrinfo(hptr, pptr, &hints, &res); -#else - if (!NIL_P(family)) { - error = getaddrinfo(hptr, pptr, &hints, &res); - } - else { - error = rb_getaddrinfo(hptr, pptr, &hints, &res); - } -#endif if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -1917,13 +1859,14 @@ sock_s_getnameinfo(argc, argv) VALUE *argv; { VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags; - static char hbuf[1024], pbuf[1024]; char *hptr, *pptr; + char hbuf[1024], pbuf[1024]; int fl; - struct addrinfo hints, *res = NULL; + struct addrinfo hints, *res = NULL, *r; int error; struct sockaddr_storage ss; struct sockaddr *sap; + char *ep; sa = flags = Qnil; rb_scan_args(argc, argv, "11", &sa, &flags); @@ -1932,7 +1875,6 @@ sock_s_getnameinfo(argc, argv) if (!NIL_P(flags)) { fl = NUM2INT(flags); } - if (TYPE(sa) == T_STRING) { if (sizeof(ss) < RSTRING(sa)->len) { rb_raise(rb_eTypeError, "sockaddr length too big"); @@ -1944,6 +1886,7 @@ sock_s_getnameinfo(argc, argv) sap = (struct sockaddr *)&ss; } else if (TYPE(sa) == T_ARRAY) { + MEMZERO(&hints, struct addrinfo, 1); if (RARRAY(sa)->len == 3) { af = RARRAY(sa)->ptr[0]; port = RARRAY(sa)->ptr[1]; @@ -1956,11 +1899,19 @@ sock_s_getnameinfo(argc, argv) if (NIL_P(host)) { host = RARRAY(sa)->ptr[2]; } + else { + /* + * 4th element holds numeric form, don't resolve. + * see ipaddr(). + */ + hints.ai_flags |= AI_NUMERICHOST; + } } else { rb_raise(rb_eArgError, "array size should be 3 or 4, %d given", RARRAY(sa)->len); } + /* host */ if (NIL_P(host)) { hptr = NULL; } @@ -1969,6 +1920,7 @@ sock_s_getnameinfo(argc, argv) hbuf[sizeof(hbuf) - 1] = '\0'; hptr = hbuf; } + /* port */ if (NIL_P(port)) { strcpy(pbuf, "0"); pptr = NULL; @@ -1976,15 +1928,21 @@ sock_s_getnameinfo(argc, argv) else if (FIXNUM_P(port)) { snprintf(pbuf, sizeof(pbuf), "%ld", NUM2INT(port)); pptr = pbuf; - fl |= NI_NUMERICSERV; } else { strncpy(pbuf, STR2CSTR(port), sizeof(pbuf)); pbuf[sizeof(pbuf) - 1] = '\0'; pptr = pbuf; } - MEMZERO(&hints, struct addrinfo, 1); - if (strcmp(STR2CSTR(af), "AF_INET") == 0) { + hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM; + /* af */ + if (NIL_P(af)) { + hints.ai_family = PF_UNSPEC; + } + else if (FIXNUM_P(af)) { + hints.ai_family = FIX2INT(af); + } + else if (strcmp(STR2CSTR(af), "AF_INET") == 0) { hints.ai_family = PF_INET; } #ifdef INET6 @@ -1992,13 +1950,8 @@ sock_s_getnameinfo(argc, argv) hints.ai_family = PF_INET6; } #endif - else { - hints.ai_family = PF_UNSPEC; - } error = getaddrinfo(hptr, pptr, &hints, &res); - if (error) { - rb_raise(rb_eSocket, "%s", gai_strerror(error)); - } + if (error) goto error_exit; sap = res->ai_addr; } else { @@ -2007,13 +1960,25 @@ sock_s_getnameinfo(argc, argv) error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), fl); - if (error) { - rb_raise(rb_eSocket, "%s", gai_strerror(error)); - } - if (res) - freeaddrinfo(res); + if (error) goto error_exit; + for (r = res->ai_next; r; r = r->ai_next) { + char hbuf2[1024], pbuf2[1024]; + sap = r->ai_addr; + error = getnameinfo(sap, SA_LEN(sap), hbuf2, sizeof(hbuf2), + pbuf2, sizeof(pbuf2), fl); + if (error) goto error_exit; + if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) { + freeaddrinfo(res); + rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename"); + } + } + freeaddrinfo(res); return rb_assoc_new(rb_tainted_str_new2(hbuf), rb_tainted_str_new2(pbuf)); + + error_exit: + if (res) freeaddrinfo(res); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } static VALUE mConst; @@ -2175,12 +2140,6 @@ Init_socket() sock_define_const("PF_INET6", PF_INET6); #endif - sock_define_const("LOOKUP_INET", LOOKUP_ORDER_INET); - sock_define_const("LOOKUP_INET6", LOOKUP_ORDER_INET6); - sock_define_const("LOOKUP_UNSPEC", LOOKUP_ORDER_UNSPEC); - rb_define_singleton_method(rb_cBasicSocket, "lookup_order", lookup_order_get, 0); - rb_define_singleton_method(rb_cBasicSocket, "lookup_order=", lookup_order_set, 1); - sock_define_const("MSG_OOB", MSG_OOB); #ifdef MSG_PEEK sock_define_const("MSG_PEEK", MSG_PEEK); diff --git a/file.c b/file.c index c6a0544cd9..94f1ecb628 100644 --- a/file.c +++ b/file.c @@ -1330,19 +1330,20 @@ rb_file_s_basename(argc, argv) name = STR2CSTR(fname); p = strrchr(name, '/'); if (!p) { - if (!NIL_P(fext)) { - f = rmext(name, ext); - if (f) return rb_str_new(name, f); + if (NIL_P(fext) || !(f = rmext(p, ext))) + return fname; + basename = rb_str_new(p, f); + } + else { + p++; /* skip last `/' */ + if (NIL_P(fext) || !(f = rmext(p, ext))) { + basename = rb_str_new2(p); + } + else { + basename = rb_str_new(p, f); } - return fname; } - p++; /* skip last `/' */ - if (!NIL_P(fext)) { - f = rmext(p, ext); - if (f) return rb_str_new(p, f); - } - basename = rb_str_new2(p); - if (OBJ_TAINTED(fname)) OBJ_TAINT(basename); + OBJ_INFECT(basename, fname); return basename; } diff --git a/keywords b/keywords index f5380382d3..eafc5ed8ab 100644 --- a/keywords +++ b/keywords @@ -11,7 +11,7 @@ break, kBREAK, kBREAK, EXPR_END case, kCASE, kCASE, EXPR_BEG class, kCLASS, kCLASS, EXPR_CLASS def, kDEF, kDEF, EXPR_FNAME -defined?, kDEFINED, kDEFINED, EXPR_END +defined?, kDEFINED, kDEFINED, EXPR_ARG do, kDO, kDO, EXPR_BEG else, kELSE, kELSE, EXPR_BEG elsif, kELSIF, kELSIF, EXPR_BEG @@ -27,11 +27,11 @@ nil, kNIL, kNIL, EXPR_END not, kNOT, kNOT, EXPR_BEG or, kOR, kOR, EXPR_BEG redo, kREDO, kREDO, EXPR_END -rescue, kRESCUE, kRESCUE_MOD, EXPR_MID +rescue, kRESCUE, kRESCUE_MOD, EXPR_END retry, kRETRY, kRETRY, EXPR_END return, kRETURN, kRETURN, EXPR_MID self, kSELF, kSELF, EXPR_END -super, kSUPER, kSUPER, EXPR_END +super, kSUPER, kSUPER, EXPR_ARG then, kTHEN, kTHEN, EXPR_BEG true, kTRUE, kTRUE, EXPR_END undef, kUNDEF, kUNDEF, EXPR_FNAME @@ -39,4 +39,4 @@ unless, kUNLESS, kUNLESS_MOD, EXPR_BEG until, kUNTIL, kUNTIL_MOD, EXPR_BEG when, kWHEN, kWHEN, EXPR_BEG while, kWHILE, kWHILE_MOD, EXPR_BEG -yield, kYIELD, kYIELD, EXPR_END +yield, kYIELD, kYIELD, EXPR_ARG diff --git a/lex.c b/lex.c index 61b3c4e14b..0784c245bb 100644 --- a/lex.c +++ b/lex.c @@ -1,4 +1,4 @@ -/* C code produced by gperf version 2.7 */ +/* C code produced by gperf version 2.7.1 (19981006 egcs) */ /* Command-line: gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$ ./keywords */ struct kwtable {char *name; int id[2]; enum lex_state state;}; @@ -79,10 +79,10 @@ rb_reserved_word (str, len) {"module", kMODULE, kMODULE, EXPR_BEG}, {"elsif", kELSIF, kELSIF, EXPR_BEG}, {"def", kDEF, kDEF, EXPR_FNAME}, - {"rescue", kRESCUE, kRESCUE_MOD, EXPR_MID}, + {"rescue", kRESCUE, kRESCUE_MOD, EXPR_END}, {"not", kNOT, kNOT, EXPR_BEG}, {"then", kTHEN, kTHEN, EXPR_BEG}, - {"yield", kYIELD, kYIELD, EXPR_END}, + {"yield", kYIELD, kYIELD, EXPR_ARG}, {"for", kFOR, kFOR, EXPR_BEG}, {"self", kSELF, kSELF, EXPR_END}, {"false", kFALSE, kFALSE, EXPR_END}, @@ -90,8 +90,8 @@ rb_reserved_word (str, len) {"return", kRETURN, kRETURN, EXPR_MID}, {"true", kTRUE, kTRUE, EXPR_END}, {"if", kIF, kIF_MOD, EXPR_BEG}, - {"defined?", kDEFINED, kDEFINED, EXPR_END}, - {"super", kSUPER, kSUPER, EXPR_END}, + {"defined?", kDEFINED, kDEFINED, EXPR_ARG}, + {"super", kSUPER, kSUPER, EXPR_ARG}, {"undef", kUNDEF, kUNDEF, EXPR_FNAME}, {"break", kBREAK, kBREAK, EXPR_END}, {"in", kIN, kIN, EXPR_BEG}, diff --git a/lib/thread.rb b/lib/thread.rb index a0e6967a28..fd51d6d562 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -162,9 +162,11 @@ class Queue end t.run if t end - alias enq push + def enq(obj) + push(obj) + end - def pop non_block=false + def pop(non_block=false) Thread.critical = true begin loop do @@ -182,8 +184,10 @@ class Queue Thread.critical = false end end - alias shift pop - alias deq pop + def shift(non_block=false) + pop(non_block=false) + end + alias deq shift def empty? @que.length == 0 @@ -196,8 +200,9 @@ class Queue def length @que.length end - alias size length - + def size + length + end def num_waiting @waiting.size diff --git a/lib/timeout.rb b/lib/timeout.rb index ba93a62f15..4e6f546e0c 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -29,6 +29,7 @@ class TimeoutErrorname); @@ -244,7 +247,8 @@ require_libraries() free(list); list = tmp; } - ruby_eval_tree = save; + ruby_eval_tree = save[0]; + ruby_eval_tree_begin = save[1]; ruby_sourcefile = orig_sourcefile; } @@ -622,8 +626,10 @@ proc_options(argc, argv) ruby_set_argv(argc, argv); process_sflag(); +#if 0 Init_ext(); /* should be called here for some reason :-( */ require_libraries(); +#endif ruby_sourcefile = argv0; if (e_script) { @@ -643,6 +649,11 @@ proc_options(argc, argv) process_sflag(); xflag = 0; + +#if 1 + Init_ext(); /* should be called here for some reason :-( */ + require_libraries(); +#endif } extern int ruby__end__seen; diff --git a/sample/test.rb b/sample/test.rb index dca87d2e55..8f789fdd88 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -1026,10 +1026,10 @@ ok($x == Marshal.load($y)) check "pack" -$format = "c2x5CCxsdila6"; +$format = "c2x5CCxsdils_l_a6"; # Need the expression in here to force ary[5] to be numeric. This avoids # test2 failing because ary2 goes str->numeric->str and ary does not. -ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,"abcdef"] +ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,-32767,-123456,"abcdef"] $x = ary.pack($format) ary2 = $x.unpack($format) diff --git a/version.h b/version.h index fcb2ac5527..e07486f936 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.5.4" -#define RUBY_RELEASE_DATE "2000-05-28" +#define RUBY_RELEASE_DATE "2000-05-30" #define RUBY_VERSION_CODE 154 -#define RUBY_RELEASE_CODE 20000528 +#define RUBY_RELEASE_CODE 20000530 diff --git a/win32/config.status b/win32/config.status index 44659edb84..aed17e8d6e 100644 --- a/win32/config.status +++ b/win32/config.status @@ -6,7 +6,7 @@ s%@CXXFLAGS@%%g s%@FFLAGS@%%g s%@DEFS@% -DUSE_THREAD -DSIZEOF_INT=4 -DSIZEOF_SHORT=2 -DSIZEOF_LONG=4 -DSIZEOF_VOIDP=4 -DSIZEOF_FLOAT=4 -DSIZEOF_DOUBLE=8 -DHAVE_PROTOTYPES=1 -DHAVE_STDARG_PROTOTYPES=1 -DHAVE_STDLIB_H=1 -DHAVE_LIMITS_H=1 -DHAVE_FCNTL_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_ST_RDEV=1 -DGETGROUPS_T=int -DRETSIGTYPE=void -DHAVE_ALLOCA=1 -DHAVE_FMOD=1 -DHAVE_WAITPID=1 -DHAVE_GETCWD=1 -DHAVE_CHSIZE=1 -DHAVE_GETGROUPS=1 -DHAVE_GETLOGIN=1 -DRSHIFT=\(x,y\)\ \(\(x\)\>\>y\) -DFILE_COUNT=_cnt -DDLEXT=\".so\" -DDLEXT2=\".dll\" -DRUBY_PLATFORM=\"i386-mswin32\" %g -s%@LDFLAGS@%%g +s%@LDFLAGS@%$(CFLAGS) -Fm%g s%@LIBS@%user32.lib advapi32.lib wsock32.lib%g s%@exec_prefix@%${prefix}%g s%@prefix@%/usr/local%g @@ -57,7 +57,7 @@ s%@LIBRUBY_A@%lib$(RUBY_INSTALL_NAME).lib%g s%@LIBRUBY_SO@%%g s%@LIBRUBY_ALIASES@%%g s%@LIBRUBY@%libruby.lib%g -s%@LIBRUBYARG@%libruby.lib%g +s%@LIBRUBYARG@%$(topdir)/rubymw.lib%g s%@SOLIBS@%%g s%@DLDLIBS@%%g s%@arch@%i386-mswin32%g diff --git a/win32/ruby.def b/win32/ruby.def index 722480d353..4ec787af07 100644 --- a/win32/ruby.def +++ b/win32/ruby.def @@ -88,6 +88,7 @@ EXPORTS ;range.c rb_cRange ;re.c + ruby_ignorecase rb_cRegexp ;regex.c re_mbctab @@ -236,6 +237,8 @@ EXPORTS rb_define_alias rb_define_attr rb_scan_args +;dir.c + rb_glob ;dln.c dln_load dln_find_exe @@ -479,6 +482,17 @@ EXPORTS rb_reg_regsub rb_get_kcode rb_set_kcode +;regex.c + ruby_re_set_casetable + ruby_re_compile_pattern + ruby_re_free_pattern + ruby_re_compile_fastmap + ruby_re_adjust_startpos + ruby_re_search + ruby_re_match + ruby_re_copy_registers + ruby_re_free_registers + ruby_re_mbcinit ;ruby.c rb_load_file ruby_script