1
0
Fork 0
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:
matz 2001-05-02 04:22:21 +00:00
parent 902524c35b
commit fd06a2a7fb
44 changed files with 1712 additions and 952 deletions

270
ChangeLog
View file

@ -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
View file

@ -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
View file

@ -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);

View file

@ -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
View file

@ -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;

View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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))) {

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -3,3 +3,4 @@ README
depend
extconf.rb
gdbm.c
testgdbm.rb

View file

@ -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);

View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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;
}

View file

@ -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
View file

@ -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);

View file

@ -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
View file

@ -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 *));

View file

@ -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);
}

View file

@ -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
View file

@ -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
View file

@ -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;

View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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;

View file

@ -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

View file

@ -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));

View file

@ -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;
}

View file

@ -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
View file

@ -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;

View file

@ -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);

View file

@ -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
View file

@ -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
View file

@ -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 *

View file

@ -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

View file

@ -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