From de7161526014b781468cea5d84411e23be945f79 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 5 Jan 2000 04:41:21 +0000 Subject: [PATCH] 20000105 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@598 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 144 ++++++ Makefile.in | 15 +- README | 1 + README.jp | 49 +- ToDo | 1 + array.c | 166 ++++-- bignum.c | 80 ++- class.c | 2 +- compar.c | 2 +- configure | 8 +- configure.in | 71 +-- cygwin/GNUmakefile.in | 5 +- defines.h | 4 +- dir.c | 2 +- dln.c | 2 +- enum.c | 2 +- error.c | 4 +- eval.c | 269 +++++----- ext/Win32API/Win32API.c | 15 +- ext/socket/socket.c | 11 +- ext/tk/lib/tk.rb | 94 ++-- ext/tk/lib/tkcanvas.rb | 12 +- ext/tk/lib/tktext.rb | 12 +- file.c | 155 +++++- gc.c | 8 +- hash.c | 156 ++---- inits.c | 2 +- intern.h | 7 +- io.c | 34 +- lib/cgi.rb | 2 +- lib/debug.rb | 1060 +++++++++++++++++++++++++-------------- lib/find.rb | 4 +- lib/mkmf.rb | 4 +- lib/timeout.rb | 4 +- main.c | 2 +- marshal.c | 83 ++- math.c | 2 +- misc/ruby-mode.el | 23 +- missing/x68.c | 2 + node.h | 2 +- numeric.c | 2 +- object.c | 6 +- pack.c | 12 +- parse.y | 56 ++- prec.c | 4 +- process.c | 2 +- random.c | 2 +- range.c | 2 +- re.c | 59 ++- re.h | 2 +- ruby.c | 10 +- ruby.h | 30 +- rubyio.h | 2 +- sample/mpart.rb | 2 +- signal.c | 4 +- sprintf.c | 18 +- st.c | 2 +- st.h | 2 +- string.c | 109 ++-- struct.c | 14 +- time.c | 20 +- util.c | 14 +- util.h | 2 +- variable.c | 12 + version.c | 4 +- win32/Makefile | 2 +- win32/config.status | 2 +- win32/win32.c | 55 +- win32/win32.h | 4 +- 69 files changed, 1873 insertions(+), 1103 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1df3c184a1..96607f1da5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,147 @@ +Wed Jan 5 02:14:46 2000 EGUCHI Osamu + + * parse.y: Fix SEGV on empty parens with UMINUS or UPLUS. + +Tue Jan 4 22:25:54 2000 Yukihiro Matsumoto + + * parse.y (stmt): `() while cond' dumped core. + +Tue Jan 4 06:04:14 2000 WATANABE Hirofumi + + * configure.in: modify for cross-compiling. + use target_* instead of host_*. + use AC_CANONICAL_TARGET. + + * Makefile.in: ditto. + + * cygwin/GNUmakefile.in: ditto. + +Sat Jan 1 13:26:14 2000 Yukihiro Matsumoto + + * eval.c (rb_yield_0): force_recycle ruby_dyna_vars to performance + gain. + + * array.c (rb_ary_delete_at_m): takes same argument pattern with + rb_ary_aref. + +Sat Jan 1 10:12:26 2000 Nobuyoshi Nakada + + * ruby.h,util.c (rb_special_const_p): peep hole optimization. + + * ruby.h,util.c (rb_test_false_or_nil): removed. + + * ruby.h (RTEST, SPECIAL_CONST_P): peep hole optimization. + + * ruby.h (FL_ABLE, FL_SET, FL_UNSET, FL_REVERSE): made expressions + not statements. + + * ruby.h (OBJ_INFECT): newly added which copies taint from `s' to + `x'. + +Sat Jan 1 02:04:18 2000 Yukihiro Matsumoto + + * eval.c (rb_thread_safe_level): new method. + + * eval.c (rb_yield_0): recycle dyna_var_map to reduce object + allocation. + +Fri Dec 31 00:52:48 1999 Yukihiro Matsumoto + + * eval.c: thread independent trace_func not needed. + +Thu Dec 30 14:47:31 1999 akira yamada + + * configure.in: specifies -soname in LIBRUBY_DLDFLAGS on linux + platforms. + +Thu Dec 30 10:51:27 1999 Yukihiro Matsumoto + + * array.c,io.c,hash,c,re.c,string.c: `_m' suffix instead of + `_method' for wrapper functions to implement method, + e.g. `rb_str_join_m()'. + +Thu Dec 30 02:08:02 1999 Yukihiro Matsumoto + + * bignum.c (rb_cstr2inum): non-numeric format check added. + currently it works only with base == 0 (i.e. Integer()). + + * bignum.c (rb_str2inum): now takes VALUE to 1st argument. null + byte check added. + + * array.c (rb_ary_replace): unless replacement is an array, + replacement shall be converted to array by `[replacement]', not + by `replacement.to_a'. + + * array.c (rb_ary_plus): right operand must be an array. + + * array.c (rb_ary_concat): argument must be an array. + +Mon Dec 27 12:35:47 1999 Katsuyuki Komatsu + + * ext/socket/socket.c (sock_finalize): mswin32: fix socket handle leak. + + * win32/win32.c (myfdclose): ditto. + +Sun Dec 26 23:15:13 1999 Katsuyuki Komatsu + + * win32/win32.c (mypopen): raise catchable error instead of rb_fatal. + * win32/win32.c (mypclose): fix process handle laek. + +Sun Dec 26 16:17:11 1999 Katsuyuki Komatsu + + * ext/Win32API/Win32API.c (Win32API_initialize): use UINT2NUM + instead of INT2NUM to set __dll__ and __proc__. + +Sat Dec 25 00:08:59 1999 KANEKO Naoshi + + * ext/Win32API/Win32API.c (Win32API_Call): remove 'dword ptr' + from _asm. + +Fri Dec 24 10:26:47 1999 Koji Oda + + * win32/win32.h: use "C++" linkage. + +Fri Dec 24 02:00:57 1999 Yukihiro Matsumoto + + * eval.c (THREAD_ALLOC): should initialize th->trace. + +Fri Dec 24 00:43:39 1999 KANEKO Naoshi + + * io.c (pipe_open): check for `fptr->f == NULL'. + * win32/win32.c (mypopen): STDERR does not work during ` function. + +Tue Dec 21 17:21:28 1999 Koji Oda + + * ext/socket/socket.c (sock_finalize): mswin32: fix FILE* leak. + +Sun Dec 19 22:56:31 1999 KANEKO Naoshi + + * lib/find.rb: support dosish root directory. + * win32/Makefile: ditto. + * win32/config.status: ditto. + * win32/win32.c (opendir): ditto. + * win32/win32.c (opendir): use CharPrev() to get last character + of the directory name. + +Sat Dec 18 03:00:01 1999 Yukihiro Matsumoto + + * file.c (path_check_1): check should be done by absolute path. + + * marshal.c (r_ivar): should restore generic_ivar too. + + * marshal.c (w_ivar): should dump generic_ivar too. + +Fri Dec 17 19:27:43 1999 IWAMURO Motonori + + * eval.c (rb_load): should initialize ruby_frame->last_class. + +Wed Dec 15 01:35:29 1999 Yukihiro Matsumoto + + * ruby.c (proc_options): option to change directory changed to + `-C' like tar. + + * ruby.c (proc_options): argv boundary check for `-X'. + Mon Dec 13 15:15:31 1999 Yukihiro Matsumoto * regex.c (re_adjust_startpos): separate startpos adjustment diff --git a/Makefile.in b/Makefile.in index 5b66caa96b..859525483a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -81,8 +81,8 @@ OBJS = array.@OBJEXT@ \ version.@OBJEXT@ \ $(MISSING) -all: miniruby$(EXEEXT) rbconfig.rb - @./miniruby$(EXEEXT) -Xext extmk.rb @EXTSTATIC@ +all: miniruby$(EXEEXT) @PREP@ rbconfig.rb + @@MINIRUBY@ -Xext extmk.rb @EXTSTATIC@ miniruby$(EXEEXT): config.status $(LIBRUBY_A) $(MAINOBJ) dmyext.@OBJEXT@ @rm -f $@ @@ -98,16 +98,16 @@ $(LIBRUBY_A): $(OBJS) dmyext.@OBJEXT@ $(LIBRUBY_SO): $(OBJS) dmyext.@OBJEXT@ $(LDSHARED) $(DLDFLAGS) $(SOLIBS) $(OBJS) dmyext.@OBJEXT@ -o $@ - @-./miniruby -e 'ARGV.each{|link| File.delete link if File.exist? link; \ + @-@MINIRUBY@ -e 'ARGV.each{|link| File.delete link if File.exist? link; \ File.symlink "$(LIBRUBY_SO)", link}' \ $(LIBRUBY_ALIASES) || true install: rbconfig.rb - ./miniruby$(EXEEXT) $(srcdir)/instruby.rb $(DESTDIR) + @MINIRUBY@ $(srcdir)/instruby.rb $(DESTDIR) clean:; @rm -f $(OBJS) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY_ALIASES) $(MAINOBJ) rbconfig.rb @rm -f ext/extinit.c ext/extinit.@OBJEXT@ dmyext.@OBJEXT@ - @-./miniruby$(EXEEXT) -Xext extmk.rb clean 2> /dev/null || true + @-@MINIRUBY@ -Xext extmk.rb clean 2> /dev/null || true @rm -f $(PROGRAM) miniruby$(EXEEXT) distclean: clean @@ -123,7 +123,10 @@ test: miniruby$(EXEEXT) @./miniruby$(EXEEXT) $(srcdir)/rubytest.rb rbconfig.rb: miniruby$(EXEEXT) - @./miniruby$(EXEEXT) $(srcdir)/mkconfig.rb rbconfig.rb + @@MINIRUBY@ $(srcdir)/mkconfig.rb rbconfig.rb + +prep.rb: miniruby$(EXEEXT) + @echo 'PLATFORM=RUBY_PLATFORM="@arch@"' > $@ config.status: $(srcdir)/configure $(SHELL) ./config.status --recheck diff --git a/README b/README index 5ed6015be0..429e0c31de 100644 --- a/README +++ b/README @@ -116,6 +116,7 @@ You can redistribute it and/or modify it under either the terms of the GPL 4. You may modify and include the part of the software into any other software (possibly commercial). But some files in the distribution are not written by the author, so that they are not under this terms. + They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some files under the ./missing directory. See each file for the copying condition. diff --git a/README.jp b/README.jp index 515f658609..b20cc1827b 100644 --- a/README.jp +++ b/README.jp @@ -135,29 +135,30 @@ UNIX * 配布条件 -Rubyはフリーソフトウェアです.GPL(the GNU General Public -License)または以下に示す条件でRubyを再配布できます.GPLにつ -いてはCOPYINGファイルを参照して下さい. +本プログラムはフリーソフトウェアです.GPL(the GNU General +Public License)または以下に示す条件で本プログラムを再配布で +きます.GPLについてはCOPYINGファイルを参照して下さい. 1. 複製は制限なく自由です. - 2. 以下の条件のいずれかを満たす時に手元のRubyのソースを自 - 由に変更できます. + 2. 以下の条件のいずれかを満たす時に本プログラムのソースを + 自由に変更できます. (a) ネットニューズにポストしたり,作者に変更を送付する などの方法で,変更を公開する. - (b) 変更したRubyを自分の所属する組織内部だけで使う. + (b) 変更した本プログラムを自分の所属する組織内部だけで + 使う. (c) 変更点を明示したうえ,ソフトウェアの名前を変更する. - そのソフトウェアを配布する時には変更前のRubyも同時 - に配布する.または変更前のRubyのソースの入手法を明 - 示する. + そのソフトウェアを配布する時には変更前の本プログラ + ムも同時に配布する.または変更前の本プログラムのソー + スの入手法を明示する. (d) その他の変更条件を作者と合意する. - 3. 以下の条件のいずれかを満たす時にRubyをオブジェクトコー - ドや実行形式でも配布できます. + 3. 以下の条件のいずれかを満たす時に本プログラムをコンパイ + ルしたオブジェクトコードや実行形式でも配布できます. (a) バイナリを受け取った人がソースを入手できるように, ソースの入手法を明示する. @@ -170,21 +171,23 @@ License) (d) その他の配布条件を作者と合意する. 4. 他のプログラムへの引用はいかなる目的であれ自由です.た - だし,Rubyに含まれる他の作者によるコードは,それぞれの - 作者の意向による制限が加えられます.具体的にはgc.c(一部), - util.c(一部),st.[ch],regex.[ch] および ./missingディ - レクトリ下のファイル群が該当します.それぞれの配布条件 - などに付いては各ファイルを参照してください. + だし,本プログラムに含まれる他の作者によるコードは,そ + れぞれの作者の意向による制限が加えらる場合があります. - 5. Rubyへの入力となるスクリプトおよび,Rubyからの出力の権 - 利はRubyの作者ではなく,それぞれの入出力を生成した人に - 属します.また,Rubyに組み込むための拡張ライブラリにつ - いても同様です. + 具体的にはgc.c(一部),util.c(一部),st.[ch],regex.[ch] + および ./missingディレクトリ下のファイル群が該当します. + それぞれの配布条件などに付いては各ファイルを参照してく + ださい. - 6. Rubyは無保証です.作者はRubyをサポートする意志はありま - すが,Ruby自身のバグあるいはRubyスクリプトのバグなどか - ら発生するいかなる損害に対しても責任を持ちません. + 5. 本プログラムへの入力となるスクリプトおよび,本プログラ + ムからの出力の権利は本プログラムの作者ではなく,それぞ + れの入出力を生成した人に属します.また,本プログラムに + 組み込まれるための拡張ライブラリについても同様です. + 6. 本プログラムは無保証です.作者は本プログラムをサポート + する意志はありますが,プログラム自身のバグあるいは本プ + ログラムの実行などから発生するいかなる損害に対しても責 + 任を持ちません. * 著者 diff --git a/ToDo b/ToDo index 8bc7ac58a2..66847b927a 100644 --- a/ToDo +++ b/ToDo @@ -44,6 +44,7 @@ Standard Libraries - sprintf/printf's $ to specify argument order - Dir.glob("**/*.c") ala zsh - Remove Enumerable#{size,length} +* Marshal should handle generic instance variables. * SyntaxError and NameError should not be subclasses of StandardError, maybe. * debugger for thread programming * Struct::new([name,]member,...) ?? diff --git a/array.c b/array.c index 6401bc4886..d4b040d112 100644 --- a/array.c +++ b/array.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 6 09:46:12 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -268,7 +268,7 @@ rb_ary_push(ary, item) } static VALUE -rb_ary_push_method(argc, argv, ary) +rb_ary_push_m(argc, argv, ary) int argc; VALUE *argv; VALUE ary; @@ -292,6 +292,31 @@ rb_ary_pop(ary) return RARRAY(ary)->ptr[--RARRAY(ary)->len]; } +static VALUE +rb_ary_pop_m(argc, argv, ary) + int argc; + VALUE *argv; + VALUE ary; +{ + int n = 1; + VALUE result; + + if (argc == 0) { + return rb_ary_pop(ary); + } + if (argc > 2) { + rb_raise(rb_eArgError, "wrong # of arguments (%d for 1)", argc); + } + n = NUM2INT(argv[0]); + if (RARRAY(ary)->len < n) + n = RARRAY(ary)->len; + result = rb_ary_new2(n); + while (n--) { + rb_ary_store(result, n, rb_ary_pop(ary)); + } + return result; +} + VALUE rb_ary_shift(ary) VALUE ary; @@ -314,6 +339,31 @@ rb_ary_shift(ary) return top; } +static VALUE +rb_ary_shift_m(argc, argv, ary) + int argc; + VALUE *argv; + VALUE ary; +{ + int n = 1; + VALUE result; + + if (argc == 0) { + return rb_ary_shift(ary); + } + if (argc > 2) { + rb_raise(rb_eArgError, "wrong # of arguments (%d for 1)", argc); + } + n = NUM2INT(argv[0]); + if (RARRAY(ary)->len < n) + n = RARRAY(ary)->len; + result = rb_ary_new2(n); + while (n--) { + rb_ary_push(result, rb_ary_shift(ary)); + } + return result; +} + VALUE rb_ary_unshift(ary, item) VALUE ary, item; @@ -506,8 +556,11 @@ rb_ary_replace(ary, beg, len, rpl) len = RARRAY(ary)->len - beg; } - if (TYPE(rpl) != T_ARRAY) { - rpl = rb_Array(rpl); + if (NIL_P(rpl)) { + rpl = rb_ary_new2(0); + } + else if (TYPE(rpl) != T_ARRAY) { + rpl = rb_ary_new3(1, rpl); } rb_ary_modify(ary); @@ -631,19 +684,23 @@ static VALUE rb_ary_clone(ary) VALUE ary; { - VALUE ary2 = rb_ary_new2(RARRAY(ary)->len); + VALUE clone = rb_ary_new2(RARRAY(ary)->len); - CLONESETUP(ary2, ary); - MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len); - RARRAY(ary2)->len = RARRAY(ary)->len; - return ary2; + CLONESETUP(clone, ary); + MEMCPY(RARRAY(clone)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len); + RARRAY(clone)->len = RARRAY(ary)->len; + return clone; } static VALUE rb_ary_dup(ary) VALUE ary; { - return rb_ary_s_create(RARRAY(ary)->len, RARRAY(ary)->ptr, CLASS_OF(ary)); + VALUE dup; + + dup = rb_ary_s_create(RARRAY(ary)->len, RARRAY(ary)->ptr, CLASS_OF(ary)); + if (OBJ_TAINTED(ary)) OBJ_TAINT(dup); + return dup; } static VALUE @@ -668,10 +725,15 @@ rb_ary_join(ary, sep) VALUE ary, sep; { long i; + int taint; VALUE result, tmp; + if (RARRAY(ary)->len == 0) return rb_str_new(0, 0); + if (OBJ_TAINTED(ary)) taint = 1; + if (OBJ_TAINTED(sep)) taint = 1; tmp = RARRAY(ary)->ptr[0]; + if (OBJ_TAINTED(tmp)) taint = 1; switch (TYPE(tmp)) { case T_STRING: result = rb_str_dup(tmp); @@ -715,14 +777,15 @@ rb_ary_join(ary, sep) } if (!NIL_P(sep)) rb_str_concat(result, sep); rb_str_cat(result, RSTRING(tmp)->ptr, RSTRING(tmp)->len); - if (OBJ_TAINTED(tmp)) OBJ_TAINT(result); + if (OBJ_TAINTED(tmp)) taint = 1; } + if (taint) OBJ_TAINT(result); return result; } static VALUE -rb_ary_join_method(argc, argv, ary) +rb_ary_join_m(argc, argv, ary) int argc; VALUE *argv; VALUE ary; @@ -788,10 +851,14 @@ rb_protect_inspect(func, obj, arg) inspect_tbl = rb_ary_new(); rb_thread_local_aset(rb_thread_current(), inspect_key, inspect_tbl); } + if (rb_ary_includes(inspect_tbl, obj)) { + return (*func)(obj, arg); + } rb_ary_push(inspect_tbl, obj); iarg.func = func; iarg.arg1 = obj; iarg.arg2 = arg; + return rb_ensure(inspect_call, (VALUE)&iarg, inspect_ensure, obj); } @@ -866,7 +933,7 @@ rb_ary_reverse(ary) } static VALUE -rb_ary_reverse_method(ary) +rb_ary_reverse_m(ary) VALUE ary; { return rb_ary_reverse(rb_ary_dup(ary)); @@ -985,11 +1052,11 @@ rb_ary_delete(ary, item) } VALUE -rb_ary_delete_at(ary, at) +rb_ary_delete_at(ary, pos) VALUE ary; - VALUE at; + long pos; { - long i, pos = NUM2LONG(at), len = RARRAY(ary)->len; + long i, len = RARRAY(ary)->len; VALUE del = Qnil; rb_ary_modify(ary); @@ -1006,6 +1073,47 @@ rb_ary_delete_at(ary, at) return del; } +static VALUE +rb_ary_delete_at_m(argc, argv, ary) + int argc; + VALUE *argv; + VALUE ary; +{ + VALUE arg1, arg2; + long pos, len, i; + + rb_ary_modify(ary); + if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) { + pos = NUM2LONG(arg1); + len = NUM2LONG(arg2); + delete_pos_len: + if (pos < 0) { + pos = RARRAY(ary)->len + pos; + } + arg2 = rb_ary_subary(ary, pos, len); + rb_ary_replace(ary, pos, len, Qnil); /* Qnil/rb_ary_new2(0) */ + return arg2; + } + + if (!FIXNUM_P(arg1) && rb_range_beg_len(arg1, &pos, &len, RARRAY(ary)->len, 1)) { + goto delete_pos_len; + } + + pos = NUM2LONG(arg1); + len = RARRAY(ary)->len; + + if (pos >= len) return Qnil; + if (pos < 0) pos += len; + if (pos < 0) return Qnil; + + arg2 = RARRAY(ary)->ptr[pos]; + for (i = pos + 1; i < len; i++, pos++) { + RARRAY(ary)->ptr[pos] = RARRAY(ary)->ptr[i]; + } + RARRAY(ary)->len = pos; + + return arg2; +} static VALUE rb_ary_delete_if(ary) VALUE ary; @@ -1039,7 +1147,7 @@ rb_ary_filter(ary) } static VALUE -rb_ary_replace_method(ary, ary2) +rb_ary_replace_m(ary, ary2) VALUE ary, ary2; { ary2 = to_ary(ary2); @@ -1116,9 +1224,7 @@ rb_ary_plus(x, y) { VALUE z; - if (TYPE(y) != T_ARRAY) { - y = rb_Array(y); - } + Check_Type(y, T_ARRAY); z = rb_ary_new2(RARRAY(x)->len + RARRAY(y)->len); MEMCPY(RARRAY(z)->ptr, RARRAY(x)->ptr, VALUE, RARRAY(x)->len); @@ -1134,9 +1240,7 @@ rb_ary_concat(x, y) VALUE *p, *pend; rb_ary_modify(x); - if (TYPE(y) != T_ARRAY) { - y = rb_Array(y); - } + Check_Type(y, T_ARRAY); p = RARRAY(y)->ptr; pend = p + RARRAY(y)->len; @@ -1339,7 +1443,7 @@ rb_ary_or(ary1, ary2) if (TYPE(ary2) != T_ARRAY) { if (rb_ary_includes(ary1, ary2)) return ary1; - else return rb_ary_plus(ary1, ary2); + else return rb_ary_push(ary1, ary2); } ary3 = rb_ary_new(); @@ -1495,9 +1599,9 @@ Init_Array() rb_define_method(rb_cArray, "last", rb_ary_last, 0); rb_define_method(rb_cArray, "concat", rb_ary_concat, 1); rb_define_method(rb_cArray, "<<", rb_ary_push, 1); - rb_define_method(rb_cArray, "push", rb_ary_push_method, -1); - 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, "push", rb_ary_push_m, -1); + rb_define_method(rb_cArray, "pop", rb_ary_pop_m, -1); + rb_define_method(rb_cArray, "shift", rb_ary_shift_m, -1); rb_define_method(rb_cArray, "unshift", rb_ary_unshift, 1); rb_define_method(rb_cArray, "each", rb_ary_each, 0); rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0); @@ -1511,18 +1615,18 @@ Init_Array() rb_define_method(rb_cArray, "indices", rb_ary_indexes, -1); rb_define_method(rb_cArray, "clone", rb_ary_clone, 0); rb_define_method(rb_cArray, "dup", rb_ary_dup, 0); - rb_define_method(rb_cArray, "join", rb_ary_join_method, -1); - rb_define_method(rb_cArray, "reverse", rb_ary_reverse_method, 0); + rb_define_method(rb_cArray, "join", rb_ary_join_m, -1); + rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0); rb_define_method(rb_cArray, "reverse!", rb_ary_reverse, 0); rb_define_method(rb_cArray, "sort", rb_ary_sort, 0); rb_define_method(rb_cArray, "sort!", rb_ary_sort_bang, 0); rb_define_method(rb_cArray, "collect", rb_ary_collect, 0); rb_define_method(rb_cArray, "delete", rb_ary_delete, 1); - rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at, 1); + rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, -1); rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0); rb_define_method(rb_cArray, "reject!", rb_ary_delete_if, 0); rb_define_method(rb_cArray, "filter", rb_ary_filter, 0); - rb_define_method(rb_cArray, "replace", rb_ary_replace_method, 1); + rb_define_method(rb_cArray, "replace", rb_ary_replace_m, 1); rb_define_method(rb_cArray, "clear", rb_ary_clear, 0); rb_define_method(rb_cArray, "fill", rb_ary_fill, -1); rb_define_method(rb_cArray, "include?", rb_ary_includes, 1); diff --git a/bignum.c b/bignum.c index 828e0cb9aa..ecc5953681 100644 --- a/bignum.c +++ b/bignum.c @@ -15,10 +15,10 @@ VALUE rb_cBignum; typedef unsigned short USHORT; -#define BDIGITS(x) RBIGNUM(x)->digits +#define BDIGITS(x) ((USHORT*)RBIGNUM(x)->digits) #define BITSPERDIG (sizeof(short)*CHAR_BIT) #define BIGRAD (1L << BITSPERDIG) -#define DIGSPERINT ((unsigned int)(sizeof(long)/sizeof(short))) +#define DIGSPERLONG ((unsigned int)(sizeof(long)/sizeof(short))) #define BIGUP(x) ((unsigned long)(x) << BITSPERDIG) #define BIGDN(x) RSHIFT(x,BITSPERDIG) #define BIGLO(x) ((USHORT)((x) & (BIGRAD-1))) @@ -33,7 +33,7 @@ bignew_1(klass, len, sign) OBJSETUP(big, klass, T_BIGNUM); big->sign = sign; big->len = len; - BDIGITS(big) = ALLOC_N(USHORT, len); + big->digits = ALLOC_N(USHORT, len); return (VALUE)big; } @@ -116,14 +116,14 @@ rb_uint2big(n) VALUE big; i = 0; - big = bignew(DIGSPERINT, 1); + big = bignew(DIGSPERLONG, 1); digits = BDIGITS(big); - while (i < DIGSPERINT) { + while (i < DIGSPERLONG) { digits[i++] = BIGLO(n); n = BIGDN(n); } - i = DIGSPERINT; + i = DIGSPERLONG; while (i-- && !digits[i]) ; RBIGNUM(big)->len = i+1; return big; @@ -164,10 +164,13 @@ rb_int2inum(n) } VALUE -rb_str2inum(str, base) +rb_cstr2inum(str, base) const char *str; int base; { + const char *s = str; + char *end; + int badcheck = (base==0)?1:0; char sign = 1, c; unsigned long num; long len, blen = 1; @@ -175,7 +178,7 @@ rb_str2inum(str, base) VALUE z; USHORT *zds; - while (ISSPACE(*str)) str++; + while (*str && ISSPACE(*str)) str++; if (*str == '+') { str++; @@ -197,11 +200,12 @@ rb_str2inum(str, base) } else { base = 8; + if (!*str) return INT2FIX(0); } - if (*str == '\0') return INT2FIX(0); } else { base = 10; + if (!*str) return INT2FIX(0); } } if (base == 8) { @@ -215,12 +219,23 @@ rb_str2inum(str, base) if (base == 2 && str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) { str += 2; } - while (str[0] == '0') str++; + while (*str && *str == '0') str++; + if (!*str) str--; len = 4*strlen(str)*sizeof(char); } if (len <= (sizeof(VALUE)*CHAR_BIT)) { - unsigned long val = strtoul((char*)str, 0, base); + unsigned long val = strtoul((char*)str, &end, base); + + if (badcheck) { + if (end == str || *end) + goto bad; + while (*end && ISSPACE(*end)) end++; + if (*end) { + bad: + rb_raise(rb_eArgError, "invalid literal for Integer: %s", s); + } + } if (POSFIXABLE(val)) { if (sign) return INT2FIX(val); @@ -256,6 +271,15 @@ rb_str2inum(str, base) break; default: c = base; + if (badcheck) { + if (ISSPACE(c)) { + while (*str && ISSPACE(*str)) str++; + if (*str) { + break; + } + } + rb_raise(rb_eArgError, "invalid literal for Integer: %s", s); + } break; } if (c >= base) break; @@ -274,9 +298,25 @@ rb_str2inum(str, base) break; } } + return bignorm(z); } +VALUE +rb_str2inum(str, base) + VALUE str; + int base; +{ + char *s; + int len; + + s = rb_str2cstr(str, &len); + if (len != strlen(s)) { + rb_raise(rb_eArgError, "string for Integer contains null byte"); + } + return rb_cstr2inum(s, base); +} + static char hexmap[] = "0123456789abcdef"; VALUE rb_big2str(x, base) @@ -354,16 +394,17 @@ rb_big_to_s(x) return rb_big2str(x, 10); } -unsigned long -rb_big2ulong(x) +static unsigned long +big2ulong(x, type) VALUE x; + char *type; { unsigned long num; long len = RBIGNUM(x)->len; USHORT *ds; if (len > sizeof(long)/sizeof(USHORT)) - rb_raise(rb_eArgError, "bignum too big to convert into `uint'"); + rb_raise(rb_eArgError, "bignum too big to convert into `%s'", type); ds = BDIGITS(x); num = 0; while (len--) { @@ -373,11 +414,20 @@ rb_big2ulong(x) return num; } +unsigned long +rb_big2ulong(x) + VALUE x; +{ + unsigned long num = big2ulong(x, "unsigned long"); + + if (!RBIGNUM(x)->sign) return -num; +} + long rb_big2long(x) VALUE x; { - unsigned long num = rb_big2ulong(x); + unsigned long num = big2ulong(x, "int"); if ((long)num < 0) { rb_raise(rb_eArgError, "bignum too big to convert into `int'"); diff --git a/class.c b/class.c index 46989474a8..19171d71cf 100644 --- a/class.c +++ b/class.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 15:05:44 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/compar.c b/compar.c index 677b6a3cbd..6046a70ce3 100644 --- a/compar.c +++ b/compar.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Aug 26 14:39:48 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/configure b/configure index 0a63be065b..560cc57310 100644 --- a/configure +++ b/configure @@ -1732,7 +1732,7 @@ case "$host_os" in nextstep*) ;; openstep*) ;; rhapsody*) ;; -human*) ;; +human*) ac_cv_func_getpgrp_void=yes;; beos*) ;; cygwin*) ;; *) LIBS="-lm $LIBS";; @@ -4360,7 +4360,7 @@ else echo "$ac_t""no" 1>&6 fi - for ac_func in select + for ac_func in select gettimeofday do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4367: checking for $ac_func" >&5 @@ -4501,7 +4501,7 @@ EOF fi LIBOBJS="$LIBOBJS x68.o" - CFLAGS="$CFLAGS -fansi-only -cc1-stack=196608 -cpp-stack=2694144" + CFLAGS="$CFLAGS -fansi-only -cc1-stack=262144 -cpp-stack=2694144" EXEEXT=.x OBJEXT=o setup=Setup.x68 @@ -4572,7 +4572,7 @@ if test "$enable_shared" = 'yes'; then LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' ;; linux*) - XLDFLAGS='-Wl,-rpath,${prefix}/lib':/usr/lib:/lib + LIBRUBY_DLDFLAGS='-Wl,-soname,lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR)' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' ;; freebsd*) diff --git a/configure.in b/configure.in index e4ac66aeec..54cb416e4f 100644 --- a/configure.in +++ b/configure.in @@ -26,6 +26,7 @@ then fi AC_CANONICAL_HOST +AC_CANONICAL_TARGET dnl checks for fat-binary fat_binary=no @@ -36,7 +37,7 @@ AC_ARG_ENABLE(fat-binary, AC_MSG_CHECKING(target architecture) - case "$host_os" in + case "$target_os" in rhapsody*) echo -n "MacOS X Server: " if test "$TARGET_ARCHS" = "" ; then @@ -136,11 +137,11 @@ if test "$rb_cv_have_attr_noreturn" = yes; then fi dnl Checks for libraries. -case "$host_os" in +case "$target_os" in nextstep*) ;; openstep*) ;; rhapsody*) ;; -human*) ;; +human*) ac_cv_func_getpgrp_void=yes;; beos*) ;; cygwin*) ;; *) LIBS="-lm $LIBS";; @@ -326,7 +327,7 @@ AC_ARG_WITH(dln-a-out, AC_SUBST(XLDFLAGS)dnl -case "$host_os" in +case "$target_os" in linux*) AC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf, [AC_TRY_RUN([ @@ -351,7 +352,7 @@ main() { rb_cv_binary_elf=yes)]) if test "$rb_cv_binary_elf" = no; then with_dln_a_out=yes - host_os=${host_os}-a_out + target_os=${target_os}-a_out else LDFLAGS="-rdynamic" fi;; @@ -370,7 +371,7 @@ if test "$with_dln_a_out" != yes; then rb_cv_dlopen=unknown AC_MSG_CHECKING(whether OS depend dynamic link works) if test "$GCC" = yes; then - case "$host_os" in + case "$target_os" in nextstep*) ;; openstep*) ;; rhapsody*) ;; @@ -378,14 +379,14 @@ if test "$with_dln_a_out" != yes; then bsdi*) ;; cygwin*) ;; netbsd*) CCDLFLAGS=-fpic - case "$host_cpu" in + case "$target_cpu" in mips*) CCDLFLAGS=-fPIC ;; *) ;; esac ;; *) CCDLFLAGS=-fPIC;; esac else - case "$host_os" in + case "$target_os" in hpux*) CCDLFLAGS='+z';; solaris*|irix*) CCDLFLAGS='-K PIC' ;; sunos*) CCDLFLAGS='-PIC' ;; @@ -394,7 +395,7 @@ if test "$with_dln_a_out" != yes; then esac fi - case "$host_os" in + case "$target_os" in hpux*) DLDFLAGS="-E" LDSHARED='ld -b' LDFLAGS="-Wl,-E" @@ -429,7 +430,7 @@ if test "$with_dln_a_out" != yes; then fi rb_cv_dlopen=yes ;; netbsd*) LDSHARED="ld -shared" - case "$host_cpu" in + case "$target_cpu" in alpha) LDFLAGS="-export-dynamic" ;; esac @@ -464,7 +465,7 @@ if test "$with_dln_a_out" != yes; then LDSHARED='' LDFLAGS='' rb_cv_dlopen=yes ;; - beos*) case "$host_cpu" in + beos*) case "$target_cpu" in powerpc*) LDSHARED="ld -xms" DLDFLAGS="-f ruby.exp -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o" @@ -477,7 +478,7 @@ if test "$with_dln_a_out" != yes; then DLDFLAGS="ruby.def -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o" esac rb_cv_dlopen=yes ;; - cygwin*) LDSHARED='dllwrap --export-all -s' + cygwin*) : ${LDSHARED='dllwrap --export-all -s'} rb_cv_dlopen=yes ;; *) LDSHARED='ld' ;; esac @@ -513,7 +514,7 @@ if test "$dln_a_out_works" = yes; then AC_DEFINE(DLEXT, ".so") CCDLFLAGS= else - case "$host_os" in + case "$target_os" in hpux*) DLEXT=sl AC_DEFINE(DLEXT, ".sl");; nextstep*) DLEXT=bundle @@ -538,7 +539,7 @@ else STRIP=strip fi -case "$host_os" in +case "$target_os" in linux*) STRIP='strip -S -x';; nextstep*) @@ -559,11 +560,11 @@ AC_ARG_WITH(static-linked-ext, *) ;; esac]) -case "$host_os" in +case "$target_os" in human*) AC_CHECK_LIB(signal, _harderr) AC_CHECK_LIB(hmem, hmemset) - AC_CHECK_FUNCS(select) + AC_CHECK_FUNCS(select gettimeofday) AC_CACHE_CHECK(whether PD libc _dtos18 fail to convert big number, rb_cv_missing__dtos18, [AC_TRY_RUN( @@ -602,7 +603,7 @@ rb_cv_missing_fconvert=yes, rb_cv_missing_fconvert=no, rb_cv_missing_fconvert=no AC_DEFINE(MISSING_FCONVERT) fi LIBOBJS="$LIBOBJS x68.o" - CFLAGS="$CFLAGS -fansi-only -cc1-stack=196608 -cpp-stack=2694144" + CFLAGS="$CFLAGS -fansi-only -cc1-stack=262144 -cpp-stack=2694144" EXEEXT=.x OBJEXT=o setup=Setup.x68 @@ -630,16 +631,26 @@ if test "$fat_binary" = yes ; then CFLAGS="$CFLAGS $ARCH_FLAG" fi +if test x"$cross_compiling" = xyes; then + MINIRUBY='ruby -I.. -rprep' + PREP=prep.rb +else + MINIRUBY='./miniruby$(EXEEXT)' + PREP='' +fi +AC_SUBST(MINIRUBY) +AC_SUBST(PREP) + LIBRUBY_A='lib$(RUBY_INSTALL_NAME).a' LIBRUBY='$(LIBRUBY_A)' LIBRUBYARG='$(LIBRUBY_A)' SOLIBS= -if test "$host_os" = "beos"; then +if test "$target_os" = "beos"; then LIBRUBY='$(LIBRUBY_SO)' LIBRUBYARG='-l$(RUBY_INSTALL_NAME)' SOLIBS='-lnet' echo creating ruby.def - case "$host_cpu" in + case "$target_cpu" in powerpc*) cp beos/ruby.def.in ruby.exp CFLAGS="$CFLAGS -relax_pointers" @@ -666,12 +677,12 @@ if test "$enable_shared" = 'yes'; then LIBRUBY='$(LIBRUBY_SO)' LIBRUBYARG='-L. -l$(RUBY_INSTALL_NAME)' CFLAGS="$CFLAGS $CCDLFLAGS" - case "$host_os" in + case "$target_os" in sunos4*) LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' ;; linux*) - XLDFLAGS='-Wl,-rpath,${prefix}/lib':/usr/lib:/lib + LIBRUBY_DLDFLAGS='-Wl,-soname,lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR)' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' ;; freebsd*) @@ -683,7 +694,7 @@ if test "$enable_shared" = 'yes'; then ;; netbsd*) LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR)' - case "$host_cpu" in + case "$target_cpu" in alpha|mipsel|mipseb|powerpc|sparc64) # ELF platforms LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR) lib$(RUBY_INSTALL_NAME).so' ;; *) LIBRUBY_ALIASES= ;; # a.out platforms @@ -716,13 +727,17 @@ if test "$enable_shared" = 'yes'; then FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in LIBOBJS="$LIBOBJS strftime.o" CCDLFLAGS=-DUSEIMPORTLIB + : ${NM=nm} + AC_SUBST(NM) + : ${DLLWRAP=dllwrap} + AC_SUBST(DLLWRAP) ;; *) ;; esac fi -case "$host_os" in +case "$target_os" in nextstep*) CFLAGS="$CFLAGS -pipe" ;; @@ -765,16 +780,16 @@ configure_args=$ac_configure_args AC_SUBST(configure_args)dnl if test "$fat_binary" = yes ; then - arch="fat-${host_os}" + arch="fat-${target_os}" AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB, - "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}") + "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${target_os}") AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB, - "${RUBY_SITE_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}") - AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${host_os}") + "${RUBY_SITE_LIB_PATH}/" __ARCHITECTURE__ "-${target_os}") + AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${target_os}") else - arch="${host_cpu}-${host_os}" + arch="${target_cpu}-${target_os}" AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}") fi AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${RUBY_LIB_PATH}/${arch}") diff --git a/cygwin/GNUmakefile.in b/cygwin/GNUmakefile.in index 970e90e24a..06aa54df68 100644 --- a/cygwin/GNUmakefile.in +++ b/cygwin/GNUmakefile.in @@ -4,6 +4,5 @@ RUBYCWDLL=rubycw.dll miniruby$(EXEEXT): $(RUBYCWDLL) -$(RUBYCWDLL): $(OBJS) dmyext.o - dllwrap -o $(RUBYCWDLL) --export-all --output-lib=$(LIBRUBY_SO) --dllname=$(RUBYCWDLL) -Wl,-e,__cygwin_noncygwin_dll_entry@12 --add-stdcall-alias -s $(OBJS) dmyext.o - nm --extern-only $(OBJS) dmyext.o | sed -n '/^........ [CD] _\(.*\)$$/s//#define \1 (*__imp_\1)/p' >import.h + $(LDSHARED) $(DLDFLAGS) -o $(RUBYCWDLL) --output-lib=$(LIBRUBY_SO) --dllname=$(RUBYCWDLL) -Wl,-e,__cygwin_noncygwin_dll_entry@12 --add-stdcall-alias $(OBJS) dmyext.o + @NM@ --extern-only $(OBJS) dmyext.o | sed -n '/^........ [CD] _\(.*\)$$/s//#define \1 (*__imp_\1)/p' >import.h diff --git a/defines.h b/defines.h index 6485fd7a59..5690eff34c 100644 --- a/defines.h +++ b/defines.h @@ -14,7 +14,7 @@ /* define RUBY_USE_EUC/SJIS for default kanji-code */ #ifndef DEFAULT_KCODE -#if defined(MSDOS) || defined(__CYGWIN32__) || defined(__human68k__) || defined(__MACOS__) || defined(__EMX__) || defined(OS2) || defined(NT) +#if defined(MSDOS) || defined(__CYGWIN__) || defined(__human68k__) || defined(__MACOS__) || defined(__EMX__) || defined(OS2) || defined(NT) #define DEFAULT_KCODE KCODE_SJIS #else #define DEFAULT_KCODE KCODE_EUC @@ -55,7 +55,7 @@ #endif #define PATH_SEP_CHAR PATH_SEP[0] -#if defined(__human68k__) || defined(__CYGWIN32__) +#if defined(__human68k__) || defined(__CYGWIN__) #undef HAVE_RANDOM #undef HAVE_SETITIMER #endif diff --git a/dir.c b/dir.c index 3c0581c777..47c2de272e 100644 --- a/dir.c +++ b/dir.c @@ -6,7 +6,7 @@ $Date$ created at: Wed Jan 5 09:51:01 JST 1994 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/dln.c b/dln.c index 02ef484b36..a30c7c1251 100644 --- a/dln.c +++ b/dln.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 18 17:05:06 JST 1994 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/enum.c b/enum.c index 054c59786d..f6927c4e77 100644 --- a/enum.c +++ b/enum.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 1 15:15:19 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/error.c b/error.c index 762151cc79..7959620d69 100644 --- a/error.c +++ b/error.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 16:11:34 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -279,7 +279,7 @@ rb_exc_new3(etype, str) char *s; int len; - s = str2cstr(str, &len); + s = rb_str2cstr(str, &len); return rb_exc_new(etype, s, len); } diff --git a/eval.c b/eval.c index 0e16db765a..7eb1cc7598 100644 --- a/eval.c +++ b/eval.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Jun 10 14:22:17 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -566,6 +566,8 @@ struct RVarmap *ruby_dyna_vars; ruby_dyna_vars = _old; \ } +#define DVAR_DONT_RECYCLE FL_USER0 + static struct RVarmap* new_dvar(id, value, prev) ID id; @@ -790,6 +792,7 @@ static VALUE massign _((VALUE,NODE*,VALUE,int)); static void assign _((VALUE,NODE*,VALUE,int)); static VALUE trace_func = 0; +static int tracing = 0; static void call_trace_func _((char*,char*,int,VALUE,ID,VALUE)); static void @@ -990,6 +993,7 @@ ruby_options(argc, argv) POP_TAG(); if (state) { trace_func = 0; + tracing = 0; error_print(); exit(1); } @@ -1110,7 +1114,7 @@ compile_error(at) char *mesg; int len; - mesg = str2cstr(ruby_errinfo, &len); + mesg = rb_str2cstr(ruby_errinfo, &len); ruby_nerrs = 0; str = rb_str_new2("compile error"); if (at) { @@ -1397,6 +1401,9 @@ rb_undef(klass, id) VALUE origin; NODE *body; + if (ruby_class == rb_cObject) { + rb_secure(4); + } if (safe_level >= 4 && !OBJ_TAINTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't undef"); } @@ -1481,9 +1488,14 @@ rb_mod_alias_method(mod, newname, oldname) (tmp__protect_tmp = rb_node_newnode(NODE_ALLOCA, \ ALLOC_N(VALUE,n),tmp__protect_tmp,n), \ (void*)tmp__protect_tmp->nd_head) +# define TMP_PROTECT_END do {\ + rb_gc_force_recycle((VALUE)tmp__protect_tmp);\ + alloca(0);\ +} while (0) #else # define TMP_PROTECT typedef int foobazzz # define TMP_ALLOC(n) ALLOCA_N(VALUE,n) +# define TMP_PROTECT_END #endif #define SETUP_ARGS(anode) {\ @@ -1766,18 +1778,15 @@ call_trace_func(event, file, line, self, id, klass) VALUE klass; /* OK */ { int state; - volatile VALUE trace; struct FRAME *prev; char *file_save = ruby_sourcefile; int line_save = ruby_sourceline; VALUE srcfile; if (!trace_func) return; + if (tracing) return; - trace = trace_func; - trace_func = 0; - rb_thread_critical++; - + tracing = 1; prev = ruby_frame; PUSH_FRAME(); *ruby_frame = *prev; @@ -1795,18 +1804,17 @@ call_trace_func(event, file, line, self, id, klass) PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)"); - proc_call(trace, rb_ary_new3(6, rb_str_new2(event), - srcfile, - INT2FIX(ruby_sourceline), - INT2FIX(id), - self?rb_f_binding(self):Qnil, - klass)); + proc_call(trace_func, rb_ary_new3(6, rb_str_new2(event), + srcfile, + INT2FIX(ruby_sourceline), + INT2FIX(id), + self?rb_f_binding(self):Qnil, + klass)); } POP_TMPTAG(); /* do not propagate retval */ POP_FRAME(); - rb_thread_critical--; - if (!trace_func) trace_func = trace; + tracing = 0; ruby_sourceline = line_save; ruby_sourcefile = file_save; if (state) JUMP_TAG(state); @@ -2288,6 +2296,7 @@ rb_eval(self, node) END_CALLARGS; result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0); + TMP_PROTECT_END; } break; @@ -2301,6 +2310,7 @@ rb_eval(self, node) END_CALLARGS; result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1); + TMP_PROTECT_END; } break; @@ -2333,6 +2343,7 @@ rb_eval(self, node) ruby_frame->self, ruby_frame->last_func, argc, argv, 3); POP_ITER(); + TMP_PROTECT_END; } break; @@ -2394,6 +2405,7 @@ rb_eval(self, node) argv[argc-1] = val; val = rb_funcall2(recv, aset, argc, argv); result = val; + TMP_PROTECT_END; } break; @@ -2767,9 +2779,6 @@ rb_eval(self, node) if (NIL_P(ruby_class)) { rb_raise(rb_eTypeError, "no class to undef method"); } - if (ruby_class == rb_cObject) { - rb_secure(4); - } rb_undef(ruby_class, node->nd_mid); result = Qnil; break; @@ -3006,6 +3015,7 @@ module_setup(module, node) call_trace_func("end", file, line, 0, ruby_frame->last_func, ruby_frame->last_class); } + TMP_PROTECT_END; if (state) JUMP_TAG(state); return result; @@ -3319,6 +3329,15 @@ rb_yield_0(val, self, klass, acheck) pop_state: POP_ITER(); POP_CLASS(); + if ((block->flags & BLOCK_D_SCOPE) && + !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) { + struct RVarmap *vars = ruby_dyna_vars; + + do { + rb_gc_force_recycle((VALUE)vars); + vars = vars->next; + } while (vars && vars->id != 0); + } POP_VARS(); ruby_block = block; ruby_frame = ruby_frame->prev; @@ -3339,7 +3358,10 @@ rb_yield(val) static VALUE rb_f_loop() { - for (;;) { rb_yield_0(Qnil, 0, 0, Qfalse); } + for (;;) { + rb_yield_0(Qnil, 0, 0, Qfalse); + CHECK_INTS; + } return Qnil; /* dummy */ } @@ -3538,6 +3560,7 @@ handle_rescue(self, node) if (rb_obj_is_kind_of(ruby_errinfo, argv[0])) return 1; argv++; } + TMP_PROTECT_END; return 0; } @@ -4075,6 +4098,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper) } POP_FRAME(); POP_ITER(); + TMP_PROTECT_END; return result; } @@ -4638,84 +4662,6 @@ rb_mod_module_eval(argc, argv, mod) VALUE rb_load_path; -static int -is_absolute_path(path) - const char *path; -{ - if (path[0] == '/') return 1; -# if defined(MSDOS) || defined(NT) || defined(__human68k__) || defined(__EMX__) - if (path[0] == '\\') return 1; - if (strlen(path) > 2 && path[1] == ':') return 1; -# endif - return 0; -} - -#ifdef __MACOS__ -static int -is_macos_native_path(path) - const char *path; -{ - if (strchr(path, ':')) return 1; - return 0; -} -#endif - -static char* -find_file(file) - char *file; -{ - volatile VALUE vpath; - char *path; - -#ifdef __MACOS__ - if (is_macos_native_path(file)) { - FILE *f = fopen(file, "r"); - - if (f == NULL) return 0; - fclose(f); - return file; - } -#endif - - if (is_absolute_path(file)) { - FILE *f = fopen(file, "r"); - - if (f == NULL) return 0; - fclose(f); - return file; - } - - if (file[0] == '~') { - VALUE argv[1]; - argv[0] = rb_str_new2(file); - file = STR2CSTR(rb_file_s_expand_path(1, argv)); - } - - if (rb_load_path) { - int i; - - Check_Type(rb_load_path, T_ARRAY); - vpath = rb_ary_new(); - for (i=0;ilen;i++) { - VALUE str = RARRAY(rb_load_path)->ptr[i]; - Check_SafeStr(str); - if (RSTRING(str)->len > 0) { - rb_ary_push(vpath, str); - } - } - vpath = rb_ary_join(vpath, rb_str_new2(PATH_SEP)); - path = STR2CSTR(vpath); - if (safe_level >= 2 && !rb_path_check(path)) { - rb_raise(rb_eSecurityError, "loading from unsafe path %s", path); - } - } - else { - path = 0; - } - - return dln_find_file(file, path); -} - void rb_load(fname, wrap) VALUE fname; @@ -4734,7 +4680,7 @@ rb_load(fname, wrap) else { Check_SafeStr(fname); } - file = find_file(RSTRING(fname)->ptr); + file = rb_find_file(RSTRING(fname)->ptr); if (!file) { rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr); } @@ -4755,6 +4701,7 @@ rb_load(fname, wrap) } PUSH_FRAME(); ruby_frame->last_func = 0; + ruby_frame->last_class = 0; ruby_frame->self = ruby_top_self; ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_class,0,0); PUSH_SCOPE(); @@ -4797,6 +4744,7 @@ rb_load(fname, wrap) ruby_nerrs = 0; rb_exc_raise(ruby_errinfo); } + TMP_PROTECT_END; if (state) JUMP_TAG(state); } @@ -4892,7 +4840,7 @@ rb_f_require(obj, fname) if (ext) { if (strcmp(".rb", ext) == 0) { feature = file = RSTRING(fname)->ptr; - file = find_file(file); + file = rb_find_file(file); if (file) goto load_rb; } else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) { @@ -4905,19 +4853,19 @@ rb_f_require(obj, fname) file = feature = buf; if (rb_provided(feature)) return Qfalse; } - file = find_file(file); + file = rb_find_file(file); if (file) goto load_dyna; } else if (strcmp(DLEXT, ext) == 0) { feature = RSTRING(fname)->ptr; - file = find_file(feature); + file = rb_find_file(feature); if (file) goto load_dyna; } } buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5); strcpy(buf, RSTRING(fname)->ptr); strcat(buf, ".rb"); - file = find_file(buf); + file = rb_find_file(buf); if (file) { fname = rb_str_new2(file); feature = buf; @@ -4925,7 +4873,7 @@ rb_f_require(obj, fname) } strcpy(buf, RSTRING(fname)->ptr); strcat(buf, DLEXT); - file = find_file(buf); + file = rb_find_file(buf); if (file) { feature = buf; goto load_dyna; @@ -5576,7 +5524,7 @@ bind_clone(self) Data_Get_Struct(self, struct BLOCK, orig); bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data); - CLONESETUP(bind,self); + CLONESETUP(bind, self); MEMCPY(data, orig, struct BLOCK, 1); frame_dup(&data->frame); @@ -5595,6 +5543,7 @@ rb_f_binding(self) VALUE self; { struct BLOCK *data; + struct RVarmap *vars; VALUE bind; PUSH_BLOCK(0,0); @@ -5616,6 +5565,9 @@ rb_f_binding(self) data->prev = 0; } + for (vars = data->d_vars; vars; vars = vars->next) { + FL_SET(vars, DVAR_DONT_RECYCLE); + } scope_dup(data->scope); POP_BLOCK(); @@ -5671,6 +5623,7 @@ proc_s_new(klass) { volatile VALUE proc; struct BLOCK *data; + struct RVarmap *vars; if (!rb_iterator_p() && !rb_f_iterator_p()) { rb_raise(rb_eArgError, "tried to create Procedure-Object out of iterator"); @@ -5691,6 +5644,9 @@ proc_s_new(klass) } data->flags |= BLOCK_DYNAMIC; + for (vars = data->d_vars; vars; vars = vars->next) { + FL_SET(vars, DVAR_DONT_RECYCLE); + } scope_dup(data->scope); proc_save_safe_level(proc); @@ -6134,12 +6090,12 @@ struct thread { VALUE klass; VALUE wrapper; - VALUE trace; int flags; /* misc. states (vmode/rb_trap_immediate/raised) */ char *file; int line; + int tracing; VALUE errinfo; VALUE last_status; VALUE last_line; @@ -6207,7 +6163,6 @@ thread_mark(th) rb_gc_mark(th->errinfo); rb_gc_mark(th->last_line); rb_gc_mark(th->last_match); - rb_gc_mark(th->trace); rb_mark_tbl(th->locals); /* mark data in copied stack */ @@ -6286,7 +6241,7 @@ rb_thread_save_context(th) th->stk_pos = (rb_gc_stack_start<(VALUE*)&v)?rb_gc_stack_start :rb_gc_stack_start - len; if (len > th->stk_max) { -REALLOC_N(th->stk_ptr, VALUE, len); + REALLOC_N(th->stk_ptr, VALUE, len); th->stk_max = len; } th->stk_len = len; @@ -6302,13 +6257,13 @@ REALLOC_N(th->stk_ptr, VALUE, len); th->flags = scope_vmode | (rb_trap_immediate<<8); th->iter = ruby_iter; th->tag = prot_tag; + th->tracing = tracing; th->errinfo = ruby_errinfo; th->last_status = rb_last_status; th->last_line = rb_lastline_get(); th->last_match = rb_backref_get(); th->safe = safe_level; - th->trace = trace_func; th->file = ruby_sourcefile; th->line = ruby_sourceline; } @@ -6371,11 +6326,11 @@ rb_thread_restore_context(th, exit) rb_trap_immediate = (th->flags&0x100)?1:0; ruby_iter = th->iter; prot_tag = th->tag; + tracing = th->tracing; ruby_errinfo = th->errinfo; rb_last_status = th->last_status; safe_level = th->safe; - trace_func = th->trace; ruby_sourcefile = th->file; ruby_sourceline = th->line; @@ -6515,7 +6470,7 @@ rb_thread_schedule() } FOREACH_THREAD_FROM(curr, th) { - if (th->status != THREAD_STOPPED && th->status != THREAD_KILLED) { + if (th->status == THREAD_RUNNABLE || th->status == THREAD_TO_KILL) { if (!next || next->priority < th->priority) next = th; } @@ -6885,6 +6840,26 @@ rb_thread_main() return main_thread->thread; } +VALUE +rb_thread_list() +{ + thread_t th; + VALUE ary = rb_ary_new(); + + FOREACH_THREAD(th) { + switch (th->status) { + case THREAD_RUNNABLE: + case THREAD_STOPPED: + rb_ary_push(ary, th->thread); + default: + break; + } + } + END_FOREACH(th); + + return ary; +} + VALUE rb_thread_wakeup(thread) VALUE thread; @@ -7014,6 +6989,16 @@ rb_thread_priority_set(thread, prio) return thread; } +static VALUE +rb_thread_safe_level(thread) + VALUE thread; +{ + thread_t th; + + th = rb_thread_check(thread); + return INT2NUM(th->safe); +} + static int thread_abort; static VALUE @@ -7074,6 +7059,7 @@ rb_thread_abort_exc_set(thread, val) th->block = 0;\ th->iter = 0;\ th->tag = 0;\ + th->tracing = 0;\ th->errinfo = 0;\ th->last_status = 0;\ th->last_line = 0;\ @@ -7280,6 +7266,18 @@ rb_thread_status(thread) return Qnil; } + if (th->status == THREAD_STOPPED) + return rb_str_new2("sleep"); + return rb_str_new2("run"); +} + +static VALUE +rb_thread_alive_p(thread) + VALUE thread; +{ + thread_t th = rb_thread_check(thread); + + if (rb_thread_dead(th)) return Qfalse; return Qtrue; } @@ -7523,7 +7521,36 @@ rb_thread_key_p(thread, id) return Qfalse; } -static VALUE rb_cContinuation; +static VALUE +rb_thread_inspect(thread) + VALUE thread; +{ + char *cname = rb_class2name(CLASS_OF(thread)); + thread_t th = rb_thread_check(thread); + char *s, *status; + VALUE str; + + switch (th->status) { + case THREAD_RUNNABLE: + status = "run"; break; + case THREAD_STOPPED: + status = "sleep"; break; + case THREAD_TO_KILL: + status = "aborting"; break; + case THREAD_KILLED: + status = "dead"; break; + default: + status = "unknown"; break; + } + s = ALLOCA_N(char, strlen(cname)+6+16+9+1); /* 6:tags 16:addr 9:status 1:nul */ + sprintf(s, "#<%s:0x%lx %s>", cname, thread, status); + str = rb_str_new2(s); + OBJ_INFECT(str, thread); + + return str; +} + +static VALUE rb_cCont; static VALUE rb_callcc(self) @@ -7534,7 +7561,7 @@ rb_callcc(self) struct tag *tag; THREAD_ALLOC(th); - th->thread = cont = Data_Wrap_Struct(rb_cContinuation, thread_mark, + th->thread = cont = Data_Wrap_Struct(rb_cCont, thread_mark, thread_free, th); FL_SET(ruby_scope, SCOPE_DONT_RECYCLE); @@ -7551,7 +7578,7 @@ rb_callcc(self) } static VALUE -rb_continuation_call(argc, argv, cont) +rb_cont_call(argc, argv, cont) int argc; VALUE *argv; VALUE cont; @@ -7569,6 +7596,7 @@ rb_continuation_call(argc, argv, cont) th->result = rb_ary_new4(argc, argv); break; } + rb_thread_restore_context(th, RESTORE_NORMAL); return Qnil; } @@ -7590,6 +7618,7 @@ Init_Thread() rb_define_singleton_method(rb_cThread, "join", rb_thread_s_join, 1); rb_define_singleton_method(rb_cThread, "current", rb_thread_current, 0); rb_define_singleton_method(rb_cThread, "main", rb_thread_main, 0); + rb_define_singleton_method(rb_cThread, "list", rb_thread_list, 0); rb_define_singleton_method(rb_cThread, "critical", rb_thread_critical_get, 0); rb_define_singleton_method(rb_cThread, "critical=", rb_thread_critical_set, 1); @@ -7599,11 +7628,12 @@ Init_Thread() rb_define_method(rb_cThread, "run", rb_thread_run, 0); rb_define_method(rb_cThread, "wakeup", rb_thread_wakeup, 0); + rb_define_method(rb_cThread, "kill", rb_thread_kill, 0); rb_define_method(rb_cThread, "exit", rb_thread_kill, 0); rb_define_method(rb_cThread, "value", rb_thread_value, 0); rb_define_method(rb_cThread, "status", rb_thread_status, 0); rb_define_method(rb_cThread, "join", rb_thread_join, 0); - rb_define_method(rb_cThread, "alive?", rb_thread_status, 0); + rb_define_method(rb_cThread, "alive?", rb_thread_alive_p, 0); rb_define_method(rb_cThread, "stop?", rb_thread_stop_p, 0); rb_define_method(rb_cThread, "raise", rb_thread_raise, -1); @@ -7612,17 +7642,20 @@ Init_Thread() rb_define_method(rb_cThread, "priority", rb_thread_priority, 0); rb_define_method(rb_cThread, "priority=", rb_thread_priority_set, 1); + rb_define_method(rb_cThread, "safe_level", rb_thread_safe_level, 0); rb_define_method(rb_cThread, "[]", rb_thread_aref, 1); rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2); rb_define_method(rb_cThread, "key?", rb_thread_key_p, 1); + rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0); + /* allocate main thread */ main_thread = rb_thread_alloc(rb_cThread); - rb_cContinuation = rb_define_class("Continuation", rb_cObject); - rb_undef_method(CLASS_OF(rb_cContinuation), "new"); - rb_define_method(rb_cContinuation, "call", rb_continuation_call, -1); + rb_cCont = rb_define_class("Continuation", rb_cObject); + rb_undef_method(CLASS_OF(rb_cCont), "new"); + rb_define_method(rb_cCont, "call", rb_cont_call, -1); rb_define_global_function("callcc", rb_callcc, 0); } @@ -7653,7 +7686,7 @@ static VALUE catch_i(tag) ID tag; { - return rb_f_catch(0, FIX2INT(tag)); + return rb_funcall(Qnil, rb_intern("catch"), 0, FIX2INT(tag)); } VALUE diff --git a/ext/Win32API/Win32API.c b/ext/Win32API/Win32API.c index 8efb3ddad6..38268d0474 100644 --- a/ext/Win32API/Win32API.c +++ b/ext/Win32API/Win32API.c @@ -68,9 +68,9 @@ Win32API_initialize(self, dllname, proc, import, export) rb_raise(rb_eRuntimeError, "GetProcAddress: %s or %s\n", RSTRING(proc)->ptr, RSTRING(str)->ptr); } - rb_iv_set(self, "__dll__", INT2NUM((int)hdll)); + rb_iv_set(self, "__dll__", UINT2NUM((unsigned long)hdll)); rb_iv_set(self, "__dllname__", dllname); - rb_iv_set(self, "__proc__", INT2NUM((int)hproc)); + rb_iv_set(self, "__proc__", UINT2NUM((unsigned long)hproc)); a_import = rb_ary_new(); ptr = RARRAY(import)->ptr; @@ -124,7 +124,7 @@ Win32API_Call(argc, argv, obj) ApiVoid *ApiFunctionVoid; ApiInteger *ApiFunctionInteger; - long lParam; + long lParam; char *pParam; VALUE Return; @@ -144,7 +144,7 @@ Win32API_Call(argc, argv, obj) obj_import = rb_iv_get(obj, "__import__"); obj_export = rb_iv_get(obj, "__export__"); - nimport = RARRAY(obj_import)->len; + nimport = RARRAY(obj_import)->len; texport = FIX2INT(obj_export); if (items != nimport) @@ -165,7 +165,7 @@ Win32API_Call(argc, argv, obj) mov eax, lParam push eax } -#elif defined(__CYGWIN32__) || defined(__MINGW32__) +#elif defined(__CYGWIN__) || defined(__MINGW32__) asm volatile ("pushl %0" :: "g" (lParam)); #else #error @@ -184,10 +184,10 @@ Win32API_Call(argc, argv, obj) } #if defined(_MSC_VER) || defined(__LCC__) _asm { - mov eax, dword ptr pParam + mov eax, pParam push eax } -#elif defined(__CYGWIN32__) || defined(__MINGW32__) +#elif defined(__CYGWIN__) || defined(__MINGW32__) asm volatile ("pushl %0" :: "g" (pParam)); #else #error @@ -195,7 +195,6 @@ Win32API_Call(argc, argv, obj) break; } } - } switch (texport) { diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 94597055aa..e8ceacf621 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -92,17 +92,10 @@ static void sock_finalize(fptr) OpenFile *fptr; { - SOCKET s; - extern int errno; - if (!fptr->f) return; - myfdclose(fptr->f); - if(fptr->f2) myfdclose(fptr->f); -/* - s = get_osfhandle(fileno(fptr->f)); - closesocket(s); -*/ + myfdclose(fptr->f); + if(fptr->f2) myfdclose(fptr->f2); } #endif diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index 9f1bae1d40..fd0a3bb2e4 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -1452,24 +1452,20 @@ module TkTreatFont alias fontobj font_configinfo def font_configure(slot) - if (fnt = slot['font']) - slot['font'] = nil + if (fnt = slot.delete('font')) if fnt.kind_of? TkFont return fnt.call_font_configure(self.path, self.path,'configure',slot) else latinfont_configure(fnt) if fnt end end - if (ltn = slot['latinfont']) - slot['latinfont'] = nil + if (ltn = slot.delete('latinfont')) latinfont_configure(ltn) if ltn end - if (ltn = slot['asciifont']) - slot['asciifont'] = nil + if (ltn = slot.delete('asciifont')) latinfont_configure(ltn) if ltn end - if (knj = slot['kanjifont']) - slot['kanjifont'] = nil + if (knj = slot.delete('kanjifont')) kanjifont_configure(knj) if knj end @@ -1878,42 +1874,24 @@ class TkToplevel @@ -1179,10 +1180,11 @@ rb_file_s_expand_path(argc, argv) VALUE fname, dname; char *s, *p; char buf[MAXPATHLEN+2]; - int tainted = 0; + int tainted; rb_scan_args(argc, argv, "11", &fname, &dname); + tainted = OBJ_TAINTED(fname); s = STR2CSTR(fname); p = buf; if (s[0] == '~') { @@ -1950,6 +1952,155 @@ rb_file_const(name, value) rb_define_const(rb_mConst, name, value); } +static int +is_absolute_path(path) + const char *path; +{ + if (path[0] == '/') return 1; +# if defined(MSDOS) || defined(NT) || defined(__human68k__) || defined(__EMX__) + if (path[0] == '\\') return 1; + if (strlen(path) > 2 && path[1] == ':') return 1; +# endif + return 0; +} + +static int +path_check_1(path) + char *path; +{ + struct stat st; + char *p = 0; + char *s; + + if (!is_absolute_path(path)) { + char buf[MAXPATHLEN+1]; + +#ifdef HAVE_GETCWD + if (getcwd(path, sizeof(path)) == 0) return 0; +#else + if (getwd(path) == 0) return 0; +#endif + strncat(buf, path, MAXPATHLEN); + buf[MAXPATHLEN] = '\0'; + return path_check_1(buf); + } + for (;;) { + if (stat(path, &st) == 0 && (st.st_mode & 002)) { + return 0; + } + s = strrchr(path, '/'); + if (p) *p = '/'; + if (!s || s == path) return 1; + p = s; + *p = '\0'; + } +} + +int +rb_path_check(path) + char *path; +{ + char *p, *pend; + const char sep = PATH_SEP_CHAR; + + if (!path) return 1; + + p = path; + pend = strchr(path, sep); + + for (;;) { + int safe; + + if (pend) *pend = '\0'; + safe = path_check_1(p); + if (!safe) return 0; + if (!pend) break; + *pend = sep; + p = pend + 1; + pend = strchr(p, sep); + } + return 1; +} + +#ifdef __MACOS__ +static int +is_macos_native_path(path) + const char *path; +{ + if (strchr(path, ':')) return 1; + return 0; +} +#endif + +char* +rb_find_file(file) + char *file; +{ + extern VALUE rb_load_path; + volatile VALUE vpath; + VALUE fname; + char *path; + +#ifdef __MACOS__ + if (is_macos_native_path(file)) { + FILE *f; + + if (safe_level >= 2 && !rb_path_check(file)) { + rb_raise(rb_eSecurityError, "loading from unsafe file %s", file); + } + f= fopen(file, "r"); + if (f == NULL) return 0; + fclose(f); + return file; + } +#endif + + if (is_absolute_path(file)) { + FILE *f; + + if (rb_safe_level() >= 2 && !rb_path_check(file)) { + rb_raise(rb_eSecurityError, "loading from unsafe file %s", file); + } + f = fopen(file, "r"); + if (f == NULL) return 0; + fclose(f); + return file; + } + + if (file[0] == '~') { + fname = rb_str_new2(file); + fname = rb_file_s_expand_path(1, &fname); + if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) { + rb_raise(rb_eSecurityError, "loading from unsafe file %s", file); + } + file = STR2CSTR(fname); + } + + if (rb_load_path) { + int i; + + Check_Type(rb_load_path, T_ARRAY); + vpath = rb_ary_new(); + for (i=0;ilen;i++) { + VALUE str = RARRAY(rb_load_path)->ptr[i]; + Check_SafeStr(str); + if (RSTRING(str)->len > 0) { + rb_ary_push(vpath, str); + } + } + vpath = rb_ary_join(vpath, rb_str_new2(PATH_SEP)); + path = STR2CSTR(vpath); + if (rb_safe_level() >= 2 && !rb_path_check(path)) { + rb_raise(rb_eSecurityError, "loading from unsafe path %s", path); + } + } + else { + path = 0; + } + + return dln_find_file(file, path); +} + void Init_File() { diff --git a/gc.c b/gc.c index ad0e2d2ebf..6a0e7c527a 100644 --- a/gc.c +++ b/gc.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Oct 5 09:44:46 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -71,7 +71,7 @@ xmalloc(size) void *mem; if (size < 0) { - rb_raise(rb_eArgError, "negative allocation size (or too big)"); + rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); } if (size == 0) size = 1; malloc_memories += size; @@ -422,6 +422,7 @@ rb_gc_mark(ptr) Top: if (FIXNUM_P(obj)) return; /* fixnum not marked */ if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */ + if ((VALUE)obj == Qundef) return; /* special placeholder */ if (obj->as.basic.flags == 0) return; /* free cell */ if (obj->as.basic.flags & FL_MARK) return; /* already marked */ @@ -878,6 +879,9 @@ _rb_setjmp: movem.l d3-d7/a3-a5,(a0) moveq.l #0,d0 rts"); +#ifdef setjmp +#undef setjmp +#endif #else #if defined(DJGPP) typedef unsigned long rb_jmp_buf[6]; diff --git a/hash.c b/hash.c index bfead82e8a..b6a1d507c0 100644 --- a/hash.c +++ b/hash.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Nov 22 18:51:18 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -15,9 +15,6 @@ #include "util.h" #include "rubysig.h" -#include -#include - #ifndef HAVE_STRING_H char *strchr _((char*,char)); #endif @@ -142,7 +139,7 @@ rb_hash_foreach_iter(key, value, arg) st_table *tbl = RHASH(arg->hash)->tbl; struct st_table_entry **bins = tbl->bins; - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; status = (*arg->func)(key, value, arg->arg); if (RHASH(arg->hash)->tbl != tbl || RHASH(arg->hash)->tbl->bins != bins){ rb_raise(rb_eIndexError, "rehash occurred during iteration"); @@ -166,7 +163,7 @@ rb_hash_foreach_ensure(hash) if (RHASH(hash)->iter_lev == 0) { if (FL_TEST(hash, HASH_DELETED)) { - st_cleanup_safe(RHASH(hash)->tbl, Qnil); + st_cleanup_safe(RHASH(hash)->tbl, Qundef); FL_UNSET(hash, HASH_DELETED); } } @@ -275,30 +272,31 @@ static VALUE rb_hash_clone(hash) VALUE hash; { - NEWOBJ(hash2, struct RHash); - CLONESETUP(hash2, hash); + NEWOBJ(clone, struct RHash); + CLONESETUP(clone, hash); - hash2->iter_lev = 0; - hash2->ifnone = RHASH(hash)->ifnone; - hash2->tbl = 0; /* avoid GC crashing */ - hash2->tbl = (st_table*)st_copy(RHASH(hash)->tbl); + clone->iter_lev = 0; + clone->ifnone = RHASH(hash)->ifnone; + clone->tbl = 0; /* avoid GC crashing */ + clone->tbl = (st_table*)st_copy(RHASH(hash)->tbl); - return (VALUE)hash2; + return (VALUE)clone; } static VALUE rb_hash_dup(hash) VALUE hash; { - NEWOBJ(hash2, struct RHash); - OBJSETUP(hash2, CLASS_OF(hash), T_HASH); + NEWOBJ(dup, struct RHash); + OBJSETUP(dup, CLASS_OF(hash), T_HASH); - hash2->iter_lev = 0; - hash2->ifnone = RHASH(hash)->ifnone; - hash2->tbl = 0; /* avoid GC crashing */ - hash2->tbl = (st_table*)st_copy(RHASH(hash)->tbl); + dup->iter_lev = 0; + dup->ifnone = RHASH(hash)->ifnone; + dup->tbl = 0; /* avoid GC crashing */ + dup->tbl = (st_table*)st_copy(RHASH(hash)->tbl); - return (VALUE)hash2; + if (OBJ_TAINTED(hash)) OBJ_TAINT(dup); + return (VALUE)dup; } static VALUE @@ -313,9 +311,7 @@ rb_hash_rehash_i(key, value, tbl) VALUE key, value; st_table *tbl; { - if (key != Qnil) { - st_insert(tbl, key, value); - } + if (key != Qundef) st_insert(tbl, key, value); return ST_CONTINUE; } @@ -405,7 +401,7 @@ rb_hash_index(hash, value) VALUE args[2]; args[0] = value; - args[1] = Qnil; + args[1] = RHASH(hash)->ifnone; st_foreach(RHASH(hash)->tbl, index_i, args); @@ -437,7 +433,7 @@ rb_hash_delete(hash, key) rb_hash_modify(hash); if (RHASH(hash)->iter_lev > 0 && - st_delete_safe(RHASH(hash)->tbl, &key, &val, Qnil)) { + st_delete_safe(RHASH(hash)->tbl, &key, &val, Qundef)) { FL_SET(hash, HASH_DELETED); return val; } @@ -446,7 +442,7 @@ rb_hash_delete(hash, key) if (rb_iterator_p()) { return rb_yield(key); } - return Qnil; + return RHASH(hash)->ifnone; } struct shift_var { @@ -460,7 +456,7 @@ shift_i(key, value, var) VALUE key, value; struct shift_var *var; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; if (var->stop) return ST_STOP; var->stop = 1; var->key = key; @@ -478,7 +474,7 @@ rb_hash_shift(hash) var.stop = 0; st_foreach(RHASH(hash)->tbl, shift_i, &var); - if (var.stop == 0) return Qnil; + if (var.stop == 0) return RHASH(hash)->ifnone; return rb_assoc_new(var.key, var.val); } @@ -486,7 +482,7 @@ static int delete_if_i(key, value) VALUE key, value; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; if (RTEST(rb_yield(rb_assoc_new(key, value)))) return ST_DELETE; return ST_CONTINUE; @@ -572,7 +568,7 @@ static int each_value_i(key, value) VALUE key, value; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; rb_yield(value); return ST_CONTINUE; } @@ -589,7 +585,7 @@ static int each_key_i(key, value) VALUE key, value; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; rb_yield(key); return ST_CONTINUE; } @@ -606,7 +602,7 @@ static int each_pair_i(key, value) VALUE key, value; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; rb_yield(rb_assoc_new(key, value)); return ST_CONTINUE; } @@ -623,7 +619,7 @@ static int to_a_i(key, value, ary) VALUE key, value, ary; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; rb_ary_push(ary, rb_assoc_new(key, value)); return ST_CONTINUE; } @@ -636,6 +632,7 @@ rb_hash_to_a(hash) ary = rb_ary_new(); st_foreach(RHASH(hash)->tbl, to_a_i, ary); + if (OBJ_TAINTED(hash)) OBJ_TAINT(ary); return ary; } @@ -653,7 +650,7 @@ inspect_i(key, value, str) { VALUE str2; - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; if (RSTRING(str)->len > 1) { rb_str_cat(str, ", ", 2); } @@ -689,23 +686,20 @@ rb_hash_inspect(hash) } static VALUE -hash_to_s(hash) +to_s_hash(hash) VALUE hash; { - VALUE str; - - if (rb_inspecting_p(hash)) return rb_str_new2("{...}"); - str = rb_ary_to_s(rb_hash_to_a(hash)); - if (OBJ_TAINTED(hash)) OBJ_TAINT(str); - return hash; + return rb_ary_to_s(rb_hash_to_a(hash)); } static VALUE rb_hash_to_s(hash) VALUE hash; { + VALUE str; + if (rb_inspecting_p(hash)) return rb_str_new2("{...}"); - return rb_protect_inspect(hash_to_s, hash, 0); + return rb_protect_inspect(to_s_hash, hash, 0); } static VALUE @@ -719,7 +713,7 @@ static int keys_i(key, value, ary) VALUE key, value, ary; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; rb_ary_push(ary, key); return ST_CONTINUE; } @@ -740,7 +734,7 @@ static int values_i(key, value, ary) VALUE key, value, ary; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; rb_ary_push(ary, value); return ST_CONTINUE; } @@ -772,7 +766,7 @@ static int rb_hash_search_value(key, value, data) VALUE key, value, *data; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; if (rb_equal(value, data[1])) { data[0] = Qtrue; return ST_STOP; @@ -805,7 +799,7 @@ equal_i(key, val1, data) { VALUE val2; - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; if (!st_lookup(data->tbl, key, &val2)) { data->result = Qfalse; return ST_STOP; @@ -839,7 +833,7 @@ rb_hash_invert_i(key, value, hash) VALUE key, value; VALUE hash; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; rb_hash_aset(hash, value, key); return ST_CONTINUE; } @@ -859,7 +853,7 @@ rb_hash_update_i(key, value, hash) VALUE key, value; VALUE hash; { - if (key == Qnil) return ST_CONTINUE; + if (key == Qundef) return ST_CONTINUE; rb_hash_aset(hash, key, value); return ST_CONTINUE; } @@ -888,23 +882,25 @@ env_delete(obj, name) char *nam, *val; rb_secure(4); - nam = str2cstr(name, &len); + nam = rb_str2cstr(name, &len); if (strlen(nam) != len) { rb_raise(rb_eArgError, "bad environment variable name"); } val = getenv(nam); if (val) { + VALUE value = rb_tainted_str_new2(val); + ruby_setenv(nam, 0); if (strcmp(nam, "PATH") == 0 && !OBJ_TAINTED(name)) { path_tainted = 0; } - return rb_tainted_str_new2(val); + return value; } return Qnil; } static VALUE -env_delete_method(obj, name) +env_delete_m(obj, name) VALUE obj, name; { VALUE val = env_delete(obj, name); @@ -919,7 +915,7 @@ rb_f_getenv(obj, name) char *nam, *env; int len; - nam = str2cstr(name, &len); + nam = rb_str2cstr(name, &len); if (strlen(nam) != len) { rb_raise(rb_eArgError, "bad environment variable name"); } @@ -932,54 +928,6 @@ rb_f_getenv(obj, name) return Qnil; } -static int -path_check_1(path) - char *path; -{ - struct stat st; - char *p = 0; - char *s; - - for (;;) { - if (stat(path, &st) == 0 && (st.st_mode & 002)) { - return 0; - } - s = strrchr(path, '/'); - if (p) *p = '/'; - if (!s || s == path) return 1; - p = s; - *p = '\0'; - } -} - -int -rb_path_check(path) - char *path; -{ - char *p, *pend; - const char sep = PATH_SEP_CHAR; - - if (!path) return 1; - - p = path; - pend = strchr(path, sep); - - for (;;) { - int safe; - - if (pend) *pend = '\0'; - safe = path_check_1(p); - if (!pend) break; - *pend = sep; - if (!safe) { - return 0; - } - p = pend + 1; - pend = strchr(p, sep); - } - return 1; -} - static void path_tainted_p(path) char *path; @@ -1153,8 +1101,8 @@ rb_f_setenv(obj, nm, val) return Qnil; } - name = str2cstr(nm, &nlen); - value = str2cstr(val, &vlen); + name = rb_str2cstr(nm, &nlen); + value = rb_str2cstr(val, &vlen); if (strlen(name) != nlen) rb_raise(rb_eArgError, "bad environment variable name"); if (strlen(value) != vlen) @@ -1371,7 +1319,7 @@ env_index(dmy, value) char *s = strchr(*env, '=')+1; if (s) { if (strncmp(s, RSTRING(value)->ptr, strlen(s)) == 0) { - return rb_tainted_str_new(*env, s-*env); + return rb_tainted_str_new(*env, s-*env-1); } } env++; @@ -1497,7 +1445,7 @@ Init_Hash() rb_define_singleton_method(envtbl,"each_pair", env_each, 0); rb_define_singleton_method(envtbl,"each_key", env_each_key, 0); rb_define_singleton_method(envtbl,"each_value", env_each_value, 0); - rb_define_singleton_method(envtbl,"delete", env_delete_method, 1); + rb_define_singleton_method(envtbl,"delete", env_delete_m, 1); rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0); rb_define_singleton_method(envtbl,"reject!", env_delete_if, 0); rb_define_singleton_method(envtbl,"to_s", env_to_s, 0); diff --git a/inits.c b/inits.c index fdc49f0f4b..5c2dba552c 100644 --- a/inits.c +++ b/inits.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 28 16:01:58 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/intern.h b/intern.h index bcf3921aa9..14d2fdc452 100644 --- a/intern.h +++ b/intern.h @@ -25,7 +25,7 @@ VALUE rb_ary_reverse _((VALUE)); VALUE rb_ary_sort _((VALUE)); VALUE rb_ary_sort_bang _((VALUE)); VALUE rb_ary_delete _((VALUE, VALUE)); -VALUE rb_ary_delete_at _((VALUE, VALUE)); +VALUE rb_ary_delete_at _((VALUE, long)); VALUE rb_ary_plus _((VALUE, VALUE)); VALUE rb_ary_concat _((VALUE, VALUE)); VALUE rb_ary_assoc _((VALUE, VALUE)); @@ -41,7 +41,8 @@ VALUE rb_uint2big _((unsigned long)); VALUE rb_int2big _((long)); VALUE rb_uint2inum _((unsigned long)); VALUE rb_int2inum _((long)); -VALUE rb_str2inum _((const char*, int)); +VALUE rb_cstr2inum _((const char*, int)); +VALUE rb_str2inum _((VALUE, int)); VALUE rb_big2str _((VALUE, int)); long rb_big2long _((VALUE)); #define rb_big2int(x) rb_big2long(x) @@ -150,6 +151,7 @@ VALUE rb_thread_local_aset _((VALUE, ID, VALUE)); int eaccess _((const char*, int)); VALUE rb_file_s_expand_path _((int, VALUE *)); void rb_file_const _((const char*, VALUE)); +char *rb_find_file _((char*)); /* gc.c */ void rb_global_variable _((VALUE*)); void rb_gc_mark_locations _((VALUE*, VALUE*)); @@ -314,6 +316,7 @@ VALUE rb_f_trace_var _((int, VALUE*)); VALUE rb_f_untrace_var _((int, VALUE*)); VALUE rb_f_global_variables _((void)); void rb_alias_variable _((ID, ID)); +struct st_table* rb_generic_ivar_table _((VALUE)); void rb_clone_generic_ivar _((VALUE,VALUE)); void rb_mark_generic_ivar _((VALUE)); void rb_mark_generic_ivar_tbl _((void)); diff --git a/io.c b/io.c index 1db0cef426..1e84717562 100644 --- a/io.c +++ b/io.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 15 18:08:59 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -82,7 +82,6 @@ VALUE rb_eIOError; VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout; static VALUE orig_stdin, orig_stdout, orig_stderr; -VALUE rb_fs; VALUE rb_output_fs; VALUE rb_rs; VALUE rb_output_rs; @@ -701,7 +700,7 @@ rb_io_gets(io) } static VALUE -rb_io_gets_method(argc, argv, io) +rb_io_gets_m(argc, argv, io) int argc; VALUE *argv; VALUE io; @@ -767,7 +766,7 @@ rb_io_readline(argc, argv, io) VALUE *argv; VALUE io; { - VALUE line = rb_io_gets_method(argc, argv, io); + VALUE line = rb_io_gets_m(argc, argv, io); if (NIL_P(line)) { rb_eof_error(); @@ -885,12 +884,12 @@ rb_io_ungetc(io, c) VALUE io, c; { OpenFile *fptr; + int cc = NUM2INT(c); - Check_Type(c, T_FIXNUM); GetOpenFile(io, fptr); rb_io_check_readable(fptr); - if (ungetc(FIX2INT(c), fptr->f) == EOF) + if (ungetc(cc, fptr->f) == EOF) rb_sys_fail(fptr->path); return Qnil; } @@ -966,7 +965,7 @@ rb_io_close(io) } static VALUE -rb_io_close_method(io) +rb_io_close_m(io) VALUE io; { if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) { @@ -1260,6 +1259,9 @@ rb_fopen(fname, mode) rb_sys_fail(fname); } } +#ifdef __human68k__ + fmode(file, _IOTEXT); +#endif return file; } @@ -1809,11 +1811,11 @@ rb_io_clone(io) int fd; char *mode; - NEWOBJ(obj, struct RFile); - CLONESETUP(obj, io); + NEWOBJ(clone, struct RFile); + CLONESETUP(clone, io); GetOpenFile(io, orig); - MakeOpenFile(obj, fptr); + MakeOpenFile(clone, fptr); if (orig->f2) { fflush(orig->f2); @@ -1847,10 +1849,10 @@ rb_io_clone(io) fptr->f = rb_fdopen(fd, "w"); } if (fptr->mode & FMODE_BINMODE) { - rb_io_binmode((VALUE)obj); + rb_io_binmode((VALUE)clone); } - return (VALUE)obj; + return (VALUE)clone; } static VALUE @@ -3211,9 +3213,7 @@ Init_IO() rb_define_singleton_method(rb_cIO, "select", rb_f_select, -1); rb_define_singleton_method(rb_cIO, "pipe", rb_io_s_pipe, 0); - rb_fs = rb_output_fs = Qnil; - rb_define_hooked_variable("$;", &rb_fs, 0, rb_str_setter); - rb_define_hooked_variable("$-F", &rb_fs, 0, rb_str_setter); + rb_output_fs = Qnil; rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter); rb_rs = rb_default_rs = rb_str_new2("\n"); rb_output_rs = Qnil; @@ -3255,7 +3255,7 @@ Init_IO() rb_define_method(rb_cIO, "read", io_read, -1); rb_define_method(rb_cIO, "write", io_write, 1); - rb_define_method(rb_cIO, "gets", rb_io_gets_method, -1); + rb_define_method(rb_cIO, "gets", rb_io_gets_m, -1); rb_define_method(rb_cIO, "readline", rb_io_readline, -1); rb_define_method(rb_cIO, "getc", rb_io_getc, 0); rb_define_method(rb_cIO, "readchar", rb_io_readchar, 0); @@ -3273,7 +3273,7 @@ Init_IO() rb_define_method(rb_cIO, "eof", rb_io_eof, 0); rb_define_method(rb_cIO, "eof?", rb_io_eof, 0); - rb_define_method(rb_cIO, "close", rb_io_close_method, 0); + rb_define_method(rb_cIO, "close", rb_io_close_m, 0); rb_define_method(rb_cIO, "closed?", rb_io_closed, 0); rb_define_method(rb_cIO, "close_read", rb_io_close_read, 0); rb_define_method(rb_cIO, "close_write", rb_io_close_write, 0); diff --git a/lib/cgi.rb b/lib/cgi.rb index 4a17c8b191..e2ba3141bc 100644 --- a/lib/cgi.rb +++ b/lib/cgi.rb @@ -186,7 +186,7 @@ $-v = false RELEASE_DATE = "$Date$" $-v = v - NEEDS_BINMODE = true if /WIN/ni === PLATFORM + NEEDS_BINMODE = true if /WIN/ni === RUBY_PLATFORM PATH_SEPARATOR = {'UNIX'=>'/', 'WINDOWS'=>'\\', 'MACINTOSH'=>':'} HTTP_STATUS = { diff --git a/lib/debug.rb b/lib/debug.rb index 244db021e2..d9c4864c16 100644 --- a/lib/debug.rb +++ b/lib/debug.rb @@ -1,399 +1,701 @@ -LINES__ = {} unless defined? LINES__ +if $SAFE > 0 + STDERR.print "-r debug.rb is not available in safe mode\n" + exit 1 +end +SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ class DEBUGGER__ - begin - require 'readline' - def readline(prompt, hist) - Readline::readline(prompt, hist) + class Mutex + def initialize + @locker = nil + @waiting = [] + @locked = false; end - rescue LoadError - def readline(prompt, hist) - STDOUT.print prompt - STDOUT.flush - line = STDIN.gets - line.chomp! - line + + def locked? + @locked + end + + def lock + return if @locker == Thread.current + while (Thread.critical = true; @locked) + @waiting.push Thread.current + Thread.stop + end + @locked = true + @locker = Thread.current + Thread.critical = false + self + end + + def unlock + return unless @locked + unless @locker == Thread.current + raise RuntimeError, "unlocked by other" + end + Thread.critical = true + t = @waiting.shift + @locked = false + @locker = nil + Thread.critical = false + t.run if t + self end - USE_READLINE = false end + MUTEX = Mutex.new - trap("INT") { DEBUGGER__::CONTEXT.interrupt } - $DEBUG = true - def initialize - @break_points = [] - @display = [] - @stop_next = 1 - @frames = [nil] - @last_file = nil - @last = [nil, nil] - @no_step = nil - @finish_pos = 0 - end + class Context + DEBUG_LAST_CMD = [] - DEBUG_LAST_CMD = [] - - def interrupt - @stop_next = 1 - end - - def debug_eval(str, binding) begin - val = eval(str, binding) - val - rescue - at = caller(0) - STDOUT.printf "%s:%s\n", at.shift, $! - for i in at - break if i =~ /`debug_(eval|command)'$/ #` - STDOUT.printf "\tfrom %s\n", i + require 'readline' + def readline(prompt, hist) + Readline::readline(prompt, hist) end + rescue LoadError + def readline(prompt, hist) + STDOUT.print prompt + STDOUT.flush + line = STDIN.gets + exit unless line + line.chomp! + line + end + USE_READLINE = false end - end - def debug_command(file, line, id, binding) - frame_pos = 0 - binding_file = file - binding_line = line - previus_line = nil - if (ENV['EMACS'] == 't') - STDOUT.printf "\032\032%s:%d:\n", binding_file, binding_line - else - STDOUT.printf "%s:%d:%s", binding_file, binding_line, - line_at(binding_file, binding_line) - end - @frames[0] = binding - display_expressions(binding) - while input = readline("(rdb:-) ", true) - if input == "" - input = DEBUG_LAST_CMD[0] - else - DEBUG_LAST_CMD[0] = input - end - - case input - when /^b(?:reak)?\s+((?:[^:\n]+:)?.+)$/ - pos = $1 - if pos.index(":") - file, pos = pos.split(":") - end - file = File.basename(file) - if pos =~ /^\d+$/ - pname = pos - pos = pos.to_i - else - pname = pos = pos.intern.id2name - end - @break_points.push [true, 0, file, pos] - STDOUT.printf "Set breakpoint %d at %s:%s\n", @break_points.size, file, - pname - - when /^wat(?:ch)?\s+(.+)$/ - exp = $1 - @break_points.push [true, 1, exp] - STDOUT.printf "Set watchpoint %d\n", @break_points.size, exp - - when /^b(?:reak)?$/, /^info b(?:reak)?$/ - n = 1 - STDOUT.print "breakpoints:\n" - for b in @break_points - if b[0] and (b[1] == 0) - STDOUT.printf " %d %s:%s\n", n, b[2], b[3] - end - n += 1 - end - n = 1 - STDOUT.print "\n" - STDOUT.print "watchpoints:\n" - for b in @break_points - if b[0] and (b[1] == 1) - STDOUT.printf " %d %s\n", n, b[2] - end - n += 1 - end - STDOUT.print "\n" - - when /^del(?:ete)?(?:\s+(\d+))?$/ - pos = $1 - unless pos - input = readline("clear all breakpoints? (y/n) ", false) - if input == "y" - for b in @break_points - b[0] = false - end - end - else - pos = pos.to_i - if @break_points[pos-1] - @break_points[pos-1][0] = false - else - STDOUT.printf "Breakpoint %d is not defined\n", pos - end - end - - when /^disp(?:lay)?\s+(.+)$/ - exp = $1 - @display.push.push [true, exp] - STDOUT.printf " %d: %s = %s\n", @display.size, exp, - debug_eval(exp, binding).to_s - - when /^disp(?:lay)?$/, /^info disp(?:lay)?$/ - display_expressions(binding) - - when /^undisp(?:lay)?(?:\s+(\d+))?$/ - pos = $1 - unless pos - input = readline("clear all expressions? (y/n) ", false) - if input == "y" - for d in @display - d[0] = false - end - end - else - pos = pos.to_i - if @display[pos-1] - @display[pos-1][0] = false - else - STDOUT.printf "display expression %d is not defined\n", pos - end - end - - when /^c(?:ont)?$/ - return - - when /^s(?:tep)?(?:\s+(\d+))?$/ - if $1 - lev = $1.to_i - else - lev = 1 - end - @stop_next = lev - return - - when /^n(?:ext)?(?:\s+(\d+))?$/ - if $1 - lev = $1.to_i - else - lev = 1 - end - @stop_next = lev - @no_step = @frames.size - frame_pos - return - - when /^w(?:here)?$/, /^f(?:rame)?$/ - at = caller(0) - 0.upto(@frames.size - 1) do |n| - if frame_pos == n - STDOUT.printf "--> #%d %s\n", n, at[-(@frames.size - n)] - else - STDOUT.printf " #%d %s\n", n, at[-(@frames.size - n)] - end - end - - when /^l(?:ist)?(?:\s+(.+))?$/ - if not $1 - b = previus_line ? previus_line + 10 : binding_line - 5 - e = b + 9 - elsif $1 == '-' - b = previus_line ? previus_line - 10 : binding_line - 5 - e = b + 9 - else - b, e = $1.split(/[-,]/) - if e - b = b.to_i - e = e.to_i - else - b = b.to_i - 5 - e = b + 9 - end - end - previus_line = b - STDOUT.printf "[%d, %d] in %s\n", b, e, binding_file - line_at(binding_file, binding_line) - if lines = LINES__[binding_file] and lines != true - n = 0 - b.upto(e) do |n| - if n > 0 && lines[n-1] - if n == binding_line - STDOUT.printf "=> %d %s\n", n, lines[n-1].chomp - else - STDOUT.printf " %d %s\n", n, lines[n-1].chomp - end - end - end - else - STDOUT.printf "no sourcefile available for %s\n", binding_file - end - - when /^up(?:\s+(\d+))?$/ - previus_line = nil - if $1 - lev = $1.to_i - else - lev = 1 - end - frame_pos += lev - if frame_pos >= @frames.size - frame_pos = @frames.size - 1 - STDOUT.print "at toplevel\n" - end - binding = @frames[frame_pos] - info, binding_file, binding_line = frame_info(frame_pos) - STDOUT.printf "#%d %s\n", frame_pos, info - - when /^down(?:\s+(\d+))?$/ - previus_line = nil - if $1 - lev = $1.to_i - else - lev = 1 - end - frame_pos -= lev - if frame_pos < 0 - frame_pos = 0 - STDOUT.print "at stack bottom\n" - end - binding = @frames[frame_pos] - info, binding_file, binding_line = frame_info(frame_pos) - STDOUT.printf "#%d %s\n", frame_pos, info - - when /^fi(?:nish)?$/ - if frame_pos == 0 - STDOUT.print "\"finish\" not meaningful in the outermost frame.\n" - else - @finish_pos = @frames.size - frame_pos - frame_pos = 0 - return - end - - when /^q(?:uit)?$/ - input = readline("really quit? (y/n) ", false) - exit if input == "y" - - when /^p\s+/ - p debug_eval($', binding) - - else - v = debug_eval(input, binding) - p v unless (v == nil) - end - end - end - - def display_expressions(binding) - n = 1 - for d in @display - if d[0] - STDOUT.printf "%d: %s = %s\n", n, d[1], debug_eval(d[1], binding).to_s - end - n += 1 - end - end - - def frame_info(pos = 0) - info = caller(0)[-(@frames.size - pos)] - info.sub(/:in `.*'$/, "") =~ /^(.*):(\d+)$/ #` - [info, $1, $2.to_i] - end - - def line_at(file, line) - lines = LINES__[file] - if lines - return "\n" if lines == true - line = lines[line-1] - return "\n" unless line - return line - end - return "\n" - end - - def debug_funcname(id) - if id == 0 - "toplevel" - else - id.id2name - end - end - - def check_break_points(file, pos, binding, id) - file = File.basename(file) - n = 1 - for b in @break_points - if b[0] - if b[1] == 0 and b[2] == file and b[3] == pos - STDOUT.printf "breakpoint %d, %s at %s:%s\n", n, debug_funcname(id), - file, pos - return true - elsif b[1] == 1 and debug_eval(b[2], binding) - STDOUT.printf "watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), - file, pos - return true - end - end - n += 1 - end - return false - end - - def excn_handle(file, line, id, binding) - fs = @frames.size - tb = caller(0)[-fs..-1] - - STDOUT.printf "%s\n", $! - for i in tb - STDOUT.printf "\tfrom %s\n", i - end - debug_command(file, line, id, binding) - end - - def trace_func(event, file, line, id, binding) - case event - when 'line' - if !@no_step or @frames.size == @no_step - @stop_next -= 1 - elsif @frames.size < @no_step - @stop_next = 0 # break here before leaving... - else - # nothing to do. skipped. - end - if @stop_next == 0 - if [file, line] == @last - @stop_next = 1 - else - @no_step = nil - debug_command(file, line, id, binding) - @last = [file, line] - end - end - if check_break_points(file, line, binding, id) - debug_command(file, line, id, binding) - end - - when 'call' - @frames.unshift binding - if check_break_points(file, id.id2name, binding, id) - debug_command(file, line, id, binding) - end - - when 'class' - @frames.unshift binding - - when 'return', 'end' - @frames.shift - if @frames.size == @finish_pos + def initialize + if Thread.current == Thread.main @stop_next = 1 + else + @stop_next = 0 end - - when 'raise' - excn_handle(file, line, id, binding) - + @last_file = nil + @last = [nil, nil] + @file = nil + @line = nil + @no_step = nil + @frames = [] + @finish_pos = 0 + end + + def stop_next(n=1) + @stop_next = n + end + + def stdout + DEBUGGER__.stdout + end + def break_points + DEBUGGER__.break_points + end + def display + DEBUGGER__.display + end + + def debug_eval(str, binding) + begin + val = eval(str, binding) + val + rescue + at = eval("caller(0)", binding) + stdout.printf "%s:%s\n", at.shift, $!.to_s.sub(/\(eval\):1:(in `.*?':)?/, '') #` + for i in at + stdout.printf "\tfrom %s\n", i + end + throw :debug_error + end + end + + def var_list(ary, binding) + ary.sort! + if ary.size > 24 + f = open("|less", "w") + for v in ary + f.printf " %s => %s\n", v, eval(v, binding).inspect + end + f.close + else + for v in ary + stdout.printf " %s => %s\n", v, eval(v, binding).inspect + end + end + end + + def debug_variable_info(input, binding) + case input + when /^\s*g(?:lobal)?$/ + f = open("|less", "w") + var_list(global_variables, binding) + + when /^\s*l(?:ocal)?$/ + var_list(eval("local_variables", binding), binding) + + when /^\s*i(?:nstance)?\s+/ + obj = debug_eval($', binding) + var_list(obj.instance_variables, binding) + + when /^\s*c(?:onst(?:ant)?)?\s+/ + obj = debug_eval($', binding) + unless obj.kind_of? Module + stdout.print "should be Class/Module: ", $', "\n" + else + var_list(obj.constants, obj.module_eval{binding()}) + end + end + end + + def debug_method_info(input, binding) + case input + when /^i(:?nstance)?\s+/ + obj = debug_eval($', binding) + + len = 0 + for v in obj.methods.sort + len += v.size + 1 + if len > 70 + len = v.size + 1 + stdout.print "\n" + end + stdout.print v, " " + end + stdout.print "\n" + + else + obj = debug_eval($', binding) + unless obj.kind_of? Module + stdout.print "should be Class/Module: ", $', "\n" + else + len = 0 + for v in obj.instance_methods.sort + len += v.size + 1 + if len > 70 + len = v.size + 1 + stdout.print "\n" + end + stdout.print v, " " + end + stdout.print "\n" + end + end + end + + def thnum + num = DEBUGGER__.instance_eval{@thread_list[Thread.current]} + unless num + DEBUGGER__.make_thread_list + num = DEBUGGER__.instance_eval{@thread_list[Thread.current]} + end + num + end + + def debug_command(file, line, id, binding) + MUTEX.lock + DEBUGGER__.set_last_thread(Thread.current) + frame_pos = 0 + binding_file = file + binding_line = line + previous_line = nil + if (ENV['EMACS'] == 't') + stdout.printf "\032\032%s:%d:\n", binding_file, binding_line + else + stdout.printf "%s:%d:%s", binding_file, binding_line, + line_at(binding_file, binding_line) + end + @frames[0] = [binding, file, line, id] + display_expressions(binding) + while input = readline("(rdb:%d) "%thnum(), true) + catch (:debug_error) do + if input == "" + input = DEBUG_LAST_CMD[0] + stdout.print input, "\n" + else + DEBUG_LAST_CMD[0] = input + end + + case input + when /^\s*b(?:reak)?\s+((?:.*?+:)?.+)$/ + pos = $1 + if pos.index(":") + file, pos = pos.split(":") + end + file = File.basename(file) + if pos =~ /^\d+$/ + pname = pos + pos = pos.to_i + else + pname = pos = pos.intern.id2name + end + break_points.push [true, 0, file, pos] + stdout.printf "Set breakpoint %d at %s:%s\n", break_points.size, file, + pname + + when /^\s*wat(?:ch)?\s+(.+)$/ + exp = $1 + break_points.push [true, 1, exp] + stdout.printf "Set watchpoint %d\n", break_points.size, exp + + when /^\s*b(?:reak)?$/ + if break_points.find{|b| b[1] == 0} + n = 1 + stdout.print "breakpoints:\n" + for b in break_points + if b[0] and b[1] == 0 + stdout.printf " %d %s:%s\n", n, b[2], b[3] + end + n += 1 + end + end + if break_points.find{|b| b[1] == 1} + n = 1 + stdout.print "\n" + stdout.print "watchpoints:\n" + for b in break_points + if b[0] and b[1] == 1 + stdout.printf " %d %s\n", n, b[2] + end + n += 1 + end + end + if break_points.size == 0 + stdout.print "no breakpoints\n" + else + stdout.print "\n" + end + + when /^\s*del(?:ete)?(?:\s+(\d+))?$/ + pos = $1 + unless pos + input = readline("clear all breakpoints? (y/n) ", false) + if input == "y" + for b in break_points + b[0] = false + end + end + else + pos = pos.to_i + if break_points[pos-1] + break_points[pos-1][0] = false + else + stdout.printf "Breakpoint %d is not defined\n", pos + end + end + + when /^\s*disp(?:lay)?\s+(.+)$/ + exp = $1 + display.push.push [true, exp] + stdout.printf " %d: %s = %s\n", display.size, exp, + eval(exp, binding) rescue "--" + + when /^\s*disp(?:lay)?$/ + display_expressions(binding) + + when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/ + pos = $1 + unless pos + input = readline("clear all expressions? (y/n) ", false) + if input == "y" + for d in display + d[0] = false + end + end + else + pos = pos.to_i + if display[pos-1] + display[pos-1][0] = false + else + stdout.printf "display expression %d is not defined\n", pos + end + end + + when /^\s*c(?:ont)?$/ + MUTEX.unlock + return + + when /^\s*s(?:tep)?(?:\s+(\d+))?$/ + if $1 + lev = $1.to_i + else + lev = 1 + end + @stop_next = lev + return + + when /^\s*n(?:ext)?(?:\s+(\d+))?$/ + if $1 + lev = $1.to_i + else + lev = 1 + end + @stop_next = lev + @no_step = @frames.size - frame_pos + return + + when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/ + display_frames(frame_pos) + + when /^\s*l(?:ist)?(?:\s+(.+))?$/ + if not $1 + b = previous_line ? previous_line + 10 : binding_line - 5 + e = b + 9 + elsif $1 == '-' + b = previous_line ? previous_line - 10 : binding_line - 5 + e = b + 9 + else + b, e = $1.split(/[-,]/) + if e + b = b.to_i + e = e.to_i + else + b = b.to_i - 5 + e = b + 9 + end + end + previous_line = b + display_list(b, e, binding_file, binding_line) + + when /^\s*up(?:\s+(\d+))?$/ + previous_line = nil + if $1 + lev = $1.to_i + else + lev = 1 + end + frame_pos += lev + if frame_pos >= @frames.size + frame_pos = @frames.size - 1 + stdout.print "at toplevel\n" + end + binding, binding_file, binding_line = @frames[frame_pos] + stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line + + when /^\s*down(?:\s+(\d+))?$/ + previous_line = nil + if $1 + lev = $1.to_i + else + lev = 1 + end + frame_pos -= lev + if frame_pos < 0 + frame_pos = 0 + stdout.print "at stack bottom\n" + end + binding, binding_file, binding_line = @frames[frame_pos] + stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line + + when /^\s*fi(?:nish)?$/ + if frame_pos == 0 + stdout.print "\"finish\" not meaningful in the outermost frame.\n" + else + @finish_pos = @frames.size - frame_pos + frame_pos = 0 + return + end + + when /^\s*q(?:uit)?$/ + input = readline("really quit? (y/n) ", false) + exit if input == "y" + + when /^\s*v(?:ar)?\s+/ + debug_variable_info($', binding) + + when /^\s*m(?:ethod)?\s+/ + debug_method_info($', binding) + + when /^\s*th(?:read)?\s+/ + if DEBUGGER__.debug_thread_info($', binding) == :cont + MUTEX.unlock + return + end + + when /^\s*p\s+/ + p debug_eval($', binding) + + else + v = debug_eval(input, binding) + p v unless (v == nil) + end + end + end + end + + def display_expressions(binding) + n = 1 + for d in display + if d[0] + stdout.printf "%d: %s = %s\n", n, d[1], debug_eval(d[1], binding).to_s + end + n += 1 + end + end + + def frame_set_pos(file, line) + if @frames[0] + @frames[0][1] = file + @frames[0][2] = line + end + end + + def display_frames(pos) + pos += 1 + n = 0 + at = @frames + for bind, file, line, id in at + n += 1 + break unless bind + if pos == n + stdout.printf "--> #%d %s:%s%s\n", n, file, line, id != 0 ? ":in `#{id.id2name}'":"" + else + stdout.printf " #%d %s:%s%s\n", n, file, line, id != 0 ? ":in `#{id.id2name}'":"" + end + end + end + + def display_list(b, e, file, line) + stdout.printf "[%d, %d] in %s\n", b, e, file + if lines = SCRIPT_LINES__[file] and lines != true + n = 0 + b.upto(e) do |n| + if n > 0 && lines[n-1] + if n == line + stdout.printf "=> %d %s\n", n, lines[n-1].chomp + else + stdout.printf " %d %s\n", n, lines[n-1].chomp + end + end + end + else + stdout.printf "no sourcefile available for %s\n", file + end + end + + def line_at(file, line) + lines = SCRIPT_LINES__[file] + if lines + return "\n" if lines == true + line = lines[line-1] + return "\n" unless line + return line + end + return "\n" + end + + def debug_funcname(id) + if id == 0 + "toplevel" + else + id.id2name + end + end + + def check_break_points(file, pos, binding, id) + file = File.basename(file) + n = 1 + for b in break_points + if b[0] + if b[1] == 0 and b[2] == file and b[3] == pos + MUTEX.lock + stdout.printf "breakpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos + return true + elsif b[1] == 1 and debug_eval(b[2], binding) + MUTEX.lock + stdout.printf "watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos + return true + end + end + n += 1 + end + return false + end + + def excn_handle(file, line, id, binding) + if $!.type <= SystemExit + set_trace_func nil + exit + end + MUTEX.lock + fs = @frames.size + tb = caller(0)[-fs..-1] + + stdout.printf "%s\n", $! + if tb + for i in tb + stdout.printf "\tfrom %s\n", i + end + end + debug_command(file, line, id, binding) + end + + def trace_func(event, file, line, id, binding, klass) + @file = file + @line = line + case event + when 'line' + frame_set_pos(file, line) + if !@no_step or @frames.size == @no_step + @stop_next -= 1 + elsif @frames.size < @no_step + @stop_next = 0 # break here before leaving... + else + # nothing to do. skipped. + end + if @stop_next == 0 or check_break_points(file, line, binding, id) + if [file, line] == @last + @stop_next = 1 + else + @no_step = nil + debug_command(file, line, id, binding) + @last = [file, line] + end + end + + when 'call' + @frames.unshift [binding, file, line, id] + if check_break_points(file, id.id2name, binding, id) or + check_break_points(klass.to_s, id.id2name, binding, id) + debug_command(file, line, id, binding) + end + + when 'c-call' + frame_set_pos(file, line) + + when 'class' + @frames.unshift [binding, file, line, id] + + when 'return', 'end' + @frames.shift + if @frames.size == @finish_pos + @stop_next = 1 + end + + when 'end' + @frames.shift + + when 'raise' + excn_handle(file, line, id, binding) + + end + @last_file = file end - @last_file = file end - CONTEXT = new + trap("INT") { DEBUGGER__.interrupt } +# $DEBUG = true + @last_thread = Thread::main + @max_thread = 1 + @thread_list = {Thread::main => 1} + @break_points = [] + @display = [] + @stdout = STDOUT + class <num_entries, arg->arg); + st_foreach(tbl, obj_each, arg); + } + else { + w_long(0, arg->arg); + } +} + static void w_object(obj, arg, limit) VALUE obj; @@ -207,6 +224,7 @@ w_object(obj, arg, limit) int limit; { struct dump_call_arg c_arg; + st_table *ivtbl = 0;; if (limit == 0) { rb_raise(rb_eRuntimeError, "exceed depth limit"); @@ -262,6 +280,10 @@ w_object(obj, arg, limit) return; } + if (ivtbl = rb_generic_ivar_table(obj)) { + w_byte(TYPE_IVAR, arg); + } + switch (BUILTIN_TYPE(obj)) { case T_CLASS: w_byte(TYPE_CLASS, arg); @@ -269,7 +291,7 @@ w_object(obj, arg, limit) VALUE path = rb_class_path(obj); w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg); } - return; + break; case T_MODULE: w_byte(TYPE_MODULE, arg); @@ -277,12 +299,12 @@ w_object(obj, arg, limit) VALUE path = rb_class_path(obj); w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg); } - return; + break; case T_FLOAT: w_byte(TYPE_FLOAT, arg); w_float(RFLOAT(obj)->value, arg); - return; + break; case T_BIGNUM: w_byte(TYPE_BIGNUM, arg); @@ -298,20 +320,20 @@ w_object(obj, arg, limit) d++; } } - return; + break; case T_STRING: w_uclass(obj, rb_cString, arg); w_byte(TYPE_STRING, arg); w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg); - return; + break; case T_REGEXP: w_uclass(obj, rb_cRegexp, arg); w_byte(TYPE_REGEXP, arg); w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg); w_byte(rb_reg_options(obj), arg); - return; + break; case T_ARRAY: w_uclass(obj, rb_cArray, arg); @@ -375,13 +397,7 @@ w_object(obj, arg, limit) } path = rb_class2name(klass); w_unique(path, arg); - if (ROBJECT(obj)->iv_tbl) { - w_long(ROBJECT(obj)->iv_tbl->num_entries, arg); - st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &c_arg); - } - else { - w_long(0, arg); - } + w_ivar(ROBJECT(obj)->iv_tbl); } break; @@ -391,6 +407,9 @@ w_object(obj, arg, limit) break; } } + if (ivtbl) { + w_ivar(ivtbl, &c_arg); + } } static VALUE @@ -471,6 +490,8 @@ struct load_arg { VALUE proc; }; +static VALUE r_object _((struct load_arg *arg)); + static int r_byte(arg) struct load_arg *arg; @@ -624,6 +645,23 @@ r_regist(v, arg) return v; } +static void +r_ivar(obj, arg) + VALUE obj; + struct load_arg *arg; +{ + int len; + + len = r_long(arg); + if (len > 0) { + while (len--) { + ID id = r_symbol(arg); + VALUE val = r_object(arg); + rb_ivar_set(obj, id, val); + } + } +} + static VALUE r_object(arg) struct load_arg *arg; @@ -642,6 +680,11 @@ r_object(arg) return v; break; + case TYPE_IVAR: + v = r_object(arg); + r_ivar(v, arg); + return v; + case TYPE_UCLASS: { VALUE c = rb_path2class(r_unique(arg)); @@ -793,19 +836,11 @@ r_object(arg) case TYPE_OBJECT: { VALUE klass; - int len; klass = rb_path2class(r_unique(arg)); - len = r_long(arg); v = rb_obj_alloc(klass); r_regist(v, arg); - if (len > 0) { - while (len--) { - ID id = r_symbol(arg); - VALUE val = r_object(arg); - rb_ivar_set(v, id, val); - } - } + r_ivar(v, arg); return v; } break; @@ -887,7 +922,7 @@ marshal_load(argc, argv) int len; arg.fp = 0; - arg.ptr = str2cstr(port, &len); + arg.ptr = rb_str2cstr(port, &len); arg.end = arg.ptr + len; } else { diff --git a/math.c b/math.c index 978a23c73c..39bc48aa1c 100644 --- a/math.c +++ b/math.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 25 14:12:56 JST 1994 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index 098ddd5e04..1b7effc459 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -189,7 +189,7 @@ The variable ruby-indent-level controls the amount of indentation. (indent-to x) (move-to-column (+ x shift)))))) -(defun ruby-expr-beg (&optional modifier) +(defun ruby-expr-beg (&optional option) (save-excursion (if (looking-at "\\?") (progn @@ -201,15 +201,11 @@ The variable ruby-indent-level controls the amount of indentation. (or (bolp) (looking-at ruby-operator-re) (looking-at "[\\[({]") - (and (not modifier) (looking-at "[!?]")) + (and (not (eq option 'modifier)) + (looking-at "[!?]")) (and (looking-at ruby-symbol-re) - (save-restriction - (let ((p (point))) - (beginning-of-line) - (narrow-to-region (point) p) - (goto-char p) - (forward-word -1))) - (if (and (not modifier) (bolp)) + (skip-chars-backward ruby-symbol-chars) + (if (and (not (eq option 'modifier)) (bolp)) t (if (or (looking-at ruby-block-beg-re) (looking-at ruby-block-op-re) @@ -217,7 +213,8 @@ The variable ruby-indent-level controls the amount of indentation. (progn (goto-char (match-end 0)) (looking-at "\\>")) - (looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]")))))))) + (and (not (eq option 'expr-arg)) + (looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]"))))))))) (defun ruby-parse-region (start end) (let ((indent-point end) @@ -252,7 +249,7 @@ The variable ruby-indent-level controls the amount of indentation. (goto-char indent-point)))) ((looking-at "/") (cond - ((and (not (eobp)) (ruby-expr-beg)) + ((and (not (eobp)) (ruby-expr-beg 'expr-arg)) (if (re-search-forward "[^\\]/" indent-point t) nil (setq in-string (point)) @@ -261,7 +258,7 @@ The variable ruby-indent-level controls the amount of indentation. (goto-char pnt)))) ((looking-at "%") (cond - ((and (not (eobp)) (ruby-expr-beg) + ((and (not (eobp)) (ruby-expr-beg 'expr-arg) (not (looking-at "%=")) (looking-at "%[Qqrxw]?\\(.\\)")) (setq w (buffer-substring (match-beginning 1) @@ -352,7 +349,7 @@ The variable ruby-indent-level controls the amount of indentation. (progn (goto-char (match-beginning 0)) (if (looking-at ruby-modifier-re) - (ruby-expr-beg t) + (ruby-expr-beg 'modifier) t)) t) (goto-char pnt) diff --git a/missing/x68.c b/missing/x68.c index dbfe662874..9a8f0a2a9c 100644 --- a/missing/x68.c +++ b/missing/x68.c @@ -18,6 +18,7 @@ link(const char *src, const char *dst) return symlink(src, dst); } +#ifndef HAVE_GETTIMEOFDAY #include #include @@ -34,3 +35,4 @@ gettimeofday(struct timeval *tv, struct timezone *tz) return 0; } +#endif diff --git a/node.h b/node.h index e402d0f944..6c98d79a9b 100644 --- a/node.h +++ b/node.h @@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 15:14:02 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/numeric.c b/numeric.c index 77b52ffec9..28ecba54d3 100644 --- a/numeric.c +++ b/numeric.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 13 18:33:09 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/object.c b/object.c index 0851989184..afdd9e9aca 100644 --- a/object.c +++ b/object.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Jul 15 12:01:24 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -801,7 +801,7 @@ rb_Integer(val) return val; case T_STRING: - return rb_str2inum(RSTRING(val)->ptr, 0); + return rb_str2inum(val, 0); case T_NIL: return INT2FIX(0); @@ -827,8 +827,6 @@ rb_f_integer(obj, arg) return rb_Integer(arg); } -double rb_big2dbl _((VALUE)); - VALUE rb_Float(val) VALUE val; diff --git a/pack.c b/pack.c index 999f93a0e7..0b0ebb0202 100644 --- a/pack.c +++ b/pack.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Feb 10 15:17:05 JST 1994 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -329,7 +329,7 @@ pack_pack(ary, fmt) int natint; /* native integer */ #endif - p = str2cstr(fmt, &plen); + p = rb_str2cstr(fmt, &plen); pend = p + plen; res = rb_str_new(0, 0); @@ -379,7 +379,7 @@ pack_pack(ary, fmt) plen = 0; } else { - ptr = str2cstr(from, &plen); + ptr = rb_str2cstr(from, &plen); } if (p[-1] == '*') @@ -813,7 +813,7 @@ pack_pack(ary, fmt) case 'u': case 'm': - ptr = str2cstr(NEXTFROM, &plen); + ptr = rb_str2cstr(NEXTFROM, &plen); if (len <= 1) len = 45; @@ -1030,9 +1030,9 @@ pack_unpack(str, fmt) int natint; /* native integer */ #endif - s = str2cstr(str, &len); + s = rb_str2cstr(str, &len); send = s + len; - p = str2cstr(fmt, &len); + p = rb_str2cstr(fmt, &len); pend = p + len; ary = rb_ary_new(); diff --git a/parse.y b/parse.y index 86cbf78362..d7ee97269a 100644 --- a/parse.y +++ b/parse.y @@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 18:02:42 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -331,21 +331,31 @@ stmt : block_call | stmt kWHILE_MOD expr { value_expr($3); - if (nd_type($1) == NODE_BEGIN) { - $$ = NEW_WHILE(cond($3), $1->nd_body, 0); + if ($1) { + if (nd_type($1) == NODE_BEGIN) { + $$ = NEW_WHILE(cond($3), $1->nd_body, 0); + } + else { + $$ = NEW_WHILE(cond($3), $1, 1); + } } else { - $$ = NEW_WHILE(cond($3), $1, 1); + $$ = 0; } } | stmt kUNTIL_MOD expr { value_expr($3); - if (nd_type($1) == NODE_BEGIN) { - $$ = NEW_UNTIL(cond($3), $1->nd_body, 0); + if ($1) { + if (nd_type($1) == NODE_BEGIN) { + $$ = NEW_UNTIL(cond($3), $1->nd_body, 0); + } + else { + $$ = NEW_UNTIL(cond($3), $1, 1); + } } else { - $$ = NEW_UNTIL(cond($3), $1, 1); + $$ = 0; } } | stmt kRESCUE_MOD expr @@ -606,7 +616,7 @@ op : tDOT2 { $$ = tDOT2; } | tASET { $$ = tASET; } | '`' { $$ = '`'; } -reswords : k__LINE__ | k__FILE__ | klBEGIN | klEND +reswords : k__LINE__ | k__FILE__ | klBEGIN | klEND | kALIAS | kAND | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | kDEFINED | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE | kFOR | kIF_MOD | kIN | kMODULE | kNEXT | kNIL | kNOT @@ -713,7 +723,7 @@ arg : lhs '=' arg } | tUPLUS arg { - if (nd_type($2) == NODE_LIT) { + if ($2 && nd_type($2) == NODE_LIT) { $$ = $2; } else { @@ -722,7 +732,7 @@ arg : lhs '=' arg } | tUMINUS arg { - if (nd_type($2) == NODE_LIT && FIXNUM_P($2->nd_lit)) { + if ($2 && nd_type($2) == NODE_LIT && FIXNUM_P($2->nd_lit)) { long i = FIX2LONG($2->nd_lit); $2->nd_lit = INT2FIX(-i); @@ -1781,16 +1791,17 @@ int ruby__end__seen; static VALUE ruby_debug_lines; static NODE* -yycompile(f) +yycompile(f, line) char *f; + int line; { int n; if (!ruby_in_eval && rb_safe_level() == 0 && - rb_const_defined(rb_cObject, rb_intern("LINES__"))) { + rb_const_defined(rb_cObject, rb_intern("SCRIPT_LINES__"))) { VALUE hash, fname; - hash = rb_const_get(rb_cObject, rb_intern("LINES__")); + hash = rb_const_get(rb_cObject, rb_intern("SCRIPT_LINES__")); if (TYPE(hash) == T_HASH) { fname = rb_str_new2(f); ruby_debug_lines = rb_hash_aref(hash, fname); @@ -1799,6 +1810,13 @@ yycompile(f) rb_hash_aset(hash, fname, ruby_debug_lines); } } + if (line > 1) { + VALUE str = rb_str_new(0,0); + while (line > 1) { + rb_ary_push(ruby_debug_lines, str); + line--; + } + } } ruby__end__seen = 0; @@ -1864,7 +1882,7 @@ rb_compile_string(f, s, line) ruby_sourceline = line - 1; compile_for_eval = 1; - return yycompile(f); + return yycompile(f, line); } NODE* @@ -1886,7 +1904,7 @@ rb_compile_file(f, file, start) lex_pbeg = lex_p = lex_pend = 0; ruby_sourceline = start - 1; - return yycompile(strdup(f)); + return yycompile(strdup(f), start); } #if defined(__GNUC__) && __GNUC__ >= 2 @@ -2873,7 +2891,7 @@ yylex() } while (c = nextc()); pushback(c); tokfix(); - yylval.val = rb_str2inum(tok(), 16); + yylval.val = rb_cstr2inum(tok(), 16); return tINTEGER; } if (c == 'b' || c == 'B') { @@ -2889,7 +2907,7 @@ yylex() } while (c = nextc()); pushback(c); tokfix(); - yylval.val = rb_str2inum(tok(), 2); + yylval.val = rb_cstr2inum(tok(), 2); return tINTEGER; } if (c >= '0' && c <= '7' || c == '_') { @@ -2901,7 +2919,7 @@ yylex() } while (c = nextc()); pushback(c); tokfix(); - yylval.val = rb_str2inum(tok(), 8); + yylval.val = rb_cstr2inum(tok(), 8); return tINTEGER; } if (c > '7' && c <= '9') { @@ -2977,7 +2995,7 @@ yylex() yylval.val = rb_float_new(d); return tFLOAT; } - yylval.val = rb_str2inum(tok(), 10); + yylval.val = rb_cstr2inum(tok(), 10); return tINTEGER; } diff --git a/prec.c b/prec.c index e4e116c347..65d84af736 100644 --- a/prec.c +++ b/prec.c @@ -4,9 +4,9 @@ $Author$ $Date$ - created at: Tue Jan 26 02:40:41 1999 + created at: Tue Jan 26 02:40:41 2000 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto *************************************************/ diff --git a/process.c b/process.c index c134a9e95a..f68753b1eb 100644 --- a/process.c +++ b/process.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 14:30:50 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/random.c b/random.c index 67c752d0f7..62d300af56 100644 --- a/random.c +++ b/random.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Dec 24 16:39:21 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/range.c b/range.c index b6cda5dc1e..8eca8588e4 100644 --- a/range.c +++ b/range.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Aug 19 17:46:47 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/re.c b/re.c index 46ed3ef4a9..15eb0cef97 100644 --- a/re.c +++ b/re.c @@ -5,7 +5,7 @@ $Author$ created at: Mon Aug 9 18:24:49 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -311,7 +311,7 @@ rb_reg_casefold_p(re) } static VALUE -rb_reg_kcode_method(re) +rb_reg_kcode_m(re) VALUE re; { char *kcode = "$KCODE"; @@ -382,21 +382,21 @@ match_alloc() } static VALUE -match_clone(orig) - VALUE orig; +match_clone(match) + VALUE match; { - NEWOBJ(match, struct RMatch); - OBJSETUP(match, rb_cMatch, T_MATCH); + NEWOBJ(clone, struct RMatch); + OBJSETUP(clone, rb_cMatch, T_MATCH); - match->str = RMATCH(orig)->str; - match->regs = 0; + clone->str = RMATCH(match)->str; + clone->regs = 0; - match->regs = ALLOC(struct re_registers); - match->regs->allocated = 0; - re_copy_registers(match->regs, RMATCH(orig)->regs); - CLONESETUP(match, orig); + clone->regs = ALLOC(struct re_registers); + clone->regs->allocated = 0; + re_copy_registers(clone->regs, RMATCH(match)->regs); + CLONESETUP(clone, match); - return (VALUE)match; + return (VALUE)clone; } static VALUE @@ -587,6 +587,7 @@ rb_reg_search(reg, str, pos, reverse) "Stack overfow in regexp matcher", reg); } if (result < 0) { + FL_UNSET(match, FL_TAINT); matchcache = match; rb_backref_set(Qnil); } @@ -595,6 +596,8 @@ rb_reg_search(reg, str, pos, reverse) rb_backref_set(match); } + OBJ_INFECT(match, reg); + OBJ_INFECT(match, str); return result; } @@ -616,6 +619,7 @@ rb_reg_nth_match(nth, match) int nth; VALUE match; { + VALUE str; int start, end, len; if (NIL_P(match)) return Qnil; @@ -626,7 +630,9 @@ rb_reg_nth_match(nth, match) if (start == -1) return Qnil; end = RMATCH(match)->END(nth); len = end - start; - return rb_str_new(RSTRING(RMATCH(match)->str)->ptr + start, len); + str = rb_str_new(RSTRING(RMATCH(match)->str)->ptr + start, len); + if (OBJ_TAINTED(match)) OBJ_TAINT(str); + return str; } VALUE @@ -745,6 +751,7 @@ match_to_s(match) if (NIL_P(str)) str = rb_str_new(0,0); if (OBJ_TAINTED(match)) OBJ_TAINT(str); + if (OBJ_TAINTED(RMATCH(match)->str)) OBJ_TAINT(str); return str; } @@ -913,7 +920,7 @@ rb_reg_match2(re) } static VALUE -rb_reg_match_method(re, str) +rb_reg_match_m(re, str) VALUE re, str; { VALUE result = rb_reg_match(re, str); @@ -967,7 +974,7 @@ rb_reg_s_new(argc, argv, self) char *p; int len; - p = str2cstr(src, &len); + p = rb_str2cstr(src, &len); return rb_reg_new_1(self, p, len, flag); } } @@ -989,7 +996,7 @@ rb_reg_s_quote(argc, argv) curr_kcode = reg_kcode; reg_kcode = kcode_saved; } - s = str2cstr(str, &len); + s = rb_str2cstr(str, &len); send = s + len; tmp = ALLOCA_N(char, len*2); t = tmp; @@ -1072,15 +1079,15 @@ rb_reg_options(re) } static VALUE -rb_reg_clone(orig) - VALUE orig; -{ +rb_reg_clone(reg) VALUE reg; +{ + VALUE clone; - reg = rb_reg_new_1(CLASS_OF(orig), RREGEXP(orig)->str, RREGEXP(orig)->len, - rb_reg_options(orig)); - CLONESETUP(reg, orig); - return reg; + clone = rb_reg_new_1(CLASS_OF(reg), RREGEXP(reg)->str, RREGEXP(reg)->len, + rb_reg_options(reg)); + CLONESETUP(clone, reg); + return clone; } VALUE @@ -1292,11 +1299,11 @@ Init_Regexp() rb_define_method(rb_cRegexp, "=~", rb_reg_match, 1); rb_define_method(rb_cRegexp, "===", rb_reg_match, 1); rb_define_method(rb_cRegexp, "~", rb_reg_match2, 0); - rb_define_method(rb_cRegexp, "match", rb_reg_match_method, 1); + rb_define_method(rb_cRegexp, "match", rb_reg_match_m, 1); rb_define_method(rb_cRegexp, "inspect", rb_reg_inspect, 0); rb_define_method(rb_cRegexp, "source", rb_reg_source, 0); rb_define_method(rb_cRegexp, "casefold?", rb_reg_casefold_p, 0); - rb_define_method(rb_cRegexp, "kcode", rb_reg_kcode_method, 0); + rb_define_method(rb_cRegexp, "kcode", rb_reg_kcode_m, 0); rb_define_const(rb_cRegexp, "IGNORECASE", INT2FIX(RE_OPTION_IGNORECASE)); rb_define_const(rb_cRegexp, "EXTENDED", INT2FIX(RE_OPTION_EXTENDED)); diff --git a/re.h b/re.h index 2ce2134ccc..a9daa72e0b 100644 --- a/re.h +++ b/re.h @@ -6,7 +6,7 @@ $Date$ created at: Thu Sep 30 14:18:32 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/ruby.c b/ruby.c index 50e425b562..4f87d74818 100644 --- a/ruby.c +++ b/ruby.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 12:47:31 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -79,6 +79,7 @@ usage(name) "-0[octal] specify record separator (\\0, if no argument)", "-a autosplit mode with -n or -p (splits $_ into $F)", "-c check syntax only", +"-Cdirectory cd to directory, before executing your script", "-d set debugging flags (set $DEBUG to true)", "-e 'command' one line of script. Several -e's allowed. Omit [programfile]", "-Fpattern split() pattern for autosplit (-a)", @@ -95,7 +96,6 @@ usage(name) "-v enables verbose mode", "-w turn warnings on for compilation of your script", "-x[directory] strip off text before #!ruby line and perhaps cd to directory", -"-Xdirectory cd to directory, before executing your script", "--copyright print the copyright", "--version print the version", "\n", @@ -441,13 +441,17 @@ proc_options(argc, argv) } break; + case 'C': case 'X': s++; if (!*s) { s = argv[1]; argc--,argv++; } - if (*s && chdir(s) < 0) { + if (!s || !*s) { + rb_fatal("Can't chdir"); + } + if (chdir(s) < 0) { rb_fatal("Can't chdir to %s", s); } break; diff --git a/ruby.h b/ruby.h index fd87c0bcb2..a5c9e39ad3 100644 --- a/ruby.h +++ b/ruby.h @@ -5,7 +5,7 @@ $Author$ created at: Thu Jun 10 14:26:32 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto *************************************************/ @@ -131,8 +131,9 @@ VALUE rb_uint2inum _((unsigned long)); #define Qfalse 0 #define Qtrue 2 #define Qnil 4 +#define Qundef 6 /* undefined value for placeholder */ -#define RTEST(v) rb_test_false_or_nil((VALUE)(v)) +#define RTEST(v) ((VALUE)(v) & ~Qnil) #define NIL_P(v) ((VALUE)(v) == Qnil) #define CLASS_OF(v) rb_class_of((VALUE)(v)) @@ -306,7 +307,7 @@ struct RBignum { struct RBasic basic; char sign; long len; - unsigned short *digits; + void *digits; }; #define R_CAST(st) (struct st*) @@ -343,14 +344,17 @@ struct RBignum { #define FL_UMASK (0xff<flags&(f)):0) -#define FL_SET(x,f) if (FL_ABLE(x)) {RBASIC(x)->flags |= (f);} -#define FL_UNSET(x,f) if(FL_ABLE(x)){RBASIC(x)->flags &= ~(f);} -#define FL_REVERSE(x,f) if(FL_ABLE(x)){RBASIC(x)->flags ^= f;} +#define FL_SET(x,f) (FL_ABLE(x) && (RBASIC(x)->flags |= (f))) +#define FL_UNSET(x,f) (FL_ABLE(x) && (RBASIC(x)->flags &= ~(f))) +#define FL_REVERSE(x,f) (FL_ABLE(x) && (RBASIC(x)->flags ^= (f))) #define OBJ_TAINTED(x) FL_TEST((x), FL_TAINT) #define OBJ_TAINT(x) FL_SET((x), FL_TAINT) +#define OBJ_INFECT(x,s) (FL_ABLE(x) && FL_ABLE(s) && (RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT)) void *xmalloc _((size_t)); void *xcalloc _((size_t,size_t)); @@ -503,7 +507,6 @@ EXTERN VALUE rb_eFloatDomainError; extern __inline__ VALUE rb_class_of _((VALUE)); extern __inline__ int rb_type _((VALUE)); extern __inline__ int rb_special_const_p _((VALUE)); -extern __inline__ int rb_test_false_or_nil _((VALUE)); extern __inline__ VALUE rb_class_of(VALUE obj) @@ -529,23 +532,14 @@ rb_type(VALUE obj) extern __inline__ int rb_special_const_p(VALUE obj) { - if (FIXNUM_P(obj)) return Qtrue; - if (obj == Qnil) return Qtrue; - if (obj == Qfalse) return Qtrue; - if (obj == Qtrue) return Qtrue;; + if (SPECIAL_CONST_P(obj)) return Qtrue; return Qfalse; } -extern __inline__ int -rb_test_false_or_nil(VALUE v) -{ - return (v != Qnil) && (v != Qfalse); -} #else VALUE rb_class_of _((VALUE)); int rb_type _((VALUE)); int rb_special_const_p _((VALUE)); -int rb_test_false_or_nil _((VALUE)); #endif #include "intern.h" diff --git a/rubyio.h b/rubyio.h index f4b72781e5..145b420696 100644 --- a/rubyio.h +++ b/rubyio.h @@ -6,7 +6,7 @@ $Date$ created at: Fri Nov 12 16:47:09 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ diff --git a/sample/mpart.rb b/sample/mpart.rb index 6c40d50e18..a88eba0ef6 100644 --- a/sample/mpart.rb +++ b/sample/mpart.rb @@ -31,7 +31,7 @@ for i in ifp = open(basename) end ofp.write(i) line = line + 1 - if line >= lines + if line >= lines and !ifp.eof? ofp.write("END--cut here--cut here\n") ofp.close part = part + 1 diff --git a/signal.c b/signal.c index fe1107d46d..f5f8d822d1 100644 --- a/signal.c +++ b/signal.c @@ -317,7 +317,7 @@ signal_exec(sig) case SIGINT: rb_thread_interrupt(); break; -#ifndef NT +#if !defined(NT) && !defined(__human68k__) case SIGHUP: #endif #ifdef SIGQUIT @@ -498,7 +498,7 @@ trap(arg) if (func == SIG_DFL) { switch (sig) { case SIGINT: -#ifndef NT +#if !defined(NT) && !defined(__human68k__) case SIGHUP: #endif #ifdef SIGQUIT diff --git a/sprintf.c b/sprintf.c index 5badb61f71..a428e0483e 100644 --- a/sprintf.c +++ b/sprintf.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 15 10:39:26 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -111,8 +111,6 @@ remove_sign_bits(str, base) return str; } -double rb_big2dbl _((VALUE)); - #define FNONE 0 #define FSHARP 1 #define FMINUS 2 @@ -178,7 +176,7 @@ rb_f_sprintf(argc, argv) fmt = GETARG(); if (OBJ_TAINTED(fmt)) tainted = 1; - p = str2cstr(fmt, &blen); + p = rb_str2cstr(fmt, &blen); end = p + blen; blen = 0; bsiz = 120; @@ -397,22 +395,22 @@ rb_f_sprintf(argc, argv) bin_retry: switch (TYPE(val)) { - case T_FIXNUM: - v = FIX2LONG(val); - break; case T_FLOAT: val = rb_dbl2big(RFLOAT(val)->value); if (FIXNUM_P(val)) goto bin_retry; bignum = 1; break; case T_STRING: - val = rb_str2inum(RSTRING(val)->ptr, 10); + val = rb_str2inum(val, 0); goto bin_retry; case T_BIGNUM: bignum = 1; break; default: - Check_Type(val, T_FIXNUM); + v = NUM2LONG(val); + break; + case T_FIXNUM: + v = FIX2LONG(val); break; } @@ -616,7 +614,7 @@ rb_f_sprintf(argc, argv) fval = strtod(RSTRING(val)->ptr, 0); break; default: - Check_Type(val, T_FLOAT); + fval = NUM2DBL(val); break; } diff --git a/st.c b/st.c index 503686b111..08651d05c2 100644 --- a/st.c +++ b/st.c @@ -1,4 +1,4 @@ -/* This is a general purpose hash table package written by Peter Moore @ UCB. */ +/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */ static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; diff --git a/st.h b/st.h index b626969f83..6397f8763b 100644 --- a/st.h +++ b/st.h @@ -1,4 +1,4 @@ -/* This is a general purpose hash table package written by Peter Moore @ UCB. */ +/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */ /* @(#) st.h 5.1 89/12/14 */ diff --git a/string.c b/string.c index 97f4f89b69..e1f213496a 100644 --- a/string.c +++ b/string.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 17:12:58 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -22,16 +22,12 @@ #include #endif -#ifndef atof -double strtod(); -#endif - VALUE rb_cString; #define STR_FREEZE FL_USER1 #define STR_NO_ORIG FL_USER3 -extern VALUE rb_rs; +VALUE rb_fs; VALUE rb_str_new(ptr, len) @@ -167,19 +163,19 @@ rb_obj_as_string(obj) } static VALUE -rb_str_clone(orig) - VALUE orig; -{ +rb_str_clone(str) VALUE str; +{ + VALUE clone; - if (RSTRING(orig)->orig && !FL_TEST(orig, STR_NO_ORIG)) - str = rb_str_new3(RSTRING(orig)->orig); + if (RSTRING(str)->orig && !FL_TEST(str, STR_NO_ORIG)) + clone = rb_str_new3(RSTRING(str)->orig); else - str = rb_str_new(RSTRING(orig)->ptr, RSTRING(orig)->len); - if (RSTRING(orig)->orig && FL_TEST(orig, STR_NO_ORIG)) - RSTRING(str)->orig = RSTRING(orig)->orig; - CLONESETUP(str, orig); - return str; + clone = rb_str_new(RSTRING(str)->ptr, RSTRING(str)->len); + if (RSTRING(str)->orig && FL_TEST(str, STR_NO_ORIG)) + RSTRING(str)->orig = RSTRING(str)->orig; + CLONESETUP(clone, str); + return clone; } VALUE @@ -454,7 +450,7 @@ rb_str_hash(str) } static VALUE -rb_str_hash_method(str) +rb_str_hash_m(str) VALUE str; { int key = rb_str_hash(str); @@ -501,7 +497,7 @@ rb_str_equal(str1, str2) } static VALUE -rb_str_cmp_method(str1, str2) +rb_str_cmp_m(str1, str2) VALUE str1, str2; { int result; @@ -570,7 +566,7 @@ rb_str_index(str, sub, offset) } static VALUE -rb_str_index_method(argc, argv, str) +rb_str_index_m(argc, argv, str) int argc; VALUE *argv; VALUE str; @@ -782,7 +778,7 @@ rb_str_upto(beg, end, excl) } static VALUE -rb_str_upto_method(beg, end) +rb_str_upto_m(beg, end) VALUE beg, end; { return rb_str_upto(beg, end, 0); @@ -835,7 +831,7 @@ rb_str_aref(str, indx) } static VALUE -rb_str_aref_method(argc, argv, str) +rb_str_aref_m(argc, argv, str) int argc; VALUE *argv; VALUE str; @@ -936,7 +932,7 @@ rb_str_aset(str, indx, val) } static VALUE -rb_str_aset_method(argc, argv, str) +rb_str_aset_m(argc, argv, str) int argc; VALUE *argv; VALUE str; @@ -1067,12 +1063,14 @@ rb_str_gsub_bang(argc, argv, str) int iter = 0; char *buf, *bp, *cp; int offset, blen, len; + int tainted = 0; if (argc == 1 && rb_iterator_p()) { iter = 1; } else if (argc == 2) { - repl = rb_obj_as_string(argv[1]);; + repl = rb_obj_as_string(argv[1]); + if (OBJ_TAINTED(repl)) tainted = 1; } else { rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc); @@ -1101,6 +1099,7 @@ rb_str_gsub_bang(argc, argv, str) else { val = rb_reg_regsub(repl, str, regs); } + if (OBJ_TAINTED(val)) tainted = 1; len = (bp - buf) + (beg - offset) + RSTRING(val)->len + 3; if (blen < len) { while (blen < len) blen *= 2; @@ -1146,6 +1145,7 @@ rb_str_gsub_bang(argc, argv, str) RSTRING(str)->ptr = buf; RSTRING(str)->len = len = bp - buf; RSTRING(str)->ptr[len] = '\0'; + if (tainted) OBJ_TAINT(str); return str; } @@ -1162,7 +1162,7 @@ rb_str_gsub(argc, argv, str) } static VALUE -rb_str_replace_method(str, str2) +rb_str_replace_m(str, str2) VALUE str, str2; { if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2); @@ -1299,7 +1299,7 @@ static VALUE rb_str_to_i(str) VALUE str; { - return rb_str2inum(RSTRING(str)->ptr, 10); + return rb_str2inum(str, 10); } static VALUE @@ -1977,7 +1977,7 @@ rb_str_count(argc, argv, str) } static VALUE -rb_str_split_method(argc, argv, str) +rb_str_split_m(argc, argv, str) int argc; VALUE *argv; VALUE str; @@ -2004,9 +2004,9 @@ rb_str_split_method(argc, argv, str) char_sep = ' '; } else { + fs_set: switch (TYPE(spat)) { case T_STRING: - fs_set: if (RSTRING(spat)->len == 1) { char_sep = (unsigned char)RSTRING(spat)->ptr[0]; } @@ -2123,7 +2123,7 @@ rb_str_split(str, sep0) if (TYPE(str) != T_STRING) str = rb_str_to_str(str); sep = rb_str_new2(sep0); - return rb_str_split_method(1, &sep, str); + return rb_str_split_m(1, &sep, str); } static VALUE @@ -2131,7 +2131,7 @@ rb_f_split(argc, argv) int argc; VALUE *argv; { - return rb_str_split_method(argc, argv, uscore_get()); + return rb_str_split_m(argc, argv, uscore_get()); } static VALUE @@ -2193,6 +2193,32 @@ rb_str_each_line(argc, argv, str) return str; } +#ifdef STR_TO_A_USE_EACH +static VALUE +to_a_push(str, ary) + VALUE str, ary; +{ + return rb_ary_push(ary, str); +} +#endif + +static VALUE +rb_str_to_a(str) + VALUE str; +{ +#ifdef STR_TO_A_USE_EACH + VALUE ary; + + if (RSTRING(str)->len == 0) return rb_ary_new3(1, str); + ary = rb_ary_new(); + rb_iterate(rb_each, str, to_a_push, ary); + + return ary; +#else + return rb_ary_new3(1, str); +#endif +} + static VALUE rb_str_each_byte(str) VALUE str; @@ -2431,7 +2457,7 @@ static VALUE rb_str_hex(str) VALUE str; { - return rb_str2inum(RSTRING(str)->ptr, 16); + return rb_str2inum(str, 16); } static VALUE @@ -2452,7 +2478,7 @@ rb_str_oct(str) break; } } - return rb_str2inum(RSTRING(str)->ptr, base); + return rb_str2inum(str, base); } static VALUE @@ -2597,16 +2623,16 @@ Init_String() rb_define_singleton_method(rb_cString, "new", rb_str_s_new, 1); rb_define_method(rb_cString, "clone", rb_str_clone, 0); rb_define_method(rb_cString, "dup", rb_str_dup, 0); - rb_define_method(rb_cString, "<=>", rb_str_cmp_method, 1); + rb_define_method(rb_cString, "<=>", rb_str_cmp_m, 1); rb_define_method(rb_cString, "==", rb_str_equal, 1); rb_define_method(rb_cString, "===", rb_str_equal, 1); rb_define_method(rb_cString, "eql?", rb_str_equal, 1); - rb_define_method(rb_cString, "hash", rb_str_hash_method, 0); + rb_define_method(rb_cString, "hash", rb_str_hash_m, 0); rb_define_method(rb_cString, "+", rb_str_plus, 1); rb_define_method(rb_cString, "*", rb_str_times, 1); rb_define_method(rb_cString, "%", rb_str_format, 1); - rb_define_method(rb_cString, "[]", rb_str_aref_method, -1); - rb_define_method(rb_cString, "[]=", rb_str_aset_method, -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, "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); @@ -2616,16 +2642,17 @@ Init_String() rb_define_method(rb_cString, "succ!", rb_str_succ_bang, 0); rb_define_method(rb_cString, "next", rb_str_succ, 0); rb_define_method(rb_cString, "next!", rb_str_succ_bang, 0); - rb_define_method(rb_cString, "upto", rb_str_upto_method, 1); - rb_define_method(rb_cString, "index", rb_str_index_method, -1); + rb_define_method(rb_cString, "upto", rb_str_upto_m, 1); + rb_define_method(rb_cString, "index", rb_str_index_m, -1); rb_define_method(rb_cString, "rindex", rb_str_rindex, -1); - rb_define_method(rb_cString, "replace", rb_str_replace_method, 1); + rb_define_method(rb_cString, "replace", rb_str_replace_m, 1); rb_define_method(rb_cString, "freeze", rb_str_freeze, 0); rb_define_method(rb_cString, "frozen?", rb_str_frozen_p, 0); rb_define_method(rb_cString, "to_i", rb_str_to_i, 0); rb_define_method(rb_cString, "to_f", rb_str_to_f, 0); + rb_define_method(rb_cString, "to_a", rb_str_to_a, 0); rb_define_method(rb_cString, "to_s", rb_str_to_s, 0); rb_define_method(rb_cString, "to_str", rb_str_to_s, 0); rb_define_method(rb_cString, "inspect", rb_str_inspect, 0); @@ -2643,7 +2670,7 @@ Init_String() rb_define_method(rb_cString, "hex", rb_str_hex, 0); rb_define_method(rb_cString, "oct", rb_str_oct, 0); - rb_define_method(rb_cString, "split", rb_str_split_method, -1); + rb_define_method(rb_cString, "split", rb_str_split_m, -1); rb_define_method(rb_cString, "reverse", rb_str_reverse, 0); rb_define_method(rb_cString, "reverse!", rb_str_reverse_bang, 0); rb_define_method(rb_cString, "concat", rb_str_concat, 1); @@ -2703,4 +2730,8 @@ Init_String() rb_define_global_function("split", rb_f_split, -1); to_str = rb_intern("to_s"); + + rb_fs = Qnil; + rb_define_hooked_variable("$;", &rb_fs, 0, rb_str_setter); + rb_define_hooked_variable("$-F", &rb_fs, 0, rb_str_setter); } diff --git a/struct.c b/struct.c index 1114577729..790e185b63 100644 --- a/struct.c +++ b/struct.c @@ -407,14 +407,14 @@ static VALUE rb_struct_clone(s) VALUE s; { - NEWOBJ(st, struct RStruct); - CLONESETUP(st, s); - st->len = 0; /* avoid GC crashing */ - st->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len); - st->len = RSTRUCT(s)->len; - MEMCPY(st->ptr, RSTRUCT(s)->ptr, VALUE, st->len); + NEWOBJ(clone, struct RStruct); + CLONESETUP(clone, s); + clone->len = 0; /* avoid GC crashing */ + clone->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len); + clone->len = RSTRUCT(s)->len; + MEMCPY(clone->ptr, RSTRUCT(s)->ptr, VALUE, clone->len); - return (VALUE)st; + return (VALUE)clone; } static VALUE diff --git a/time.c b/time.c index 4d18827597..65e479a5f6 100644 --- a/time.c +++ b/time.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 28 14:31:59 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -188,7 +188,7 @@ obj2long(obj) VALUE obj; { if (TYPE(obj) == T_STRING) { - obj = rb_str2inum(RSTRING(obj)->ptr, 10); + obj = rb_str2inum(obj, 10); } return NUM2LONG(obj); @@ -470,15 +470,15 @@ static VALUE time_clone(time) VALUE time; { - VALUE obj; - struct time_object *tobj, *newtobj; + VALUE clone; + struct time_object *tobj, *tclone; GetTimeval(time, tobj); - obj = Data_Make_Struct(0, struct time_object, 0, free, newtobj); - CLONESETUP(obj, time); - MEMCPY(newtobj, tobj, struct time_object, 1); + clone = Data_Make_Struct(0, struct time_object, 0, free, tclone); + CLONESETUP(clone, time); + MEMCPY(tclone, tobj, struct time_object, 1); - return obj; + return clone; } static VALUE @@ -838,7 +838,7 @@ time_strftime(time, format) if (tobj->tm_got == 0) { time_get_tm(time, tobj->gmt); } - fmt = str2cstr(format, &len); + fmt = rb_str2cstr(format, &len); if (len == 0) { rb_warning("strftime called with empty format string"); } @@ -948,7 +948,7 @@ time_load(klass, str) struct tm tm; int i; - buf = str2cstr(str, &i); + buf = rb_str2cstr(str, &i); if (i != 8) { rb_raise(rb_eTypeError, "marshaled time format differ"); } diff --git a/util.c b/util.c index 04b3dd6dbe..a48b420915 100644 --- a/util.c +++ b/util.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Mar 10 17:22:34 JST 1995 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -51,21 +51,11 @@ int rb_special_const_p(obj) VALUE obj; { - if (FIXNUM_P(obj)) return Qtrue; - if (obj == Qnil) return Qtrue; - if (obj == Qfalse) return Qtrue; - if (obj == Qtrue) return Qtrue; + if (SPECIAL_CONST_P(obj)) return Qtrue; return Qfalse; } -int -rb_test_false_or_nil(v) - VALUE v; -{ - return (v != Qnil) && (v != Qfalse); -} - #include "util.h" #ifndef HAVE_STRING_H char *strchr _((char*,char)); diff --git a/util.h b/util.h index 41ce2a5a19..84ad5fcc5f 100644 --- a/util.h +++ b/util.h @@ -6,7 +6,7 @@ $Date$ created at: Thu Mar 9 11:55:53 JST 1995 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ #ifndef UTIL_H diff --git a/variable.c b/variable.c index fef84f7128..176faac2f2 100644 --- a/variable.c +++ b/variable.c @@ -714,6 +714,18 @@ rb_alias_variable(name1, name2) static int special_generic_ivar = 0; static st_table *generic_iv_tbl; +st_table* +rb_generic_ivar_table(obj) + VALUE obj; +{ + st_table *tbl; + VALUE val; + + if (!generic_iv_tbl) return 0; + if (!st_lookup(generic_iv_tbl, obj, &tbl)) return 0; + return tbl; +} + static VALUE generic_ivar_get(obj, id) VALUE obj; diff --git a/version.c b/version.c index 6cd9943430..fa27427c67 100644 --- a/version.c +++ b/version.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Sep 30 20:08:01 JST 1993 - Copyright (C) 1993-1999 Yukihiro Matsumoto + Copyright (C) 1993-2000 Yukihiro Matsumoto ************************************************/ @@ -40,6 +40,6 @@ ruby_show_version() void ruby_show_copyright() { - printf("ruby - Copyright (C) 1993-1999 Yukihiro Matsumoto\n"); + printf("ruby - Copyright (C) 1993-2000 Yukihiro Matsumoto\n"); exit(0); } diff --git a/win32/Makefile b/win32/Makefile index 24148b3c87..7573ef62cf 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -18,7 +18,7 @@ LDFLAGS = $(CFLAGS) -Fm #LDFLAGS = $(CFLAGS) -Fm XLDFLAGS = #EXTLIBS = -LIBS = advapi32.lib wsock32.lib $(EXTLIBS) +LIBS = user32.lib advapi32.lib wsock32.lib $(EXTLIBS) MISSING = crypt.obj alloca.obj win32.obj isinf.obj isnan.obj LDSHARED = DLDFLAGS = diff --git a/win32/config.status b/win32/config.status index 0e79324ae6..36ffc99949 100644 --- a/win32/config.status +++ b/win32/config.status @@ -7,7 +7,7 @@ s%@FFLAGS@%%g s%@DEFS@% -DUSE_THREAD -DSIZEOF_INT=4 -DSIZEOF_SHORT=2 -DSIZEOF_LONG=4 -DSIZEOF_VOIDP=4 -DSIZEOF_FLOAT=4 -DSIZEOF_DOUBLE=8 -DHAVE_PROTOTYPES=1 -DHAVE_STDARG_PROTOTYPES=1 -DHAVE_STDLIB_H=1 -DHAVE_LIMITS_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_ST_RDEV=1 -DGETGROUPS_T=int -DRETSIGTYPE=void -DHAVE_ALLOCA=1 -DHAVE_FMOD=1 -DHAVE_WAITPID=1 -DHAVE_GETCWD=1 -DHAVE_CHSIZE=1 -DHAVE_GETGROUPS=1 -DHAVE_GETLOGIN=1 -DRSHIFT=\(x,y\)\ \(\(x\)\>\>y\) -DFILE_COUNT=_cnt -DDLEXT=\".dll\" -DRUBY_PLATFORM=\"i386-mswin32\" %g s%@LDFLAGS@%%g -s%@LIBS@%advapi32.lib wsock32.lib%g +s%@LIBS@%user32.lib advapi32.lib wsock32.lib%g s%@exec_prefix@%${prefix}%g s%@prefix@%/usr/local%g s%@program_transform_name@%s,x,x,%g diff --git a/win32/win32.c b/win32/win32.c index 864fbfb5df..6989ebeeb7 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -495,7 +495,7 @@ mypopen (char *cmd, char *mode) int p[2]; BOOL fRet; - HANDLE hInFile, hOutFile, hStdin, hStdout; + HANDLE hInFile, hOutFile; LPCSTR lpApplicationName = NULL; LPTSTR lpCommandLine; LPTSTR lpCmd2 = NULL; @@ -533,35 +533,14 @@ mypopen (char *cmd, char *mode) aStartupInfo.dwFlags = STARTF_USESTDHANDLES; if (reading) { - aStartupInfo.hStdInput = GetStdHandle(STD_OUTPUT_HANDLE);//hStdin; - aStartupInfo.hStdError = INVALID_HANDLE_VALUE; - //for save - DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE), - GetCurrentProcess(), &hStdout, - 0, FALSE, DUPLICATE_SAME_ACCESS - ); - //for redirect - DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), - GetCurrentProcess(), &hStdin, - 0, TRUE, DUPLICATE_SAME_ACCESS - ); + aStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); aStartupInfo.hStdOutput = hOutFile; } else { - aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); //hStdout; - aStartupInfo.hStdError = INVALID_HANDLE_VALUE; - // for save - DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), - GetCurrentProcess(), &hStdin, - 0, FALSE, DUPLICATE_SAME_ACCESS - ); - //for redirect - DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE), - GetCurrentProcess(), &hStdout, - 0, TRUE, DUPLICATE_SAME_ACCESS - ); - aStartupInfo.hStdInput = hInFile; + aStartupInfo.hStdInput = hInFile; + aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); } + aStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); dwCreationFlags = (NORMAL_PRIORITY_CLASS); @@ -587,24 +566,12 @@ mypopen (char *cmd, char *mode) CloseHandle(aProcessInformation.hThread); if (reading) { - HANDLE hDummy; - fd = _open_osfhandle((long)hInFile, (_O_RDONLY | pipemode)); CloseHandle(hOutFile); - DuplicateHandle(GetCurrentProcess(), hStdout, - GetCurrentProcess(), &hDummy, - 0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE) - ); } else { - HANDLE hDummy; - fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode)); CloseHandle(hInFile); - DuplicateHandle(GetCurrentProcess(), hStdin, - GetCurrentProcess(), &hDummy, - 0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE) - ); } if (fd == -1) @@ -1245,8 +1212,10 @@ opendir(char *filename) // check to see if we\'ve got a directory // - if (stat (filename, &sbuf) < 0 || - sbuf.st_mode & _S_IFDIR == 0) { + if ((stat (filename, &sbuf) < 0 || + sbuf.st_mode & _S_IFDIR == 0) && + (!isalpha(filename[0]) || filename[1] != ':' || filename[2] != '\0' || + ((1 << (filename[0] & 0x5f) - 'A') & GetLogicalDrives()) == 0)) { return NULL; } @@ -1264,7 +1233,7 @@ opendir(char *filename) strcpy(scanname, filename); - if (index("/\\", *(scanname + strlen(scanname) - 1)) == NULL) + if (index("/\\:", *CharPrev(scanname, scanname + strlen(scanname))) == NULL) strcat(scanname, "/*"); else strcat(scanname, "*"); @@ -1802,6 +1771,10 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex, if (!NtSocketsInitialized++) { StartSockets(); } + if (nfds == 0 && timeout) { + Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000); + return 0; + } if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) { errno = WSAGetLastError(); switch (errno) { diff --git a/win32/win32.h b/win32/win32.h index 04cb192c43..a55641eada 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -87,7 +87,7 @@ #undef leave #if defined(__cplusplus) -} +extern "C++" { #endif #include @@ -103,7 +103,7 @@ #include #if defined(__cplusplus) -extern "C" { +} #endif #define UIDTYPE int