mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* eval.c (block_pass): should not downgrade safe level.
* ext/dbm/extconf.rb: allow specifying dbm-type explicitly. * ext/dbm/extconf.rb: avoid gdbm if possible, because it leaks memory, whereas gdbm.so doesn't. potential incompatibility. * string.c (rb_str_insert): new method. * parse.y (yylex): lex_state after RESCUE_MOD should be EXPR_BEG. * array.c (rb_ary_insert): new method. * array.c (rb_ary_update): new utility function. * io.c (set_outfile): should check if closed before assignment. * eval.c (rb_eval): should preserve value of ruby_errinfo. * eval.c (rb_thread_schedule): infinite sleep should not cause dead lock. * array.c (rb_ary_flatten_bang): proper recursive detection. * eval.c (yield_under): need not to prohibit at safe level 4. * pack.c (pack_pack): p/P packs nil into NULL. * pack.c (pack_unpack): p/P unpacks NULL into nil. * pack.c (pack_pack): size check for P template. * ruby.c (set_arg0): wrong predicate when new $0 value is bigger than original space. * gc.c (id2ref): should use NUM2ULONG() * object.c (rb_mod_const_get): check whether name is a class variable name. * object.c (rb_mod_const_set): ditto. * object.c (rb_mod_const_defined): ditto. * marshal.c (w_float): precision changed to "%.16g" * eval.c (rb_call0): wrong retry behavior. * numeric.c (fix_aref): a bug on long>int architecture. * eval.c (rb_eval_string_wrap): should restore ruby_wrapper. * regex.c (re_compile_pattern): char class at either edge of range should be invalid. * eval.c (handle_rescue): use === to compare exception match. * error.c (syserr_eqq): comparison between SytemCallErrors should based on their error numbers. * eval.c (safe_getter): should use INT2NUM(). * bignum.c (rb_big2long): 2**31 cannot fit in 31 bit long. * regex.c (calculate_must_string): wrong length calculation. * eval.c (rb_thread_start_0): fixed memory leak. * parse.y (none): should clear cmdarg_stack too. * io.c (rb_fopen): use setvbuf() to avoid recursive malloc() on some platforms. * file.c (rb_stat_dev): device functions should honor stat field types (except long long such as dev_t). * eval.c (rb_mod_nesting): should not push nil for nesting array. * eval.c (rb_mod_s_constants): should not search array by rb_mod_const_at() for nil (happens for singleton class). * class.c (rb_singleton_class_attached): should modify iv_tbl by itself, no longer use rb_iv_set() to avoid freeze check error. * variable.c (rb_const_get): error message "uninitialized constant Foo at Bar::Baz" instead of "uninitialized constantBar::Baz::Foo". * eval.c (rb_mod_included): new hook called from rb_mod_include(). * io.c (opt_i_set): should strdup() inplace_edit string. * eval.c (exec_under): need to push cref too. * eval.c (rb_f_missing): raise NameError for "undefined local variable or method". * error.c (Init_Exception): new exception NoMethodError. NameError moved under ScriptError again. * eval.c (rb_f_missing): use NoMethodError instead of NameError. * file.c (Init_File): should redifine "new" class method. * eval.c (PUSH_CREF): sharing cref node was problematic. maintain runtime cref list instead. * eval.c (rb_eval): copy defn node before registering. * eval.c (rb_load): clear ruby_cref before loading. * variable.c (rb_const_get): no recursion to show full class path for modules. * eval.c (rb_set_safe_level): should set safe level in curr_thread as well. * eval.c (safe_setter): ditto. * object.c (rb_obj_is_instance_of): nil belongs to false, not true. * time.c (make_time_t): proper (I hope) daylight saving time handling for both US and Europe. I HATE DST! * eval.c (rb_thread_wait_for): non blocked signal interrupt should stop the interval. * eval.c (proc_eq): class check aded. * eval.c (proc_eq): typo fixed ("return" was ommitted). * error.c (Init_Exception): move NameError under StandardError. * class.c (rb_mod_clone): should copy method bodies too. * bignum.c (bigdivrem): should trim trailing zero bdigits of remainder, even if dd == 0. * file.c (check3rdbyte): safe string check moved here. * time.c (make_time_t): remove HAVE_TM_ZONE code since it sometimes reports wrong time. * time.c (make_time_t): remove unnecessary range check for platforms where negative time_t is available. * process.c (proc_waitall): should push Process::Status instead of Finuxm status. * process.c (waitall_each): should add all entries in pid_tbl. these changes are inspired by Koji Arai. Thanks. * process.c (proc_wait): should not iterate if pid_tbl is 0. * process.c (proc_waitall): ditto. * numeric.c (flodivmod): a bug in no fmod case. * process.c (pst_wifsignaled): should apply WIFSIGNALED for status (int), not st (VALUE). * io.c (Init_IO): value of $/ and $\ are no longer restricted to strings. type checks are done on demand. * class.c (rb_include_module): module inclusion should be check taints. * ruby.h (STR2CSTR): replace to StringType() and StringTypePtr(). * ruby.h (rb_str2cstr): ditto. * eval.c (rb_load): should not copy topleve local variables. It cause variable/method ambiguity. Thanks to L. Peter Deutsch. * class.c (rb_include_module): freeze check at first. * eval.c (rb_attr): sprintf() and rb_intern() moved into conditional body. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1356 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
902524c35b
commit
fd06a2a7fb
44 changed files with 1712 additions and 952 deletions
270
ChangeLog
270
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
Wed May 2 11:46:13 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||
|
||||
* eval.c (block_pass): should not downgrade safe level.
|
||||
|
||||
Wed May 2 03:07:49 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* ext/dbm/extconf.rb: allow specifying dbm-type explicitly.
|
||||
|
||||
* ext/dbm/extconf.rb: avoid gdbm if possible, because it leaks
|
||||
memory, whereas gdbm.so doesn't. potential incompatibility.
|
||||
|
||||
Wed May 2 02:02:18 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* string.c (rb_str_insert): new method.
|
||||
|
||||
Tue May 1 17:55:58 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (yylex): lex_state after RESCUE_MOD should be EXPR_BEG.
|
||||
|
||||
Tue May 1 16:23:03 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* array.c (rb_ary_insert): new method.
|
||||
|
||||
* array.c (rb_ary_update): new utility function.
|
||||
|
||||
Tue May 1 03:24:05 2001 Akinori MUSHA <knu@iDaemons.org>
|
||||
|
||||
* lib/irb/completion.rb, lib/irb/frame.rb, lib/irb/xmp.rb,
|
||||
|
@ -12,6 +37,10 @@ Tue May 1 03:07:17 2001 Akinori MUSHA <knu@iDaemons.org>
|
|||
|
||||
* lib/irb/main.rb: This file is not needed anymore.
|
||||
|
||||
Fri Apr 27 09:27:10 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* io.c (set_outfile): should check if closed before assignment.
|
||||
|
||||
Thu Apr 26 22:36:11 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||
|
||||
* configure.in: don't use tzname on cygwin 1.3.1+.
|
||||
|
@ -19,6 +48,36 @@ Thu Apr 26 22:36:11 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
|||
* configure.in: add -mieee/-ieee to CFLAGS on OSF1/Alpha
|
||||
to disable "DIVISION BY ZERO" exception.
|
||||
|
||||
Thu Apr 26 22:30:43 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_eval): should preserve value of ruby_errinfo.
|
||||
|
||||
Thu Apr 26 10:36:09 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_thread_schedule): infinite sleep should not cause
|
||||
dead lock.
|
||||
|
||||
Wed Apr 25 16:40:44 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* array.c (rb_ary_flatten_bang): proper recursive detection.
|
||||
|
||||
Wed Apr 25 15:36:15 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||
|
||||
* eval.c (yield_under): need not to prohibit at safe level 4.
|
||||
|
||||
Wed Apr 25 15:22:20 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* pack.c (pack_pack): p/P packs nil into NULL.
|
||||
|
||||
* pack.c (pack_unpack): p/P unpacks NULL into nil.
|
||||
|
||||
Tue Apr 24 15:35:32 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* pack.c (pack_pack): size check for P template.
|
||||
|
||||
* ruby.c (set_arg0): wrong predicate when new $0 value is bigger
|
||||
than original space.
|
||||
|
||||
Tue Apr 24 15:18:49 2001 Akinori MUSHA <knu@iDaemons.org>
|
||||
|
||||
* ext/extmk.rb.in, lib/mkmf.rb: (dir_config) do not add the
|
||||
|
@ -27,6 +86,33 @@ Tue Apr 24 15:18:49 2001 Akinori MUSHA <knu@iDaemons.org>
|
|||
* ext/extmk.rb.in, lib/mkmf.rb: (dir_config) return a more useful
|
||||
value, [include_dir, lib_dir].
|
||||
|
||||
Mon Apr 23 14:43:59 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* gc.c (id2ref): should use NUM2ULONG()
|
||||
|
||||
* object.c (rb_mod_const_get): check whether name is a class
|
||||
variable name.
|
||||
|
||||
* object.c (rb_mod_const_set): ditto.
|
||||
|
||||
* object.c (rb_mod_const_defined): ditto.
|
||||
|
||||
Sat Apr 21 22:33:26 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* marshal.c (w_float): precision changed to "%.16g"
|
||||
|
||||
Sat Apr 21 22:07:58 2001 Guy Decoux <decoux@moulon.inra.fr>
|
||||
|
||||
* eval.c (rb_call0): wrong retry behavior.
|
||||
|
||||
Fri Apr 20 19:12:20 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* numeric.c (fix_aref): a bug on long>int architecture.
|
||||
|
||||
Fri Apr 20 14:57:15 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||
|
||||
* eval.c (rb_eval_string_wrap): should restore ruby_wrapper.
|
||||
|
||||
Sun Apr 22 17:44:37 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||
|
||||
* configure.in: add -mieee to CFLAGS on Linux/Alpha
|
||||
|
@ -38,16 +124,145 @@ Wed Apr 18 04:37:51 2001 Wakou Aoyama <wakou@fsinet.or.jp>
|
|||
|
||||
* lib/cgi.rb: CGI::Cookie: no use PATH_INFO.
|
||||
|
||||
Wed Apr 18 00:24:40 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* regex.c (re_compile_pattern): char class at either edge of range
|
||||
should be invalid.
|
||||
|
||||
Tue Apr 17 17:33:55 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (handle_rescue): use === to compare exception match.
|
||||
|
||||
* error.c (syserr_eqq): comparison between SytemCallErrors should
|
||||
based on their error numbers.
|
||||
|
||||
Tue Apr 17 16:54:39 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||
|
||||
* eval.c (safe_getter): should use INT2NUM().
|
||||
|
||||
Tue Apr 17 15:12:56 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* bignum.c (rb_big2long): 2**31 cannot fit in 31 bit long.
|
||||
|
||||
Sat Apr 14 22:46:43 2001 Guy Decoux <decoux@moulon.inra.fr>
|
||||
|
||||
* regex.c (calculate_must_string): wrong length calculation.
|
||||
|
||||
Sat Apr 14 13:37:32 2001 Usaku Nakamura <usa@osb.att.ne.jp>
|
||||
|
||||
* win32/config.status.in: no longer use missing/alloca.c.
|
||||
|
||||
* win32/Makefile.sub: ditto.
|
||||
|
||||
Fri Apr 13 12:40:48 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||
|
||||
* eval.c (rb_thread_start_0): fixed memory leak.
|
||||
|
||||
Fri Apr 13 16:41:18 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (none): should clear cmdarg_stack too.
|
||||
|
||||
Fri Apr 13 06:19:29 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
|
||||
|
||||
* io.c (rb_fopen): use setvbuf() to avoid recursive malloc() on
|
||||
some platforms.
|
||||
|
||||
Wed Apr 11 23:36:26 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* file.c (rb_stat_dev): device functions should honor stat field
|
||||
types (except long long such as dev_t).
|
||||
|
||||
Wed Apr 11 18:07:53 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||
|
||||
* eval.c (rb_mod_nesting): should not push nil for nesting array.
|
||||
|
||||
* eval.c (rb_mod_s_constants): should not search array by
|
||||
rb_mod_const_at() for nil (happens for singleton class).
|
||||
|
||||
Wed Apr 11 13:29:26 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* class.c (rb_singleton_class_attached): should modify iv_tbl by
|
||||
itself, no longer use rb_iv_set() to avoid freeze check error.
|
||||
|
||||
* variable.c (rb_const_get): error message "uninitialized constant
|
||||
Foo at Bar::Baz" instead of "uninitialized constantBar::Baz::Foo".
|
||||
|
||||
Tue Apr 10 17:52:10 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_mod_included): new hook called from rb_mod_include().
|
||||
|
||||
Tue Apr 10 02:24:40 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||
|
||||
* io.c (opt_i_set): should strdup() inplace_edit string.
|
||||
|
||||
Mon Apr 9 23:29:54 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (exec_under): need to push cref too.
|
||||
|
||||
Mon Apr 9 15:20:21 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_f_missing): raise NameError for "undefined local
|
||||
variable or method".
|
||||
|
||||
* error.c (Init_Exception): new exception NoMethodError.
|
||||
NameError moved under ScriptError again.
|
||||
|
||||
* eval.c (rb_f_missing): use NoMethodError instead of NameError.
|
||||
|
||||
Mon Apr 9 12:05:44 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* file.c (Init_File): should redifine "new" class method.
|
||||
|
||||
Mon Apr 9 11:56:52 2001 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* lib/net/imap.rb: fix typo.
|
||||
|
||||
Fri Apr 6 01:46:35 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (PUSH_CREF): sharing cref node was problematic. maintain
|
||||
runtime cref list instead.
|
||||
|
||||
* eval.c (rb_eval): copy defn node before registering.
|
||||
|
||||
* eval.c (rb_load): clear ruby_cref before loading.
|
||||
|
||||
Thu Apr 5 22:40:12 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* variable.c (rb_const_get): no recursion to show full class path
|
||||
for modules.
|
||||
|
||||
* eval.c (rb_set_safe_level): should set safe level in curr_thread
|
||||
as well.
|
||||
|
||||
* eval.c (safe_setter): ditto.
|
||||
|
||||
Thu Apr 5 13:46:06 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||
|
||||
* object.c (rb_obj_is_instance_of): nil belongs to false, not true.
|
||||
|
||||
Thu Apr 5 02:19:03 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* time.c (make_time_t): proper (I hope) daylight saving time
|
||||
handling for both US and Europe. I HATE DST!
|
||||
|
||||
* eval.c (rb_thread_wait_for): non blocked signal interrupt should
|
||||
stop the interval.
|
||||
|
||||
Wed Apr 4 03:47:03 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (proc_eq): class check aded.
|
||||
|
||||
* eval.c (proc_eq): typo fixed ("return" was ommitted).
|
||||
|
||||
* error.c (Init_Exception): move NameError under StandardError.
|
||||
|
||||
* class.c (rb_mod_clone): should copy method bodies too.
|
||||
|
||||
* bignum.c (bigdivrem): should trim trailing zero bdigits of
|
||||
remainder, even if dd == 0.
|
||||
|
||||
* file.c (check3rdbyte): safe string check moved here.
|
||||
|
||||
Tue Apr 3 09:56:20 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||
|
||||
* ext/extmk.rb.in (create_makefile): create def file only if
|
||||
|
@ -55,6 +270,26 @@ Tue Apr 3 09:56:20 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
|||
|
||||
* lib/mkmf.rb: ditto.
|
||||
|
||||
Tue Apr 3 00:05:07 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* time.c (make_time_t): remove HAVE_TM_ZONE code since it
|
||||
sometimes reports wrong time.
|
||||
|
||||
* time.c (make_time_t): remove unnecessary range check for
|
||||
platforms where negative time_t is available.
|
||||
|
||||
Mon Apr 2 16:52:48 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* process.c (proc_waitall): should push Process::Status instead of
|
||||
Finuxm status.
|
||||
|
||||
* process.c (waitall_each): should add all entries in pid_tbl.
|
||||
these changes are inspired by Koji Arai. Thanks.
|
||||
|
||||
* process.c (proc_wait): should not iterate if pid_tbl is 0.
|
||||
|
||||
* process.c (proc_waitall): ditto.
|
||||
|
||||
Mon Apr 2 14:25:49 2001 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* lib/monitor.rb (wait): ensure reentrance.
|
||||
|
@ -87,14 +322,49 @@ Mon Apr 2 01:16:24 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
|||
|
||||
* win32/dir.h, dir.c, Makefile: ditto.
|
||||
|
||||
Sun Apr 1 23:26:14 2001 TOYOFUKU Chikanobu <toyofuku@juice.or.jp>
|
||||
|
||||
* numeric.c (flodivmod): a bug in no fmod case.
|
||||
|
||||
Sun Apr 1 18:36:14 2001 Koji Arai <JCA02266@nifty.ne.jp>
|
||||
|
||||
* process.c (pst_wifsignaled): should apply WIFSIGNALED for status
|
||||
(int), not st (VALUE).
|
||||
|
||||
Sat Mar 31 04:47:55 2001 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* lib/net/imap.rb: add document and example code.
|
||||
|
||||
Sat Mar 31 03:24:10 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* io.c (Init_IO): value of $/ and $\ are no longer restricted to
|
||||
strings. type checks are done on demand.
|
||||
|
||||
* class.c (rb_include_module): module inclusion should be check
|
||||
taints.
|
||||
|
||||
* ruby.h (STR2CSTR): replace to StringType() and StringTypePtr().
|
||||
|
||||
* ruby.h (rb_str2cstr): ditto.
|
||||
|
||||
Fri Mar 30 23:37:49 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_load): should not copy topleve local variables. It
|
||||
cause variable/method ambiguity. Thanks to L. Peter Deutsch.
|
||||
|
||||
Fri Mar 30 22:56:56 2001 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* lib/net/imap.rb: rename ContinueRequest to ContinuationRequest.
|
||||
|
||||
Fri Mar 30 12:51:19 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* class.c (rb_include_module): freeze check at first.
|
||||
|
||||
Thu Mar 29 17:05:09 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_attr): sprintf() and rb_intern() moved into
|
||||
conditional body.
|
||||
|
||||
Wed Mar 28 23:43:00 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||
|
||||
* ext/extmk.rb.in, lib/mkmf.rb: add C++ rules in addition to C
|
||||
|
|
4
ToDo
4
ToDo
|
@ -46,6 +46,9 @@ Hacking Interpreter
|
|||
* MicroRuby
|
||||
* Built-in Interactive Ruby.
|
||||
* trap every method invocation, which can be enabled by e.g. trap_call :method.
|
||||
* unify Errno exceptions of same errno, or new exception comparison scheme.
|
||||
* signal list (Signal::trap, Signal::list??).
|
||||
* 2.times{|i| if i==0 then a = 15 else puts eval("a") end} should print nil.
|
||||
|
||||
Standard Libraries
|
||||
|
||||
|
@ -78,6 +81,7 @@ Standard Libraries
|
|||
* new user-defined marshal scheme. _dump(dumper), _load(restorer)
|
||||
* warn, warning for Ruby level
|
||||
* hash etc. should handle self referenceing array/hash
|
||||
* move NameError under StandardError.
|
||||
|
||||
Extension Libraries
|
||||
|
||||
|
|
119
array.c
119
array.c
|
@ -541,12 +541,12 @@ rb_ary_indexes(argc, argv, ary)
|
|||
}
|
||||
|
||||
static void
|
||||
rb_ary_replace(ary, beg, len, rpl)
|
||||
VALUE ary, rpl;
|
||||
rb_ary_update(ary, beg, len, rpl, rlen)
|
||||
VALUE ary;
|
||||
long beg, len;
|
||||
{
|
||||
VALUE *rpl;
|
||||
long rlen;
|
||||
|
||||
{
|
||||
if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len);
|
||||
if (beg < 0) {
|
||||
beg += RARRAY(ary)->len;
|
||||
|
@ -559,14 +559,6 @@ rb_ary_replace(ary, beg, len, rpl)
|
|||
len = RARRAY(ary)->len - beg;
|
||||
}
|
||||
|
||||
if (NIL_P(rpl)) {
|
||||
rpl = rb_ary_new2(0);
|
||||
}
|
||||
else if (TYPE(rpl) != T_ARRAY) {
|
||||
rpl = rb_ary_new3(1, rpl);
|
||||
}
|
||||
rlen = RARRAY(rpl)->len;
|
||||
|
||||
rb_ary_modify(ary);
|
||||
if (beg >= RARRAY(ary)->len) {
|
||||
len = beg + rlen;
|
||||
|
@ -575,7 +567,7 @@ rb_ary_replace(ary, beg, len, rpl)
|
|||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
}
|
||||
rb_mem_clear(RARRAY(ary)->ptr+RARRAY(ary)->len, beg-RARRAY(ary)->len);
|
||||
MEMCPY(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, rlen);
|
||||
MEMCPY(RARRAY(ary)->ptr+beg, rpl, VALUE, rlen);
|
||||
RARRAY(ary)->len = len;
|
||||
}
|
||||
else {
|
||||
|
@ -591,15 +583,31 @@ rb_ary_replace(ary, beg, len, rpl)
|
|||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
}
|
||||
|
||||
if (len != RARRAY(rpl)->len) {
|
||||
if (len != rlen) {
|
||||
MEMMOVE(RARRAY(ary)->ptr+beg+rlen, RARRAY(ary)->ptr+beg+len,
|
||||
VALUE, RARRAY(ary)->len-(beg+len));
|
||||
RARRAY(ary)->len = alen;
|
||||
}
|
||||
MEMMOVE(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, rlen);
|
||||
MEMMOVE(RARRAY(ary)->ptr+beg, rpl, VALUE, rlen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ary_replace(ary, beg, len, rpl)
|
||||
VALUE ary, rpl;
|
||||
long beg, len;
|
||||
{
|
||||
long rlen;
|
||||
|
||||
if (NIL_P(rpl)) {
|
||||
rpl = rb_ary_new2(0);
|
||||
}
|
||||
else if (TYPE(rpl) != T_ARRAY) {
|
||||
rpl = rb_ary_new3(1, rpl);
|
||||
}
|
||||
rb_ary_update(ary, beg, len, RARRAY(rpl)->ptr, RARRAY(rpl)->len);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_aset(argc, argv, ary)
|
||||
int argc;
|
||||
|
@ -634,6 +642,19 @@ rb_ary_aset(argc, argv, ary)
|
|||
return argv[1];
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_insert(argc, argv, ary)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE ary;
|
||||
{
|
||||
if (argc < 2) {
|
||||
rb_raise(rb_eArgError, "wrong # of arguments(at least 2)");
|
||||
}
|
||||
rb_ary_update(ary, NUM2LONG(argv[0]), 0, argv+1, argc-1);
|
||||
return ary;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_ary_each(ary)
|
||||
VALUE ary;
|
||||
|
@ -1233,7 +1254,7 @@ rb_ary_fill(argc, argv, ary)
|
|||
end = beg + len;
|
||||
if (end > RARRAY(ary)->len) {
|
||||
if (end >= RARRAY(ary)->capa) {
|
||||
RARRAY(ary)->capa=end;
|
||||
RARRAY(ary)->capa = end;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
}
|
||||
if (beg > RARRAY(ary)->len) {
|
||||
|
@ -1267,19 +1288,11 @@ VALUE
|
|||
rb_ary_concat(x, y)
|
||||
VALUE x, y;
|
||||
{
|
||||
long xlen = RARRAY(x)->len;
|
||||
long ylen;
|
||||
|
||||
y = to_ary(y);
|
||||
ylen = RARRAY(y)->len;
|
||||
if (ylen > 0) {
|
||||
rb_ary_modify(x);
|
||||
if (xlen + ylen > RARRAY(x)->capa) {
|
||||
RARRAY(x)->capa = xlen + ylen;
|
||||
REALLOC_N(RARRAY(x)->ptr, VALUE, RARRAY(x)->capa);
|
||||
}
|
||||
MEMCPY(RARRAY(x)->ptr+xlen, RARRAY(y)->ptr, VALUE, ylen);
|
||||
RARRAY(x)->len = xlen + ylen;
|
||||
if (RARRAY(y)->len > 0) {
|
||||
rb_ary_replace(x, RARRAY(x)->len, 0, y);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
@ -1598,35 +1611,54 @@ rb_ary_nitems(ary)
|
|||
return INT2NUM(n);
|
||||
}
|
||||
|
||||
static int
|
||||
flatten(ary, idx, ary2, memo)
|
||||
VALUE ary;
|
||||
long idx;
|
||||
VALUE ary2, memo;
|
||||
{
|
||||
VALUE id;
|
||||
long i = idx;
|
||||
long n, lim = idx + RARRAY(ary2)->len;
|
||||
|
||||
id = rb_obj_id(ary2);
|
||||
if (rb_ary_includes(memo, id)) {
|
||||
rb_raise(rb_eArgError, "tried to flatten recursive array");
|
||||
}
|
||||
rb_ary_push(memo, id);
|
||||
rb_ary_replace(ary, idx, 1, ary2);
|
||||
while (i < lim) {
|
||||
if (TYPE(RARRAY(ary)->ptr[i]) == T_ARRAY) {
|
||||
n = flatten(ary, i, RARRAY(ary)->ptr[i], memo);
|
||||
i += n; lim += n;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
rb_ary_pop(memo);
|
||||
|
||||
return lim - idx - 1; /* returns number of increased items */
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_flatten_bang(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
long i;
|
||||
long i = 0;
|
||||
int mod = 0;
|
||||
VALUE flattening = Qnil;
|
||||
VALUE memo = Qnil;
|
||||
|
||||
rb_ary_modify(ary);
|
||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||
while (i<RARRAY(ary)->len) {
|
||||
VALUE ary2 = RARRAY(ary)->ptr[i];
|
||||
if (TYPE(ary2) == T_ARRAY) {
|
||||
if (ary == ary2) {
|
||||
ary2 = Qnil;
|
||||
} else {
|
||||
VALUE id;
|
||||
|
||||
if (NIL_P(flattening)) {
|
||||
flattening = rb_ary_new();
|
||||
}
|
||||
id = rb_obj_id(ary2);
|
||||
if (rb_ary_includes(flattening, id)) {
|
||||
rb_raise(rb_eArgError, "tried to flatten recursive array");
|
||||
}
|
||||
rb_ary_push(flattening, id);
|
||||
if (TYPE(ary2) == T_ARRAY) {
|
||||
if (NIL_P(memo)) {
|
||||
memo = rb_ary_new();
|
||||
}
|
||||
rb_ary_replace(ary, i--, 1, ary2);
|
||||
i += flatten(ary, i, ary2, memo);
|
||||
mod = 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (mod == 0) return Qnil;
|
||||
return ary;
|
||||
|
@ -1673,6 +1705,7 @@ Init_Array()
|
|||
rb_define_method(rb_cArray, "pop", rb_ary_pop, 0);
|
||||
rb_define_method(rb_cArray, "shift", rb_ary_shift, 0);
|
||||
rb_define_method(rb_cArray, "unshift", rb_ary_unshift_m, -1);
|
||||
rb_define_method(rb_cArray, "insert", rb_ary_insert, -1);
|
||||
rb_define_method(rb_cArray, "each", rb_ary_each, 0);
|
||||
rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
|
||||
rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
|
||||
|
|
20
bignum.c
20
bignum.c
|
@ -22,12 +22,12 @@ VALUE rb_cBignum;
|
|||
|
||||
#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
|
||||
typedef unsigned int BDIGIT;
|
||||
typedef unsigned long long BDIGIT_DBL;
|
||||
typedef unsigned LONG_LONG BDIGIT_DBL;
|
||||
typedef long long BDIGIT_DBL_SIGNED;
|
||||
#elif SIZEOF_INT*2 <= SIZEOF___INT64
|
||||
#elif SIZEOF_ING*2 <= SIZEOF_LONG
|
||||
typedef unsigned int BDIGIT;
|
||||
typedef unsigned __int64 BDIGIT_DBL;
|
||||
typedef __int64 BDIGIT_DBL_SIGNED;
|
||||
typedef unsigned long BDIGIT_DBL;
|
||||
typedef long long BDIGIT_DBL_SIGNED;
|
||||
#else
|
||||
typedef unsigned short BDIGIT;
|
||||
typedef unsigned long BDIGIT_DBL;
|
||||
|
@ -343,7 +343,9 @@ rb_str2inum(str, base)
|
|||
char *s;
|
||||
int len;
|
||||
|
||||
s = rb_str2cstr(str, &len);
|
||||
StringValue(str);
|
||||
s = RSTRING(str)->ptr;
|
||||
len = RSTRING(str)->len;
|
||||
if (s[len]) { /* no sentinel somehow */
|
||||
char *p = ALLOCA_N(char, len+1);
|
||||
|
||||
|
@ -471,7 +473,7 @@ rb_big2long(x)
|
|||
{
|
||||
unsigned long num = big2ulong(x, "int");
|
||||
|
||||
if ((long)num < 0 && (long)num != LONG_MIN) {
|
||||
if ((long)num < 0 && (RBIGNUM(x)->sign || (long)num != LONG_MIN)) {
|
||||
rb_raise(rb_eRangeError, "bignum too big to convert into `int'");
|
||||
}
|
||||
if (!RBIGNUM(x)->sign) return -(long)num;
|
||||
|
@ -917,10 +919,10 @@ bigdivrem(x, y, divp, modp)
|
|||
}
|
||||
if (modp) { /* just normalize remainder */
|
||||
*modp = rb_big_clone(z);
|
||||
zds = BDIGITS(*modp);
|
||||
while (!zds[ny-1]) ny--;
|
||||
if (dd) {
|
||||
zds = BDIGITS(*modp);
|
||||
while (ny-- && !zds[ny]) ;
|
||||
t2 = 0; i = ++ny;
|
||||
t2 = 0; i = ny;
|
||||
while(i--) {
|
||||
t2 = (t2 | zds[i]) >> dd;
|
||||
q = zds[i];
|
||||
|
|
87
class.c
87
class.c
|
@ -33,16 +33,6 @@ rb_class_new(super)
|
|||
return (VALUE)klass;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_singleton_class_new(super)
|
||||
VALUE super;
|
||||
{
|
||||
VALUE klass = rb_class_new(super);
|
||||
|
||||
FL_SET(klass, FL_SINGLETON);
|
||||
return klass;
|
||||
}
|
||||
|
||||
static int
|
||||
clone_method(mid, body, tbl)
|
||||
ID mid;
|
||||
|
@ -53,6 +43,47 @@ clone_method(mid, body, tbl)
|
|||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_clone(module)
|
||||
VALUE module;
|
||||
{
|
||||
NEWOBJ(clone, struct RClass);
|
||||
CLONESETUP(clone, module);
|
||||
|
||||
clone->super = RCLASS(module)->super;
|
||||
if (RCLASS(module)->iv_tbl) {
|
||||
clone->iv_tbl = st_copy(RCLASS(module)->iv_tbl);
|
||||
}
|
||||
if (RCLASS(module)->m_tbl) {
|
||||
clone->m_tbl = st_init_numtable();
|
||||
st_foreach(RCLASS(module)->m_tbl, clone_method, clone->m_tbl);
|
||||
}
|
||||
|
||||
return (VALUE)clone;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_dup(mod)
|
||||
VALUE mod;
|
||||
{
|
||||
VALUE dup = rb_mod_clone(mod);
|
||||
OBJSETUP(dup, RBASIC(mod)->klass, BUILTIN_TYPE(mod));
|
||||
if (FL_TEST(mod, FL_SINGLETON)) {
|
||||
FL_SET(dup, FL_SINGLETON);
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_singleton_class_new(super)
|
||||
VALUE super;
|
||||
{
|
||||
VALUE klass = rb_class_new(super);
|
||||
|
||||
FL_SET(klass, FL_SINGLETON);
|
||||
return klass;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_singleton_class_clone(klass)
|
||||
VALUE klass;
|
||||
|
@ -81,8 +112,12 @@ void
|
|||
rb_singleton_class_attached(klass, obj)
|
||||
VALUE klass, obj;
|
||||
{
|
||||
if (FL_TEST(klass, FL_SINGLETON))
|
||||
rb_iv_set(klass, "__attached__", obj);
|
||||
if (FL_TEST(klass, FL_SINGLETON)) {
|
||||
if (!RCLASS(klass)->iv_tbl) {
|
||||
RCLASS(klass)->iv_tbl = st_init_numtable();
|
||||
}
|
||||
st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
|
||||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -112,8 +147,11 @@ rb_define_class(name, super)
|
|||
ID id;
|
||||
|
||||
id = rb_intern(name);
|
||||
if (rb_const_defined(rb_cObject, id)) {
|
||||
klass = rb_const_get(rb_cObject, id);
|
||||
rb_raise(rb_eNameError, "%s is already defined", name);
|
||||
}
|
||||
klass = rb_define_class_id(id, super);
|
||||
|
||||
st_add_direct(rb_class_tbl, id, klass);
|
||||
|
||||
return klass;
|
||||
|
@ -129,6 +167,10 @@ rb_define_class_under(outer, name, super)
|
|||
ID id;
|
||||
|
||||
id = rb_intern(name);
|
||||
if (rb_const_defined_at(outer, id)) {
|
||||
klass = rb_const_get(outer, id);
|
||||
rb_raise(rb_eNameError, "%s is already defined", name);
|
||||
}
|
||||
klass = rb_define_class_id(id, super);
|
||||
rb_const_set(outer, id, klass);
|
||||
rb_set_class_path(klass, outer, name);
|
||||
|
@ -170,6 +212,12 @@ rb_define_module(name)
|
|||
ID id;
|
||||
|
||||
id = rb_intern(name);
|
||||
if (rb_const_defined(rb_cObject, id)) {
|
||||
module = rb_const_get(rb_cObject, id);
|
||||
if (TYPE(module) == T_MODULE)
|
||||
return module;
|
||||
rb_raise(rb_eTypeError, "%s is not a module", rb_class2name(CLASS_OF(module)));
|
||||
}
|
||||
module = rb_define_module_id(id);
|
||||
st_add_direct(rb_class_tbl, id, module);
|
||||
|
||||
|
@ -185,6 +233,13 @@ rb_define_module_under(outer, name)
|
|||
ID id;
|
||||
|
||||
id = rb_intern(name);
|
||||
if (rb_const_defined(outer, id)) {
|
||||
module = rb_const_get(rb_cObject, id);
|
||||
if (TYPE(module) == T_MODULE)
|
||||
return module;
|
||||
rb_raise(rb_eTypeError, "%s::%s is not a module",
|
||||
rb_class2name(outer), rb_class2name(CLASS_OF(module)));
|
||||
}
|
||||
module = rb_define_module_id(id);
|
||||
rb_const_set(outer, id, module);
|
||||
rb_set_class_path(module, outer, name);
|
||||
|
@ -222,6 +277,11 @@ rb_include_module(klass, module)
|
|||
VALUE p;
|
||||
int changed = 0;
|
||||
|
||||
rb_frozen_class_p(klass);
|
||||
if (!OBJ_TAINTED(klass)) {
|
||||
rb_secure(4);
|
||||
}
|
||||
|
||||
if (NIL_P(module)) return;
|
||||
if (klass == module) return;
|
||||
|
||||
|
@ -246,7 +306,6 @@ rb_include_module(klass, module)
|
|||
return;
|
||||
}
|
||||
}
|
||||
rb_frozen_class_p(klass);
|
||||
RCLASS(klass)->super = include_class_new(module, RCLASS(klass)->super);
|
||||
klass = RCLASS(klass)->super;
|
||||
module = RCLASS(module)->super;
|
||||
|
|
10
defines.h
10
defines.h
|
@ -12,6 +12,16 @@
|
|||
|
||||
#define RUBY
|
||||
|
||||
#if SIZEOF_LONG_LONG > 0
|
||||
# define HAVE_LONG_LONG
|
||||
# define LONG_LONG long long
|
||||
#elif SIZEOF___INT64 > 0
|
||||
# define HAVE_LONG_LONG
|
||||
# define LONG_LONG __int64
|
||||
# undef SIZEOF_LONG_LONG
|
||||
# define SIZEOF_LONG_LONG SIZEOF___INT64
|
||||
#endif
|
||||
|
||||
/* define RUBY_USE_EUC/SJIS for default kanji-code */
|
||||
#ifndef DEFAULT_KCODE
|
||||
#if defined(MSDOS) || defined(__CYGWIN__) || defined(__human68k__) || defined(__MACOS__) || defined(__EMX__) || defined(OS2) || defined(NT)
|
||||
|
|
15
dir.c
15
dir.c
|
@ -254,7 +254,7 @@ dir_initialize(dir, dirname)
|
|||
{
|
||||
DIR *dirp;
|
||||
|
||||
SafeStr(dirname);
|
||||
SafeStringValue(dirname);
|
||||
if (DATA_PTR(dir)) closedir(DATA_PTR(dir));
|
||||
DATA_PTR(dir) = NULL;
|
||||
dirp = opendir(RSTRING(dirname)->ptr);
|
||||
|
@ -425,7 +425,7 @@ dir_s_chdir(argc, argv, obj)
|
|||
|
||||
rb_secure(2);
|
||||
if (rb_scan_args(argc, argv, "01", &path) == 1) {
|
||||
SafeStr(path);
|
||||
SafeStringValue(path);
|
||||
dist = RSTRING(path)->ptr;
|
||||
}
|
||||
else {
|
||||
|
@ -467,7 +467,7 @@ dir_s_chroot(dir, path)
|
|||
{
|
||||
#if defined(HAVE_CHROOT) && !defined(__CHECKER__)
|
||||
rb_secure(2);
|
||||
SafeStr(path);
|
||||
SafeStringValue(path);
|
||||
|
||||
if (chroot(RSTRING(path)->ptr) == -1)
|
||||
rb_sys_fail(RSTRING(path)->ptr);
|
||||
|
@ -495,7 +495,7 @@ dir_s_mkdir(argc, argv, obj)
|
|||
mode = 0777;
|
||||
}
|
||||
|
||||
SafeStr(path);
|
||||
SafeStringValue(path);
|
||||
rb_secure(2);
|
||||
#if !defined(NT)
|
||||
if (mkdir(RSTRING(path)->ptr, mode) == -1)
|
||||
|
@ -512,7 +512,7 @@ static VALUE
|
|||
dir_s_rmdir(obj, dir)
|
||||
VALUE obj, dir;
|
||||
{
|
||||
SafeStr(dir);
|
||||
SafeStringValue(dir);
|
||||
rb_secure(2);
|
||||
if (rmdir(RSTRING(dir)->ptr) < 0)
|
||||
rb_sys_fail(RSTRING(dir)->ptr);
|
||||
|
@ -853,12 +853,13 @@ dir_s_glob(dir, str)
|
|||
int nest;
|
||||
VALUE ary = 0;
|
||||
|
||||
SafeStr(str);
|
||||
SafeStringValue(str);
|
||||
if (!rb_block_given_p()) {
|
||||
ary = rb_ary_new();
|
||||
}
|
||||
if (RSTRING(str)->len >= MAXPATHLEN)
|
||||
if (RSTRING(str)->len >= MAXPATHLEN) {
|
||||
buf = xmalloc(RSTRING(str)->len + 1);
|
||||
}
|
||||
|
||||
p = RSTRING(str)->ptr;
|
||||
pend = p + RSTRING(str)->len;
|
||||
|
|
21
dln.c
21
dln.c
|
@ -1214,7 +1214,7 @@ aix_loaderror(const char *pathname)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
void*
|
||||
dln_load(file)
|
||||
const char *file;
|
||||
{
|
||||
|
@ -1242,13 +1242,13 @@ dln_load(file)
|
|||
}
|
||||
/* Call the init code */
|
||||
(*init_fct)();
|
||||
return;
|
||||
return handle;
|
||||
#else
|
||||
#ifdef USE_DLN_A_OUT
|
||||
if (load(file) == -1) {
|
||||
goto failed;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
#else
|
||||
|
||||
char buf[MAXPATHLEN];
|
||||
|
@ -1274,11 +1274,12 @@ dln_load(file)
|
|||
}
|
||||
|
||||
if ((init_fct = (void(*)())dlsym(handle, buf)) == NULL) {
|
||||
dlclose(handle);
|
||||
goto failed;
|
||||
}
|
||||
/* Call the init code */
|
||||
(*init_fct)();
|
||||
return;
|
||||
return handle;
|
||||
}
|
||||
#endif /* USE_DLN_DLOPEN */
|
||||
|
||||
|
@ -1304,7 +1305,7 @@ dln_load(file)
|
|||
}
|
||||
}
|
||||
(*init_fct)();
|
||||
return;
|
||||
return (void*)lib;
|
||||
}
|
||||
#endif /* hpux */
|
||||
|
||||
|
@ -1321,7 +1322,7 @@ dln_load(file)
|
|||
aix_loaderror(file);
|
||||
}
|
||||
(*init_fct)();
|
||||
return;
|
||||
return (void*)init_fct;
|
||||
}
|
||||
#endif /* _AIX */
|
||||
|
||||
|
@ -1360,7 +1361,7 @@ dln_load(file)
|
|||
|
||||
init_fct = (void(*)())init_address;
|
||||
(*init_fct)();
|
||||
return;
|
||||
return (void*)init_address;
|
||||
}
|
||||
#else/* OPENSTEP dyld functions */
|
||||
{
|
||||
|
@ -1390,7 +1391,7 @@ dln_load(file)
|
|||
init_fct = NSAddressOfSymbol(NSLookupAndBindSymbol(buf));
|
||||
(*init_fct)();
|
||||
|
||||
return;
|
||||
return (void*)init_fct;
|
||||
}
|
||||
#endif /* rld or dyld */
|
||||
#endif
|
||||
|
@ -1438,7 +1439,7 @@ dln_load(file)
|
|||
|
||||
/* call module initialize function. */
|
||||
(*init_fct)();
|
||||
return;
|
||||
return (void*)img_id;
|
||||
}
|
||||
#endif /* __BEOS__*/
|
||||
|
||||
|
@ -1486,7 +1487,7 @@ dln_load(file)
|
|||
|
||||
init_fct = (void (*)())symAddr;
|
||||
(*init_fct)();
|
||||
return;
|
||||
return (void*)init_fct;
|
||||
}
|
||||
#endif /* __MACOS__ */
|
||||
|
||||
|
|
2
dln.h
2
dln.h
|
@ -27,5 +27,5 @@ char *dln_find_file _((const char*,const char*));
|
|||
extern char *dln_argv0;
|
||||
#endif
|
||||
|
||||
void dln_load _((const char*));
|
||||
void *dln_load _((const char*));
|
||||
#endif
|
||||
|
|
43
error.c
43
error.c
|
@ -262,6 +262,7 @@ VALUE rb_eRangeError;
|
|||
VALUE rb_eSecurityError;
|
||||
VALUE rb_eNotImpError;
|
||||
VALUE rb_eNoMemError;
|
||||
VALUE rb_eNoMethodError;
|
||||
|
||||
VALUE rb_eScriptError;
|
||||
VALUE rb_eNameError;
|
||||
|
@ -295,11 +296,8 @@ VALUE
|
|||
rb_exc_new3(etype, str)
|
||||
VALUE etype, str;
|
||||
{
|
||||
char *s;
|
||||
int len;
|
||||
|
||||
s = rb_str2cstr(str, &len);
|
||||
return rb_exc_new(etype, s, len);
|
||||
StringValue(str);
|
||||
return rb_exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -311,7 +309,7 @@ exc_initialize(argc, argv, exc)
|
|||
VALUE mesg;
|
||||
|
||||
if (rb_scan_args(argc, argv, "01", &mesg) == 1) {
|
||||
STR2CSTR(mesg); /* ensure mesg can be converted to String */
|
||||
StringValue(mesg); /* ensure mesg can be converted to String */
|
||||
}
|
||||
rb_iv_set(exc, "mesg", mesg);
|
||||
|
||||
|
@ -522,6 +520,29 @@ syserr_errno(self)
|
|||
return rb_iv_get(self, "errno");
|
||||
}
|
||||
|
||||
static VALUE
|
||||
syserr_eqq(self, exc)
|
||||
VALUE self, exc;
|
||||
{
|
||||
VALUE num;
|
||||
|
||||
if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) return Qfalse;
|
||||
if (self == rb_eSystemCallError) return Qtrue;
|
||||
|
||||
num = rb_iv_get(exc, "errno");
|
||||
if (NIL_P(num)) {
|
||||
VALUE klass = CLASS_OF(exc);
|
||||
|
||||
while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
|
||||
klass = (VALUE)RCLASS(klass)->super;
|
||||
}
|
||||
num = rb_const_get(klass, rb_intern("Errno"));
|
||||
}
|
||||
if (rb_const_get(self, rb_intern("Errno")) == num)
|
||||
return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
#ifdef __BEOS__
|
||||
static VALUE
|
||||
get_syserr(int i)
|
||||
|
@ -568,10 +589,11 @@ Init_Exception()
|
|||
rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal);
|
||||
|
||||
rb_eStandardError = rb_define_class("StandardError", rb_eException);
|
||||
rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
|
||||
rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
|
||||
rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
|
||||
rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
|
||||
rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
|
||||
rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
|
||||
rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
|
||||
rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
|
||||
rb_eNoMethodError = rb_define_class("NoMethodError", rb_eStandardError);
|
||||
|
||||
rb_eScriptError = rb_define_class("ScriptError", rb_eException);
|
||||
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
|
||||
|
@ -749,6 +771,7 @@ init_syserr()
|
|||
#endif
|
||||
rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
|
||||
rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
|
||||
rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
|
||||
|
||||
rb_mErrno = rb_define_module("Errno");
|
||||
#ifdef __BEOS__
|
||||
|
|
306
eval.c
306
eval.c
|
@ -128,33 +128,8 @@ int ruby_safe_level = 0;
|
|||
4 - no global (non-tainted) variable modification/no direct output
|
||||
*/
|
||||
|
||||
void
|
||||
rb_set_safe_level(level)
|
||||
int level;
|
||||
{
|
||||
if (level > ruby_safe_level) {
|
||||
ruby_safe_level = level;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
safe_getter()
|
||||
{
|
||||
return INT2FIX(ruby_safe_level);
|
||||
}
|
||||
|
||||
static void
|
||||
safe_setter(val)
|
||||
VALUE val;
|
||||
{
|
||||
int level = NUM2INT(val);
|
||||
|
||||
if (level < ruby_safe_level) {
|
||||
rb_raise(rb_eSecurityError, "tried to downgrade safe level from %d to %d",
|
||||
ruby_safe_level, level);
|
||||
}
|
||||
ruby_safe_level = level;
|
||||
}
|
||||
static VALUE safe_getter _((void));
|
||||
static void safe_setter _((VALUE val));
|
||||
|
||||
void
|
||||
rb_secure(level)
|
||||
|
@ -501,9 +476,9 @@ rb_attr(klass, id, read, write, ex)
|
|||
rb_clear_cache_by_id(id);
|
||||
rb_funcall(klass, added, 1, ID2SYM(id));
|
||||
}
|
||||
sprintf(buf, "%s=", name);
|
||||
id = rb_intern(buf);
|
||||
if (write) {
|
||||
sprintf(buf, "%s=", name);
|
||||
id = rb_intern(buf);
|
||||
rb_add_method(klass, id, NEW_ATTRSET(attriv), noex);
|
||||
rb_clear_cache_by_id(id);
|
||||
rb_funcall(klass, added, 1, ID2SYM(id));
|
||||
|
@ -820,6 +795,11 @@ static VALUE ruby_wrapper; /* security wrapper */
|
|||
|
||||
#define POP_CLASS() ruby_class = _class; }
|
||||
|
||||
static NODE *ruby_cref = 0;
|
||||
static NODE *top_cref;
|
||||
#define PUSH_CREF(c) ruby_cref = rb_node_newnode(NODE_CREF,(c),0,ruby_cref)
|
||||
#define POP_CREF() ruby_cref = ruby_cref->nd_next
|
||||
|
||||
#define PUSH_SCOPE() { \
|
||||
volatile int _vmode = scope_vmode; \
|
||||
struct SCOPE * volatile _old; \
|
||||
|
@ -937,7 +917,9 @@ error_print()
|
|||
eclass = CLASS_OF(ruby_errinfo);
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if (EXEC_TAG() == 0) {
|
||||
einfo = str2cstr(rb_obj_as_string(ruby_errinfo), &elen);
|
||||
VALUE e = rb_obj_as_string(ruby_errinfo);
|
||||
einfo = RSTRING(e)->ptr;
|
||||
elen = RSTRING(e)->len;
|
||||
}
|
||||
else {
|
||||
einfo = "";
|
||||
|
@ -1046,7 +1028,9 @@ ruby_init()
|
|||
rb_call_inits();
|
||||
ruby_class = rb_cObject;
|
||||
ruby_frame->self = ruby_top_self;
|
||||
ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,rb_cObject,0,0);
|
||||
top_cref = rb_node_newnode(NODE_CREF,rb_cObject,0,0);
|
||||
ruby_cref = top_cref;
|
||||
ruby_frame->cbase = (VALUE)ruby_cref;
|
||||
rb_define_global_const("TOPLEVEL_BINDING", rb_f_binding(ruby_top_self));
|
||||
#ifdef __MACOS__
|
||||
_macruby_init();
|
||||
|
@ -1276,6 +1260,7 @@ rb_eval_string_wrap(str, state)
|
|||
{
|
||||
int status;
|
||||
VALUE self = ruby_top_self;
|
||||
VALUE wrapper = ruby_wrapper;
|
||||
VALUE val;
|
||||
|
||||
PUSH_CLASS();
|
||||
|
@ -1287,6 +1272,7 @@ rb_eval_string_wrap(str, state)
|
|||
ruby_top_self = self;
|
||||
|
||||
POP_CLASS();
|
||||
ruby_wrapper = wrapper;
|
||||
if (state) {
|
||||
*state = status;
|
||||
}
|
||||
|
@ -1468,7 +1454,7 @@ rb_mod_nesting()
|
|||
VALUE ary = rb_ary_new();
|
||||
|
||||
while (cbase && cbase->nd_next) {
|
||||
rb_ary_push(ary, cbase->nd_clss);
|
||||
if (!NIL_P(cbase->nd_clss)) rb_ary_push(ary, cbase->nd_clss);
|
||||
cbase = cbase->nd_next;
|
||||
}
|
||||
return ary;
|
||||
|
@ -1481,11 +1467,11 @@ rb_mod_s_constants()
|
|||
VALUE ary = rb_ary_new();
|
||||
|
||||
while (cbase) {
|
||||
rb_mod_const_at(cbase->nd_clss, ary);
|
||||
if (!NIL_P(cbase->nd_clss)) rb_mod_const_at(cbase->nd_clss, ary);
|
||||
cbase = cbase->nd_next;
|
||||
}
|
||||
|
||||
rb_mod_const_of(ruby_cbase, ary);
|
||||
if (!NIL_P(ruby_cbase)) rb_mod_const_of(ruby_cbase, ary);
|
||||
return ary;
|
||||
}
|
||||
|
||||
|
@ -1606,6 +1592,23 @@ rb_mod_alias_method(mod, newname, oldname)
|
|||
return mod;
|
||||
}
|
||||
|
||||
static NODE*
|
||||
copy_node_scope(node, rval)
|
||||
NODE *node;
|
||||
VALUE rval;
|
||||
{
|
||||
NODE *copy = rb_node_newnode(NODE_SCOPE,0,rval,node->nd_next);
|
||||
|
||||
if (node->nd_tbl) {
|
||||
copy->nd_tbl = ALLOC_N(ID, node->nd_tbl[0]+1);
|
||||
MEMCPY(copy->nd_tbl, node->nd_tbl, ID, node->nd_tbl[0]+1);
|
||||
}
|
||||
else {
|
||||
copy->nd_tbl = 0;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
#ifdef C_ALLOCA
|
||||
# define TMP_PROTECT NODE * volatile tmp__protect_tmp=0
|
||||
# define TMP_ALLOC(n) \
|
||||
|
@ -2371,9 +2374,11 @@ rb_eval(self, n)
|
|||
POP_TAG();
|
||||
if (node->nd_ensr) {
|
||||
VALUE retval = prot_tag->retval; /* save retval */
|
||||
VALUE errinfo = ruby_errinfo;
|
||||
|
||||
rb_eval(self, node->nd_ensr);
|
||||
return_value(retval);
|
||||
ruby_errinfo = errinfo;
|
||||
}
|
||||
if (state) JUMP_TAG(state);
|
||||
break;
|
||||
|
@ -2534,6 +2539,7 @@ rb_eval(self, n)
|
|||
case NODE_SCOPE:
|
||||
{
|
||||
struct FRAME frame;
|
||||
NODE *saved_cref = 0;
|
||||
|
||||
frame = *ruby_frame;
|
||||
frame.tmp = ruby_frame;
|
||||
|
@ -2541,7 +2547,11 @@ rb_eval(self, n)
|
|||
|
||||
PUSH_SCOPE();
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if (node->nd_rval) ruby_frame->cbase = node->nd_rval;
|
||||
if (node->nd_rval) {
|
||||
saved_cref = ruby_cref;
|
||||
ruby_cref = (NODE*)node->nd_rval;
|
||||
ruby_frame->cbase = node->nd_rval;
|
||||
}
|
||||
if (node->nd_tbl) {
|
||||
VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1);
|
||||
*vars++ = (VALUE)node;
|
||||
|
@ -2559,6 +2569,8 @@ rb_eval(self, n)
|
|||
POP_TAG();
|
||||
POP_SCOPE();
|
||||
ruby_frame = frame.tmp;
|
||||
if (saved_cref)
|
||||
ruby_cref = saved_cref;
|
||||
if (state) JUMP_TAG(state);
|
||||
}
|
||||
break;
|
||||
|
@ -2897,7 +2909,7 @@ rb_eval(self, n)
|
|||
|
||||
case NODE_DEFN:
|
||||
if (node->nd_defn) {
|
||||
NODE *body;
|
||||
NODE *body, *defn;
|
||||
VALUE origin;
|
||||
int noex;
|
||||
|
||||
|
@ -2911,11 +2923,6 @@ rb_eval(self, n)
|
|||
rb_warn("redefining `%s' may cause serious problem",
|
||||
rb_id2name(node->nd_mid));
|
||||
}
|
||||
if (node->nd_defn->nd_rval &&
|
||||
((NODE*)node->nd_defn->nd_rval)->nd_clss != ruby_class) {
|
||||
node->nd_defn->nd_rval =
|
||||
(VALUE)rb_node_newnode(NODE_CREF,ruby_class,0, node->nd_defn->nd_rval);
|
||||
}
|
||||
rb_frozen_class_p(ruby_class);
|
||||
body = search_method(ruby_class, node->nd_mid, &origin);
|
||||
if (body){
|
||||
|
@ -2944,11 +2951,13 @@ rb_eval(self, n)
|
|||
if (body && origin == ruby_class && body->nd_noex & NOEX_UNDEF) {
|
||||
noex |= NOEX_UNDEF;
|
||||
}
|
||||
rb_add_method(ruby_class, node->nd_mid, node->nd_defn, noex);
|
||||
|
||||
defn = copy_node_scope(node->nd_defn, ruby_cref);
|
||||
rb_add_method(ruby_class, node->nd_mid, defn, noex);
|
||||
rb_clear_cache_by_id(node->nd_mid);
|
||||
if (scope_vmode == SCOPE_MODFUNC) {
|
||||
rb_add_method(rb_singleton_class(ruby_class),
|
||||
node->nd_mid, node->nd_defn, NOEX_PUBLIC);
|
||||
node->nd_mid, defn, NOEX_PUBLIC);
|
||||
rb_funcall(ruby_class, singleton_added, 1, ID2SYM(node->nd_mid));
|
||||
}
|
||||
if (FL_TEST(ruby_class, FL_SINGLETON)) {
|
||||
|
@ -2966,7 +2975,7 @@ rb_eval(self, n)
|
|||
if (node->nd_defn) {
|
||||
VALUE recv = rb_eval(self, node->nd_recv);
|
||||
VALUE klass;
|
||||
NODE *body = 0;
|
||||
NODE *body = 0, *defn;
|
||||
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(recv)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure; can't define singleton method");
|
||||
|
@ -2978,11 +2987,6 @@ rb_eval(self, n)
|
|||
rb_class2name(CLASS_OF(recv)));
|
||||
}
|
||||
|
||||
if (node->nd_defn->nd_rval &&
|
||||
((NODE*)node->nd_defn->nd_rval)->nd_clss != ruby_class) {
|
||||
node->nd_defn->nd_rval =
|
||||
(VALUE)rb_node_newnode(NODE_CREF,ruby_class,0, node->nd_defn->nd_rval);
|
||||
}
|
||||
if (OBJ_FROZEN(recv)) rb_error_frozen("object");
|
||||
klass = rb_singleton_class(recv);
|
||||
if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) {
|
||||
|
@ -2993,7 +2997,9 @@ rb_eval(self, n)
|
|||
rb_warning("redefine %s", rb_id2name(node->nd_mid));
|
||||
}
|
||||
}
|
||||
rb_add_method(klass, node->nd_mid, node->nd_defn,
|
||||
defn = copy_node_scope(node->nd_defn, ruby_cref);
|
||||
defn->nd_rval = (VALUE)ruby_cref;
|
||||
rb_add_method(klass, node->nd_mid, defn,
|
||||
NOEX_PUBLIC|(body?body->nd_noex&NOEX_UNDEF:0));
|
||||
rb_clear_cache_by_id(node->nd_mid);
|
||||
rb_funcall(recv, singleton_added, 1, ID2SYM(node->nd_mid));
|
||||
|
@ -3191,16 +3197,11 @@ module_setup(module, n)
|
|||
frame.tmp = ruby_frame;
|
||||
ruby_frame = &frame;
|
||||
|
||||
/* fill c-ref */
|
||||
node->nd_clss = module;
|
||||
node = node->nd_body;
|
||||
|
||||
PUSH_CLASS();
|
||||
ruby_class = module;
|
||||
PUSH_SCOPE();
|
||||
PUSH_VARS();
|
||||
|
||||
if (node->nd_rval) ruby_frame->cbase = node->nd_rval;
|
||||
if (node->nd_tbl) {
|
||||
VALUE *vars = TMP_ALLOC(node->nd_tbl[0]+1);
|
||||
*vars++ = (VALUE)node;
|
||||
|
@ -3213,6 +3214,8 @@ module_setup(module, n)
|
|||
ruby_scope->local_tbl = 0;
|
||||
}
|
||||
|
||||
PUSH_CREF(module);
|
||||
ruby_frame->cbase = (VALUE)ruby_cref;
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
if (trace_func) {
|
||||
|
@ -3223,6 +3226,7 @@ module_setup(module, n)
|
|||
result = rb_eval(ruby_class, node->nd_next);
|
||||
}
|
||||
POP_TAG();
|
||||
POP_CREF();
|
||||
POP_VARS();
|
||||
POP_SCOPE();
|
||||
POP_CLASS();
|
||||
|
@ -3362,10 +3366,13 @@ rb_longjmp(tag, mesg)
|
|||
|
||||
if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo)
|
||||
&& !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
|
||||
VALUE e = ruby_errinfo;
|
||||
|
||||
StringValue(e);
|
||||
fprintf(stderr, "Exception `%s' at %s:%d - %s\n",
|
||||
rb_class2name(CLASS_OF(ruby_errinfo)),
|
||||
ruby_sourcefile, ruby_sourceline,
|
||||
STR2CSTR(ruby_errinfo));
|
||||
RSTRING(e)->ptr);
|
||||
}
|
||||
|
||||
rb_trap_restore_mask();
|
||||
|
@ -3845,7 +3852,7 @@ handle_rescue(self, node)
|
|||
if (!rb_obj_is_kind_of(argv[0], rb_cModule)) {
|
||||
rb_raise(rb_eTypeError, "class or module required for rescue clause");
|
||||
}
|
||||
if (rb_obj_is_kind_of(ruby_errinfo, argv[0])) return 1;
|
||||
if (rb_funcall(*argv, eqq, 1, ruby_errinfo)) return 1;
|
||||
argv++;
|
||||
}
|
||||
return 0;
|
||||
|
@ -3999,7 +4006,8 @@ rb_f_missing(argc, argv, obj)
|
|||
VALUE *argv;
|
||||
VALUE obj;
|
||||
{
|
||||
ID id;
|
||||
ID id;
|
||||
VALUE exc = rb_eNoMethodError;
|
||||
volatile VALUE d = 0;
|
||||
char *format = 0;
|
||||
char *desc = "";
|
||||
|
@ -4042,6 +4050,7 @@ rb_f_missing(argc, argv, obj)
|
|||
|
||||
if (('a' <= mname[0] && mname[0] <= 'z') || mname[0] == '_') {
|
||||
format = "undefined local variable or method `%s' for %s%s%s";
|
||||
exc = rb_eNameError;
|
||||
}
|
||||
}
|
||||
if (!format) {
|
||||
|
@ -4058,7 +4067,7 @@ rb_f_missing(argc, argv, obj)
|
|||
PUSH_FRAME(); /* fake frame */
|
||||
*ruby_frame = *_frame.prev->prev;
|
||||
|
||||
rb_raise(rb_eNameError, format, rb_id2name(id),
|
||||
rb_raise(exc, format, rb_id2name(id),
|
||||
desc, desc[0]=='#'?"":":",
|
||||
desc[0]=='#'?"":rb_class2name(CLASS_OF(obj)));
|
||||
POP_FRAME();
|
||||
|
@ -4305,14 +4314,19 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
|
|||
result = proc_call(body->nd_cval, rb_ary_new4(argc, argv));
|
||||
break;
|
||||
|
||||
default:
|
||||
case NODE_SCOPE:
|
||||
{
|
||||
int state;
|
||||
VALUE *local_vars; /* OK */
|
||||
NODE *saved_cref = 0;
|
||||
|
||||
PUSH_SCOPE();
|
||||
|
||||
if (body->nd_rval) ruby_frame->cbase = body->nd_rval;
|
||||
if (body->nd_rval) {
|
||||
saved_cref = ruby_cref;
|
||||
ruby_cref = (NODE*)body->nd_rval;
|
||||
ruby_frame->cbase = body->nd_rval;
|
||||
}
|
||||
if (body->nd_tbl) {
|
||||
local_vars = TMP_ALLOC(body->nd_tbl[0]+1);
|
||||
*local_vars++ = (VALUE)body;
|
||||
|
@ -4405,6 +4419,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
|
|||
POP_TAG();
|
||||
POP_VARS();
|
||||
POP_SCOPE();
|
||||
ruby_cref = saved_cref;
|
||||
if (trace_func) {
|
||||
char *file = ruby_frame->prev->file;
|
||||
int line = ruby_frame->prev->line;
|
||||
|
@ -4420,7 +4435,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
|
|||
|
||||
case TAG_RETRY:
|
||||
if (rb_block_given_p()) {
|
||||
break;
|
||||
JUMP_TAG(state);
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
|
@ -4428,6 +4443,11 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
|
|||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
rb_bug("unknown node type %d", nd_type(body));
|
||||
break;
|
||||
}
|
||||
POP_FRAME();
|
||||
POP_ITER();
|
||||
|
@ -4851,17 +4871,17 @@ rb_f_eval(argc, argv, self)
|
|||
|
||||
rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
|
||||
if (argc >= 3) {
|
||||
file = STR2CSTR(vfile);
|
||||
file = StringValuePtr(vfile);
|
||||
}
|
||||
if (argc >= 4) {
|
||||
line = NUM2INT(vline);
|
||||
}
|
||||
|
||||
if (ruby_safe_level >= 4) {
|
||||
src = rb_str_to_str(src);
|
||||
StringValue(src);
|
||||
}
|
||||
else {
|
||||
SafeStr(src);
|
||||
SafeStringValue(src);
|
||||
}
|
||||
if (NIL_P(scope) && ruby_frame->prev) {
|
||||
struct FRAME *prev;
|
||||
|
@ -4900,6 +4920,7 @@ exec_under(func, under, args)
|
|||
if (ruby_cbase != under) {
|
||||
ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,under,0,ruby_frame->cbase);
|
||||
}
|
||||
PUSH_CREF(under);
|
||||
|
||||
mode = scope_vmode;
|
||||
SCOPE_SET(SCOPE_PUBLIC);
|
||||
|
@ -4908,6 +4929,7 @@ exec_under(func, under, args)
|
|||
val = (*func)(args);
|
||||
}
|
||||
POP_TAG();
|
||||
POP_CREF();
|
||||
SCOPE_SET(mode);
|
||||
POP_FRAME();
|
||||
POP_CLASS();
|
||||
|
@ -4933,10 +4955,10 @@ eval_under(under, self, src, file, line)
|
|||
VALUE args[4];
|
||||
|
||||
if (ruby_safe_level >= 4) {
|
||||
src = rb_str_to_str(src);
|
||||
StringValue(src);
|
||||
}
|
||||
else {
|
||||
SafeStr(src);
|
||||
SafeStringValue(src);
|
||||
}
|
||||
args[0] = self;
|
||||
args[1] = src;
|
||||
|
@ -4983,8 +5005,6 @@ static VALUE
|
|||
yield_under(under, self)
|
||||
VALUE under, self;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(self))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't eval");
|
||||
return exec_under(yield_under_i, under, self);
|
||||
}
|
||||
|
||||
|
@ -5010,17 +5030,20 @@ specific_eval(argc, argv, klass, self)
|
|||
}
|
||||
else {
|
||||
if (ruby_safe_level >= 4) {
|
||||
src = rb_str_to_str(src);
|
||||
StringValue(src);
|
||||
}
|
||||
else {
|
||||
SafeStr(src);
|
||||
SafeStringValue(src);
|
||||
}
|
||||
if (argc > 3) {
|
||||
rb_raise(rb_eArgError, "wrong # of arguments: %s(src) or %s{..}",
|
||||
rb_id2name(ruby_frame->last_func),
|
||||
rb_id2name(ruby_frame->last_func));
|
||||
}
|
||||
if (argc > 1) file = STR2CSTR(argv[1]);
|
||||
if (argc > 1) {
|
||||
src = argv[1];
|
||||
file = StringValuePtr(src);
|
||||
}
|
||||
if (argc > 2) line = NUM2INT(argv[2]);
|
||||
}
|
||||
return eval_under(klass, self, argv[0], file, line);
|
||||
|
@ -5066,13 +5089,14 @@ rb_load(fname, wrap)
|
|||
volatile ID last_func;
|
||||
volatile VALUE wrapper = 0;
|
||||
volatile VALUE self = ruby_top_self;
|
||||
NODE *saved_cref = ruby_cref;
|
||||
TMP_PROTECT;
|
||||
|
||||
if (wrap) {
|
||||
fname = rb_str_to_str(fname);
|
||||
StringValue(fname);
|
||||
}
|
||||
else {
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
}
|
||||
file = rb_find_file(RSTRING(fname)->ptr);
|
||||
if (!file) {
|
||||
|
@ -5083,6 +5107,7 @@ rb_load(fname, wrap)
|
|||
PUSH_VARS();
|
||||
PUSH_CLASS();
|
||||
wrapper = ruby_wrapper;
|
||||
ruby_cref = top_cref;
|
||||
if (!wrap) {
|
||||
rb_secure(4); /* should alter global state */
|
||||
ruby_class = rb_cObject;
|
||||
|
@ -5093,6 +5118,7 @@ rb_load(fname, wrap)
|
|||
ruby_class = ruby_wrapper = rb_module_new();
|
||||
self = rb_obj_clone(ruby_top_self);
|
||||
rb_extend_object(self, ruby_class);
|
||||
PUSH_CREF(ruby_wrapper);
|
||||
}
|
||||
PUSH_FRAME();
|
||||
ruby_frame->last_func = 0;
|
||||
|
@ -5100,19 +5126,8 @@ rb_load(fname, wrap)
|
|||
ruby_frame->self = self;
|
||||
ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_class,0,0);
|
||||
PUSH_SCOPE();
|
||||
if (ruby_class == rb_cObject && top_scope->local_tbl) {
|
||||
int len = top_scope->local_tbl[0]+1;
|
||||
ID *tbl = ALLOC_N(ID, len);
|
||||
VALUE *vars = TMP_ALLOC(len);
|
||||
*vars++ = 0;
|
||||
MEMCPY(tbl, top_scope->local_tbl, ID, len);
|
||||
MEMCPY(vars, top_scope->local_vars, VALUE, len-1);
|
||||
ruby_scope->local_tbl = tbl; /* copy toplevel scope */
|
||||
ruby_scope->local_vars = vars; /* will not alter toplevel variables */
|
||||
}
|
||||
/* default visibility is private at loading toplevel */
|
||||
SCOPE_SET(SCOPE_PRIVATE);
|
||||
|
||||
PUSH_TAG(PROT_NONE);
|
||||
state = EXEC_TAG();
|
||||
last_func = ruby_frame->last_func;
|
||||
|
@ -5135,6 +5150,7 @@ rb_load(fname, wrap)
|
|||
free(ruby_scope->local_tbl);
|
||||
}
|
||||
POP_TAG();
|
||||
ruby_cref = saved_cref;
|
||||
POP_SCOPE();
|
||||
POP_FRAME();
|
||||
POP_CLASS();
|
||||
|
@ -5177,6 +5193,7 @@ rb_f_load(argc, argv)
|
|||
return Qtrue;
|
||||
}
|
||||
|
||||
VALUE ruby_dln_librefs;
|
||||
static VALUE rb_features;
|
||||
static st_table *loading_tbl;
|
||||
|
||||
|
@ -5192,7 +5209,8 @@ rb_feature_p(feature, wait)
|
|||
p = RARRAY(rb_features)->ptr;
|
||||
pend = p + RARRAY(rb_features)->len;
|
||||
while (p < pend) {
|
||||
f = STR2CSTR(*p);
|
||||
VALUE v = *p;
|
||||
f = StringValuePtr(v);
|
||||
if (strcmp(f, feature) == 0) {
|
||||
goto load_wait;
|
||||
}
|
||||
|
@ -5266,7 +5284,7 @@ rb_f_require(obj, fname)
|
|||
int state;
|
||||
volatile int safe = ruby_safe_level;
|
||||
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (rb_feature_p(RSTRING(fname)->ptr, Qtrue))
|
||||
return Qfalse;
|
||||
ext = strrchr(RSTRING(fname)->ptr, '.');
|
||||
|
@ -5344,9 +5362,12 @@ rb_f_require(obj, fname)
|
|||
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
void *handle;
|
||||
|
||||
load = rb_str_new2(file);
|
||||
file = RSTRING(load)->ptr;
|
||||
dln_load(file);
|
||||
handle = dln_load(file);
|
||||
rb_ary_push(ruby_dln_librefs, INT2NUM((long)handle));
|
||||
}
|
||||
POP_TAG();
|
||||
if (state) JUMP_TAG(state);
|
||||
|
@ -5525,6 +5546,13 @@ rb_mod_modfunc(argc, argv, module)
|
|||
return module;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_included(module, include)
|
||||
VALUE module, include;
|
||||
{
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_append_features(module, include)
|
||||
VALUE module, include;
|
||||
|
@ -5553,6 +5581,7 @@ rb_mod_include(argc, argv, module)
|
|||
for (i=0; i<argc; i++) {
|
||||
Check_Type(argv[i], T_MODULE);
|
||||
rb_funcall(argv[i], rb_intern("append_features"), 1, module);
|
||||
rb_funcall(argv[i], rb_intern("included"), 1, module);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
@ -5849,6 +5878,7 @@ Init_eval()
|
|||
rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
|
||||
rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
|
||||
rb_define_private_method(rb_cModule, "include", rb_mod_include, -1);
|
||||
rb_define_private_method(rb_cModule, "included", rb_mod_included, 1);
|
||||
rb_define_private_method(rb_cModule, "public", rb_mod_public, -1);
|
||||
rb_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
|
||||
rb_define_private_method(rb_cModule, "private", rb_mod_private, -1);
|
||||
|
@ -5914,6 +5944,9 @@ Init_load()
|
|||
rb_define_global_function("require", rb_f_require, 1);
|
||||
rb_define_global_function("autoload", rb_f_autoload, 2);
|
||||
rb_global_variable(&ruby_wrapper);
|
||||
|
||||
ruby_dln_librefs = rb_ary_new();
|
||||
rb_global_variable(&ruby_dln_librefs);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5982,6 +6015,7 @@ blk_copy_prev(block)
|
|||
struct BLOCK *block;
|
||||
{
|
||||
struct BLOCK *tmp;
|
||||
struct RVarmap* vars;
|
||||
|
||||
while (block->prev) {
|
||||
tmp = ALLOC_N(struct BLOCK, 1);
|
||||
|
@ -5993,6 +6027,12 @@ blk_copy_prev(block)
|
|||
}
|
||||
scope_dup(tmp->scope);
|
||||
tmp->tag->flags |= BLOCK_DYNAMIC;
|
||||
|
||||
for (vars = tmp->dyna_vars; vars; vars = vars->next) {
|
||||
if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
|
||||
FL_SET(vars, DVAR_DONT_RECYCLE);
|
||||
}
|
||||
|
||||
block->prev = tmp;
|
||||
block = tmp;
|
||||
}
|
||||
|
@ -6316,8 +6356,10 @@ proc_eq(self, other)
|
|||
{
|
||||
struct BLOCK *data, *data2;
|
||||
|
||||
if (self == other) return Qtrue;
|
||||
if (TYPE(other) != T_DATA) return Qfalse;
|
||||
if (RDATA(other)->dmark != (RUBY_DATA_FUNC)blk_mark) Qfalse;
|
||||
if (RDATA(other)->dmark != (RUBY_DATA_FUNC)blk_mark) return Qfalse;
|
||||
if (CLASS_OF(self) != CLASS_OF(other)) return Qfalse;
|
||||
Data_Get_Struct(self, struct BLOCK, data);
|
||||
Data_Get_Struct(other, struct BLOCK, data2);
|
||||
if (data->tag == data2->tag) return Qtrue;
|
||||
|
@ -6380,6 +6422,8 @@ block_pass(self, node)
|
|||
state = EXEC_TAG();
|
||||
if (state == 0) {
|
||||
proc_set_safe_level(block);
|
||||
if (safe > ruby_safe_level)
|
||||
ruby_safe_level = safe;
|
||||
result = rb_eval(self, node->nd_iter);
|
||||
}
|
||||
POP_TAG();
|
||||
|
@ -6551,8 +6595,8 @@ method_call(argc, argv, method)
|
|||
Data_Get_Struct(method, struct METHOD, data);
|
||||
PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if (OBJ_TAINTED(method)) {
|
||||
if (ruby_safe_level < 4) ruby_safe_level = 4;
|
||||
if (OBJ_TAINTED(method) && ruby_safe_level < 4) {
|
||||
ruby_safe_level = 4;
|
||||
}
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
result = rb_call0(data->klass,data->recv,data->id,argc,argv,data->body,0);
|
||||
|
@ -6836,6 +6880,7 @@ struct thread {
|
|||
struct tag *tag;
|
||||
VALUE klass;
|
||||
VALUE wrapper;
|
||||
NODE *cref;
|
||||
|
||||
int flags; /* misc. states (vmode/rb_trap_immediate/raised) */
|
||||
|
||||
|
@ -6879,6 +6924,37 @@ struct thread {
|
|||
#define FOREACH_THREAD(x) FOREACH_THREAD_FROM(curr_thread,x)
|
||||
#define END_FOREACH(x) END_FOREACH_FROM(curr_thread,x)
|
||||
|
||||
/* $SAFE accessor */
|
||||
void
|
||||
rb_set_safe_level(level)
|
||||
int level;
|
||||
{
|
||||
if (level > ruby_safe_level) {
|
||||
ruby_safe_level = level;
|
||||
curr_thread->safe = level;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
safe_getter()
|
||||
{
|
||||
return INT2NUM(ruby_safe_level);
|
||||
}
|
||||
|
||||
static void
|
||||
safe_setter(val)
|
||||
VALUE val;
|
||||
{
|
||||
int level = NUM2INT(val);
|
||||
|
||||
if (level < ruby_safe_level) {
|
||||
rb_raise(rb_eSecurityError, "tried to downgrade safe level from %d to %d",
|
||||
ruby_safe_level, level);
|
||||
}
|
||||
ruby_safe_level = level;
|
||||
curr_thread->safe = level;
|
||||
}
|
||||
|
||||
/* Return the current time as a floating-point number */
|
||||
static double
|
||||
timeofday()
|
||||
|
@ -6904,6 +6980,7 @@ thread_mark(th)
|
|||
|
||||
rb_gc_mark(th->klass);
|
||||
rb_gc_mark(th->wrapper);
|
||||
rb_gc_mark((VALUE)th->cref);
|
||||
|
||||
rb_gc_mark((VALUE)th->scope);
|
||||
rb_gc_mark((VALUE)th->dyna_vars);
|
||||
|
@ -7021,6 +7098,7 @@ rb_thread_save_context(th)
|
|||
th->scope = ruby_scope;
|
||||
th->klass = ruby_class;
|
||||
th->wrapper = ruby_wrapper;
|
||||
th->cref = ruby_cref;
|
||||
th->dyna_vars = ruby_dyna_vars;
|
||||
th->block = ruby_block;
|
||||
th->flags &= THREAD_FLAGS_MASK;
|
||||
|
@ -7111,6 +7189,7 @@ rb_thread_restore_context(th, exit)
|
|||
ruby_scope = th->scope;
|
||||
ruby_class = th->klass;
|
||||
ruby_wrapper = th->wrapper;
|
||||
ruby_cref = th->cref;
|
||||
ruby_dyna_vars = th->dyna_vars;
|
||||
ruby_block = th->block;
|
||||
scope_vmode = th->flags&SCOPE_MASK;
|
||||
|
@ -7327,10 +7406,14 @@ rb_thread_schedule()
|
|||
if (th_delay <= 0.0) {
|
||||
th->status = THREAD_RUNNABLE;
|
||||
found = 1;
|
||||
} else if (th_delay < delay) {
|
||||
}
|
||||
else if (th_delay < delay) {
|
||||
delay = th_delay;
|
||||
need_select = 1;
|
||||
}
|
||||
else if (th->delay == DELAY_INFTY) {
|
||||
need_select = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
END_FOREACH_FROM(curr, th);
|
||||
|
@ -7511,7 +7594,14 @@ rb_thread_wait_for(time)
|
|||
n = select(0, 0, 0, 0, &time);
|
||||
TRAP_END;
|
||||
if (n == 0) return;
|
||||
|
||||
if (n < 0) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
return;
|
||||
default:
|
||||
rb_sys_fail("sleep");
|
||||
}
|
||||
}
|
||||
#ifndef linux
|
||||
d = limit - timeofday();
|
||||
|
||||
|
@ -7915,6 +8005,7 @@ rb_thread_abort_exc_set(thread, val)
|
|||
th->scope = 0;\
|
||||
th->klass = 0;\
|
||||
th->wrapper = 0;\
|
||||
th->cref = ruby_cref;\
|
||||
th->dyna_vars = ruby_dyna_vars;\
|
||||
th->block = 0;\
|
||||
th->iter = 0;\
|
||||
|
@ -8004,6 +8095,7 @@ rb_thread_start_0(fn, arg, th_arg)
|
|||
{
|
||||
volatile rb_thread_t th = th_arg;
|
||||
volatile VALUE thread = th->thread;
|
||||
struct BLOCK* saved_block = 0;
|
||||
enum thread_status status;
|
||||
int state;
|
||||
|
||||
|
@ -8021,7 +8113,11 @@ rb_thread_start_0(fn, arg, th_arg)
|
|||
#endif
|
||||
|
||||
if (ruby_block) { /* should nail down higher scopes */
|
||||
blk_copy_prev(ruby_block);
|
||||
struct BLOCK dummy;
|
||||
|
||||
dummy.prev = ruby_block;
|
||||
blk_copy_prev(&dummy);
|
||||
saved_block = ruby_block = dummy.prev;
|
||||
}
|
||||
scope_dup(ruby_scope);
|
||||
FL_SET(ruby_scope, SCOPE_SHARED);
|
||||
|
@ -8048,6 +8144,16 @@ rb_thread_start_0(fn, arg, th_arg)
|
|||
}
|
||||
POP_TAG();
|
||||
status = th->status;
|
||||
|
||||
while (saved_block) {
|
||||
struct BLOCK *tmp = saved_block;
|
||||
|
||||
if (tmp->frame.argc > 0)
|
||||
free(tmp->frame.argv);
|
||||
saved_block = tmp->prev;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
if (th == main_thread) ruby_stop(state);
|
||||
rb_thread_remove(th);
|
||||
if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
|
||||
|
@ -8059,11 +8165,15 @@ rb_thread_start_0(fn, arg, th_arg)
|
|||
}
|
||||
else if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
|
||||
if (th->safe >= 4) {
|
||||
rb_raise(rb_eSecurityError, "Insecure exit at level %d",
|
||||
ruby_safe_level);
|
||||
char buf[32];
|
||||
|
||||
sprintf(buf, "Insecure exit at level %d", th->safe);
|
||||
th->errinfo = rb_exc_new2(rb_eSecurityError, buf);
|
||||
}
|
||||
else {
|
||||
/* delegate exception to main_thread */
|
||||
rb_thread_raise(1, &ruby_errinfo, main_thread);
|
||||
}
|
||||
/* delegate exception to main_thread */
|
||||
rb_thread_raise(1, &ruby_errinfo, main_thread);
|
||||
}
|
||||
else if (th->safe < 4 &&
|
||||
(thread_abort || th->abort || RTEST(ruby_debug))) {
|
||||
|
|
|
@ -347,7 +347,7 @@ curses_addstr(obj, str)
|
|||
VALUE str;
|
||||
{
|
||||
if (!NIL_P(str)) {
|
||||
addstr(STR2CSTR(str));
|
||||
addstr(StringValuePtr(str));
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
@ -711,7 +711,7 @@ window_addstr(obj, str)
|
|||
struct windata *winp;
|
||||
|
||||
GetWINDOW(obj, winp);
|
||||
waddstr(winp->window, STR2CSTR(str));
|
||||
waddstr(winp->window, StringValuePtr(str));
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ fdbm_initialize(argc, argv, obj)
|
|||
else {
|
||||
mode = NUM2INT(vmode);
|
||||
}
|
||||
Check_SafeStr(file);
|
||||
SafeStringValue(file);
|
||||
|
||||
dbm = 0;
|
||||
if (mode >= 0) {
|
||||
|
@ -150,7 +150,7 @@ fdbm_fetch(obj, keystr, ifnone)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
|
@ -196,7 +196,7 @@ fdbm_index(obj, valstr)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
Check_Type(valstr, T_STRING);
|
||||
StringValue(valstr);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
||||
|
@ -238,7 +238,7 @@ fdbm_delete(obj, keystr)
|
|||
DBM *dbm;
|
||||
|
||||
rb_secure(4);
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
|
@ -273,14 +273,15 @@ fdbm_shift(obj)
|
|||
rb_secure(4);
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
dbmp->di_size = -1;
|
||||
|
||||
key = dbm_firstkey(dbm);
|
||||
if (!key.dptr) return Qnil;
|
||||
val = dbm_fetch(dbm, key);
|
||||
dbm_delete(dbm, key);
|
||||
|
||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
dbm_delete(dbm, key);
|
||||
|
||||
return rb_assoc_new(keystr, valstr);
|
||||
}
|
||||
|
||||
|
@ -292,20 +293,35 @@ fdbm_delete_if(obj)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
VALUE keystr, valstr;
|
||||
VALUE ret, ary = rb_ary_new();
|
||||
int i, status = 0, n;
|
||||
|
||||
rb_secure(4);
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
n = dbmp->di_size;
|
||||
dbmp->di_size = -1;
|
||||
|
||||
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
|
||||
val = dbm_fetch(dbm, key);
|
||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
if (RTEST(rb_yield(rb_assoc_new(keystr, valstr)))) {
|
||||
if (dbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eDBMError, "dbm_delete failed");
|
||||
}
|
||||
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
|
||||
if (status != 0) break;
|
||||
if (RTEST(ret)) rb_ary_push(ary, keystr);
|
||||
}
|
||||
|
||||
for (i = 0; i < RARRAY(ary)->len; i++) {
|
||||
keystr = RARRAY(ary)->ptr[i];
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
if (dbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eDBMError, "dbm_delete failed");
|
||||
}
|
||||
}
|
||||
if (status) rb_jump_tag(status);
|
||||
if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -321,11 +337,13 @@ fdbm_clear(obj)
|
|||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
dbmp->di_size = -1;
|
||||
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
|
||||
while (key = dbm_firstkey(dbm), key.dptr) {
|
||||
if (dbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eDBMError, "dbm_delete failed");
|
||||
}
|
||||
}
|
||||
dbmp->di_size = 0;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -569,7 +587,7 @@ fdbm_has_key(obj, keystr)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
|
@ -588,7 +606,7 @@ fdbm_has_value(obj, valstr)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
Check_Type(valstr, T_STRING);
|
||||
StringValue(valstr);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
||||
|
@ -682,7 +700,7 @@ Init_dbm()
|
|||
rb_define_method(cDBM, "each_pair", fdbm_each_pair, 0);
|
||||
rb_define_method(cDBM, "keys", fdbm_keys, 0);
|
||||
rb_define_method(cDBM, "values", fdbm_values, 0);
|
||||
rb_define_method(cDBM, "shift", fdbm_shift, 1);
|
||||
rb_define_method(cDBM, "shift", fdbm_shift, 0);
|
||||
rb_define_method(cDBM, "delete", fdbm_delete, 1);
|
||||
rb_define_method(cDBM, "delete_if", fdbm_delete_if, 0);
|
||||
rb_define_method(cDBM, "reject!", fdbm_delete_if, 0);
|
||||
|
|
|
@ -1,13 +1,38 @@
|
|||
require 'mkmf'
|
||||
|
||||
dir_config("dbm")
|
||||
if have_library("gdbm", "dbm_open")
|
||||
gdbm = true
|
||||
|
||||
$db_hdr = "ndbm.h"
|
||||
$db_prefix = ""
|
||||
dblib = with_config("dbm-type", nil)
|
||||
|
||||
def db_check(db)
|
||||
if /^db2?$/ =~ db
|
||||
$db_prefix = "__db_n"
|
||||
$db_hdr = db+".h"
|
||||
end
|
||||
r = have_library(db, db_prefix("dbm_open"))
|
||||
if db == "gdbm"
|
||||
$have_gdbm = true
|
||||
end
|
||||
return r
|
||||
end
|
||||
gdbm or have_library("db", "dbm_open") or have_library("dbm", "dbm_open")
|
||||
|
||||
def db_prefix(func)
|
||||
$db_prefix+func
|
||||
end
|
||||
|
||||
if dblib
|
||||
db_check(dblib)
|
||||
else
|
||||
for dblib in %w(db db2 db1 dbm gdbm)
|
||||
db_check(dblib) and break
|
||||
end
|
||||
end
|
||||
|
||||
have_header("cdefs.h")
|
||||
have_header("sys/cdefs.h")
|
||||
if have_header("ndbm.h") and have_func("dbm_open")
|
||||
have_func("dbm_clearerr") unless gdbm
|
||||
if have_header($db_hdr) and have_func(db_prefix("dbm_open"))
|
||||
have_func(db_prefix("dbm_clearerr")) unless $have_gdbm
|
||||
create_makefile("dbm")
|
||||
end
|
||||
|
|
|
@ -3,3 +3,4 @@ README
|
|||
depend
|
||||
extconf.rb
|
||||
gdbm.c
|
||||
testgdbm.rb
|
||||
|
|
337
ext/gdbm/gdbm.c
337
ext/gdbm/gdbm.c
|
@ -14,7 +14,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
VALUE cGDBM, rb_eGDBMError;
|
||||
static VALUE cGDBM, rb_eGDBMError;
|
||||
|
||||
#define MY_BLOCK_SIZE (2048)
|
||||
#define MY_FATAL_FUNC (0)
|
||||
|
@ -83,7 +83,7 @@ fgdbm_initialize(argc, argv, obj)
|
|||
if (!NIL_P(vflags))
|
||||
flags = NUM2INT(vflags);
|
||||
|
||||
Check_SafeStr(file);
|
||||
SafeStringValue(file);
|
||||
|
||||
dbm = 0;
|
||||
if (mode >= 0)
|
||||
|
@ -147,42 +147,112 @@ fgdbm_close(obj)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static datum
|
||||
gdbm_fetch_1(dbm, key)
|
||||
static VALUE
|
||||
rb_gdbm_fetch(dbm, key)
|
||||
GDBM_FILE dbm;
|
||||
datum key;
|
||||
{
|
||||
static char *ptr;
|
||||
datum val;
|
||||
NEWOBJ(str, struct RString);
|
||||
OBJSETUP(str, rb_cString, T_STRING);
|
||||
|
||||
val = gdbm_fetch(dbm, key);
|
||||
if (ptr) free(ptr);
|
||||
ptr = val.dptr;
|
||||
if (val.dptr == 0)
|
||||
return Qnil;
|
||||
|
||||
return val;
|
||||
str->ptr = 0;
|
||||
str->len = val.dsize;
|
||||
str->orig = 0;
|
||||
str->ptr = REALLOC_N(val.dptr,char,val.dsize+1);
|
||||
str->ptr[str->len] = '\0';
|
||||
|
||||
OBJ_TAINT(str);
|
||||
return (VALUE)str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_gdbm_fetch2(dbm, keystr)
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr;
|
||||
{
|
||||
datum key;
|
||||
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
return rb_gdbm_fetch(dbm, key);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_gdbm_firstkey(dbm)
|
||||
GDBM_FILE dbm;
|
||||
{
|
||||
datum key;
|
||||
NEWOBJ(str, struct RString);
|
||||
OBJSETUP(str, rb_cString, T_STRING);
|
||||
|
||||
key = gdbm_firstkey(dbm);
|
||||
if (key.dptr == 0)
|
||||
return Qnil;
|
||||
|
||||
str->ptr = 0;
|
||||
str->len = key.dsize;
|
||||
str->orig = 0;
|
||||
str->ptr = REALLOC_N(key.dptr,char,key.dsize+1);
|
||||
str->ptr[str->len] = '\0';
|
||||
|
||||
OBJ_TAINT(str);
|
||||
return (VALUE)str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_gdbm_nextkey(dbm, keystr)
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr;
|
||||
{
|
||||
datum key, key2;
|
||||
NEWOBJ(str, struct RString);
|
||||
OBJSETUP(str, rb_cString, T_STRING);
|
||||
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
key2 = gdbm_nextkey(dbm, key);
|
||||
if (key2.dptr == 0)
|
||||
return Qnil;
|
||||
|
||||
str->ptr = 0;
|
||||
str->len = key2.dsize;
|
||||
str->orig = 0;
|
||||
str->ptr = REALLOC_N(key2.dptr,char,key2.dsize+1);
|
||||
str->ptr[str->len] = '\0';
|
||||
|
||||
OBJ_TAINT(str);
|
||||
return (VALUE)str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
fgdbm_fetch(obj, keystr, ifnone)
|
||||
VALUE obj, keystr, ifnone;
|
||||
{
|
||||
datum key, value;
|
||||
datum key;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE valstr;
|
||||
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
value = gdbm_fetch_1(dbm, key);
|
||||
if (value.dptr == 0) {
|
||||
valstr = rb_gdbm_fetch(dbm, key);
|
||||
if (NIL_P(valstr)) {
|
||||
if (ifnone == Qnil && rb_block_given_p())
|
||||
return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
|
||||
return ifnone;
|
||||
}
|
||||
return rb_tainted_str_new(value.dptr, value.dsize);
|
||||
return valstr;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -212,21 +282,23 @@ static VALUE
|
|||
fgdbm_index(obj, valstr)
|
||||
VALUE obj, valstr;
|
||||
{
|
||||
datum key, val;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr, valstr2;
|
||||
|
||||
Check_Type(valstr, T_STRING);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
||||
StringValue(valstr);
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
if (val.dsize == RSTRING(valstr)->len &&
|
||||
memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
|
||||
return rb_tainted_str_new(key.dptr, key.dsize);
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
valstr2 = rb_gdbm_fetch2(dbm, keystr);
|
||||
if (!NIL_P(valstr2) &&
|
||||
RSTRING(valstr)->len == RSTRING(valstr2)->len &&
|
||||
memcmp(RSTRING(valstr)->ptr, RSTRING(valstr2)->ptr,
|
||||
RSTRING(valstr)->len) == 0) {
|
||||
return keystr;
|
||||
}
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
@ -248,6 +320,36 @@ fgdbm_indexes(argc, argv, obj)
|
|||
return new;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_gdbm_delete(obj, keystr)
|
||||
VALUE obj, keystr;
|
||||
{
|
||||
datum key;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
|
||||
rb_secure(4);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
if (!gdbm_exists(dbm, key)) {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
dbmp->di_size = -1;
|
||||
rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
|
||||
}
|
||||
else if (dbmp->di_size >= 0) {
|
||||
dbmp->di_size--;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
fgdbm_delete(obj, keystr)
|
||||
VALUE obj, keystr;
|
||||
|
@ -257,7 +359,7 @@ fgdbm_delete(obj, keystr)
|
|||
GDBM_FILE dbm;
|
||||
|
||||
rb_secure(4);
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
|
@ -283,7 +385,6 @@ static VALUE
|
|||
fgdbm_shift(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, val;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr, valstr;
|
||||
|
@ -292,13 +393,11 @@ fgdbm_shift(obj)
|
|||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
key = gdbm_firstkey(dbm);
|
||||
if (!key.dptr) return Qnil;
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
gdbm_delete(dbm, key);
|
||||
keystr = rb_gdbm_firstkey(dbm);
|
||||
if (NIL_P(keystr)) return Qnil;
|
||||
valstr = rb_gdbm_fetch2(dbm, keystr);
|
||||
rb_gdbm_delete(obj, keystr);
|
||||
|
||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
return rb_assoc_new(keystr, valstr);
|
||||
}
|
||||
|
||||
|
@ -306,24 +405,32 @@ static VALUE
|
|||
fgdbm_delete_if(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, val;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr, valstr;
|
||||
VALUE ret, ary = rb_ary_new();
|
||||
int i, status = 0, n;
|
||||
|
||||
rb_secure(4);
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
if (RTEST(rb_yield(rb_assoc_new(keystr, valstr)))) {
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
|
||||
}
|
||||
}
|
||||
n = dbmp->di_size;
|
||||
dbmp->di_size = -1;
|
||||
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
valstr = rb_gdbm_fetch2(dbm, keystr);
|
||||
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
|
||||
if (status != 0) break;
|
||||
if (RTEST(ret)) rb_ary_push(ary, keystr);
|
||||
}
|
||||
|
||||
for (i = 0; i < RARRAY(ary)->len; i++)
|
||||
rb_gdbm_delete(obj, RARRAY(ary)->ptr[i]);
|
||||
if (status) rb_jump_tag(status);
|
||||
if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -331,7 +438,7 @@ static VALUE
|
|||
fgdbm_clear(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, nextkey;
|
||||
datum key;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
|
||||
|
@ -339,12 +446,16 @@ fgdbm_clear(obj)
|
|||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
dbmp->di_size = -1;
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
|
||||
nextkey = gdbm_nextkey(dbm, key);
|
||||
|
||||
while (key = gdbm_firstkey(dbm), key.dptr) {
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
free(key.dptr);
|
||||
rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
|
||||
}
|
||||
free(key.dptr);
|
||||
}
|
||||
dbmp->di_size = 0;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -352,7 +463,6 @@ static VALUE
|
|||
fgdbm_invert(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, val;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr, valstr;
|
||||
|
@ -360,10 +470,10 @@ fgdbm_invert(obj)
|
|||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
valstr = rb_gdbm_fetch2(dbm, keystr);
|
||||
|
||||
rb_hash_aset(hash, valstr, keystr);
|
||||
}
|
||||
return hash;
|
||||
|
@ -416,12 +526,11 @@ fgdbm_store(obj, keystr, valstr)
|
|||
GDBM_FILE dbm;
|
||||
|
||||
rb_secure(4);
|
||||
keystr = rb_obj_as_string(keystr);
|
||||
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
valstr = rb_obj_as_string(valstr);
|
||||
StringValue(valstr);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
||||
|
@ -440,7 +549,7 @@ static VALUE
|
|||
fgdbm_length(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key;
|
||||
datum key, nextkey;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
int i = 0;
|
||||
|
@ -449,7 +558,9 @@ fgdbm_length(obj)
|
|||
if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
|
||||
nextkey = gdbm_nextkey(dbm, key);
|
||||
free(key.dptr);
|
||||
i++;
|
||||
}
|
||||
dbmp->di_size = i;
|
||||
|
@ -464,20 +575,20 @@ fgdbm_empty_p(obj)
|
|||
datum key;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
int i = 0;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
if (dbmp->di_size < 0) {
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
i++;
|
||||
key = gdbm_firstkey(dbm);
|
||||
if (key.dptr) {
|
||||
free(key.dptr);
|
||||
return Qfalse;
|
||||
}
|
||||
return Qtrue;
|
||||
}
|
||||
else {
|
||||
i = dbmp->di_size;
|
||||
}
|
||||
if (i == 0) return Qtrue;
|
||||
|
||||
if (dbmp->di_size == 0) return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
|
@ -485,15 +596,17 @@ static VALUE
|
|||
fgdbm_each_value(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, val;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
rb_yield(rb_tainted_str_new(val.dptr, val.dsize));
|
||||
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
rb_yield(rb_gdbm_fetch2(dbm, keystr));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
@ -502,14 +615,17 @@ static VALUE
|
|||
fgdbm_each_key(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
|
||||
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
rb_yield(rb_str_dup(keystr));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
@ -518,19 +634,18 @@ static VALUE
|
|||
fgdbm_each_pair(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, val;
|
||||
GDBM_FILE dbm;
|
||||
struct dbmdata *dbmp;
|
||||
VALUE keystr, valstr;
|
||||
VALUE keystr;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
rb_yield(rb_assoc_new(keystr, valstr));
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
rb_yield(rb_assoc_new(rb_str_dup(keystr),
|
||||
rb_gdbm_fetch2(dbm, keystr)));
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -540,17 +655,18 @@ static VALUE
|
|||
fgdbm_keys(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE ary;
|
||||
VALUE keystr, ary;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
ary = rb_ary_new();
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
rb_ary_push(ary, keystr);
|
||||
}
|
||||
|
||||
return ary;
|
||||
|
@ -560,18 +676,20 @@ static VALUE
|
|||
fgdbm_values(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, val;
|
||||
datum key, nextkey;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE ary;
|
||||
VALUE valstr, ary;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
ary = rb_ary_new();
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
|
||||
nextkey = gdbm_nextkey(dbm, key);
|
||||
valstr = rb_gdbm_fetch(dbm, key);
|
||||
free(key.dptr);
|
||||
rb_ary_push(ary, valstr);
|
||||
}
|
||||
|
||||
return ary;
|
||||
|
@ -585,7 +703,7 @@ fgdbm_has_key(obj, keystr)
|
|||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
|
@ -600,21 +718,24 @@ static VALUE
|
|||
fgdbm_has_value(obj, valstr)
|
||||
VALUE obj, valstr;
|
||||
{
|
||||
datum key, val;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE keystr, valstr2;
|
||||
|
||||
Check_Type(valstr, T_STRING);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
||||
StringValue(valstr);
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
if (val.dsize == RSTRING(valstr)->len &&
|
||||
memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
valstr2 = rb_gdbm_fetch2(dbm, keystr);
|
||||
|
||||
if (!NIL_P(valstr2) &&
|
||||
RSTRING(valstr)->len == RSTRING(valstr2)->len &&
|
||||
memcmp(RSTRING(valstr)->ptr, RSTRING(valstr2)->ptr,
|
||||
RSTRING(valstr)->len) == 0) {
|
||||
return Qtrue;
|
||||
}
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
|
@ -623,19 +744,19 @@ static VALUE
|
|||
fgdbm_to_a(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, val;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE ary;
|
||||
VALUE keystr, ary;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
ary = rb_ary_new();
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
|
||||
rb_tainted_str_new(val.dptr, val.dsize)));
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
rb_ary_push(ary, rb_assoc_new(rb_str_dup(keystr),
|
||||
rb_gdbm_fetch2(dbm, keystr)));
|
||||
}
|
||||
|
||||
return ary;
|
||||
|
@ -675,7 +796,6 @@ fgdbm_set_cachesize(obj, val)
|
|||
{
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE hash;
|
||||
int optval;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
|
@ -694,7 +814,6 @@ fgdbm_set_fastmode(obj, val)
|
|||
{
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE hash;
|
||||
int optval;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
|
@ -720,7 +839,6 @@ fgdbm_set_syncmode(obj, val)
|
|||
#else
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE hash;
|
||||
int optval;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
|
@ -741,19 +859,18 @@ static VALUE
|
|||
fgdbm_to_hash(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key, val;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE hash;
|
||||
VALUE keystr, hash;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
hash = rb_hash_new();
|
||||
for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
|
||||
val = gdbm_fetch_1(dbm, key);
|
||||
rb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),
|
||||
rb_tainted_str_new(val.dptr, val.dsize));
|
||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||
|
||||
rb_hash_aset(hash, keystr, rb_gdbm_fetch2(dbm, keystr));
|
||||
}
|
||||
|
||||
return hash;
|
||||
|
@ -794,7 +911,7 @@ Init_gdbm()
|
|||
rb_define_method(cGDBM, "each_pair", fgdbm_each_pair, 0);
|
||||
rb_define_method(cGDBM, "keys", fgdbm_keys, 0);
|
||||
rb_define_method(cGDBM, "values", fgdbm_values, 0);
|
||||
rb_define_method(cGDBM, "shift", fgdbm_shift, 1);
|
||||
rb_define_method(cGDBM, "shift", fgdbm_shift, 0);
|
||||
rb_define_method(cGDBM, "delete", fgdbm_delete, 1);
|
||||
rb_define_method(cGDBM, "delete_if", fgdbm_delete_if, 0);
|
||||
rb_define_method(cGDBM, "reject!", fgdbm_delete_if, 0);
|
||||
|
|
|
@ -21,12 +21,10 @@ md5i_update(obj, str)
|
|||
VALUE obj, str;
|
||||
{
|
||||
md5_state_t *md5;
|
||||
char *p;
|
||||
int len;
|
||||
|
||||
p = rb_str2cstr(str, &len);
|
||||
StringValue(str);
|
||||
Data_Get_Struct(obj, md5_state_t, md5);
|
||||
md5_append(md5, p, len);
|
||||
md5_append(md5, RSTRING(str)->ptr, RSTRING(str)->len);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -83,13 +81,14 @@ md5i_new(argc, argv, class)
|
|||
VALUE* argv;
|
||||
VALUE class;
|
||||
{
|
||||
VALUE obj;
|
||||
VALUE obj, str;
|
||||
md5_state_t *md5;
|
||||
|
||||
obj = Data_Make_Struct(class, md5_state_t, 0, free, md5);
|
||||
md5_init(md5);
|
||||
rb_scan_args(argc, argv, "01", &str);
|
||||
if (argc == 1) {
|
||||
md5i_update(obj, argv[0]);
|
||||
md5i_update(obj, str);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
|
203
file.c
203
file.c
|
@ -86,7 +86,7 @@ apply2files(func, vargs, arg)
|
|||
|
||||
for (i=0; i<args->len; i++) {
|
||||
path = args->ptr[i];
|
||||
SafeStr(path);
|
||||
SafeStringValue(path);
|
||||
if ((*func)(RSTRING(path)->ptr, arg) < 0)
|
||||
rb_sys_fail(RSTRING(path)->ptr);
|
||||
}
|
||||
|
@ -110,7 +110,8 @@ rb_file_path(obj)
|
|||
#endif
|
||||
|
||||
static VALUE
|
||||
stat_new(st)
|
||||
stat_new_0(klass, st)
|
||||
VALUE klass;
|
||||
struct stat *st;
|
||||
{
|
||||
struct stat *nst;
|
||||
|
@ -118,7 +119,14 @@ stat_new(st)
|
|||
|
||||
nst = ALLOC(struct stat);
|
||||
*nst = *st;
|
||||
return Data_Wrap_Struct(rb_cStat, NULL, free, nst);
|
||||
return Data_Wrap_Struct(klass, NULL, free, nst);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
stat_new(st)
|
||||
struct stat *st;
|
||||
{
|
||||
return stat_new_0(rb_cStat, st);
|
||||
}
|
||||
|
||||
static struct stat*
|
||||
|
@ -149,42 +157,42 @@ static VALUE
|
|||
rb_stat_dev(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX((int)get_stat(self)->st_dev);
|
||||
return INT2NUM(get_stat(self)->st_dev);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_stat_ino(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX((int)get_stat(self)->st_ino);
|
||||
return ULONG2NUM(get_stat(self)->st_ino);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_stat_mode(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX((int)get_stat(self)->st_mode);
|
||||
return UINT2NUM(get_stat(self)->st_mode);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_stat_nlink(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX((int)get_stat(self)->st_nlink);
|
||||
return UINT2NUM(get_stat(self)->st_nlink);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_stat_uid(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX((int)get_stat(self)->st_uid);
|
||||
return UINT2NUM(get_stat(self)->st_uid);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_stat_gid(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX((int)get_stat(self)->st_gid);
|
||||
return UINT2NUM(get_stat(self)->st_gid);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -192,7 +200,7 @@ rb_stat_rdev(self)
|
|||
VALUE self;
|
||||
{
|
||||
#ifdef HAVE_ST_RDEV
|
||||
return INT2FIX((int)get_stat(self)->st_rdev);
|
||||
return ULONG2NUM(get_stat(self)->st_rdev);
|
||||
#else
|
||||
return INT2FIX(0);
|
||||
#endif
|
||||
|
@ -202,7 +210,7 @@ static VALUE
|
|||
rb_stat_size(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX((int)get_stat(self)->st_size);
|
||||
return LONG2NUM(get_stat(self)->st_size);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -210,7 +218,7 @@ rb_stat_blksize(self)
|
|||
VALUE self;
|
||||
{
|
||||
#ifdef HAVE_ST_BLKSIZE
|
||||
return INT2FIX((int)get_stat(self)->st_blksize);
|
||||
return ULONG2NUM(get_stat(self)->st_blksize);
|
||||
#else
|
||||
return INT2FIX(0);
|
||||
#endif
|
||||
|
@ -221,7 +229,7 @@ rb_stat_blocks(self)
|
|||
VALUE self;
|
||||
{
|
||||
#ifdef HAVE_ST_BLOCKS
|
||||
return INT2FIX((int)get_stat(self)->st_blocks);
|
||||
return ULONG2NUM(get_stat(self)->st_blocks);
|
||||
#else
|
||||
return INT2FIX(0);
|
||||
#endif
|
||||
|
@ -306,7 +314,7 @@ rb_stat(file, st)
|
|||
GetOpenFile(file, fptr);
|
||||
return fstat(fileno(fptr->f), st);
|
||||
}
|
||||
SafeStr(file);
|
||||
SafeStringValue(file);
|
||||
#if defined DJGPP
|
||||
if (RSTRING(file)->len == 0) return -1;
|
||||
#endif
|
||||
|
@ -314,12 +322,12 @@ rb_stat(file, st)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_stat(obj, fname)
|
||||
VALUE obj, fname;
|
||||
rb_file_s_stat(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (stat(RSTRING(fname)->ptr, &st) == -1) {
|
||||
rb_sys_fail(RSTRING(fname)->ptr);
|
||||
}
|
||||
|
@ -341,19 +349,19 @@ rb_io_stat(obj)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_lstat(obj, fname)
|
||||
VALUE obj, fname;
|
||||
rb_file_s_lstat(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
#ifdef HAVE_LSTAT
|
||||
struct stat st;
|
||||
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (lstat(RSTRING(fname)->ptr, &st) == -1) {
|
||||
rb_sys_fail(RSTRING(fname)->ptr);
|
||||
}
|
||||
return stat_new(&st);
|
||||
#else
|
||||
return rb_file_s_stat(obj, fname);
|
||||
return rb_file_s_stat(klass, fname);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -500,7 +508,7 @@ test_l(obj, fname)
|
|||
#ifdef S_ISLNK
|
||||
struct stat st;
|
||||
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (lstat(RSTRING(fname)->ptr, &st) < 0) return Qfalse;
|
||||
if (S_ISLNK(st.st_mode)) return Qtrue;
|
||||
#endif
|
||||
|
@ -588,7 +596,7 @@ static VALUE
|
|||
test_r(obj, fname)
|
||||
VALUE obj, fname;
|
||||
{
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (eaccess(RSTRING(fname)->ptr, R_OK) < 0) return Qfalse;
|
||||
return Qtrue;
|
||||
}
|
||||
|
@ -597,7 +605,7 @@ static VALUE
|
|||
test_R(obj, fname)
|
||||
VALUE obj, fname;
|
||||
{
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (access(RSTRING(fname)->ptr, R_OK) < 0) return Qfalse;
|
||||
return Qtrue;
|
||||
}
|
||||
|
@ -606,7 +614,7 @@ static VALUE
|
|||
test_w(obj, fname)
|
||||
VALUE obj, fname;
|
||||
{
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (eaccess(RSTRING(fname)->ptr, W_OK) < 0) return Qfalse;
|
||||
return Qtrue;
|
||||
}
|
||||
|
@ -615,7 +623,7 @@ static VALUE
|
|||
test_W(obj, fname)
|
||||
VALUE obj, fname;
|
||||
{
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (access(RSTRING(fname)->ptr, W_OK) < 0) return Qfalse;
|
||||
return Qtrue;
|
||||
}
|
||||
|
@ -624,7 +632,7 @@ static VALUE
|
|||
test_x(obj, fname)
|
||||
VALUE obj, fname;
|
||||
{
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (eaccess(RSTRING(fname)->ptr, X_OK) < 0) return Qfalse;
|
||||
return Qtrue;
|
||||
}
|
||||
|
@ -633,7 +641,7 @@ static VALUE
|
|||
test_X(obj, fname)
|
||||
VALUE obj, fname;
|
||||
{
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (access(RSTRING(fname)->ptr, X_OK) < 0) return Qfalse;
|
||||
return Qtrue;
|
||||
}
|
||||
|
@ -712,13 +720,14 @@ test_grpowned(obj, fname)
|
|||
|
||||
#if defined(S_ISUID) || defined(S_ISGID) || defined(S_ISVTX)
|
||||
static VALUE
|
||||
check3rdbyte(file, mode)
|
||||
const char *file;
|
||||
check3rdbyte(fname, mode)
|
||||
VALUE fname;
|
||||
int mode;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(file, &st) < 0) return Qfalse;
|
||||
SafeStringValue(fname);
|
||||
if (stat(RSTRING(fname)->ptr, &st) < 0) return Qfalse;
|
||||
if (st.st_mode & mode) return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
@ -729,8 +738,7 @@ test_suid(obj, fname)
|
|||
VALUE obj, fname;
|
||||
{
|
||||
#ifdef S_ISUID
|
||||
SafeStr(fname);
|
||||
return check3rdbyte(RSTRING(fname)->ptr, S_ISUID);
|
||||
return check3rdbyte(fname, S_ISUID);
|
||||
#else
|
||||
return Qfalse;
|
||||
#endif
|
||||
|
@ -741,8 +749,7 @@ test_sgid(obj, fname)
|
|||
VALUE obj, fname;
|
||||
{
|
||||
#ifdef S_ISGID
|
||||
SafeStr(fname);
|
||||
return check3rdbyte(RSTRING(fname)->ptr, S_ISGID);
|
||||
return check3rdbyte(fname, S_ISGID);
|
||||
#else
|
||||
return Qfalse;
|
||||
#endif
|
||||
|
@ -753,15 +760,15 @@ test_sticky(obj, fname)
|
|||
VALUE obj, fname;
|
||||
{
|
||||
#ifdef S_ISVTX
|
||||
return check3rdbyte(STR2CSTR(fname), S_ISVTX);
|
||||
return check3rdbyte(fname, S_ISVTX);
|
||||
#else
|
||||
return Qnil;
|
||||
#endif
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_size(obj, fname)
|
||||
VALUE obj, fname;
|
||||
rb_file_s_size(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
|
@ -778,9 +785,11 @@ rb_file_ftype(st)
|
|||
|
||||
if (S_ISREG(st->st_mode)) {
|
||||
t = "file";
|
||||
} else if (S_ISDIR(st->st_mode)) {
|
||||
}
|
||||
else if (S_ISDIR(st->st_mode)) {
|
||||
t = "directory";
|
||||
} else if (S_ISCHR(st->st_mode)) {
|
||||
}
|
||||
else if (S_ISCHR(st->st_mode)) {
|
||||
t = "characterSpecial";
|
||||
}
|
||||
#ifdef S_ISBLK
|
||||
|
@ -811,12 +820,12 @@ rb_file_ftype(st)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_ftype(obj, fname)
|
||||
VALUE obj, fname;
|
||||
rb_file_s_ftype(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (lstat(RSTRING(fname)->ptr, &st) == -1) {
|
||||
rb_sys_fail(RSTRING(fname)->ptr);
|
||||
}
|
||||
|
@ -825,8 +834,8 @@ rb_file_s_ftype(obj, fname)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_atime(obj, fname)
|
||||
VALUE obj, fname;
|
||||
rb_file_s_atime(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
|
@ -850,8 +859,8 @@ rb_file_atime(obj)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_mtime(obj, fname)
|
||||
VALUE obj, fname;
|
||||
rb_file_s_mtime(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
|
@ -875,8 +884,8 @@ rb_file_mtime(obj)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_ctime(obj, fname)
|
||||
VALUE obj, fname;
|
||||
rb_file_s_ctime(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
|
@ -1045,7 +1054,7 @@ rb_file_chown(obj, owner, group)
|
|||
return INT2FIX(0);
|
||||
}
|
||||
|
||||
#if defined(HAVE_LCHOWN)
|
||||
#if defined(HAVE_LCHOWN) && !defined(__CHECKER__)
|
||||
static void
|
||||
lchown_internal(path, args)
|
||||
const char *path;
|
||||
|
@ -1176,11 +1185,11 @@ rb_file_s_utime(argc, argv)
|
|||
#endif
|
||||
|
||||
static VALUE
|
||||
rb_file_s_link(obj, from, to)
|
||||
VALUE obj, from, to;
|
||||
rb_file_s_link(klass, from, to)
|
||||
VALUE klass, from, to;
|
||||
{
|
||||
SafeStr(from);
|
||||
SafeStr(to);
|
||||
SafeStringValue(from);
|
||||
SafeStringValue(to);
|
||||
|
||||
if (link(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
|
||||
rb_sys_fail(RSTRING(from)->ptr);
|
||||
|
@ -1188,12 +1197,12 @@ rb_file_s_link(obj, from, to)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_symlink(obj, from, to)
|
||||
VALUE obj, from, to;
|
||||
rb_file_s_symlink(klass, from, to)
|
||||
VALUE klass, from, to;
|
||||
{
|
||||
#ifdef HAVE_SYMLINK
|
||||
SafeStr(from);
|
||||
SafeStr(to);
|
||||
SafeStringValue(from);
|
||||
SafeStringValue(to);
|
||||
|
||||
if (symlink(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
|
||||
rb_sys_fail(RSTRING(from)->ptr);
|
||||
|
@ -1205,14 +1214,14 @@ rb_file_s_symlink(obj, from, to)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_readlink(obj, path)
|
||||
VALUE obj, path;
|
||||
rb_file_s_readlink(klass, path)
|
||||
VALUE klass, path;
|
||||
{
|
||||
#ifdef HAVE_READLINK
|
||||
char buf[MAXPATHLEN];
|
||||
int cc;
|
||||
|
||||
SafeStr(path);
|
||||
SafeStringValue(path);
|
||||
if ((cc = readlink(RSTRING(path)->ptr, buf, MAXPATHLEN)) < 0)
|
||||
rb_sys_fail(RSTRING(path)->ptr);
|
||||
|
||||
|
@ -1232,8 +1241,8 @@ unlink_internal(path)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_unlink(obj, args)
|
||||
VALUE obj, args;
|
||||
rb_file_s_unlink(klass, args)
|
||||
VALUE klass, args;
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -1242,11 +1251,11 @@ rb_file_s_unlink(obj, args)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_rename(obj, from, to)
|
||||
VALUE obj, from, to;
|
||||
rb_file_s_rename(klass, from, to)
|
||||
VALUE klass, from, to;
|
||||
{
|
||||
SafeStr(from);
|
||||
SafeStr(to);
|
||||
SafeStringValue(from);
|
||||
SafeStringValue(to);
|
||||
|
||||
if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) {
|
||||
#if defined __CYGWIN__
|
||||
|
@ -1299,7 +1308,7 @@ rb_file_s_expand_path(argc, argv)
|
|||
rb_scan_args(argc, argv, "11", &fname, &dname);
|
||||
|
||||
tainted = OBJ_TAINTED(fname);
|
||||
s = STR2CSTR(fname);
|
||||
s = StringValuePtr(fname);
|
||||
p = buf;
|
||||
if (s[0] == '~') {
|
||||
if (isdirsep(s[1]) || s[1] == '\0') {
|
||||
|
@ -1448,9 +1457,9 @@ rb_file_s_basename(argc, argv)
|
|||
int f;
|
||||
|
||||
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
|
||||
ext = STR2CSTR(fext);
|
||||
ext = StringValuePtr(fext);
|
||||
}
|
||||
name = STR2CSTR(fname);
|
||||
name = StringValuePtr(fname);
|
||||
p = strrchr(name, '/');
|
||||
if (!p) {
|
||||
if (NIL_P(fext) || !(f = rmext(name, ext)))
|
||||
|
@ -1471,13 +1480,13 @@ rb_file_s_basename(argc, argv)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_dirname(obj, fname)
|
||||
VALUE obj, fname;
|
||||
rb_file_s_dirname(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
char *name, *p;
|
||||
VALUE dirname;
|
||||
|
||||
name = STR2CSTR(fname);
|
||||
name = StringValuePtr(fname);
|
||||
p = strrchr(name, '/');
|
||||
if (!p) {
|
||||
return rb_str_new2(".");
|
||||
|
@ -1490,8 +1499,8 @@ rb_file_s_dirname(obj, fname)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_split(obj, path)
|
||||
VALUE obj, path;
|
||||
rb_file_s_split(klass, path)
|
||||
VALUE klass, path;
|
||||
{
|
||||
return rb_assoc_new(rb_file_s_dirname(Qnil, path), rb_file_s_basename(1,&path));
|
||||
}
|
||||
|
@ -1499,18 +1508,18 @@ rb_file_s_split(obj, path)
|
|||
static VALUE separator;
|
||||
|
||||
static VALUE
|
||||
rb_file_s_join(obj, args)
|
||||
VALUE obj, args;
|
||||
rb_file_s_join(klass, args)
|
||||
VALUE klass, args;
|
||||
{
|
||||
return rb_ary_join(args, separator);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_file_s_truncate(obj, path, len)
|
||||
VALUE obj, path, len;
|
||||
rb_file_s_truncate(klass, path, len)
|
||||
VALUE klass, path, len;
|
||||
{
|
||||
rb_secure(2);
|
||||
SafeStr(path);
|
||||
SafeStringValue(path);
|
||||
|
||||
#ifdef HAVE_TRUNCATE
|
||||
if (truncate(RSTRING(path)->ptr, NUM2INT(len)) < 0)
|
||||
|
@ -1655,7 +1664,7 @@ test_check(n, argc, argv)
|
|||
for (i=1; i<n; i++) {
|
||||
switch (TYPE(argv[i])) {
|
||||
case T_STRING:
|
||||
SafeStr(argv[i]);
|
||||
SafeStringValue(argv[i]);
|
||||
break;
|
||||
case T_FILE:
|
||||
break;
|
||||
|
@ -1804,6 +1813,30 @@ rb_f_test(argc, argv)
|
|||
return Qnil; /* not reached */
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_stat_s_new(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
VALUE s;
|
||||
struct stat st;
|
||||
|
||||
Check_SafeStr(fname);
|
||||
if (stat(RSTRING(fname)->ptr, &st) == -1) {
|
||||
rb_sys_fail(RSTRING(fname)->ptr);
|
||||
}
|
||||
s = stat_new_0(klass, &st);
|
||||
rb_obj_call_init(s, 1, &fname);
|
||||
return s;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_stat_init(klass, fname)
|
||||
VALUE klass, fname;
|
||||
{
|
||||
/* do nothing */
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_stat_ftype(obj)
|
||||
VALUE obj;
|
||||
|
@ -2210,7 +2243,7 @@ rb_find_file(file)
|
|||
if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) {
|
||||
rb_raise(rb_eSecurityError, "loading from unsafe file %s", file);
|
||||
}
|
||||
file = STR2CSTR(fname);
|
||||
file = StringValuePtr(fname);
|
||||
}
|
||||
|
||||
if (rb_load_path) {
|
||||
|
@ -2220,13 +2253,13 @@ rb_find_file(file)
|
|||
vpath = rb_ary_new();
|
||||
for (i=0;i<RARRAY(rb_load_path)->len;i++) {
|
||||
VALUE str = RARRAY(rb_load_path)->ptr[i];
|
||||
SafeStr(str);
|
||||
SafeStringValue(str);
|
||||
if (RSTRING(str)->len > 0) {
|
||||
rb_ary_push(vpath, str);
|
||||
}
|
||||
}
|
||||
vpath = rb_ary_join(vpath, rb_str_new2(PATH_SEP));
|
||||
path = STR2CSTR(vpath);
|
||||
path = StringValuePtr(vpath);
|
||||
if (rb_safe_level() >= 2 && !rb_path_check(path)) {
|
||||
rb_raise(rb_eSecurityError, "loading from unsafe path %s", path);
|
||||
}
|
||||
|
@ -2350,6 +2383,8 @@ Init_File()
|
|||
rb_define_global_function("test", rb_f_test, -1);
|
||||
|
||||
rb_cStat = rb_define_class_under(rb_cFile, "Stat", rb_cObject);
|
||||
rb_define_singleton_method(rb_cStat, "new", rb_stat_s_new, 1);
|
||||
rb_define_method(rb_cStat, "initialize", rb_stat_init, 1);
|
||||
|
||||
rb_include_module(rb_cStat, rb_mComparable);
|
||||
|
||||
|
|
38
gc.c
38
gc.c
|
@ -1147,7 +1147,7 @@ rm_final(os, proc)
|
|||
static VALUE
|
||||
finals()
|
||||
{
|
||||
rb_warn("ObjectSpace::finals is deprecated");
|
||||
rb_warn("ObjectSpace::finalizers is deprecated");
|
||||
return finalizers;
|
||||
}
|
||||
|
||||
|
@ -1283,7 +1283,7 @@ id2ref(obj, id)
|
|||
unsigned long ptr, p0;
|
||||
|
||||
rb_secure(4);
|
||||
p0 = ptr = NUM2UINT(id);
|
||||
p0 = ptr = NUM2ULONG(id);
|
||||
if (ptr == Qtrue) return Qtrue;
|
||||
if (ptr == Qfalse) return Qfalse;
|
||||
if (ptr == Qnil) return Qnil;
|
||||
|
@ -1331,37 +1331,3 @@ Init_GC()
|
|||
rb_gc_unregister_address(&rb_mObSpace);
|
||||
finalizers = rb_ary_new();
|
||||
}
|
||||
|
||||
#undef xmalloc
|
||||
#undef xcalloc
|
||||
#undef xrealloc
|
||||
#undef xfree
|
||||
|
||||
void*
|
||||
xmalloc(size)
|
||||
long size;
|
||||
{
|
||||
return ruby_xmalloc(size);
|
||||
}
|
||||
|
||||
void*
|
||||
xcalloc(n,size)
|
||||
long n,size;
|
||||
{
|
||||
return ruby_xcalloc(n, size);
|
||||
}
|
||||
|
||||
void*
|
||||
xrealloc(ptr,size)
|
||||
void *ptr;
|
||||
long size;
|
||||
{
|
||||
return ruby_xrealloc(ptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
xfree(ptr)
|
||||
void *ptr;
|
||||
{
|
||||
ruby_xfree(ptr);
|
||||
}
|
||||
|
|
35
hash.c
35
hash.c
|
@ -858,12 +858,12 @@ static VALUE
|
|||
env_delete(obj, name)
|
||||
VALUE obj, name;
|
||||
{
|
||||
int len;
|
||||
char *nam, *val;
|
||||
|
||||
rb_secure(4);
|
||||
nam = rb_str2cstr(name, &len);
|
||||
if (strlen(nam) != len) {
|
||||
StringValue(name);
|
||||
nam = RSTRING(name)->ptr;
|
||||
if (strlen(nam) != RSTRING(name)->len) {
|
||||
rb_raise(rb_eArgError, "bad environment variable name");
|
||||
}
|
||||
val = getenv(nam);
|
||||
|
@ -895,8 +895,9 @@ rb_f_getenv(obj, name)
|
|||
char *nam, *env;
|
||||
int len;
|
||||
|
||||
nam = rb_str2cstr(name, &len);
|
||||
if (strlen(nam) != len) {
|
||||
StringValue(name);
|
||||
nam = RSTRING(name)->ptr;
|
||||
if (strlen(nam) != RSTRING(name)->len) {
|
||||
rb_raise(rb_eArgError, "bad environment variable name");
|
||||
}
|
||||
env = getenv(nam);
|
||||
|
@ -915,11 +916,11 @@ env_fetch(argc, argv)
|
|||
{
|
||||
VALUE key, if_none;
|
||||
char *nam, *env;
|
||||
int len;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &key, &if_none);
|
||||
nam = rb_str2cstr(key, &len);
|
||||
if (strlen(nam) != len) {
|
||||
StringValue(key);
|
||||
nam = RSTRING(key)->ptr;
|
||||
if (strlen(nam) != RSTRING(key)->len) {
|
||||
rb_raise(rb_eArgError, "bad environment variable name");
|
||||
}
|
||||
env = getenv(nam);
|
||||
|
@ -1115,11 +1116,13 @@ rb_f_setenv(obj, nm, val)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
name = rb_str2cstr(nm, &nlen);
|
||||
value = rb_str2cstr(val, &vlen);
|
||||
if (strlen(name) != nlen)
|
||||
StringValue(nm);
|
||||
StringValue(val);
|
||||
name = RSTRING(nm)->ptr;
|
||||
value = RSTRING(val)->ptr;
|
||||
if (strlen(name) != RSTRING(nm)->len)
|
||||
rb_raise(rb_eArgError, "bad environment variable name");
|
||||
if (strlen(value) != vlen)
|
||||
if (strlen(value) != RSTRING(val)->len)
|
||||
rb_raise(rb_eArgError, "bad environment variable value");
|
||||
|
||||
ruby_setenv(name, value);
|
||||
|
@ -1335,8 +1338,12 @@ static VALUE
|
|||
env_has_key(env, key)
|
||||
VALUE env, key;
|
||||
{
|
||||
if (TYPE(key) != T_STRING) return Qfalse;
|
||||
if (getenv(STR2CSTR(key))) return Qtrue;
|
||||
char *s;
|
||||
|
||||
s = StringValuePtr(key);
|
||||
if (strlen(s) != RSTRING(key)->len)
|
||||
rb_raise(rb_eArgError, "bad environment variable name");
|
||||
if (getenv(s)) return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
|
|
29
intern.h
29
intern.h
|
@ -47,7 +47,7 @@ VALUE rb_ary_concat _((VALUE, VALUE));
|
|||
VALUE rb_ary_assoc _((VALUE, VALUE));
|
||||
VALUE rb_ary_rassoc _((VALUE, VALUE));
|
||||
VALUE rb_ary_includes _((VALUE, VALUE));
|
||||
VALUE rb_protect_inspect _((VALUE(*)(),VALUE,VALUE));
|
||||
VALUE rb_protect_inspect _((VALUE(*)(VALUE,VALUE),VALUE,VALUE));
|
||||
VALUE rb_inspecting_p _((VALUE));
|
||||
/* bignum.c */
|
||||
VALUE rb_big_clone _((VALUE));
|
||||
|
@ -78,6 +78,8 @@ VALUE rb_big_lshift _((VALUE, VALUE));
|
|||
VALUE rb_big_rand _((VALUE, double));
|
||||
/* class.c */
|
||||
VALUE rb_class_new _((VALUE));
|
||||
VALUE rb_mod_clone _((VALUE));
|
||||
VALUE rb_mod_dup _((VALUE));
|
||||
VALUE rb_singleton_class_new _((VALUE));
|
||||
VALUE rb_singleton_class_clone _((VALUE));
|
||||
void rb_singleton_class_attached _((VALUE,VALUE));
|
||||
|
@ -90,13 +92,13 @@ VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
|
|||
VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
|
||||
VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
|
||||
VALUE rb_obj_singleton_methods _((VALUE));
|
||||
void rb_define_method_id _((VALUE, ID, VALUE (*)(), int));
|
||||
void rb_define_method_id _((VALUE, ID, VALUE (*)(ANYARGS), int));
|
||||
void rb_frozen_class_p _((VALUE));
|
||||
void rb_undef _((VALUE, ID));
|
||||
void rb_define_protected_method _((VALUE, const char*, VALUE (*)(), int));
|
||||
void rb_define_private_method _((VALUE, const char*, VALUE (*)(), int));
|
||||
void rb_define_singleton_method _((VALUE,const char*,VALUE(*)(),int));
|
||||
void rb_define_private_method _((VALUE,const char*,VALUE(*)(),int));
|
||||
void rb_define_protected_method _((VALUE, const char*, VALUE (*)(ANYARGS), int));
|
||||
void rb_define_private_method _((VALUE, const char*, VALUE (*)(ANYARGS), int));
|
||||
void rb_define_singleton_method _((VALUE, const char*, VALUE(*)(ANYARGS), int));
|
||||
void rb_define_private_method _((VALUE, const char*, VALUE(*)(ANYARGS), int));
|
||||
VALUE rb_singleton_class _((VALUE));
|
||||
/* enum.c */
|
||||
VALUE rb_enum_length _((VALUE));
|
||||
|
@ -141,8 +143,8 @@ VALUE rb_f_require _((VALUE, VALUE));
|
|||
void rb_obj_call_init _((VALUE, int, VALUE*));
|
||||
VALUE rb_class_new_instance _((int, VALUE*, VALUE));
|
||||
VALUE rb_f_lambda _((void));
|
||||
VALUE rb_protect _((VALUE (*)(), VALUE, int*));
|
||||
void rb_set_end_proc _((void (*)(), VALUE));
|
||||
VALUE rb_protect _((VALUE (*)(VALUE), VALUE, int*));
|
||||
void rb_set_end_proc _((void (*)(void), VALUE));
|
||||
void rb_mark_end_proc _((void));
|
||||
void rb_exec_end_proc _((void));
|
||||
void ruby_finalize _((void));
|
||||
|
@ -161,13 +163,13 @@ void rb_thread_sleep_forever _((void));
|
|||
VALUE rb_thread_stop _((void));
|
||||
VALUE rb_thread_wakeup _((VALUE));
|
||||
VALUE rb_thread_run _((VALUE));
|
||||
VALUE rb_thread_create _((VALUE (*)(), void*));
|
||||
VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*));
|
||||
int rb_thread_scope_shared_p _((void));
|
||||
void rb_thread_interrupt _((void));
|
||||
void rb_thread_trap_eval _((VALUE, int));
|
||||
void rb_thread_signal_raise _((char*));
|
||||
int rb_thread_select();
|
||||
void rb_thread_wait_for();
|
||||
int rb_thread_select(ANYARGS);
|
||||
void rb_thread_wait_for(ANYARGS);
|
||||
VALUE rb_thread_current _((void));
|
||||
VALUE rb_thread_main _((void));
|
||||
VALUE rb_thread_local_aref _((VALUE, ID));
|
||||
|
@ -258,6 +260,7 @@ VALUE rb_backref_get _((void));
|
|||
void rb_backref_set _((VALUE));
|
||||
VALUE rb_lastline_get _((void));
|
||||
void rb_lastline_set _((VALUE));
|
||||
VALUE rb_sym_all_symbols _((void));
|
||||
/* process.c */
|
||||
int rb_proc_exec _((const char*));
|
||||
void rb_syswait _((int));
|
||||
|
@ -296,7 +299,7 @@ VALUE rb_f_kill _((int, VALUE*));
|
|||
void rb_gc_mark_trap_list _((void));
|
||||
#ifdef POSIX_SIGNAL
|
||||
#define posix_signal ruby_posix_signal
|
||||
void posix_signal _((int, void (*)()));
|
||||
void posix_signal _((int, RETSIGTYPE (*)(int)));
|
||||
#endif
|
||||
void rb_trap_exit _((void));
|
||||
void rb_trap_exec _((void));
|
||||
|
@ -337,7 +340,7 @@ VALUE rb_struct_aref _((VALUE, VALUE));
|
|||
VALUE rb_struct_aset _((VALUE, VALUE, VALUE));
|
||||
VALUE rb_struct_getmember _((VALUE, ID));
|
||||
/* time.c */
|
||||
VALUE rb_time_new();
|
||||
VALUE rb_time_new(ANYARGS);
|
||||
/* variable.c */
|
||||
VALUE rb_mod_name _((VALUE));
|
||||
VALUE rb_class_path _((VALUE));
|
||||
|
|
78
io.c
78
io.c
|
@ -27,6 +27,10 @@
|
|||
# define NO_LONG_FNAME
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(sun)
|
||||
# define USE_SETVBUF
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#if !defined(DJGPP) && !defined(NT) && !defined(__human68k__)
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -606,11 +610,10 @@ rb_io_gets_internal(argc, argv, io)
|
|||
VALUE rs;
|
||||
|
||||
if (argc == 0) {
|
||||
rs = rb_str_to_str(rb_rs);
|
||||
rs = rb_default_rs;
|
||||
}
|
||||
else {
|
||||
rb_scan_args(argc, argv, "1", &rs);
|
||||
if (!NIL_P(rs)) rs = rb_str_to_str(rs);
|
||||
}
|
||||
|
||||
if (NIL_P(rs)) {
|
||||
|
@ -621,6 +624,7 @@ rb_io_gets_internal(argc, argv, io)
|
|||
return rb_io_gets(io);
|
||||
}
|
||||
else {
|
||||
StringValue(rs);
|
||||
rslen = RSTRING(rs)->len;
|
||||
if (rslen == 0) {
|
||||
rsptr = "\n\n";
|
||||
|
@ -1379,6 +1383,10 @@ rb_fopen(fname, mode)
|
|||
rb_sys_fail(fname);
|
||||
}
|
||||
}
|
||||
#ifdef USE_SETVBUF
|
||||
if (setvbuf(file, NULL, _IOFBF, 0) != 0)
|
||||
rb_warn("setvbuf() can't be honered for %s", fname);
|
||||
#endif
|
||||
#ifdef __human68k__
|
||||
fmode(file, _IOTEXT);
|
||||
#endif
|
||||
|
@ -1402,6 +1410,11 @@ rb_fdopen(fd, mode)
|
|||
rb_sys_fail(0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_SETVBUF
|
||||
if (setvbuf(file, NULL, _IOFBF, 0) != 0)
|
||||
rb_warn("setvbuf() can't be honered (fd=%d)", fd);
|
||||
#endif
|
||||
return file;
|
||||
}
|
||||
|
||||
|
@ -1685,9 +1698,9 @@ rb_io_popen(str, argc, argv, klass)
|
|||
mode = "r";
|
||||
}
|
||||
else {
|
||||
mode = STR2CSTR(pmode);
|
||||
mode = StringValuePtr(pmode);
|
||||
}
|
||||
SafeStr(pname);
|
||||
SafeStringValue(pname);
|
||||
port = pipe_open(str, mode);
|
||||
if (NIL_P(port)) {
|
||||
/* child */
|
||||
|
@ -1715,7 +1728,7 @@ rb_io_s_popen(argc, argv, klass)
|
|||
char *str = 0;
|
||||
|
||||
if (argc >= 1) {
|
||||
str = STR2CSTR(argv[0]);
|
||||
str = StringValuePtr(argv[0]);
|
||||
}
|
||||
return rb_io_popen(str, argc, argv, klass);
|
||||
}
|
||||
|
@ -1732,7 +1745,7 @@ rb_file_s_open(argc, argv, klass)
|
|||
NEWOBJ(io, struct RFile);
|
||||
OBJSETUP(io, klass, T_FILE);
|
||||
rb_scan_args(argc, argv, "12", &fname, &vmode, &perm);
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
path = RSTRING(fname)->ptr;
|
||||
|
||||
RFILE(io)->fptr = 0;
|
||||
|
@ -1743,7 +1756,7 @@ rb_file_s_open(argc, argv, klass)
|
|||
file = rb_file_sysopen_internal((VALUE)io, path, flags, fmode);
|
||||
}
|
||||
else {
|
||||
mode = NIL_P(vmode) ? "r" : STR2CSTR(vmode);
|
||||
mode = NIL_P(vmode) ? "r" : StringValuePtr(vmode);
|
||||
file = rb_file_open_internal((VALUE)io, RSTRING(fname)->ptr, mode);
|
||||
}
|
||||
|
||||
|
@ -1760,7 +1773,7 @@ rb_f_open(argc, argv)
|
|||
VALUE *argv;
|
||||
{
|
||||
if (argc >= 1) {
|
||||
char *str = STR2CSTR(argv[0]);
|
||||
char *str = StringValuePtr(argv[0]);
|
||||
|
||||
if (str[0] == '|') {
|
||||
return rb_io_popen(str+1, argc, argv, rb_cIO);
|
||||
|
@ -1897,9 +1910,9 @@ rb_io_reopen(argc, argv, file)
|
|||
}
|
||||
}
|
||||
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
if (!NIL_P(nmode)) {
|
||||
mode = STR2CSTR(nmode);
|
||||
mode = StringValuePtr(nmode);
|
||||
}
|
||||
else {
|
||||
mode = "r";
|
||||
|
@ -1919,12 +1932,18 @@ rb_io_reopen(argc, argv, file)
|
|||
fclose(fptr->f2);
|
||||
fptr->f2 = 0;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == 0) {
|
||||
rb_sys_fail(fptr->path);
|
||||
}
|
||||
#ifdef USE_SETVBUF
|
||||
if (setvbuf(fptr->f, NULL, _IOFBF, 0) != 0)
|
||||
rb_warn("setvbuf() can't be honered for %s", RSTRING(fname)->ptr);
|
||||
#endif
|
||||
|
||||
if (fptr->f2) {
|
||||
if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == 0) {
|
||||
rb_sys_fail(fptr->path);
|
||||
|
@ -2255,7 +2274,7 @@ set_outfile(val, var, orig, stdf)
|
|||
|
||||
if (val == *var) return;
|
||||
|
||||
if (TYPE(*var) == T_FILE) {
|
||||
if (TYPE(*var) == T_FILE && !rb_io_closed(*var)) {
|
||||
rb_io_flush(*var);
|
||||
}
|
||||
if (TYPE(val) != T_FILE) {
|
||||
|
@ -2361,7 +2380,7 @@ rb_io_initialize(argc, argv, io)
|
|||
RFILE(io)->fptr = 0;
|
||||
}
|
||||
if (rb_scan_args(argc, argv, "11", &fnum, &mode) == 2) {
|
||||
SafeStr(mode);
|
||||
SafeStringValue(mode);
|
||||
m = RSTRING(mode)->ptr;
|
||||
}
|
||||
MakeOpenFile(io, fp);
|
||||
|
@ -2381,7 +2400,7 @@ rb_file_initialize(argc, argv, io)
|
|||
char *path, *mode;
|
||||
|
||||
rb_scan_args(argc, argv, "12", &fname, &vmode, &perm);
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
path = RSTRING(fname)->ptr;
|
||||
|
||||
if (RFILE(io)->fptr) {
|
||||
|
@ -2400,7 +2419,7 @@ rb_file_initialize(argc, argv, io)
|
|||
mode = "r";
|
||||
}
|
||||
else {
|
||||
mode = STR2CSTR(vmode);
|
||||
mode = StringValuePtr(vmode);
|
||||
}
|
||||
file = rb_file_open_internal(io, RSTRING(fname)->ptr, mode);
|
||||
}
|
||||
|
@ -2424,7 +2443,7 @@ rb_io_s_for_fd(argc, argv, klass)
|
|||
OBJSETUP(io, klass, T_FILE);
|
||||
|
||||
if (rb_scan_args(argc, argv, "11", &fnum, &mode) == 2) {
|
||||
SafeStr(mode);
|
||||
SafeStringValue(mode);
|
||||
m = RSTRING(mode)->ptr;
|
||||
}
|
||||
MakeOpenFile(io, fp);
|
||||
|
@ -2482,7 +2501,7 @@ next_argv()
|
|||
next_p = 0;
|
||||
if (RARRAY(rb_argv)->len > 0) {
|
||||
filename = rb_ary_shift(rb_argv);
|
||||
fn = STR2CSTR(filename);
|
||||
fn = StringValuePtr(filename);
|
||||
if (strlen(fn) == 1 && fn[0] == '-') {
|
||||
current_file = rb_stdin;
|
||||
if (ruby_inplace_mode) {
|
||||
|
@ -2681,7 +2700,7 @@ rb_f_backquote(obj, str)
|
|||
{
|
||||
VALUE port, result;
|
||||
|
||||
SafeStr(str);
|
||||
SafeStringValue(str);
|
||||
port = pipe_open(RSTRING(str)->ptr, "r");
|
||||
if (NIL_P(port)) return rb_str_new(0,0);
|
||||
result = read_all(port);
|
||||
|
@ -2885,7 +2904,7 @@ rb_io_ctl(io, req, arg, io_p)
|
|||
narg = 1;
|
||||
}
|
||||
else {
|
||||
arg = rb_str_to_str(arg);
|
||||
StringValue(arg);
|
||||
|
||||
#ifdef IOCPARM_MASK
|
||||
#ifndef IOCPARM_LEN
|
||||
|
@ -2984,10 +3003,11 @@ rb_f_syscall(argc, argv)
|
|||
arg[i] = (unsigned long)NUM2INT(*argv);
|
||||
}
|
||||
else {
|
||||
VALUE v = rb_str_to_str(*argv);
|
||||
VALUE v = *argv;
|
||||
|
||||
StringValue(v);
|
||||
rb_str_modify(v);
|
||||
arg[i] = (unsigned long)RSTRING(*argv)->ptr;
|
||||
arg[i] = (unsigned long)RSTRING(v)->ptr;
|
||||
}
|
||||
argv++;
|
||||
i++;
|
||||
|
@ -3107,7 +3127,7 @@ rb_io_s_foreach(argc, argv, io)
|
|||
struct foreach_arg arg;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &fname, &arg.sep);
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
|
||||
arg.argc = argc - 1;
|
||||
arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
|
||||
|
@ -3132,7 +3152,7 @@ rb_io_s_readlines(argc, argv, io)
|
|||
struct foreach_arg arg;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &fname, &arg.sep);
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
|
||||
arg.argc = argc - 1;
|
||||
arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
|
||||
|
@ -3157,7 +3177,7 @@ rb_io_s_read(argc, argv, io)
|
|||
struct foreach_arg arg;
|
||||
|
||||
rb_scan_args(argc, argv, "12", &fname, &arg.sep, &offset);
|
||||
SafeStr(fname);
|
||||
SafeStringValue(fname);
|
||||
|
||||
arg.argc = argc ? 1 : 0;
|
||||
arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
|
||||
|
@ -3256,7 +3276,7 @@ argf_read(argc, argv)
|
|||
if (!next_argv()) return str;
|
||||
if (TYPE(current_file) != T_FILE) {
|
||||
tmp = argf_forward();
|
||||
STR2CSTR(tmp);
|
||||
StringValue(tmp);
|
||||
}
|
||||
else {
|
||||
tmp = io_read(argc, argv, current_file);
|
||||
|
@ -3410,11 +3430,13 @@ static void
|
|||
opt_i_set(val)
|
||||
VALUE val;
|
||||
{
|
||||
if (ruby_inplace_mode) free(ruby_inplace_mode);
|
||||
if (!RTEST(val)) {
|
||||
ruby_inplace_mode = 0;
|
||||
return;
|
||||
}
|
||||
ruby_inplace_mode = STR2CSTR(val);
|
||||
StringValue(val);
|
||||
ruby_inplace_mode = strdup(RSTRING(val)->ptr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3463,9 +3485,9 @@ Init_IO()
|
|||
rb_rs = rb_default_rs = rb_str_new2("\n"); rb_output_rs = Qnil;
|
||||
rb_global_variable(&rb_default_rs);
|
||||
OBJ_FREEZE(rb_default_rs); /* avoid modifying RS_default */
|
||||
rb_define_hooked_variable("$/", &rb_rs, 0, rb_str_setter);
|
||||
rb_define_hooked_variable("$-0", &rb_rs, 0, rb_str_setter);
|
||||
rb_define_hooked_variable("$\\", &rb_output_rs, 0, rb_str_setter);
|
||||
rb_define_variable("$/", &rb_rs);
|
||||
rb_define_variable("$-0", &rb_rs);
|
||||
rb_define_variable("$\\", &rb_output_rs);
|
||||
|
||||
rb_define_hooked_variable("$.", &lineno, 0, lineno_setter);
|
||||
rb_define_virtual_variable("$_", rb_lastline_get, rb_lastline_set);
|
||||
|
|
13
marshal.c
13
marshal.c
|
@ -18,7 +18,7 @@
|
|||
double strtod();
|
||||
#endif
|
||||
|
||||
#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG || SIZEOF_INT*2 <= SIZEOF___INT64
|
||||
#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG || SIZEOF_ING*2 <= SIZEOF_LONG
|
||||
typedef unsigned int BDIGIT;
|
||||
#define SIZEOF_BDIGITS SIZEOF_INT
|
||||
#else
|
||||
|
@ -188,7 +188,7 @@ w_float(d, arg)
|
|||
{
|
||||
char buf[100];
|
||||
|
||||
sprintf(buf, "%.12g", d);
|
||||
sprintf(buf, "%.16g", d);
|
||||
w_bytes(buf, strlen(buf), arg);
|
||||
}
|
||||
|
||||
|
@ -1042,12 +1042,11 @@ marshal_load(argc, argv)
|
|||
arg.taint = Qtrue;
|
||||
}
|
||||
else if (rb_respond_to(port, rb_intern("to_str"))) {
|
||||
int len;
|
||||
|
||||
arg.taint = OBJ_TAINTED(port); /* original taintedness */
|
||||
StringValue(port); /* possible conversion */
|
||||
arg.fp = 0;
|
||||
arg.ptr = rb_str2cstr(port, &len);
|
||||
arg.end = arg.ptr + len;
|
||||
arg.taint = OBJ_TAINTED(port);
|
||||
arg.ptr = RSTRING(port)->ptr;
|
||||
arg.end = arg.ptr + RSTRING(port)->len;
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eTypeError, "instance of IO needed");
|
||||
|
|
16
node.h
16
node.h
|
@ -131,7 +131,7 @@ typedef struct RNode {
|
|||
struct RNode *node;
|
||||
ID id;
|
||||
VALUE value;
|
||||
VALUE (*cfunc)();
|
||||
VALUE (*cfunc)(ANYARGS);
|
||||
ID *tbl;
|
||||
} u1;
|
||||
union {
|
||||
|
@ -237,7 +237,7 @@ typedef struct RNode {
|
|||
#define NEW_CFUNC(f,c) rb_node_newnode(NODE_CFUNC,f,c,0)
|
||||
#define NEW_IFUNC(f,c) rb_node_newnode(NODE_IFUNC,f,c,0)
|
||||
#define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2))
|
||||
#define NEW_SCOPE(b) rb_node_newnode(NODE_SCOPE,local_tbl(),cur_cref,(b))
|
||||
#define NEW_SCOPE(b) rb_node_newnode(NODE_SCOPE,local_tbl(),0,(b))
|
||||
#define NEW_BLOCK(a) rb_node_newnode(NODE_BLOCK,a,0,0)
|
||||
#define NEW_IF(c,t,e) rb_node_newnode(NODE_IF,c,t,e)
|
||||
#define NEW_UNLESS(c,t,e) NEW_IF(c,e,t)
|
||||
|
@ -309,14 +309,12 @@ typedef struct RNode {
|
|||
#define NEW_ALIAS(n,o) rb_node_newnode(NODE_ALIAS,o,n,0)
|
||||
#define NEW_VALIAS(n,o) rb_node_newnode(NODE_VALIAS,o,n,0)
|
||||
#define NEW_UNDEF(i) rb_node_newnode(NODE_UNDEF,0,i,0)
|
||||
#define NEW_CLASS(n,b,s) rb_node_newnode(NODE_CLASS,n,NEW_CBODY(b),(s))
|
||||
#define NEW_SCLASS(r,b) rb_node_newnode(NODE_SCLASS,r,NEW_CBODY(b),0)
|
||||
#define NEW_MODULE(n,b) rb_node_newnode(NODE_MODULE,n,NEW_CBODY(b),0)
|
||||
#define NEW_CLASS(n,b,s) rb_node_newnode(NODE_CLASS,n,NEW_SCOPE(b),(s))
|
||||
#define NEW_SCLASS(r,b) rb_node_newnode(NODE_SCLASS,r,NEW_SCOPE(b),0)
|
||||
#define NEW_MODULE(n,b) rb_node_newnode(NODE_MODULE,n,NEW_SCOPE(b),0)
|
||||
#define NEW_COLON2(c,i) rb_node_newnode(NODE_COLON2,c,i,0)
|
||||
#define NEW_COLON3(i) rb_node_newnode(NODE_COLON3,0,i,0)
|
||||
#define NEW_CREF0() (cur_cref=RNODE(ruby_frame->cbase))
|
||||
#define NEW_CREF() (cur_cref=rb_node_newnode(NODE_CREF,0,0,cur_cref))
|
||||
#define NEW_CBODY(b) (cur_cref->nd_body=NEW_SCOPE(b),cur_cref)
|
||||
#define NEW_CREF(c) (rb_node_newnode(NODE_CREF,0,0,c))
|
||||
#define NEW_DOT2(b,e) rb_node_newnode(NODE_DOT2,b,e,0)
|
||||
#define NEW_DOT3(b,e) rb_node_newnode(NODE_DOT3,b,e,0)
|
||||
#define NEW_ATTRSET(a) rb_node_newnode(NODE_ATTRSET,a,0,0)
|
||||
|
@ -342,7 +340,7 @@ NODE *rb_compile_string _((const char*, VALUE, int));
|
|||
NODE *rb_compile_file _((const char*, VALUE, int));
|
||||
|
||||
void rb_add_method _((VALUE, ID, NODE *, int));
|
||||
NODE *rb_node_newnode();
|
||||
NODE *rb_node_newnode(ANYARGS);
|
||||
|
||||
struct global_entry *rb_global_entry _((ID));
|
||||
VALUE rb_gvar_get _((struct global_entry *));
|
||||
|
|
20
numeric.c
20
numeric.c
|
@ -56,7 +56,7 @@ coerce_rescue(x)
|
|||
{
|
||||
rb_raise(rb_eTypeError, "%s can't be coerced into %s",
|
||||
rb_special_const_p(x[1])?
|
||||
STR2CSTR(rb_inspect(x[1])):
|
||||
RSTRING(rb_inspect(x[1]))->ptr:
|
||||
rb_class2name(CLASS_OF(x[1])),
|
||||
rb_class2name(CLASS_OF(x[0])));
|
||||
return Qnil; /* dummy */
|
||||
|
@ -227,7 +227,8 @@ flo_to_s(flt)
|
|||
memmove(ind+2, ind, len-(ind-buf)+1);
|
||||
ind[0] = '.';
|
||||
ind[1] = '0';
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
strcat(buf, ".0");
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +333,7 @@ flodivmod(x, y, divp, modp)
|
|||
double z;
|
||||
|
||||
modf(x/y, &z);
|
||||
mod = x - z * x;
|
||||
mod = x - z * y;
|
||||
}
|
||||
#endif
|
||||
div = (x - mod) / y;
|
||||
|
@ -448,6 +449,7 @@ flo_hash(num)
|
|||
int i, hash;
|
||||
|
||||
d = RFLOAT(num)->value;
|
||||
if (d == 0) d = fabs(d);
|
||||
c = (char*)&d;
|
||||
for (hash=0, i=0; i<sizeof(double);i++) {
|
||||
hash += c[i] * 971;
|
||||
|
@ -593,8 +595,8 @@ static VALUE
|
|||
flo_eql(x, y)
|
||||
VALUE x, y;
|
||||
{
|
||||
if (TYPE(y) == T_FLOAT) {
|
||||
if (RFLOAT(x)->value == RFLOAT(y)->value) return Qtrue;
|
||||
if (TYPE(y) == T_FLOAT && RFLOAT(x)->value == RFLOAT(y)->value) {
|
||||
return Qtrue;
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
|
@ -1295,12 +1297,14 @@ static VALUE
|
|||
fix_aref(fix, idx)
|
||||
VALUE fix, idx;
|
||||
{
|
||||
unsigned long val = FIX2LONG(fix);
|
||||
long val = FIX2LONG(fix);
|
||||
int i = NUM2INT(idx);
|
||||
|
||||
if (i < 0 || sizeof(VALUE)*CHAR_BIT-1 < i)
|
||||
if (i < 0 || sizeof(VALUE)*CHAR_BIT-1 < i) {
|
||||
if (val < 0) return INT2FIX(1);
|
||||
return INT2FIX(0);
|
||||
if (val & (1<<i))
|
||||
}
|
||||
if (val & (1L<<i))
|
||||
return INT2FIX(1);
|
||||
return INT2FIX(0);
|
||||
}
|
||||
|
|
69
object.c
69
object.c
|
@ -226,12 +226,10 @@ rb_obj_is_instance_of(obj, c)
|
|||
return Qfalse;
|
||||
|
||||
case T_FALSE:
|
||||
if (obj) return Qfalse;
|
||||
return Qtrue;
|
||||
return RTEST(obj) ? Qfalse : Qtrue;
|
||||
|
||||
case T_TRUE:
|
||||
if (obj) return Qtrue;
|
||||
return Qfalse;
|
||||
return RTEST(obj) ? Qtrue : Qfalse;
|
||||
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "class or module required");
|
||||
|
@ -380,7 +378,7 @@ nil_plus(x, y)
|
|||
return y;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "tried to add %s(%s) to nil",
|
||||
STR2CSTR(rb_inspect(y)),
|
||||
RSTRING(rb_inspect(y))->ptr,
|
||||
rb_class2name(CLASS_OF(y)));
|
||||
}
|
||||
/* not reached */
|
||||
|
@ -532,36 +530,6 @@ sym_intern(sym)
|
|||
return sym;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_clone(module)
|
||||
VALUE module;
|
||||
{
|
||||
NEWOBJ(clone, struct RClass);
|
||||
CLONESETUP(clone, module);
|
||||
|
||||
clone->super = RCLASS(module)->super;
|
||||
if (RCLASS(module)->iv_tbl) {
|
||||
clone->iv_tbl = st_copy(RCLASS(module)->iv_tbl);
|
||||
}
|
||||
if (RCLASS(module)->m_tbl) {
|
||||
clone->m_tbl = st_copy(RCLASS(module)->m_tbl);
|
||||
}
|
||||
|
||||
return (VALUE)clone;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_dup(mod)
|
||||
VALUE mod;
|
||||
{
|
||||
VALUE dup = rb_mod_clone(mod);
|
||||
OBJSETUP(dup, RBASIC(mod)->klass, BUILTIN_TYPE(mod));
|
||||
if (FL_TEST(mod, FL_SINGLETON)) {
|
||||
FL_SET(dup, FL_SINGLETON);
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_to_s(klass)
|
||||
VALUE klass;
|
||||
|
@ -734,7 +702,7 @@ rb_to_id(name)
|
|||
id = SYM2ID(name);
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "%s is not a symbol", STR2CSTR(rb_inspect(name)));
|
||||
rb_raise(rb_eTypeError, "%s is not a symbol", RSTRING(rb_inspect(name))->ptr);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
@ -798,14 +766,24 @@ static VALUE
|
|||
rb_mod_const_get(mod, name)
|
||||
VALUE mod, name;
|
||||
{
|
||||
return rb_const_get(mod, rb_to_id(name));
|
||||
ID id = rb_to_id(name);
|
||||
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "wrong constant name %s", name);
|
||||
}
|
||||
return rb_const_get(mod, id);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_const_set(mod, name, value)
|
||||
VALUE mod, name, value;
|
||||
{
|
||||
rb_const_set(mod, rb_to_id(name), value);
|
||||
ID id = rb_to_id(name);
|
||||
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "wrong constant name %s", name);
|
||||
}
|
||||
rb_const_set(mod, id, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -813,7 +791,12 @@ static VALUE
|
|||
rb_mod_const_defined(mod, name)
|
||||
VALUE mod, name;
|
||||
{
|
||||
return rb_const_defined_at(mod, rb_to_id(name));
|
||||
ID id = rb_to_id(name);
|
||||
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "wrong constant name %s", name);
|
||||
}
|
||||
return rb_const_defined_at(mod, id);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -974,7 +957,7 @@ rb_Float(val)
|
|||
char *q, *p, *end;
|
||||
double d;
|
||||
|
||||
q = p = STR2CSTR(val);
|
||||
q = p = StringValuePtr(val);
|
||||
while (*p && ISSPACE(*p)) p++;
|
||||
again:
|
||||
d = strtod(p, &end);
|
||||
|
@ -1054,9 +1037,7 @@ rb_str2cstr(str, len)
|
|||
VALUE str;
|
||||
int *len;
|
||||
{
|
||||
if (TYPE(str) != T_STRING) {
|
||||
str = rb_str_to_str(str);
|
||||
}
|
||||
StringValue(str);
|
||||
if (len) *len = RSTRING(str)->len;
|
||||
else if (ruby_verbose && RSTRING(str)->len != strlen(RSTRING(str)->ptr)) {
|
||||
rb_warn("string contains \\0 character");
|
||||
|
@ -1232,6 +1213,8 @@ Init_Object()
|
|||
|
||||
rb_cSymbol = rb_define_class("Symbol", rb_cObject);
|
||||
rb_undef_method(CLASS_OF(rb_cSymbol), "new");
|
||||
rb_define_singleton_method(rb_cSymbol, "all_symbols", rb_sym_all_symbols, 0);
|
||||
|
||||
rb_define_method(rb_cSymbol, "type", sym_type, 0);
|
||||
rb_define_method(rb_cSymbol, "to_i", sym_to_i, 0);
|
||||
rb_define_method(rb_cSymbol, "to_int", sym_to_i, 0);
|
||||
|
|
70
pack.c
70
pack.c
|
@ -339,14 +339,16 @@ pack_pack(ary, fmt)
|
|||
#ifdef NATINT_PACK
|
||||
int natint; /* native integer */
|
||||
#endif
|
||||
|
||||
p = rb_str2cstr(fmt, &plen);
|
||||
pend = p + plen;
|
||||
|
||||
StringValue(fmt);
|
||||
p = RSTRING(fmt)->ptr;
|
||||
pend = p + RSTRING(fmt)->len;
|
||||
res = rb_str_new(0, 0);
|
||||
|
||||
items = RARRAY(ary)->len;
|
||||
idx = 0;
|
||||
|
||||
#define THISFROM RARRAY(ary)->ptr[idx]
|
||||
#define NEXTFROM (items-- > 0 ? RARRAY(ary)->ptr[idx++] : (rb_raise(rb_eArgError, toofew),0))
|
||||
|
||||
while (p < pend) {
|
||||
|
@ -390,7 +392,9 @@ pack_pack(ary, fmt)
|
|||
plen = 0;
|
||||
}
|
||||
else {
|
||||
ptr = rb_str2cstr(from, &plen);
|
||||
StringValue(from);
|
||||
ptr = RSTRING(from)->ptr;
|
||||
plen = RSTRING(from)->len;
|
||||
}
|
||||
|
||||
if (p[-1] == '*')
|
||||
|
@ -824,7 +828,10 @@ pack_pack(ary, fmt)
|
|||
|
||||
case 'u':
|
||||
case 'm':
|
||||
ptr = rb_str2cstr(NEXTFROM, &plen);
|
||||
from = NEXTFROM;
|
||||
StringValue(from);
|
||||
ptr = RSTRING(from)->ptr;
|
||||
plen = RSTRING(from)->len;
|
||||
|
||||
if (len <= 2)
|
||||
len = 45;
|
||||
|
@ -851,6 +858,14 @@ pack_pack(ary, fmt)
|
|||
break;
|
||||
|
||||
case 'P':
|
||||
from = THISFROM;
|
||||
if (!NIL_P(from)) {
|
||||
StringValue(from);
|
||||
if (RSTRING(from)->len < len) {
|
||||
rb_raise(rb_eArgError, "too short buffer for P(%d for %d)",
|
||||
RSTRING(from)->len, len);
|
||||
}
|
||||
}
|
||||
len = 1;
|
||||
/* FALL THROUGH */
|
||||
case 'p':
|
||||
|
@ -858,9 +873,12 @@ pack_pack(ary, fmt)
|
|||
char *t;
|
||||
from = NEXTFROM;
|
||||
if (NIL_P(from)) {
|
||||
from = rb_str_new(0, 0);
|
||||
t = 0;
|
||||
}
|
||||
else {
|
||||
StringValue(from);
|
||||
t = RSTRING(from)->ptr;
|
||||
}
|
||||
t = STR2CSTR(from);
|
||||
rb_str_associate(res, from);
|
||||
rb_str_cat(res, (char*)&t, sizeof(char*));
|
||||
}
|
||||
|
@ -1084,10 +1102,12 @@ pack_unpack(str, fmt)
|
|||
int natint; /* native integer */
|
||||
#endif
|
||||
|
||||
s = rb_str2cstr(str, &len);
|
||||
send = s + len;
|
||||
p = rb_str2cstr(fmt, &len);
|
||||
pend = p + len;
|
||||
StringValue(str);
|
||||
s = RSTRING(str)->ptr;
|
||||
send = s + RSTRING(str)->len;
|
||||
StringValue(fmt);
|
||||
p = RSTRING(fmt)->ptr;
|
||||
pend = p + RSTRING(fmt)->len;
|
||||
|
||||
ary = rb_ary_new();
|
||||
while (p < pend) {
|
||||
|
@ -1611,17 +1631,17 @@ pack_unpack(str, fmt)
|
|||
case 'P':
|
||||
if (sizeof(char *) <= send - s) {
|
||||
char *t;
|
||||
VALUE a, tmp;
|
||||
VALUE tmp;
|
||||
|
||||
if (!(a = rb_str_associated(str))) {
|
||||
rb_raise(rb_eArgError, "no associated pointer");
|
||||
}
|
||||
memcpy(&t, s, sizeof(char *));
|
||||
s += sizeof(char *);
|
||||
|
||||
if (t) {
|
||||
VALUE *p, *pend;
|
||||
VALUE a, *p, *pend;
|
||||
|
||||
if (!(a = rb_str_associated(str))) {
|
||||
rb_raise(rb_eArgError, "no associated pointer");
|
||||
}
|
||||
p = RARRAY(a)->ptr;
|
||||
pend = p + RARRAY(a)->len;
|
||||
while (p < pend) {
|
||||
|
@ -1639,7 +1659,7 @@ pack_unpack(str, fmt)
|
|||
tmp = rb_tainted_str_new(t, len);
|
||||
}
|
||||
else {
|
||||
tmp = rb_str_new(0, 0);
|
||||
tmp = Qnil;
|
||||
}
|
||||
rb_ary_push(ary, tmp);
|
||||
}
|
||||
|
@ -1652,19 +1672,20 @@ pack_unpack(str, fmt)
|
|||
if (send - s < sizeof(char *))
|
||||
break;
|
||||
else {
|
||||
VALUE tmp;
|
||||
char *t;
|
||||
VALUE a, tmp;
|
||||
VALUE *p, *pend;
|
||||
|
||||
|
||||
if (!(a = rb_str_associated(str))) {
|
||||
rb_raise(rb_eArgError, "no associated pointer");
|
||||
}
|
||||
memcpy(&t, s, sizeof(char *));
|
||||
s += sizeof(char *);
|
||||
|
||||
if (t) {
|
||||
VALUE a, tmp;
|
||||
VALUE *p, *pend;
|
||||
|
||||
p = RARRAY(a)->ptr;
|
||||
if (!(a = rb_str_associated(str))) {
|
||||
rb_raise(rb_eArgError, "no associated pointer");
|
||||
}
|
||||
pend = p + RARRAY(a)->len;
|
||||
while (p < pend) {
|
||||
if (TYPE(*p) == T_STRING && RSTRING(*p)->ptr == t) {
|
||||
|
@ -1677,6 +1698,9 @@ pack_unpack(str, fmt)
|
|||
}
|
||||
tmp = rb_str_new2(t);
|
||||
}
|
||||
else {
|
||||
tmp = Qnil;
|
||||
}
|
||||
rb_ary_push(ary, tmp);
|
||||
}
|
||||
}
|
||||
|
|
53
parse.y
53
parse.y
|
@ -56,10 +56,8 @@ static enum lex_state {
|
|||
EXPR_CLASS, /* immediate after `class', no here document. */
|
||||
} lex_state;
|
||||
|
||||
#if SIZEOF_LONG_LONG > 0
|
||||
typedef unsigned long long stack_type;
|
||||
#elif SIZEOF___INT64 > 0
|
||||
typedef unsigned __int64 stack_type;
|
||||
#ifdef HAVE_LONG_LONG
|
||||
typedef unsigned LONG_LONG stack_type;
|
||||
#else
|
||||
typedef unsigned long stack_type;
|
||||
#endif
|
||||
|
@ -132,10 +130,6 @@ static struct RVarmap *dyna_push();
|
|||
static void dyna_pop();
|
||||
static int dyna_in_block();
|
||||
|
||||
#define cref_push() NEW_CREF()
|
||||
static void cref_pop();
|
||||
static NODE *cur_cref;
|
||||
|
||||
static void top_local_init();
|
||||
static void top_local_setup();
|
||||
%}
|
||||
|
@ -270,7 +264,6 @@ program : {
|
|||
$<vars>$ = ruby_dyna_vars;
|
||||
lex_state = EXPR_BEG;
|
||||
top_local_init();
|
||||
NEW_CREF0(); /* initialize constant c-ref */
|
||||
if ((VALUE)ruby_class == rb_cObject) class_nest = 0;
|
||||
else class_nest = 1;
|
||||
}
|
||||
|
@ -289,7 +282,6 @@ program : {
|
|||
}
|
||||
ruby_eval_tree = block_append(ruby_eval_tree, $2);
|
||||
top_local_setup();
|
||||
cur_cref = 0;
|
||||
class_nest = 0;
|
||||
ruby_dyna_vars = $<vars>1;
|
||||
}
|
||||
|
@ -1249,7 +1241,6 @@ primary : literal
|
|||
if (in_def || in_single)
|
||||
yyerror("class definition in method body");
|
||||
class_nest++;
|
||||
cref_push();
|
||||
local_push();
|
||||
$<num>$ = ruby_sourceline;
|
||||
}
|
||||
|
@ -1259,7 +1250,6 @@ primary : literal
|
|||
$$ = NEW_CLASS($2, $5, $3);
|
||||
nd_set_line($$, $<num>4);
|
||||
local_pop();
|
||||
cref_pop();
|
||||
class_nest--;
|
||||
}
|
||||
| kCLASS tLSHFT expr
|
||||
|
@ -1272,7 +1262,6 @@ primary : literal
|
|||
$<num>$ = in_single;
|
||||
in_single = 0;
|
||||
class_nest++;
|
||||
cref_push();
|
||||
local_push();
|
||||
}
|
||||
compstmt
|
||||
|
@ -1281,7 +1270,6 @@ primary : literal
|
|||
$$ = NEW_SCLASS($3, $7);
|
||||
fixpos($$, $3);
|
||||
local_pop();
|
||||
cref_pop();
|
||||
class_nest--;
|
||||
in_def = $<num>4;
|
||||
in_single = $<num>6;
|
||||
|
@ -1291,7 +1279,6 @@ primary : literal
|
|||
if (in_def || in_single)
|
||||
yyerror("module definition in method body");
|
||||
class_nest++;
|
||||
cref_push();
|
||||
local_push();
|
||||
$<num>$ = ruby_sourceline;
|
||||
}
|
||||
|
@ -1301,7 +1288,6 @@ primary : literal
|
|||
$$ = NEW_MODULE($2, $4);
|
||||
nd_set_line($$, $<num>3);
|
||||
local_pop();
|
||||
cref_pop();
|
||||
class_nest--;
|
||||
}
|
||||
| kDEF fname
|
||||
|
@ -1984,6 +1970,7 @@ yycompile(f, line)
|
|||
ruby_in_compile = 0;
|
||||
cond_nest = 0;
|
||||
cond_stack = 0;
|
||||
cmdarg_stack = 0;
|
||||
class_nest = 0;
|
||||
in_single = 0;
|
||||
in_def = 0;
|
||||
|
@ -3634,7 +3621,13 @@ yylex()
|
|||
if (CMDARG_P()) return kDO_BLOCK;
|
||||
return kDO;
|
||||
}
|
||||
return kw->id[state != EXPR_BEG];
|
||||
if (state == EXPR_BEG)
|
||||
return kw->id[0];
|
||||
else {
|
||||
if (kw->id[0] != kw->id[1])
|
||||
lex_state = EXPR_BEG;
|
||||
return kw->id[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4785,12 +4778,6 @@ dyna_in_block()
|
|||
return (lvtbl->dlev > 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cref_pop()
|
||||
{
|
||||
cur_cref = cur_cref->nd_next;
|
||||
}
|
||||
|
||||
void
|
||||
rb_parser_append_print()
|
||||
{
|
||||
|
@ -4874,7 +4861,6 @@ Init_sym()
|
|||
{
|
||||
sym_tbl = st_init_strtable_with_size(200);
|
||||
sym_rev_tbl = st_init_numtable_with_size(200);
|
||||
rb_global_variable((VALUE*)&cur_cref);
|
||||
rb_global_variable((VALUE*)&lex_lastline);
|
||||
}
|
||||
|
||||
|
@ -4983,6 +4969,25 @@ rb_id2name(id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
symbols_i(key, value, ary)
|
||||
char *key;
|
||||
ID value;
|
||||
VALUE ary;
|
||||
{
|
||||
rb_ary_push(ary, ID2SYM(value));
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_sym_all_symbols()
|
||||
{
|
||||
VALUE ary = rb_ary_new2(sym_tbl->num_entries);
|
||||
|
||||
st_foreach(sym_tbl, symbols_i, ary);
|
||||
return ary;
|
||||
}
|
||||
|
||||
int
|
||||
rb_is_const_id(id)
|
||||
ID id;
|
||||
|
|
83
process.c
83
process.c
|
@ -170,7 +170,7 @@ pst_wifsignaled(st)
|
|||
{
|
||||
int status = NUM2INT(st);
|
||||
|
||||
if (WIFSIGNALED(st))
|
||||
if (WIFSIGNALED(status))
|
||||
return Qtrue;
|
||||
else
|
||||
return Qfalse;
|
||||
|
@ -314,27 +314,13 @@ wait_each(key, value, data)
|
|||
return ST_DELETE;
|
||||
}
|
||||
|
||||
struct waitall_data {
|
||||
int pid;
|
||||
int status;
|
||||
VALUE ary;
|
||||
};
|
||||
|
||||
static int
|
||||
waitall_each(key, value, data)
|
||||
int key, value;
|
||||
struct waitall_data *data;
|
||||
VALUE data;
|
||||
{
|
||||
VALUE pid_status_member;
|
||||
|
||||
if (data->status != -1) return ST_STOP;
|
||||
|
||||
data->pid = key;
|
||||
data->status = value;
|
||||
pid_status_member = rb_ary_new2(2);
|
||||
rb_ary_push(pid_status_member, INT2NUM(key));
|
||||
rb_ary_push(pid_status_member, INT2NUM(value));
|
||||
rb_ary_push(data->ary, pid_status_member);
|
||||
last_status_set(value);
|
||||
rb_ary_push(data, rb_assoc_new(INT2NUM(key), rb_last_status));
|
||||
return ST_DELETE;
|
||||
}
|
||||
#endif
|
||||
|
@ -346,11 +332,13 @@ proc_wait()
|
|||
#ifdef NO_WAITPID
|
||||
struct wait_data data;
|
||||
|
||||
data.status = -1;
|
||||
st_foreach(pid_tbl, wait_each, &data);
|
||||
if (data.status != -1) {
|
||||
last_status_set(data.status);
|
||||
return INT2FIX(data.pid);
|
||||
if (pid_tbl) {
|
||||
data.status = -1;
|
||||
st_foreach(pid_tbl, wait_each, &data);
|
||||
if (data.status != -1) {
|
||||
last_status_set(data.status);
|
||||
return INT2FIX(data.pid);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
|
@ -416,17 +404,13 @@ proc_waitpid2(argc, argv)
|
|||
static VALUE
|
||||
proc_waitall()
|
||||
{
|
||||
VALUE pid_status_ary, pid_status_member;
|
||||
VALUE result;
|
||||
int pid, status;
|
||||
#ifdef NO_WAITPID
|
||||
struct waitall_data data;
|
||||
|
||||
data.ary = pid_status_ary = rb_ary_new();
|
||||
data.status = -1;
|
||||
st_foreach(pid_tbl, waitall_each, &data);
|
||||
if (data.status != -1) {
|
||||
last_status_set(data.status);
|
||||
return pid_status_ary;
|
||||
result = rb_ary_new();
|
||||
#ifdef NO_WAITPID
|
||||
if (pid_tbl) {
|
||||
st_foreach(pid_tbl, waitall_each, result);
|
||||
}
|
||||
|
||||
for (pid = -1;;) {
|
||||
|
@ -440,15 +424,11 @@ proc_waitall()
|
|||
}
|
||||
rb_sys_fail(0);
|
||||
}
|
||||
pid_status_member = rb_ary_new2(2);
|
||||
rb_ary_push(pid_status_member, INT2NUM(pid));
|
||||
rb_ary_push(pid_status_member, INT2NUM(status));
|
||||
rb_ary_push(pid_status_ary, pid_status_member);
|
||||
}
|
||||
if (RARRAY(pid_status_ary)->len != 0)
|
||||
last_status_set(status);
|
||||
rb_ary_push(result, rb_assoc_new(INT2NUM(pid), rb_last_status));
|
||||
}
|
||||
#else
|
||||
pid_status_ary = rb_ary_new();
|
||||
rb_last_status = Qnil;
|
||||
for (pid = -1;;) {
|
||||
pid = rb_waitpid(-1, 0, &status);
|
||||
if (pid == -1) {
|
||||
|
@ -456,13 +436,10 @@ proc_waitall()
|
|||
break;
|
||||
rb_sys_fail(0);
|
||||
}
|
||||
pid_status_member = rb_ary_new2(2);
|
||||
rb_ary_push(pid_status_member, INT2NUM(pid));
|
||||
rb_ary_push(pid_status_member, INT2NUM(status));
|
||||
rb_ary_push(pid_status_ary, pid_status_member);
|
||||
rb_ary_push(result, rb_assoc_new(INT2NUM(pid), rb_last_status));
|
||||
}
|
||||
#endif
|
||||
return pid_status_ary;
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRING_H
|
||||
|
@ -564,7 +541,7 @@ proc_exec_n(argc, argv, progv)
|
|||
}
|
||||
args = ALLOCA_N(char*, argc+1);
|
||||
for (i=0; i<argc; i++) {
|
||||
SafeStr(argv[i]);
|
||||
SafeStringValue(argv[i]);
|
||||
args[i] = RSTRING(argv[i])->ptr;
|
||||
}
|
||||
args[i] = 0;
|
||||
|
@ -694,7 +671,7 @@ proc_spawn_n(argc, argv, prog)
|
|||
SafeStr(argv[i]);
|
||||
args[i] = RSTRING(argv[i])->ptr;
|
||||
}
|
||||
SafeStr(prog);
|
||||
SafeStringValue(prog);
|
||||
args[i] = (char*) 0;
|
||||
if (args[0])
|
||||
return proc_spawn_v(args, RSTRING(prog)->ptr);
|
||||
|
@ -710,7 +687,7 @@ proc_spawn(sv)
|
|||
char **argv, **a;
|
||||
int status;
|
||||
|
||||
SafeStr(sv);
|
||||
SafeStringValue(sv);
|
||||
str = s = RSTRING(sv)->ptr;
|
||||
for (s = str; *s; s++) {
|
||||
if (*s != ' ' && !ISALPHA(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) {
|
||||
|
@ -753,12 +730,12 @@ rb_f_exec(argc, argv)
|
|||
argv[0] = RARRAY(argv[0])->ptr[1];
|
||||
}
|
||||
if (prog) {
|
||||
SafeStr(prog);
|
||||
SafeStringValue(prog);
|
||||
}
|
||||
if (argc == 1 && prog == 0) {
|
||||
VALUE cmd = argv[0];
|
||||
|
||||
SafeStr(cmd);
|
||||
SafeStringValue(cmd);
|
||||
rb_proc_exec(RSTRING(cmd)->ptr);
|
||||
}
|
||||
else {
|
||||
|
@ -876,7 +853,7 @@ rb_f_system(argc, argv)
|
|||
}
|
||||
cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
|
||||
|
||||
SafeStr(cmd);
|
||||
SafeStringValue(cmd);
|
||||
status = do_spawn(RSTRING(cmd)->ptr);
|
||||
last_status_set(status);
|
||||
|
||||
|
@ -900,7 +877,7 @@ rb_f_system(argc, argv)
|
|||
}
|
||||
cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
|
||||
|
||||
SafeStr(cmd);
|
||||
SafeStringValue(cmd);
|
||||
status = system(RSTRING(cmd)->ptr);
|
||||
last_status_set((status & 0xff) << 8);
|
||||
|
||||
|
@ -957,10 +934,10 @@ rb_f_system(argc, argv)
|
|||
}
|
||||
|
||||
if (prog) {
|
||||
SafeStr(prog);
|
||||
SafeStringValue(prog);
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
SafeStr(argv[i]);
|
||||
SafeStringValue(argv[i]);
|
||||
}
|
||||
retry:
|
||||
switch (pid = vfork()) {
|
||||
|
|
26
re.c
26
re.c
|
@ -936,7 +936,7 @@ rb_reg_match(re, str)
|
|||
int start;
|
||||
|
||||
if (NIL_P(str)) return Qnil;
|
||||
str = rb_str_to_str(str);
|
||||
StringValue(str);
|
||||
start = rb_reg_search(re, str, 0, 0);
|
||||
if (start < 0) {
|
||||
return Qnil;
|
||||
|
@ -990,7 +990,7 @@ rb_reg_initialize_m(argc, argv, self)
|
|||
else if (RTEST(argv[1])) flags = RE_OPTION_IGNORECASE;
|
||||
}
|
||||
if (argc == 3) {
|
||||
char *kcode = STR2CSTR(argv[2]);
|
||||
char *kcode = StringValuePtr(argv[2]);
|
||||
|
||||
switch (kcode[0]) {
|
||||
case 'n': case 'N':
|
||||
|
@ -1016,11 +1016,8 @@ rb_reg_initialize_m(argc, argv, self)
|
|||
rb_reg_initialize(self, RREGEXP(src)->str, RREGEXP(src)->len, flags);
|
||||
}
|
||||
else {
|
||||
char *p;
|
||||
int len;
|
||||
|
||||
p = rb_str2cstr(src, &len);
|
||||
rb_reg_initialize(self, p, len, flags);
|
||||
StringValue(src);
|
||||
rb_reg_initialize(self, RSTRING(src)->ptr, RSTRING(src)->len, flags);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -1047,17 +1044,17 @@ rb_reg_s_quote(argc, argv)
|
|||
int kcode_saved = reg_kcode;
|
||||
char *s, *send, *t;
|
||||
VALUE tmp;
|
||||
int len;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &str, &kcode);
|
||||
if (!NIL_P(kcode)) {
|
||||
rb_set_kcode(STR2CSTR(kcode));
|
||||
rb_set_kcode(StringValuePtr(kcode));
|
||||
curr_kcode = reg_kcode;
|
||||
reg_kcode = kcode_saved;
|
||||
}
|
||||
s = rb_str2cstr(str, &len);
|
||||
send = s + len;
|
||||
tmp = rb_str_new(0, len*2);
|
||||
StringValue(str);
|
||||
s = RSTRING(str)->ptr;
|
||||
send = s + RSTRING(str)->len;
|
||||
tmp = rb_str_new(0, RSTRING(str)->len*2);
|
||||
t = RSTRING(tmp)->ptr;
|
||||
|
||||
for (; s < send; s++) {
|
||||
|
@ -1288,10 +1285,10 @@ rb_set_kcode(code)
|
|||
|
||||
static void
|
||||
kcode_setter(val)
|
||||
struct RString *val;
|
||||
VALUE val;
|
||||
{
|
||||
may_need_recompile = 1;
|
||||
rb_set_kcode(STR2CSTR(val));
|
||||
rb_set_kcode(StringValuePtr(val));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1406,6 +1403,7 @@ Init_Regexp()
|
|||
rb_define_method(rb_cMatch, "begin", match_begin, 1);
|
||||
rb_define_method(rb_cMatch, "end", match_end, 1);
|
||||
rb_define_method(rb_cMatch, "to_a", match_to_a, 0);
|
||||
rb_define_method(rb_cMatch, "to_ary", match_to_a, 0);
|
||||
rb_define_method(rb_cMatch, "[]", match_aref, -1);
|
||||
rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0);
|
||||
rb_define_method(rb_cMatch, "post_match", rb_reg_match_post, 0);
|
||||
|
|
12
regex.c
12
regex.c
|
@ -1049,7 +1049,7 @@ calculate_must_string(start, end)
|
|||
EXTRACT_NUMBER_AND_INCR(mcnt, p);
|
||||
if (mcnt > 0) p += mcnt;
|
||||
if ((enum regexpcode)p[-3] == jump) {
|
||||
p -= 3;
|
||||
p -= 2;
|
||||
EXTRACT_NUMBER_AND_INCR(mcnt, p);
|
||||
if (mcnt > 0) p += mcnt;
|
||||
}
|
||||
|
@ -1438,6 +1438,9 @@ re_compile_pattern(pattern, size, bufp)
|
|||
EXTEND_BUFFER;
|
||||
}
|
||||
range_retry:
|
||||
if (range && had_char_class) {
|
||||
FREE_AND_RETURN(stackb, "invalid regular expression; can't use character class as an end value of range");
|
||||
}
|
||||
PATFETCH(c);
|
||||
|
||||
if (c == ']') {
|
||||
|
@ -1459,6 +1462,7 @@ re_compile_pattern(pattern, size, bufp)
|
|||
PATFETCH_MBC(c);
|
||||
had_mbchar++;
|
||||
}
|
||||
had_char_class = 0;
|
||||
|
||||
/* \ escapes characters when inside [...]. */
|
||||
if (c == '\\') {
|
||||
|
@ -1473,6 +1477,7 @@ re_compile_pattern(pattern, size, bufp)
|
|||
if (current_mbctype) {
|
||||
set_list_bits(0x80, 0xffffffff, b);
|
||||
}
|
||||
had_char_class = 1;
|
||||
last = -1;
|
||||
continue;
|
||||
|
||||
|
@ -1483,6 +1488,7 @@ re_compile_pattern(pattern, size, bufp)
|
|||
!current_mbctype && SYNTAX(c) != Sword2))
|
||||
SET_LIST_BIT(c);
|
||||
}
|
||||
had_char_class = 1;
|
||||
last = -1;
|
||||
continue;
|
||||
|
||||
|
@ -1490,6 +1496,7 @@ re_compile_pattern(pattern, size, bufp)
|
|||
for (c = 0; c < 256; c++)
|
||||
if (ISSPACE(c))
|
||||
SET_LIST_BIT(c);
|
||||
had_char_class = 1;
|
||||
last = -1;
|
||||
continue;
|
||||
|
||||
|
@ -1499,12 +1506,14 @@ re_compile_pattern(pattern, size, bufp)
|
|||
SET_LIST_BIT(c);
|
||||
if (current_mbctype)
|
||||
set_list_bits(0x80, 0xffffffff, b);
|
||||
had_char_class = 1;
|
||||
last = -1;
|
||||
continue;
|
||||
|
||||
case 'd':
|
||||
for (c = '0'; c <= '9'; c++)
|
||||
SET_LIST_BIT(c);
|
||||
had_char_class = 1;
|
||||
last = -1;
|
||||
continue;
|
||||
|
||||
|
@ -1514,6 +1523,7 @@ re_compile_pattern(pattern, size, bufp)
|
|||
SET_LIST_BIT(c);
|
||||
if (current_mbctype)
|
||||
set_list_bits(0x80, 0xffffffff, b);
|
||||
had_char_class = 1;
|
||||
last = -1;
|
||||
continue;
|
||||
|
||||
|
|
22
ruby.c
22
ruby.c
|
@ -138,7 +138,8 @@ rubylib_mangle(s, l)
|
|||
if (*s == '\\') *s = '/';
|
||||
s++;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
notfound = 1;
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +235,8 @@ ruby_init_loadpath()
|
|||
p -= 4;
|
||||
*p = 0;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
strcpy(libpath, ".");
|
||||
p = libpath + 1;
|
||||
}
|
||||
|
@ -334,7 +336,8 @@ process_sflag()
|
|||
n = RARRAY(rb_argv)->len;
|
||||
args = RARRAY(rb_argv)->ptr;
|
||||
while (n > 0) {
|
||||
char *s = STR2CSTR(*args++);
|
||||
VALUE v = *args++;
|
||||
char *s = StringValuePtr(v);
|
||||
char *p;
|
||||
|
||||
if (s[0] != '-') break;
|
||||
|
@ -876,11 +879,13 @@ set_arg0(val, id)
|
|||
len = s - origargv[0];
|
||||
}
|
||||
#endif
|
||||
s = rb_str2cstr(val, &i);
|
||||
StringValue(val);
|
||||
s = RSTRING(val)->ptr;
|
||||
i = RSTRING(val)->len;
|
||||
#ifndef __hpux
|
||||
if (i > len) {
|
||||
memcpy(origargv[0], s, len);
|
||||
origargv[0][len] = '\0';
|
||||
if (i < len) {
|
||||
memcpy(origargv[0], s, i);
|
||||
origargv[0][i] = '\0';
|
||||
}
|
||||
else {
|
||||
memcpy(origargv[0], s, i);
|
||||
|
@ -898,7 +903,8 @@ set_arg0(val, id)
|
|||
RSTRING(val)->len = i;
|
||||
*(s + i) = '\0';
|
||||
pstat(PSTAT_SETCMD, j, PST_CLEN, 0, 0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
union pstun j;
|
||||
j.pst_command = s;
|
||||
pstat(PSTAT_SETCMD, j, i, 0, 0);
|
||||
|
|
55
ruby.h
55
ruby.h
|
@ -63,6 +63,12 @@ extern "C" {
|
|||
# define __(args) ()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define ANYARGS ...
|
||||
#else
|
||||
#define ANYARGS
|
||||
#endif
|
||||
|
||||
#ifndef NORETURN
|
||||
# define NORETURN(x) x
|
||||
#endif
|
||||
|
@ -108,9 +114,11 @@ typedef unsigned long ID;
|
|||
#define rb_fix_new(v) INT2FIX(v)
|
||||
VALUE rb_int2inum _((long));
|
||||
#define INT2NUM(v) rb_int2inum(v)
|
||||
#define LONG2NUM(v) INT2NUM(v)
|
||||
#define rb_int_new(v) rb_int2inum(v)
|
||||
VALUE rb_uint2inum _((unsigned long));
|
||||
#define UINT2NUM(v) rb_uint2inum(v)
|
||||
#define ULONG2NUM(v) UINT2NUM(v)
|
||||
#define rb_uint_new(v) rb_uint2inum(v)
|
||||
|
||||
#define FIX2LONG(x) RSHIFT((long)x,1)
|
||||
|
@ -176,15 +184,22 @@ VALUE rb_uint2inum _((unsigned long));
|
|||
|
||||
void rb_check_type _((VALUE,int));
|
||||
#define Check_Type(v,t) rb_check_type((VALUE)(v),t)
|
||||
void rb_check_safe_str _((VALUE));
|
||||
/* obsolete macro - use SafeStr(v) */
|
||||
#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))
|
||||
|
||||
VALUE rb_str_to_str _((VALUE));
|
||||
#define SafeStr(v) do {\
|
||||
v = rb_str_to_str(v);\
|
||||
#define StringValue(v) do {\
|
||||
if (TYPE(v) != T_STRING) v = rb_str_to_str(v);\
|
||||
} while (0)
|
||||
void rb_check_safe_str _((VALUE));
|
||||
/* obsolete macro - use SafeStringValue(v) */
|
||||
#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))
|
||||
#define SafeStringValue(v) do {\
|
||||
if (TYPE(v) != T_STRING) v = rb_str_to_str(v);\
|
||||
rb_check_safe_str(v);\
|
||||
} while (0)
|
||||
|
||||
#define StringValuePtr(v) \
|
||||
(((TYPE(v) != T_STRING) ? v = rb_str_to_str(v) : (v)), RSTRING(v)->ptr)
|
||||
|
||||
void rb_secure _((int));
|
||||
|
||||
EXTERN int ruby_safe_level;
|
||||
|
@ -212,8 +227,9 @@ int rb_fix2int _((VALUE));
|
|||
double rb_num2dbl _((VALUE));
|
||||
#define NUM2DBL(x) rb_num2dbl((VALUE)(x))
|
||||
|
||||
/* obsolete API - use StringValue() */
|
||||
char *rb_str2cstr _((VALUE,int*));
|
||||
#define str2cstr(x,l) rb_str2cstr((VALUE)(x),(l))
|
||||
/* obsolete API - use StringValuePtr() */
|
||||
#define STR2CSTR(x) rb_str2cstr((VALUE)(x),0)
|
||||
|
||||
#define NUM2CHR(x) (((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\
|
||||
|
@ -402,8 +418,8 @@ void xfree _((void*));
|
|||
#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))
|
||||
#define MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n))
|
||||
|
||||
void rb_glob _((char*,void(*)(),VALUE));
|
||||
void rb_iglob _((char*,void(*)(),VALUE));
|
||||
void rb_glob _((char*,void(*)(const char*,VALUE),VALUE));
|
||||
void rb_iglob _((char*,void(*)(const char*,VALUE),VALUE));
|
||||
|
||||
VALUE rb_define_class _((const char*,VALUE));
|
||||
VALUE rb_define_module _((const char*));
|
||||
|
@ -414,16 +430,16 @@ void rb_include_module _((VALUE,VALUE));
|
|||
void rb_extend_object _((VALUE,VALUE));
|
||||
|
||||
void rb_define_variable _((const char*,VALUE*));
|
||||
void rb_define_virtual_variable _((const char*,VALUE(*)(),void(*)()));
|
||||
void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(),void(*)()));
|
||||
void rb_define_virtual_variable _((const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS)));
|
||||
void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(ANYARGS),void(*)(ANYARGS)));
|
||||
void rb_define_readonly_variable _((const char*,VALUE*));
|
||||
void rb_define_const _((VALUE,const char*,VALUE));
|
||||
void rb_define_global_const _((const char*,VALUE));
|
||||
|
||||
#define RUBY_METHOD_FUNC(func) ((VALUE (*)__((...)))func)
|
||||
void rb_define_method _((VALUE,const char*,VALUE(*)(),int));
|
||||
void rb_define_module_function _((VALUE,const char*,VALUE(*)(),int));
|
||||
void rb_define_global_function _((const char*,VALUE(*)(),int));
|
||||
#define RUBY_METHOD_FUNC(func) ((VALUE (*)(ANYARGS))func)
|
||||
void rb_define_method _((VALUE,const char*,VALUE(*)(ANYARGS),int));
|
||||
void rb_define_module_function _((VALUE,const char*,VALUE(*)(ANYARGS),int));
|
||||
void rb_define_global_function _((const char*,VALUE(*)(ANYARGS),int));
|
||||
|
||||
void rb_undef_method _((VALUE,const char*));
|
||||
void rb_define_alias _((VALUE,const char*,const char*));
|
||||
|
@ -474,11 +490,11 @@ void rb_warn __((const char*, ...)); /* reports always */
|
|||
VALUE rb_each _((VALUE));
|
||||
VALUE rb_yield _((VALUE));
|
||||
int rb_block_given_p _((void));
|
||||
VALUE rb_iterate _((VALUE(*)(),VALUE,VALUE(*)(),VALUE));
|
||||
VALUE rb_rescue _((VALUE(*)(),VALUE,VALUE(*)(),VALUE));
|
||||
VALUE rb_rescue2 __((VALUE(*)(),VALUE,VALUE(*)(),VALUE,...));
|
||||
VALUE rb_ensure _((VALUE(*)(),VALUE,VALUE(*)(),VALUE));
|
||||
VALUE rb_catch _((const char*,VALUE(*)(),VALUE));
|
||||
VALUE rb_iterate _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));
|
||||
VALUE rb_rescue _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));
|
||||
VALUE rb_rescue2 __((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE,...));
|
||||
VALUE rb_ensure _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));
|
||||
VALUE rb_catch _((const char*,VALUE(*)(ANYARGS),VALUE));
|
||||
NORETURN(void rb_throw _((const char*,VALUE)));
|
||||
|
||||
VALUE rb_require _((const char*));
|
||||
|
@ -541,6 +557,7 @@ EXTERN VALUE rb_eTypeError;
|
|||
EXTERN VALUE rb_eZeroDivError;
|
||||
EXTERN VALUE rb_eNotImpError;
|
||||
EXTERN VALUE rb_eNoMemError;
|
||||
EXTERN VALUE rb_eNoMethodError;
|
||||
EXTERN VALUE rb_eFloatDomainError;
|
||||
|
||||
EXTERN VALUE rb_eScriptError;
|
||||
|
|
2
rubyio.h
2
rubyio.h
|
@ -23,7 +23,7 @@ typedef struct OpenFile {
|
|||
int pid; /* child's pid (for pipes) */
|
||||
int lineno; /* number of lines read */
|
||||
char *path; /* pathname for file */
|
||||
void (*finalize)(); /* finalize proc */
|
||||
void (*finalize) _((struct OpenFile*)); /* finalize proc */
|
||||
} OpenFile;
|
||||
|
||||
#define FMODE_READABLE 1
|
||||
|
|
|
@ -59,7 +59,7 @@ EXTERN int rb_prohibit_interrupt;
|
|||
#define ALLOW_INTS {rb_prohibit_interrupt--; CHECK_INTS;}
|
||||
#define ENABLE_INTS {rb_prohibit_interrupt--;}
|
||||
|
||||
VALUE rb_with_disable_interrupt _((VALUE(*)(),VALUE));
|
||||
VALUE rb_with_disable_interrupt _((VALUE(*)(ANYARGS),VALUE));
|
||||
|
||||
EXTERN rb_atomic_t rb_trap_pending;
|
||||
void rb_trap_restore_mask _((void));
|
||||
|
|
2
signal.c
2
signal.c
|
@ -465,7 +465,7 @@ trap(arg)
|
|||
func = SIG_IGN;
|
||||
}
|
||||
else if (TYPE(command) == T_STRING) {
|
||||
SafeStr(command); /* taint check */
|
||||
SafeStringValue(command); /* taint check */
|
||||
if (RSTRING(command)->len == 0) {
|
||||
func = SIG_IGN;
|
||||
}
|
||||
|
|
|
@ -174,8 +174,9 @@ rb_f_sprintf(argc, argv)
|
|||
|
||||
fmt = GETARG();
|
||||
if (OBJ_TAINTED(fmt)) tainted = 1;
|
||||
p = rb_str2cstr(fmt, &blen);
|
||||
end = p + blen;
|
||||
StringValue(fmt);
|
||||
p = RSTRING(fmt)->ptr;
|
||||
end = p + RSTRING(fmt)->len;
|
||||
blen = 0;
|
||||
bsiz = 120;
|
||||
buf = ALLOC_N(char, bsiz);
|
||||
|
|
9
st.c
9
st.c
|
@ -255,7 +255,8 @@ st_lookup(table, key, value)
|
|||
|
||||
if (ptr == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (value != 0) *value = ptr->record;
|
||||
return 1;
|
||||
}
|
||||
|
@ -294,7 +295,8 @@ st_insert(table, key, value)
|
|||
if (ptr == 0) {
|
||||
ADD_DIRECT(table, key, value, hash_val, bin_pos);
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ptr->record = value;
|
||||
return 1;
|
||||
}
|
||||
|
@ -498,7 +500,8 @@ st_foreach(table, func, arg)
|
|||
tmp = ptr;
|
||||
if (last == 0) {
|
||||
table->bins[i] = ptr->next;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
last->next = ptr->next;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
|
|
85
string.c
85
string.c
|
@ -209,7 +209,7 @@ rb_str_dup(str)
|
|||
VALUE str2;
|
||||
VALUE klass;
|
||||
|
||||
if (TYPE(str) != T_STRING) str = rb_str_to_str(str);
|
||||
StringValue(str);
|
||||
klass = CLASS_OF(str);
|
||||
while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
|
||||
klass = (VALUE)RCLASS(klass)->super;
|
||||
|
@ -278,7 +278,7 @@ rb_str_plus(str1, str2)
|
|||
{
|
||||
VALUE str3;
|
||||
|
||||
if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2);
|
||||
StringValue(str2);
|
||||
str3 = rb_str_new(0, RSTRING(str1)->len+RSTRING(str2)->len);
|
||||
memcpy(RSTRING(str3)->ptr, RSTRING(str1)->ptr, RSTRING(str1)->len);
|
||||
memcpy(RSTRING(str3)->ptr + RSTRING(str1)->len,
|
||||
|
@ -470,7 +470,7 @@ VALUE
|
|||
rb_str_append(str1, str2)
|
||||
VALUE str1, str2;
|
||||
{
|
||||
if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2);
|
||||
StringValue(str2);
|
||||
str1 = rb_str_cat(str1, RSTRING(str2)->ptr, RSTRING(str2)->len);
|
||||
OBJ_INFECT(str1, str2);
|
||||
|
||||
|
@ -590,7 +590,7 @@ rb_str_cmp_m(str1, str2)
|
|||
{
|
||||
int result;
|
||||
|
||||
if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2);
|
||||
StringValue(str2);
|
||||
result = rb_str_cmp(str1, str2);
|
||||
return INT2FIX(result);
|
||||
}
|
||||
|
@ -865,8 +865,7 @@ rb_str_upto(beg, end, excl)
|
|||
VALUE current;
|
||||
ID succ = rb_intern("succ");
|
||||
|
||||
if (TYPE(end) != T_STRING) end = rb_str_to_str(end);
|
||||
|
||||
StringValue(end);
|
||||
current = beg;
|
||||
while (rb_str_cmp(current, end) <= 0) {
|
||||
rb_yield(current);
|
||||
|
@ -952,14 +951,26 @@ rb_str_aref_m(argc, argv, str)
|
|||
|
||||
static void
|
||||
rb_str_replace(str, beg, len, val)
|
||||
VALUE str, val;
|
||||
VALUE str;
|
||||
long beg;
|
||||
long len;
|
||||
VALUE val;
|
||||
{
|
||||
if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len);
|
||||
if (beg < 0) {
|
||||
beg += RSTRING(str)->len;
|
||||
}
|
||||
if (beg < 0 || RSTRING(str)->len < beg) {
|
||||
if (beg < 0) {
|
||||
beg -= RSTRING(str)->len;
|
||||
}
|
||||
rb_raise(rb_eIndexError, "index %d out of string", beg);
|
||||
}
|
||||
if (RSTRING(str)->len < beg + len) {
|
||||
len = RSTRING(str)->len - beg;
|
||||
}
|
||||
|
||||
StringValue(val);
|
||||
if (len < RSTRING(val)->len) {
|
||||
/* expand string */
|
||||
REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+RSTRING(val)->len-len+1);
|
||||
|
@ -1007,7 +1018,6 @@ rb_str_aset(str, indx, val)
|
|||
RSTRING(str)->ptr[idx] = NUM2INT(val) & 0xff;
|
||||
}
|
||||
else {
|
||||
if (TYPE(val) != T_STRING) val = rb_str_to_str(val);
|
||||
rb_str_replace(str, idx, 1, val);
|
||||
}
|
||||
return val;
|
||||
|
@ -1024,7 +1034,6 @@ rb_str_aset(str, indx, val)
|
|||
case T_STRING:
|
||||
beg = rb_str_index(str, indx, 0);
|
||||
if (beg != -1) {
|
||||
if (TYPE(val) != T_STRING) val = rb_str_to_str(val);
|
||||
rb_str_replace(str, beg, RSTRING(indx)->len, val);
|
||||
}
|
||||
return val;
|
||||
|
@ -1034,7 +1043,6 @@ rb_str_aset(str, indx, val)
|
|||
{
|
||||
long beg, len;
|
||||
if (rb_range_beg_len(indx, &beg, &len, RSTRING(str)->len, 2)) {
|
||||
if (TYPE(val) != T_STRING) val = rb_str_to_str(val);
|
||||
rb_str_replace(str, beg, len, val);
|
||||
return val;
|
||||
}
|
||||
|
@ -1054,22 +1062,8 @@ rb_str_aset_m(argc, argv, str)
|
|||
if (argc == 3) {
|
||||
long beg, len;
|
||||
|
||||
if (TYPE(argv[2]) != T_STRING) argv[2] = rb_str_to_str(argv[2]);
|
||||
beg = NUM2INT(argv[0]);
|
||||
len = NUM2INT(argv[1]);
|
||||
if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len);
|
||||
if (beg < 0) {
|
||||
beg += RSTRING(str)->len;
|
||||
}
|
||||
if (beg < 0 || RSTRING(str)->len < beg) {
|
||||
if (beg < 0) {
|
||||
beg -= RSTRING(str)->len;
|
||||
}
|
||||
rb_raise(rb_eIndexError, "index %d out of string", beg);
|
||||
}
|
||||
if (beg + len > RSTRING(str)->len) {
|
||||
len = RSTRING(str)->len - beg;
|
||||
}
|
||||
rb_str_replace(str, beg, len, argv[2]);
|
||||
return argv[2];
|
||||
}
|
||||
|
@ -1079,6 +1073,14 @@ rb_str_aset_m(argc, argv, str)
|
|||
return rb_str_aset(str, argv[0], argv[1]);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_insert(str, idx, str2)
|
||||
VALUE str, idx, str2;
|
||||
{
|
||||
rb_str_replace(str, NUM2LONG(idx), 0, str2);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_slice_bang(argc, argv, str)
|
||||
int argc;
|
||||
|
@ -1136,7 +1138,8 @@ rb_str_sub_bang(argc, argv, str)
|
|||
iter = 1;
|
||||
}
|
||||
else if (argc == 2) {
|
||||
repl = rb_str_to_str(argv[1]);;
|
||||
repl = argv[1];
|
||||
StringValue(repl);
|
||||
if (OBJ_TAINTED(repl)) tainted = 1;
|
||||
}
|
||||
else {
|
||||
|
@ -1209,7 +1212,8 @@ str_gsub(argc, argv, str, bang)
|
|||
iter = 1;
|
||||
}
|
||||
else if (argc == 2) {
|
||||
repl = rb_str_to_str(argv[1]);
|
||||
repl = argv[1];
|
||||
StringValue(repl);
|
||||
if (OBJ_TAINTED(repl)) tainted = 1;
|
||||
}
|
||||
else {
|
||||
|
@ -1329,8 +1333,8 @@ rb_str_replace_m(str, str2)
|
|||
VALUE str, str2;
|
||||
{
|
||||
if (str == str2) return str;
|
||||
if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2);
|
||||
|
||||
StringValue(str2);
|
||||
if (RSTRING(str2)->orig && !FL_TEST(str2, STR_NO_ORIG)) {
|
||||
if (str_independent(str)) {
|
||||
free(RSTRING(str)->ptr);
|
||||
|
@ -1462,7 +1466,7 @@ rb_str_include(str, arg)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
if (TYPE(arg) != T_STRING) arg = rb_str_to_str(arg);
|
||||
StringValue(arg);
|
||||
i = rb_str_index(str, arg, 0);
|
||||
|
||||
if (i == -1) return Qfalse;
|
||||
|
@ -1841,13 +1845,13 @@ tr_trans(str, src, repl, sflag)
|
|||
char *s, *send;
|
||||
|
||||
rb_str_modify(str);
|
||||
if (TYPE(src) != T_STRING) src = rb_str_to_str(src);
|
||||
StringValue(src);
|
||||
StringValue(repl);
|
||||
trsrc.p = RSTRING(src)->ptr; trsrc.pend = trsrc.p + RSTRING(src)->len;
|
||||
if (RSTRING(src)->len >= 2 && RSTRING(src)->ptr[0] == '^') {
|
||||
cflag++;
|
||||
trsrc.p++;
|
||||
}
|
||||
if (TYPE(repl) != T_STRING) repl = rb_str_to_str(repl);
|
||||
if (RSTRING(repl)->len == 0) {
|
||||
return rb_str_delete_bang(1, &src, str);
|
||||
}
|
||||
|
@ -1991,8 +1995,7 @@ rb_str_delete_bang(argc, argv, str)
|
|||
for (i=0; i<argc; i++) {
|
||||
VALUE s = argv[i];
|
||||
|
||||
if (TYPE(s) != T_STRING)
|
||||
s = rb_str_to_str(s);
|
||||
StringValue(s);
|
||||
tr_setup_table(s, squeez, init);
|
||||
init = 0;
|
||||
}
|
||||
|
@ -2046,8 +2049,7 @@ rb_str_squeeze_bang(argc, argv, str)
|
|||
for (i=0; i<argc; i++) {
|
||||
VALUE s = argv[i];
|
||||
|
||||
if (TYPE(s) != T_STRING)
|
||||
s = rb_str_to_str(s);
|
||||
StringValue(s);
|
||||
tr_setup_table(s, squeez, init);
|
||||
init = 0;
|
||||
}
|
||||
|
@ -2118,8 +2120,7 @@ rb_str_count(argc, argv, str)
|
|||
for (i=0; i<argc; i++) {
|
||||
VALUE s = argv[i];
|
||||
|
||||
if (TYPE(s) != T_STRING)
|
||||
s = rb_str_to_str(s);
|
||||
StringValue(s);
|
||||
tr_setup_table(s, table, init);
|
||||
init = 0;
|
||||
}
|
||||
|
@ -2284,7 +2285,7 @@ rb_str_split(str, sep0)
|
|||
{
|
||||
VALUE sep;
|
||||
|
||||
if (TYPE(str) != T_STRING) str = rb_str_to_str(str);
|
||||
StringValue(str);
|
||||
sep = rb_str_new2(sep0);
|
||||
return rb_str_split_m(1, &sep, str);
|
||||
}
|
||||
|
@ -2319,10 +2320,7 @@ rb_str_each_line(argc, argv, str)
|
|||
rb_yield(str);
|
||||
return str;
|
||||
}
|
||||
if (TYPE(rs) != T_STRING) {
|
||||
rs = rb_str_to_str(rs);
|
||||
}
|
||||
|
||||
StringValue(rs);
|
||||
rslen = RSTRING(rs)->len;
|
||||
if (rslen == 0) {
|
||||
newline = '\n';
|
||||
|
@ -2434,7 +2432,7 @@ rb_str_chomp_bang(argc, argv, str)
|
|||
}
|
||||
if (NIL_P(rs)) return Qnil;
|
||||
|
||||
if (TYPE(rs) != T_STRING) rs = rb_str_to_str(rs);
|
||||
StringValue(rs);
|
||||
rslen = RSTRING(rs)->len;
|
||||
if (rslen == 0) {
|
||||
while (len>0 && p[len-1] == '\n') {
|
||||
|
@ -2645,7 +2643,7 @@ rb_str_crypt(str, salt)
|
|||
{
|
||||
extern char *crypt();
|
||||
|
||||
if (TYPE(salt) != T_STRING) salt = rb_str_to_str(salt);
|
||||
StringValue(salt);
|
||||
if (RSTRING(salt)->len < 2)
|
||||
rb_raise(rb_eArgError, "salt too short(need >=2 bytes)");
|
||||
return rb_str_new2(crypt(RSTRING(str)->ptr, RSTRING(salt)->ptr));
|
||||
|
@ -2804,6 +2802,7 @@ Init_String()
|
|||
rb_define_method(rb_cString, "%", rb_str_format, 1);
|
||||
rb_define_method(rb_cString, "[]", rb_str_aref_m, -1);
|
||||
rb_define_method(rb_cString, "[]=", rb_str_aset_m, -1);
|
||||
rb_define_method(rb_cString, "insert", rb_str_insert, 2);
|
||||
rb_define_method(rb_cString, "length", rb_str_length, 0);
|
||||
rb_define_method(rb_cString, "size", rb_str_length, 0);
|
||||
rb_define_method(rb_cString, "empty?", rb_str_empty, 0);
|
||||
|
|
2
struct.c
2
struct.c
|
@ -157,7 +157,7 @@ make_struct(name, member, klass)
|
|||
nstr = rb_class_new(klass);
|
||||
}
|
||||
else {
|
||||
char *cname = STR2CSTR(name);
|
||||
char *cname = StringValuePtr(name);
|
||||
id = rb_intern(cname);
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "identifier %s needs to be constant", cname);
|
||||
|
|
60
time.c
60
time.c
|
@ -270,8 +270,11 @@ time_arg(argc, argv, tm, usec)
|
|||
tm->tm_sec = NIL_P(v[5])?0:obj2long(v[5]);
|
||||
|
||||
/* value validation */
|
||||
if ( tm->tm_year < 69
|
||||
|| tm->tm_mon < 0 || tm->tm_mon > 11
|
||||
if (
|
||||
#ifndef NEGATIVE_TIME_T
|
||||
tm->tm_year < 69 ||
|
||||
#endif
|
||||
tm->tm_mon < 0 || tm->tm_mon > 11
|
||||
|| tm->tm_mday < 1 || tm->tm_mday > 31
|
||||
|| tm->tm_hour < 0 || tm->tm_hour > 23
|
||||
|| tm->tm_min < 0 || tm->tm_min > 59
|
||||
|
@ -284,14 +287,14 @@ static VALUE time_localtime _((VALUE));
|
|||
static VALUE time_get_tm _((VALUE, int));
|
||||
|
||||
static time_t
|
||||
make_time_t(tptr, utc_or_local)
|
||||
make_time_t(tptr, utc_p)
|
||||
struct tm *tptr;
|
||||
int utc_or_local;
|
||||
int utc_p;
|
||||
{
|
||||
struct timeval tv;
|
||||
time_t oguess, guess;
|
||||
struct tm *tm;
|
||||
long t, diff;
|
||||
long t, diff, i;
|
||||
|
||||
if (gettimeofday(&tv, 0) < 0) {
|
||||
rb_sys_fail("gettimeofday");
|
||||
|
@ -301,11 +304,13 @@ make_time_t(tptr, utc_or_local)
|
|||
tm = gmtime(&guess);
|
||||
if (!tm) goto error;
|
||||
t = tptr->tm_year;
|
||||
#ifndef NEGATIVE_TIME_T
|
||||
if (t < 69) goto out_of_range;
|
||||
#endif
|
||||
i = 0;
|
||||
while (diff = t - tm->tm_year) {
|
||||
oguess = guess;
|
||||
guess += diff * 363 * 24 * 3600;
|
||||
if (diff > 0 && guess <= oguess) goto out_of_range;
|
||||
if (i++ > 255) goto out_of_range;
|
||||
tm = gmtime(&guess);
|
||||
if (!tm) goto error;
|
||||
}
|
||||
|
@ -316,18 +321,18 @@ make_time_t(tptr, utc_or_local)
|
|||
if (!tm) goto error;
|
||||
if (tptr->tm_year != tm->tm_year) goto out_of_range;
|
||||
}
|
||||
oguess = guess;
|
||||
guess += (tptr->tm_mday - tm->tm_mday) * 24 * 3600;
|
||||
guess += (tptr->tm_hour - tm->tm_hour) * 3600;
|
||||
guess += (tptr->tm_min - tm->tm_min) * 60;
|
||||
guess += (tptr->tm_sec - tm->tm_sec);
|
||||
#ifndef NEGATIVE_TIME_T
|
||||
if (guess < 0) goto out_of_range;
|
||||
|
||||
if (!utc_or_local) { /* localtime zone adjust */
|
||||
#if defined(HAVE_TM_ZONE)
|
||||
tm = localtime(&guess);
|
||||
if (!tm) goto error;
|
||||
guess -= tm->tm_gmtoff;
|
||||
#else
|
||||
if (oguess > 365 * 24 * 3600 && guess < 0) goto out_of_range;
|
||||
#endif
|
||||
|
||||
if (!utc_p) { /* localtime zone adjust */
|
||||
struct tm gt, lt;
|
||||
long tzsec;
|
||||
|
||||
|
@ -351,18 +356,22 @@ make_time_t(tptr, utc_or_local)
|
|||
}
|
||||
if (lt.tm_isdst) guess += 3600;
|
||||
guess += tzsec;
|
||||
if (guess < 0) {
|
||||
goto out_of_range;
|
||||
}
|
||||
#ifndef NEGATIVE_TIME_T
|
||||
if (guess < 0) goto out_of_range;
|
||||
#endif
|
||||
tm = localtime(&guess);
|
||||
if (!tm) goto error;
|
||||
if (lt.tm_isdst != tm->tm_isdst) {
|
||||
guess -= 3600;
|
||||
if (lt.tm_isdst != tm->tm_isdst || tptr->tm_hour != tm->tm_hour) {
|
||||
oguess = guess - 3600;
|
||||
tm = localtime(&oguess);
|
||||
if (!tm) goto error;
|
||||
if (tptr->tm_hour == tm->tm_hour) {
|
||||
guess = oguess;
|
||||
}
|
||||
}
|
||||
#ifndef NEGATIVE_TIME_T
|
||||
if (guess < 0) goto out_of_range;
|
||||
#endif
|
||||
if (guess < 0) {
|
||||
goto out_of_range;
|
||||
}
|
||||
}
|
||||
|
||||
return guess;
|
||||
|
@ -926,7 +935,9 @@ time_strftime(time, format)
|
|||
if (tobj->tm_got == 0) {
|
||||
time_get_tm(time, tobj->gmt);
|
||||
}
|
||||
fmt = rb_str2cstr(format, &len);
|
||||
StringValue(format);
|
||||
fmt = RSTRING(format)->ptr;
|
||||
len = RSTRING(format)->len;
|
||||
if (len == 0) {
|
||||
rb_warning("strftime called with empty format string");
|
||||
}
|
||||
|
@ -1010,8 +1021,9 @@ time_load(klass, str)
|
|||
struct tm tm;
|
||||
int i;
|
||||
|
||||
buf = rb_str2cstr(str, &i);
|
||||
if (i != 8) {
|
||||
StringValue(str);
|
||||
buf = RSTRING(str)->ptr;
|
||||
if (RSTRING(str)->len != 8) {
|
||||
rb_raise(rb_eTypeError, "marshaled time format differ");
|
||||
}
|
||||
|
||||
|
|
303
util.c
303
util.c
|
@ -201,19 +201,25 @@ ruby_add_suffix(str, suffix)
|
|||
if (*suffix == '.') { /* Style 1 */
|
||||
if (strEQ(ext, suffix)) goto fallback;
|
||||
strcpy(p, suffix);
|
||||
} else if (suffix[1] == '\0') { /* Style 2 */
|
||||
}
|
||||
else if (suffix[1] == '\0') { /* Style 2 */
|
||||
if (extlen < 4) {
|
||||
ext[extlen] = *suffix;
|
||||
ext[++extlen] = '\0';
|
||||
} else if (baselen < 8) {
|
||||
}
|
||||
else if (baselen < 8) {
|
||||
*p++ = *suffix;
|
||||
} else if (ext[3] != *suffix) {
|
||||
}
|
||||
else if (ext[3] != *suffix) {
|
||||
ext[3] = *suffix;
|
||||
} else if (buf[7] != *suffix) {
|
||||
}
|
||||
else if (buf[7] != *suffix) {
|
||||
buf[7] = *suffix;
|
||||
} else goto fallback;
|
||||
}
|
||||
else goto fallback;
|
||||
strcpy(p, ext);
|
||||
} else { /* Style 3: Panic */
|
||||
}
|
||||
else { /* Style 3: Panic */
|
||||
fallback:
|
||||
(void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5);
|
||||
}
|
||||
|
@ -418,7 +424,8 @@ static void mmswap(a, b) register char *a, *b;
|
|||
if (low != 0) { s = A[0]; A[0] = B[0]; B[0] = s;
|
||||
if (low >= 8) { s = A[1]; A[1] = B[1]; B[1] = s;
|
||||
if (low == 12) {s = A[2]; A[2] = B[2]; B[2] = s;}}}
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
register char *t = a + mmsize;
|
||||
do {s = *a; *a++ = *b; *b++ = s;} while (a < t);
|
||||
}
|
||||
|
@ -435,12 +442,13 @@ static void mmrot3(a, b, c) register char *a, *b, *c;
|
|||
s = A[1]; A[1] = B[1]; B[1] = C[1]; C[1] = s;
|
||||
s = A[2]; A[2] = B[2]; B[2] = C[2]; C[2] = s;
|
||||
s = A[3]; A[3] = B[3]; B[3] = C[3]; C[3] = s; a += 16; b += 16; c += 16;
|
||||
}while (a < t);
|
||||
} while (a < t);
|
||||
}
|
||||
if (low != 0) { s = A[0]; A[0] = B[0]; B[0] = C[0]; C[0] = s;
|
||||
if (low >= 8) { s = A[1]; A[1] = B[1]; B[1] = C[1]; C[1] = s;
|
||||
if (low == 12) {s = A[2]; A[2] = B[2]; B[2] = C[2]; C[2] = s;}}}
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
register char *t = a + mmsize;
|
||||
do {s = *a; *a++ = *b; *b++ = *c; *c++ = s;} while (a < t);
|
||||
}
|
||||
|
@ -465,145 +473,146 @@ typedef struct { char *LL, *RR; } stack_node; /* Stack structure for L,l,R,r */
|
|||
|
||||
void ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp)();
|
||||
{
|
||||
register char *l, *r, *m; /* l,r:left,right group m:median point */
|
||||
register int t, eq_l, eq_r; /* eq_l: all items in left group are equal to S */
|
||||
char *L = base; /* left end of curren region */
|
||||
char *R = (char*)base + size*(nel-1); /* right end of current region */
|
||||
int chklim = 63; /* threshold of ordering element check */
|
||||
stack_node stack[32], *top = stack; /* 32 is enough for 32bit CPU */
|
||||
register char *l, *r, *m; /* l,r:left,right group m:median point */
|
||||
register int t, eq_l, eq_r; /* eq_l: all items in left group are equal to S */
|
||||
char *L = base; /* left end of curren region */
|
||||
char *R = (char*)base + size*(nel-1); /* right end of current region */
|
||||
int chklim = 63; /* threshold of ordering element check */
|
||||
stack_node stack[32], *top = stack; /* 32 is enough for 32bit CPU */
|
||||
|
||||
if (nel <= 1) return; /* need not to sort */
|
||||
mmprepare(base, size);
|
||||
goto start;
|
||||
|
||||
nxt:
|
||||
if (stack == top) return; /* return if stack is empty */
|
||||
POP(L,R);
|
||||
|
||||
for (;;) {
|
||||
start:
|
||||
if (L + size == R) {if ((*cmp)(L,R) > 0) mmswap(L,R); goto nxt;}/* 2 elements */
|
||||
|
||||
l = L; r = R;
|
||||
t = (r - l + size) / size; /* number of elements */
|
||||
m = l + size * (t >> 1); /* calculate median value */
|
||||
|
||||
if (t >= 60) {
|
||||
register char *m1;
|
||||
register char *m3;
|
||||
if (t >= 200) {
|
||||
t = size*(t>>3); /* number of bytes in splitting 8 */
|
||||
{
|
||||
register char *p1 = l + t;
|
||||
register char *p2 = p1 + t;
|
||||
register char *p3 = p2 + t;
|
||||
m1 = med3(p1, p2, p3);
|
||||
p1 = m + t;
|
||||
p2 = p1 + t;
|
||||
p3 = p2 + t;
|
||||
m3 = med3(p1, p2, p3);
|
||||
}
|
||||
}else{
|
||||
t = size*(t>>2); /* number of bytes in splitting 4 */
|
||||
m1 = l + t;
|
||||
m3 = m + t;
|
||||
}
|
||||
m = med3(m1, m, m3);
|
||||
}
|
||||
|
||||
if ((t = (*cmp)(l,m)) < 0) { /*3-5-?*/
|
||||
if ((t = (*cmp)(m,r)) < 0) { /*3-5-7*/
|
||||
if (chklim && nel >= chklim) { /* check if already ascending order */
|
||||
char *p;
|
||||
chklim = 0;
|
||||
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) > 0) goto fail;
|
||||
goto nxt;
|
||||
}
|
||||
fail: goto loopA; /*3-5-7*/
|
||||
}
|
||||
if (t > 0) {
|
||||
if ((*cmp)(l,r) <= 0) {mmswap(m,r); goto loopA;} /*3-5-4*/
|
||||
mmrot3(r,m,l); goto loopA; /*3-5-2*/
|
||||
}
|
||||
goto loopB; /*3-5-5*/
|
||||
}
|
||||
|
||||
if (t > 0) { /*7-5-?*/
|
||||
if ((t = (*cmp)(m,r)) > 0) { /*7-5-3*/
|
||||
if (chklim && nel >= chklim) { /* check if already ascending order */
|
||||
char *p;
|
||||
chklim = 0;
|
||||
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) < 0) goto fail2;
|
||||
while (l<r) {mmswap(l,r); l+=size; r-=size;} /* reverse region */
|
||||
goto nxt;
|
||||
}
|
||||
fail2: mmswap(l,r); goto loopA; /*7-5-3*/
|
||||
}
|
||||
if (t < 0) {
|
||||
if ((*cmp)(l,r) <= 0) {mmswap(l,m); goto loopB;} /*7-5-8*/
|
||||
mmrot3(l,m,r); goto loopA; /*7-5-6*/
|
||||
}
|
||||
mmswap(l,r); goto loopA; /*7-5-5*/
|
||||
}
|
||||
|
||||
if ((t = (*cmp)(m,r)) < 0) {goto loopA;} /*5-5-7*/
|
||||
if (t > 0) {mmswap(l,r); goto loopB;} /*5-5-3*/
|
||||
|
||||
/* deteming splitting type in case 5-5-5 */ /*5-5-5*/
|
||||
for (;;) {
|
||||
if ((l += size) == r) goto nxt; /*5-5-5*/
|
||||
if (l == m) continue;
|
||||
if ((t = (*cmp)(l,m)) > 0) {mmswap(l,r); l = L; goto loopA;} /*575-5*/
|
||||
if (t < 0) {mmswap(L,l); l = L; goto loopB;} /*535-5*/
|
||||
}
|
||||
|
||||
loopA: eq_l = 1; eq_r = 1; /* splitting type A */ /* left <= median < right */
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
if ((l += size) == r)
|
||||
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
|
||||
if (l == m) continue;
|
||||
if ((t = (*cmp)(l,m)) > 0) {eq_r = 0; break;}
|
||||
if (t < 0) eq_l = 0;
|
||||
}
|
||||
for (;;) {
|
||||
if (l == (r -= size))
|
||||
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
|
||||
if (r == m) {m = l; break;}
|
||||
if ((t = (*cmp)(r,m)) < 0) {eq_l = 0; break;}
|
||||
if (t == 0) break;
|
||||
}
|
||||
mmswap(l,r); /* swap left and right */
|
||||
}
|
||||
|
||||
loopB: eq_l = 1; eq_r = 1; /* splitting type B */ /* left < median <= right */
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
if (l == (r -= size))
|
||||
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
|
||||
if (r == m) continue;
|
||||
if ((t = (*cmp)(r,m)) < 0) {eq_l = 0; break;}
|
||||
if (t > 0) eq_r = 0;
|
||||
}
|
||||
for (;;) {
|
||||
if ((l += size) == r)
|
||||
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
|
||||
if (l == m) {m = r; break;}
|
||||
if ((t = (*cmp)(l,m)) > 0) {eq_r = 0; break;}
|
||||
if (t == 0) break;
|
||||
}
|
||||
mmswap(l,r); /* swap left and right */
|
||||
}
|
||||
|
||||
fin:
|
||||
if (eq_l == 0) /* need to sort left side */
|
||||
if (eq_r == 0) /* need to sort right side */
|
||||
if (l-L < R-r) {PUSH(r,R); R = l;} /* sort left side first */
|
||||
else {PUSH(L,l); L = r;} /* sort right side first */
|
||||
else R = l; /* need to sort left side only */
|
||||
else if (eq_r == 0) L = r; /* need to sort right side only */
|
||||
else goto nxt; /* need not to sort both sides */
|
||||
}
|
||||
if (nel <= 1) return; /* need not to sort */
|
||||
mmprepare(base, size);
|
||||
goto start;
|
||||
|
||||
nxt:
|
||||
if (stack == top) return; /* return if stack is empty */
|
||||
POP(L,R);
|
||||
|
||||
for (;;) {
|
||||
start:
|
||||
if (L + size == R) {if ((*cmp)(L,R) > 0) mmswap(L,R); goto nxt;}/* 2 elements */
|
||||
|
||||
l = L; r = R;
|
||||
t = (r - l + size) / size; /* number of elements */
|
||||
m = l + size * (t >> 1); /* calculate median value */
|
||||
|
||||
if (t >= 60) {
|
||||
register char *m1;
|
||||
register char *m3;
|
||||
if (t >= 200) {
|
||||
t = size*(t>>3); /* number of bytes in splitting 8 */
|
||||
{
|
||||
register char *p1 = l + t;
|
||||
register char *p2 = p1 + t;
|
||||
register char *p3 = p2 + t;
|
||||
m1 = med3(p1, p2, p3);
|
||||
p1 = m + t;
|
||||
p2 = p1 + t;
|
||||
p3 = p2 + t;
|
||||
m3 = med3(p1, p2, p3);
|
||||
}
|
||||
}
|
||||
else {
|
||||
t = size*(t>>2); /* number of bytes in splitting 4 */
|
||||
m1 = l + t;
|
||||
m3 = m + t;
|
||||
}
|
||||
m = med3(m1, m, m3);
|
||||
}
|
||||
|
||||
if ((t = (*cmp)(l,m)) < 0) { /*3-5-?*/
|
||||
if ((t = (*cmp)(m,r)) < 0) { /*3-5-7*/
|
||||
if (chklim && nel >= chklim) { /* check if already ascending order */
|
||||
char *p;
|
||||
chklim = 0;
|
||||
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) > 0) goto fail;
|
||||
goto nxt;
|
||||
}
|
||||
fail: goto loopA; /*3-5-7*/
|
||||
}
|
||||
if (t > 0) {
|
||||
if ((*cmp)(l,r) <= 0) {mmswap(m,r); goto loopA;} /*3-5-4*/
|
||||
mmrot3(r,m,l); goto loopA; /*3-5-2*/
|
||||
}
|
||||
goto loopB; /*3-5-5*/
|
||||
}
|
||||
|
||||
if (t > 0) { /*7-5-?*/
|
||||
if ((t = (*cmp)(m,r)) > 0) { /*7-5-3*/
|
||||
if (chklim && nel >= chklim) { /* check if already ascending order */
|
||||
char *p;
|
||||
chklim = 0;
|
||||
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) < 0) goto fail2;
|
||||
while (l<r) {mmswap(l,r); l+=size; r-=size;} /* reverse region */
|
||||
goto nxt;
|
||||
}
|
||||
fail2: mmswap(l,r); goto loopA; /*7-5-3*/
|
||||
}
|
||||
if (t < 0) {
|
||||
if ((*cmp)(l,r) <= 0) {mmswap(l,m); goto loopB;} /*7-5-8*/
|
||||
mmrot3(l,m,r); goto loopA; /*7-5-6*/
|
||||
}
|
||||
mmswap(l,r); goto loopA; /*7-5-5*/
|
||||
}
|
||||
|
||||
if ((t = (*cmp)(m,r)) < 0) {goto loopA;} /*5-5-7*/
|
||||
if (t > 0) {mmswap(l,r); goto loopB;} /*5-5-3*/
|
||||
|
||||
/* deteming splitting type in case 5-5-5 */ /*5-5-5*/
|
||||
for (;;) {
|
||||
if ((l += size) == r) goto nxt; /*5-5-5*/
|
||||
if (l == m) continue;
|
||||
if ((t = (*cmp)(l,m)) > 0) {mmswap(l,r); l = L; goto loopA;} /*575-5*/
|
||||
if (t < 0) {mmswap(L,l); l = L; goto loopB;} /*535-5*/
|
||||
}
|
||||
|
||||
loopA: eq_l = 1; eq_r = 1; /* splitting type A */ /* left <= median < right */
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
if ((l += size) == r)
|
||||
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
|
||||
if (l == m) continue;
|
||||
if ((t = (*cmp)(l,m)) > 0) {eq_r = 0; break;}
|
||||
if (t < 0) eq_l = 0;
|
||||
}
|
||||
for (;;) {
|
||||
if (l == (r -= size))
|
||||
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
|
||||
if (r == m) {m = l; break;}
|
||||
if ((t = (*cmp)(r,m)) < 0) {eq_l = 0; break;}
|
||||
if (t == 0) break;
|
||||
}
|
||||
mmswap(l,r); /* swap left and right */
|
||||
}
|
||||
|
||||
loopB: eq_l = 1; eq_r = 1; /* splitting type B */ /* left < median <= right */
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
if (l == (r -= size))
|
||||
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
|
||||
if (r == m) continue;
|
||||
if ((t = (*cmp)(r,m)) < 0) {eq_l = 0; break;}
|
||||
if (t > 0) eq_r = 0;
|
||||
}
|
||||
for (;;) {
|
||||
if ((l += size) == r)
|
||||
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
|
||||
if (l == m) {m = r; break;}
|
||||
if ((t = (*cmp)(l,m)) > 0) {eq_r = 0; break;}
|
||||
if (t == 0) break;
|
||||
}
|
||||
mmswap(l,r); /* swap left and right */
|
||||
}
|
||||
|
||||
fin:
|
||||
if (eq_l == 0) /* need to sort left side */
|
||||
if (eq_r == 0) /* need to sort right side */
|
||||
if (l-L < R-r) {PUSH(r,R); R = l;} /* sort left side first */
|
||||
else {PUSH(L,l); L = r;} /* sort right side first */
|
||||
else R = l; /* need to sort left side only */
|
||||
else if (eq_r == 0) L = r; /* need to sort right side only */
|
||||
else goto nxt; /* need not to sort both sides */
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
|
|
37
variable.c
37
variable.c
|
@ -249,7 +249,7 @@ VALUE
|
|||
rb_f_autoload(obj, klass, file)
|
||||
VALUE obj, klass, file;
|
||||
{
|
||||
rb_autoload_id(rb_to_id(klass), STR2CSTR(file));
|
||||
rb_autoload_id(rb_to_id(klass), StringValuePtr(file));
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
@ -1062,10 +1062,11 @@ rb_const_get(klass, id)
|
|||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
VALUE value;
|
||||
VALUE tmp;
|
||||
VALUE value, tmp;
|
||||
int mod_retry = 0;
|
||||
|
||||
tmp = klass;
|
||||
retry:
|
||||
while (tmp) {
|
||||
if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
|
||||
return value;
|
||||
|
@ -1073,15 +1074,18 @@ rb_const_get(klass, id)
|
|||
if (tmp == rb_cObject && top_const_get(id, &value)) return value;
|
||||
tmp = RCLASS(tmp)->super;
|
||||
}
|
||||
if (BUILTIN_TYPE(klass) == T_MODULE) {
|
||||
return rb_const_get(rb_cObject, id);
|
||||
if (!mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
|
||||
mod_retry = 1;
|
||||
tmp = rb_cObject;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* Uninitialized constant */
|
||||
if (klass && klass != rb_cObject)
|
||||
rb_raise(rb_eNameError, "uninitialized constant %s::%s",
|
||||
RSTRING(rb_class_path(klass))->ptr,
|
||||
rb_id2name(id));
|
||||
if (klass && klass != rb_cObject) {
|
||||
rb_raise(rb_eNameError, "uninitialized constant %s at %s",
|
||||
rb_id2name(id),
|
||||
RSTRING(rb_class_path(klass))->ptr);
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eNameError, "uninitialized constant %s",rb_id2name(id));
|
||||
}
|
||||
|
@ -1306,9 +1310,6 @@ rb_define_const(klass, name, val)
|
|||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "wrong constant name %s", name);
|
||||
}
|
||||
rb_const_set(klass, id, val);
|
||||
}
|
||||
|
||||
|
@ -1424,7 +1425,11 @@ rb_cv_set(klass, name, val)
|
|||
const char *name;
|
||||
VALUE val;
|
||||
{
|
||||
rb_cvar_set(klass, rb_intern(name), val);
|
||||
ID id = rb_intern(name);
|
||||
if (!rb_is_class_id(id)) {
|
||||
rb_raise(rb_eNameError, "wrong class variable name %s", name);
|
||||
}
|
||||
rb_cvar_set(klass, id, val);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -1432,7 +1437,11 @@ rb_cv_get(klass, name)
|
|||
VALUE klass;
|
||||
const char *name;
|
||||
{
|
||||
return rb_cvar_get(klass, rb_intern(name));
|
||||
ID id = rb_intern(name);
|
||||
if (!rb_is_class_id(id)) {
|
||||
rb_raise(rb_eNameError, "wrong class variable name %s", name);
|
||||
}
|
||||
return rb_cvar_get(klass, id);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define RUBY_VERSION "1.7.0"
|
||||
#define RUBY_RELEASE_DATE "2001-04-02"
|
||||
#define RUBY_RELEASE_DATE "2001-05-02"
|
||||
#define RUBY_VERSION_CODE 170
|
||||
#define RUBY_RELEASE_CODE 20010402
|
||||
#define RUBY_RELEASE_CODE 20010502
|
||||
|
|
Loading…
Reference in a new issue