1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@598 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2000-01-05 04:41:21 +00:00
parent a1d1b15167
commit de71615260
69 changed files with 1873 additions and 1103 deletions

144
ChangeLog
View file

@ -1,3 +1,147 @@
Wed Jan 5 02:14:46 2000 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
* parse.y: Fix SEGV on empty parens with UMINUS or UPLUS.
Tue Jan 4 22:25:54 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (stmt): `() while cond' dumped core.
Tue Jan 4 06:04:14 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* 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 <matz@netlab.co.jp>
* 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 <nobu.nokada@softhome.net>
* 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 <matz@netlab.co.jp>
* 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 <matz@netlab.co.jp>
* eval.c: thread independent trace_func not needed.
Thu Dec 30 14:47:31 1999 akira yamada <akira@ruby-lang.org>
* configure.in: specifies -soname in LIBRUBY_DLDFLAGS on linux
platforms.
Thu Dec 30 10:51:27 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* 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 <matz@netlab.co.jp>
* 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 <komatsu@sarion.co.jp>
* 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 <komatsu@sarion.co.jp>
* 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 <komatsu@sarion.co.jp>
* 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 <wbs01621@mail.wbs.ne.jp>
* ext/Win32API/Win32API.c (Win32API_Call): remove 'dword ptr'
from _asm.
Fri Dec 24 10:26:47 1999 Koji Oda <oda@bsd1.qnes.nec.co.jp>
* win32/win32.h: use "C++" linkage.
Fri Dec 24 02:00:57 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (THREAD_ALLOC): should initialize th->trace.
Fri Dec 24 00:43:39 1999 KANEKO Naoshi <wbs01621@mail.wbs.ne.jp>
* 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 <oda@bsd1.qnes.nec.co.jp>
* ext/socket/socket.c (sock_finalize): mswin32: fix FILE* leak.
Sun Dec 19 22:56:31 1999 KANEKO Naoshi <wbs01621@mail.wbs.ne.jp>
* 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 <matz@netlab.co.jp>
* 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 <iwa@mmp.fujitsu.co.jp>
* eval.c (rb_load): should initialize ruby_frame->last_class.
Wed Dec 15 01:35:29 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* 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 <matz@netlab.co.jp> Mon Dec 13 15:15:31 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* regex.c (re_adjust_startpos): separate startpos adjustment * regex.c (re_adjust_startpos): separate startpos adjustment

View file

@ -81,8 +81,8 @@ OBJS = array.@OBJEXT@ \
version.@OBJEXT@ \ version.@OBJEXT@ \
$(MISSING) $(MISSING)
all: miniruby$(EXEEXT) rbconfig.rb all: miniruby$(EXEEXT) @PREP@ rbconfig.rb
@./miniruby$(EXEEXT) -Xext extmk.rb @EXTSTATIC@ @@MINIRUBY@ -Xext extmk.rb @EXTSTATIC@
miniruby$(EXEEXT): config.status $(LIBRUBY_A) $(MAINOBJ) dmyext.@OBJEXT@ miniruby$(EXEEXT): config.status $(LIBRUBY_A) $(MAINOBJ) dmyext.@OBJEXT@
@rm -f $@ @rm -f $@
@ -98,16 +98,16 @@ $(LIBRUBY_A): $(OBJS) dmyext.@OBJEXT@
$(LIBRUBY_SO): $(OBJS) dmyext.@OBJEXT@ $(LIBRUBY_SO): $(OBJS) dmyext.@OBJEXT@
$(LDSHARED) $(DLDFLAGS) $(SOLIBS) $(OBJS) dmyext.@OBJEXT@ -o $@ $(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}' \ File.symlink "$(LIBRUBY_SO)", link}' \
$(LIBRUBY_ALIASES) || true $(LIBRUBY_ALIASES) || true
install: rbconfig.rb 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 clean:; @rm -f $(OBJS) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY_ALIASES) $(MAINOBJ) rbconfig.rb
@rm -f ext/extinit.c ext/extinit.@OBJEXT@ dmyext.@OBJEXT@ @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) @rm -f $(PROGRAM) miniruby$(EXEEXT)
distclean: clean distclean: clean
@ -123,7 +123,10 @@ test: miniruby$(EXEEXT)
@./miniruby$(EXEEXT) $(srcdir)/rubytest.rb @./miniruby$(EXEEXT) $(srcdir)/rubytest.rb
rbconfig.rb: miniruby$(EXEEXT) 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 config.status: $(srcdir)/configure
$(SHELL) ./config.status --recheck $(SHELL) ./config.status --recheck

1
README
View file

@ -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 4. You may modify and include the part of the software into any other
software (possibly commercial). But some files in the distribution software (possibly commercial). But some files in the distribution
are not written by the author, so that they are not under this terms. 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 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 files under the ./missing directory. See each file for the copying
condition. condition.

View file

@ -135,29 +135,30 @@ UNIX
* 配布条件 * 配布条件
RubyはフリーソフトウェアですGPL(the GNU General Public 本プログラムはフリーソフトウェアですGPL(the GNU General
License)または以下に示す条件でRubyを再配布できますGPLにつ Public License)または以下に示す条件で本プログラムを再配布で
いてはCOPYINGファイルを参照して下さい きますGPLについてはCOPYINGファイルを参照して下さい
1. 複製は制限なく自由です. 1. 複製は制限なく自由です.
2. 以下の条件のいずれかを満たす時に手元のRubyのソースを自 2. 以下の条件のいずれかを満たす時に本プログラムのソースを
由に変更できます. 由に変更できます.
(a) ネットニューズにポストしたり,作者に変更を送付する (a) ネットニューズにポストしたり,作者に変更を送付する
などの方法で,変更を公開する. などの方法で,変更を公開する.
(b) 変更したRubyを自分の所属する組織内部だけで使う (b) 変更した本プログラムを自分の所属する組織内部だけで
使う.
(c) 変更点を明示したうえ,ソフトウェアの名前を変更する. (c) 変更点を明示したうえ,ソフトウェアの名前を変更する.
そのソフトウェアを配布する時には変更前のRubyも同時 そのソフトウェアを配布する時には変更前の本プログラ
に配布するまたは変更前のRubyのソースの入手法を明 ムも同時に配布する.または変更前の本プログラムのソー
示する. スの入手法を明示する.
(d) その他の変更条件を作者と合意する. (d) その他の変更条件を作者と合意する.
3. 以下の条件のいずれかを満たす時にRubyをオブジェクトコー 3. 以下の条件のいずれかを満たす時に本プログラムをコンパイ
ドや実行形式でも配布できます. ルしたオブジェクトコードや実行形式でも配布できます.
(a) バイナリを受け取った人がソースを入手できるように, (a) バイナリを受け取った人がソースを入手できるように,
ソースの入手法を明示する. ソースの入手法を明示する.
@ -170,21 +171,23 @@ License)
(d) その他の配布条件を作者と合意する. (d) その他の配布条件を作者と合意する.
4. 他のプログラムへの引用はいかなる目的であれ自由です.た 4. 他のプログラムへの引用はいかなる目的であれ自由です.た
だしRubyに含まれる他の作者によるコードはそれぞれの だし,本プログラムに含まれる他の作者によるコードは,そ
作者の意向による制限が加えられます具体的にはgc.c(一部) れぞれの作者の意向による制限が加えらる場合があります.
util.c(一部)st.[ch]regex.[ch] および ./missingディ
レクトリ下のファイル群が該当します.それぞれの配布条件
などに付いては各ファイルを参照してください.
5. Rubyへの入力となるスクリプトおよびRubyからの出力の権 具体的にはgc.c(一部)util.c(一部)st.[ch]regex.[ch]
利はRubyの作者ではなくそれぞれの入出力を生成した人に および ./missingディレクトリ下のファイル群が該当します
属しますまたRubyに組み込むための拡張ライブラリにつ それぞれの配布条件などに付いては各ファイルを参照してく
ても同様です ださい.
6. Rubyは無保証です作者はRubyをサポートする意志はありま 5. 本プログラムへの入力となるスクリプトおよび,本プログラ
すがRuby自身のバグあるいはRubyスクリプトのバグなどか ムからの出力の権利は本プログラムの作者ではなく,それぞ
ら発生するいかなる損害に対しても責任を持ちません. れの入出力を生成した人に属します.また,本プログラムに
組み込まれるための拡張ライブラリについても同様です.
6. 本プログラムは無保証です.作者は本プログラムをサポート
する意志はありますが,プログラム自身のバグあるいは本プ
ログラムの実行などから発生するいかなる損害に対しても責
任を持ちません.
* 著者 * 著者

1
ToDo
View file

@ -44,6 +44,7 @@ Standard Libraries
- sprintf/printf's $ to specify argument order - sprintf/printf's $ to specify argument order
- Dir.glob("**/*.c") ala zsh - Dir.glob("**/*.c") ala zsh
- Remove Enumerable#{size,length} - Remove Enumerable#{size,length}
* Marshal should handle generic instance variables.
* SyntaxError and NameError should not be subclasses of StandardError, maybe. * SyntaxError and NameError should not be subclasses of StandardError, maybe.
* debugger for thread programming * debugger for thread programming
* Struct::new([name,]member,...) ?? * Struct::new([name,]member,...) ??

166
array.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri Aug 6 09:46:12 JST 1993 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 static VALUE
rb_ary_push_method(argc, argv, ary) rb_ary_push_m(argc, argv, ary)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE ary; VALUE ary;
@ -292,6 +292,31 @@ rb_ary_pop(ary)
return RARRAY(ary)->ptr[--RARRAY(ary)->len]; 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 VALUE
rb_ary_shift(ary) rb_ary_shift(ary)
VALUE ary; VALUE ary;
@ -314,6 +339,31 @@ rb_ary_shift(ary)
return top; 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 VALUE
rb_ary_unshift(ary, item) rb_ary_unshift(ary, item)
VALUE ary, item; VALUE ary, item;
@ -506,8 +556,11 @@ rb_ary_replace(ary, beg, len, rpl)
len = RARRAY(ary)->len - beg; len = RARRAY(ary)->len - beg;
} }
if (TYPE(rpl) != T_ARRAY) { if (NIL_P(rpl)) {
rpl = rb_Array(rpl); rpl = rb_ary_new2(0);
}
else if (TYPE(rpl) != T_ARRAY) {
rpl = rb_ary_new3(1, rpl);
} }
rb_ary_modify(ary); rb_ary_modify(ary);
@ -631,19 +684,23 @@ static VALUE
rb_ary_clone(ary) rb_ary_clone(ary)
VALUE ary; VALUE ary;
{ {
VALUE ary2 = rb_ary_new2(RARRAY(ary)->len); VALUE clone = rb_ary_new2(RARRAY(ary)->len);
CLONESETUP(ary2, ary); CLONESETUP(clone, ary);
MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len); MEMCPY(RARRAY(clone)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
RARRAY(ary2)->len = RARRAY(ary)->len; RARRAY(clone)->len = RARRAY(ary)->len;
return ary2; return clone;
} }
static VALUE static VALUE
rb_ary_dup(ary) rb_ary_dup(ary)
VALUE 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 static VALUE
@ -668,10 +725,15 @@ rb_ary_join(ary, sep)
VALUE ary, sep; VALUE ary, sep;
{ {
long i; long i;
int taint;
VALUE result, tmp; VALUE result, tmp;
if (RARRAY(ary)->len == 0) return rb_str_new(0, 0); 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]; tmp = RARRAY(ary)->ptr[0];
if (OBJ_TAINTED(tmp)) taint = 1;
switch (TYPE(tmp)) { switch (TYPE(tmp)) {
case T_STRING: case T_STRING:
result = rb_str_dup(tmp); result = rb_str_dup(tmp);
@ -715,14 +777,15 @@ rb_ary_join(ary, sep)
} }
if (!NIL_P(sep)) rb_str_concat(result, sep); if (!NIL_P(sep)) rb_str_concat(result, sep);
rb_str_cat(result, RSTRING(tmp)->ptr, RSTRING(tmp)->len); 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; return result;
} }
static VALUE static VALUE
rb_ary_join_method(argc, argv, ary) rb_ary_join_m(argc, argv, ary)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE ary; VALUE ary;
@ -788,10 +851,14 @@ rb_protect_inspect(func, obj, arg)
inspect_tbl = rb_ary_new(); inspect_tbl = rb_ary_new();
rb_thread_local_aset(rb_thread_current(), inspect_key, inspect_tbl); 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); rb_ary_push(inspect_tbl, obj);
iarg.func = func; iarg.func = func;
iarg.arg1 = obj; iarg.arg1 = obj;
iarg.arg2 = arg; iarg.arg2 = arg;
return rb_ensure(inspect_call, (VALUE)&iarg, inspect_ensure, obj); return rb_ensure(inspect_call, (VALUE)&iarg, inspect_ensure, obj);
} }
@ -866,7 +933,7 @@ rb_ary_reverse(ary)
} }
static VALUE static VALUE
rb_ary_reverse_method(ary) rb_ary_reverse_m(ary)
VALUE ary; VALUE ary;
{ {
return rb_ary_reverse(rb_ary_dup(ary)); return rb_ary_reverse(rb_ary_dup(ary));
@ -985,11 +1052,11 @@ rb_ary_delete(ary, item)
} }
VALUE VALUE
rb_ary_delete_at(ary, at) rb_ary_delete_at(ary, pos)
VALUE ary; VALUE ary;
VALUE at; long pos;
{ {
long i, pos = NUM2LONG(at), len = RARRAY(ary)->len; long i, len = RARRAY(ary)->len;
VALUE del = Qnil; VALUE del = Qnil;
rb_ary_modify(ary); rb_ary_modify(ary);
@ -1006,6 +1073,47 @@ rb_ary_delete_at(ary, at)
return del; 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 static VALUE
rb_ary_delete_if(ary) rb_ary_delete_if(ary)
VALUE ary; VALUE ary;
@ -1039,7 +1147,7 @@ rb_ary_filter(ary)
} }
static VALUE static VALUE
rb_ary_replace_method(ary, ary2) rb_ary_replace_m(ary, ary2)
VALUE ary, ary2; VALUE ary, ary2;
{ {
ary2 = to_ary(ary2); ary2 = to_ary(ary2);
@ -1116,9 +1224,7 @@ rb_ary_plus(x, y)
{ {
VALUE z; VALUE z;
if (TYPE(y) != T_ARRAY) { Check_Type(y, T_ARRAY);
y = rb_Array(y);
}
z = rb_ary_new2(RARRAY(x)->len + RARRAY(y)->len); z = rb_ary_new2(RARRAY(x)->len + RARRAY(y)->len);
MEMCPY(RARRAY(z)->ptr, RARRAY(x)->ptr, VALUE, RARRAY(x)->len); MEMCPY(RARRAY(z)->ptr, RARRAY(x)->ptr, VALUE, RARRAY(x)->len);
@ -1134,9 +1240,7 @@ rb_ary_concat(x, y)
VALUE *p, *pend; VALUE *p, *pend;
rb_ary_modify(x); rb_ary_modify(x);
if (TYPE(y) != T_ARRAY) { Check_Type(y, T_ARRAY);
y = rb_Array(y);
}
p = RARRAY(y)->ptr; p = RARRAY(y)->ptr;
pend = p + RARRAY(y)->len; pend = p + RARRAY(y)->len;
@ -1339,7 +1443,7 @@ rb_ary_or(ary1, ary2)
if (TYPE(ary2) != T_ARRAY) { if (TYPE(ary2) != T_ARRAY) {
if (rb_ary_includes(ary1, ary2)) return ary1; 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(); 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, "last", rb_ary_last, 0);
rb_define_method(rb_cArray, "concat", rb_ary_concat, 1); rb_define_method(rb_cArray, "concat", rb_ary_concat, 1);
rb_define_method(rb_cArray, "<<", rb_ary_push, 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, "push", rb_ary_push_m, -1);
rb_define_method(rb_cArray, "pop", rb_ary_pop, 0); rb_define_method(rb_cArray, "pop", rb_ary_pop_m, -1);
rb_define_method(rb_cArray, "shift", rb_ary_shift, 0); 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, "unshift", rb_ary_unshift, 1);
rb_define_method(rb_cArray, "each", rb_ary_each, 0); rb_define_method(rb_cArray, "each", rb_ary_each, 0);
rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0); rb_define_method(rb_cArray, "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, "indices", rb_ary_indexes, -1);
rb_define_method(rb_cArray, "clone", rb_ary_clone, 0); 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, "dup", rb_ary_dup, 0);
rb_define_method(rb_cArray, "join", rb_ary_join_method, -1); rb_define_method(rb_cArray, "join", rb_ary_join_m, -1);
rb_define_method(rb_cArray, "reverse", rb_ary_reverse_method, 0); 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, "reverse!", rb_ary_reverse, 0);
rb_define_method(rb_cArray, "sort", rb_ary_sort, 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, "sort!", rb_ary_sort_bang, 0);
rb_define_method(rb_cArray, "collect", rb_ary_collect, 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", 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, "delete_if", rb_ary_delete_if, 0);
rb_define_method(rb_cArray, "reject!", 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, "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, "clear", rb_ary_clear, 0);
rb_define_method(rb_cArray, "fill", rb_ary_fill, -1); rb_define_method(rb_cArray, "fill", rb_ary_fill, -1);
rb_define_method(rb_cArray, "include?", rb_ary_includes, 1); rb_define_method(rb_cArray, "include?", rb_ary_includes, 1);

View file

@ -15,10 +15,10 @@
VALUE rb_cBignum; VALUE rb_cBignum;
typedef unsigned short USHORT; typedef unsigned short USHORT;
#define BDIGITS(x) RBIGNUM(x)->digits #define BDIGITS(x) ((USHORT*)RBIGNUM(x)->digits)
#define BITSPERDIG (sizeof(short)*CHAR_BIT) #define BITSPERDIG (sizeof(short)*CHAR_BIT)
#define BIGRAD (1L << BITSPERDIG) #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 BIGUP(x) ((unsigned long)(x) << BITSPERDIG)
#define BIGDN(x) RSHIFT(x,BITSPERDIG) #define BIGDN(x) RSHIFT(x,BITSPERDIG)
#define BIGLO(x) ((USHORT)((x) & (BIGRAD-1))) #define BIGLO(x) ((USHORT)((x) & (BIGRAD-1)))
@ -33,7 +33,7 @@ bignew_1(klass, len, sign)
OBJSETUP(big, klass, T_BIGNUM); OBJSETUP(big, klass, T_BIGNUM);
big->sign = sign; big->sign = sign;
big->len = len; big->len = len;
BDIGITS(big) = ALLOC_N(USHORT, len); big->digits = ALLOC_N(USHORT, len);
return (VALUE)big; return (VALUE)big;
} }
@ -116,14 +116,14 @@ rb_uint2big(n)
VALUE big; VALUE big;
i = 0; i = 0;
big = bignew(DIGSPERINT, 1); big = bignew(DIGSPERLONG, 1);
digits = BDIGITS(big); digits = BDIGITS(big);
while (i < DIGSPERINT) { while (i < DIGSPERLONG) {
digits[i++] = BIGLO(n); digits[i++] = BIGLO(n);
n = BIGDN(n); n = BIGDN(n);
} }
i = DIGSPERINT; i = DIGSPERLONG;
while (i-- && !digits[i]) ; while (i-- && !digits[i]) ;
RBIGNUM(big)->len = i+1; RBIGNUM(big)->len = i+1;
return big; return big;
@ -164,10 +164,13 @@ rb_int2inum(n)
} }
VALUE VALUE
rb_str2inum(str, base) rb_cstr2inum(str, base)
const char *str; const char *str;
int base; int base;
{ {
const char *s = str;
char *end;
int badcheck = (base==0)?1:0;
char sign = 1, c; char sign = 1, c;
unsigned long num; unsigned long num;
long len, blen = 1; long len, blen = 1;
@ -175,7 +178,7 @@ rb_str2inum(str, base)
VALUE z; VALUE z;
USHORT *zds; USHORT *zds;
while (ISSPACE(*str)) str++; while (*str && ISSPACE(*str)) str++;
if (*str == '+') { if (*str == '+') {
str++; str++;
@ -197,11 +200,12 @@ rb_str2inum(str, base)
} }
else { else {
base = 8; base = 8;
if (!*str) return INT2FIX(0);
} }
if (*str == '\0') return INT2FIX(0);
} }
else { else {
base = 10; base = 10;
if (!*str) return INT2FIX(0);
} }
} }
if (base == 8) { if (base == 8) {
@ -215,12 +219,23 @@ rb_str2inum(str, base)
if (base == 2 && str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) { if (base == 2 && str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
str += 2; str += 2;
} }
while (str[0] == '0') str++; while (*str && *str == '0') str++;
if (!*str) str--;
len = 4*strlen(str)*sizeof(char); len = 4*strlen(str)*sizeof(char);
} }
if (len <= (sizeof(VALUE)*CHAR_BIT)) { 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 (POSFIXABLE(val)) {
if (sign) return INT2FIX(val); if (sign) return INT2FIX(val);
@ -256,6 +271,15 @@ rb_str2inum(str, base)
break; break;
default: default:
c = base; 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; break;
} }
if (c >= base) break; if (c >= base) break;
@ -274,9 +298,25 @@ rb_str2inum(str, base)
break; break;
} }
} }
return bignorm(z); 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"; static char hexmap[] = "0123456789abcdef";
VALUE VALUE
rb_big2str(x, base) rb_big2str(x, base)
@ -354,16 +394,17 @@ rb_big_to_s(x)
return rb_big2str(x, 10); return rb_big2str(x, 10);
} }
unsigned long static unsigned long
rb_big2ulong(x) big2ulong(x, type)
VALUE x; VALUE x;
char *type;
{ {
unsigned long num; unsigned long num;
long len = RBIGNUM(x)->len; long len = RBIGNUM(x)->len;
USHORT *ds; USHORT *ds;
if (len > sizeof(long)/sizeof(USHORT)) 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); ds = BDIGITS(x);
num = 0; num = 0;
while (len--) { while (len--) {
@ -373,11 +414,20 @@ rb_big2ulong(x)
return num; return num;
} }
unsigned long
rb_big2ulong(x)
VALUE x;
{
unsigned long num = big2ulong(x, "unsigned long");
if (!RBIGNUM(x)->sign) return -num;
}
long long
rb_big2long(x) rb_big2long(x)
VALUE x; VALUE x;
{ {
unsigned long num = rb_big2ulong(x); unsigned long num = big2ulong(x, "int");
if ((long)num < 0) { if ((long)num < 0) {
rb_raise(rb_eArgError, "bignum too big to convert into `int'"); rb_raise(rb_eArgError, "bignum too big to convert into `int'");

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Aug 10 15:05:44 JST 1993 created at: Tue Aug 10 15:05:44 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Aug 26 14:39:48 JST 1993 created at: Thu Aug 26 14:39:48 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

8
configure vendored
View file

@ -1732,7 +1732,7 @@ case "$host_os" in
nextstep*) ;; nextstep*) ;;
openstep*) ;; openstep*) ;;
rhapsody*) ;; rhapsody*) ;;
human*) ;; human*) ac_cv_func_getpgrp_void=yes;;
beos*) ;; beos*) ;;
cygwin*) ;; cygwin*) ;;
*) LIBS="-lm $LIBS";; *) LIBS="-lm $LIBS";;
@ -4360,7 +4360,7 @@ else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
fi fi
for ac_func in select for ac_func in select gettimeofday
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:4367: checking for $ac_func" >&5 echo "configure:4367: checking for $ac_func" >&5
@ -4501,7 +4501,7 @@ EOF
fi fi
LIBOBJS="$LIBOBJS x68.o" 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 EXEEXT=.x
OBJEXT=o OBJEXT=o
setup=Setup.x68 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' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so'
;; ;;
linux*) 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' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so'
;; ;;
freebsd*) freebsd*)

View file

@ -26,6 +26,7 @@ then
fi fi
AC_CANONICAL_HOST AC_CANONICAL_HOST
AC_CANONICAL_TARGET
dnl checks for fat-binary dnl checks for fat-binary
fat_binary=no fat_binary=no
@ -36,7 +37,7 @@ AC_ARG_ENABLE(fat-binary,
AC_MSG_CHECKING(target architecture) AC_MSG_CHECKING(target architecture)
case "$host_os" in case "$target_os" in
rhapsody*) rhapsody*)
echo -n "MacOS X Server: " echo -n "MacOS X Server: "
if test "$TARGET_ARCHS" = "" ; then if test "$TARGET_ARCHS" = "" ; then
@ -136,11 +137,11 @@ if test "$rb_cv_have_attr_noreturn" = yes; then
fi fi
dnl Checks for libraries. dnl Checks for libraries.
case "$host_os" in case "$target_os" in
nextstep*) ;; nextstep*) ;;
openstep*) ;; openstep*) ;;
rhapsody*) ;; rhapsody*) ;;
human*) ;; human*) ac_cv_func_getpgrp_void=yes;;
beos*) ;; beos*) ;;
cygwin*) ;; cygwin*) ;;
*) LIBS="-lm $LIBS";; *) LIBS="-lm $LIBS";;
@ -326,7 +327,7 @@ AC_ARG_WITH(dln-a-out,
AC_SUBST(XLDFLAGS)dnl AC_SUBST(XLDFLAGS)dnl
case "$host_os" in case "$target_os" in
linux*) linux*)
AC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf, AC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf,
[AC_TRY_RUN([ [AC_TRY_RUN([
@ -351,7 +352,7 @@ main() {
rb_cv_binary_elf=yes)]) rb_cv_binary_elf=yes)])
if test "$rb_cv_binary_elf" = no; then if test "$rb_cv_binary_elf" = no; then
with_dln_a_out=yes with_dln_a_out=yes
host_os=${host_os}-a_out target_os=${target_os}-a_out
else else
LDFLAGS="-rdynamic" LDFLAGS="-rdynamic"
fi;; fi;;
@ -370,7 +371,7 @@ if test "$with_dln_a_out" != yes; then
rb_cv_dlopen=unknown rb_cv_dlopen=unknown
AC_MSG_CHECKING(whether OS depend dynamic link works) AC_MSG_CHECKING(whether OS depend dynamic link works)
if test "$GCC" = yes; then if test "$GCC" = yes; then
case "$host_os" in case "$target_os" in
nextstep*) ;; nextstep*) ;;
openstep*) ;; openstep*) ;;
rhapsody*) ;; rhapsody*) ;;
@ -378,14 +379,14 @@ if test "$with_dln_a_out" != yes; then
bsdi*) ;; bsdi*) ;;
cygwin*) ;; cygwin*) ;;
netbsd*) CCDLFLAGS=-fpic netbsd*) CCDLFLAGS=-fpic
case "$host_cpu" in case "$target_cpu" in
mips*) CCDLFLAGS=-fPIC ;; mips*) CCDLFLAGS=-fPIC ;;
*) ;; *) ;;
esac ;; esac ;;
*) CCDLFLAGS=-fPIC;; *) CCDLFLAGS=-fPIC;;
esac esac
else else
case "$host_os" in case "$target_os" in
hpux*) CCDLFLAGS='+z';; hpux*) CCDLFLAGS='+z';;
solaris*|irix*) CCDLFLAGS='-K PIC' ;; solaris*|irix*) CCDLFLAGS='-K PIC' ;;
sunos*) CCDLFLAGS='-PIC' ;; sunos*) CCDLFLAGS='-PIC' ;;
@ -394,7 +395,7 @@ if test "$with_dln_a_out" != yes; then
esac esac
fi fi
case "$host_os" in case "$target_os" in
hpux*) DLDFLAGS="-E" hpux*) DLDFLAGS="-E"
LDSHARED='ld -b' LDSHARED='ld -b'
LDFLAGS="-Wl,-E" LDFLAGS="-Wl,-E"
@ -429,7 +430,7 @@ if test "$with_dln_a_out" != yes; then
fi fi
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
netbsd*) LDSHARED="ld -shared" netbsd*) LDSHARED="ld -shared"
case "$host_cpu" in case "$target_cpu" in
alpha) alpha)
LDFLAGS="-export-dynamic" ;; LDFLAGS="-export-dynamic" ;;
esac esac
@ -464,7 +465,7 @@ if test "$with_dln_a_out" != yes; then
LDSHARED='' LDSHARED=''
LDFLAGS='' LDFLAGS=''
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
beos*) case "$host_cpu" in beos*) case "$target_cpu" in
powerpc*) powerpc*)
LDSHARED="ld -xms" LDSHARED="ld -xms"
DLDFLAGS="-f ruby.exp -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o" 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" DLDFLAGS="ruby.def -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
esac esac
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
cygwin*) LDSHARED='dllwrap --export-all -s' cygwin*) : ${LDSHARED='dllwrap --export-all -s'}
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
*) LDSHARED='ld' ;; *) LDSHARED='ld' ;;
esac esac
@ -513,7 +514,7 @@ if test "$dln_a_out_works" = yes; then
AC_DEFINE(DLEXT, ".so") AC_DEFINE(DLEXT, ".so")
CCDLFLAGS= CCDLFLAGS=
else else
case "$host_os" in case "$target_os" in
hpux*) DLEXT=sl hpux*) DLEXT=sl
AC_DEFINE(DLEXT, ".sl");; AC_DEFINE(DLEXT, ".sl");;
nextstep*) DLEXT=bundle nextstep*) DLEXT=bundle
@ -538,7 +539,7 @@ else
STRIP=strip STRIP=strip
fi fi
case "$host_os" in case "$target_os" in
linux*) linux*)
STRIP='strip -S -x';; STRIP='strip -S -x';;
nextstep*) nextstep*)
@ -559,11 +560,11 @@ AC_ARG_WITH(static-linked-ext,
*) ;; *) ;;
esac]) esac])
case "$host_os" in case "$target_os" in
human*) human*)
AC_CHECK_LIB(signal, _harderr) AC_CHECK_LIB(signal, _harderr)
AC_CHECK_LIB(hmem, hmemset) 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, AC_CACHE_CHECK(whether PD libc _dtos18 fail to convert big number,
rb_cv_missing__dtos18, rb_cv_missing__dtos18,
[AC_TRY_RUN( [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) AC_DEFINE(MISSING_FCONVERT)
fi fi
LIBOBJS="$LIBOBJS x68.o" 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 EXEEXT=.x
OBJEXT=o OBJEXT=o
setup=Setup.x68 setup=Setup.x68
@ -630,16 +631,26 @@ if test "$fat_binary" = yes ; then
CFLAGS="$CFLAGS $ARCH_FLAG" CFLAGS="$CFLAGS $ARCH_FLAG"
fi 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_A='lib$(RUBY_INSTALL_NAME).a'
LIBRUBY='$(LIBRUBY_A)' LIBRUBY='$(LIBRUBY_A)'
LIBRUBYARG='$(LIBRUBY_A)' LIBRUBYARG='$(LIBRUBY_A)'
SOLIBS= SOLIBS=
if test "$host_os" = "beos"; then if test "$target_os" = "beos"; then
LIBRUBY='$(LIBRUBY_SO)' LIBRUBY='$(LIBRUBY_SO)'
LIBRUBYARG='-l$(RUBY_INSTALL_NAME)' LIBRUBYARG='-l$(RUBY_INSTALL_NAME)'
SOLIBS='-lnet' SOLIBS='-lnet'
echo creating ruby.def echo creating ruby.def
case "$host_cpu" in case "$target_cpu" in
powerpc*) powerpc*)
cp beos/ruby.def.in ruby.exp cp beos/ruby.def.in ruby.exp
CFLAGS="$CFLAGS -relax_pointers" CFLAGS="$CFLAGS -relax_pointers"
@ -666,12 +677,12 @@ if test "$enable_shared" = 'yes'; then
LIBRUBY='$(LIBRUBY_SO)' LIBRUBY='$(LIBRUBY_SO)'
LIBRUBYARG='-L. -l$(RUBY_INSTALL_NAME)' LIBRUBYARG='-L. -l$(RUBY_INSTALL_NAME)'
CFLAGS="$CFLAGS $CCDLFLAGS" CFLAGS="$CFLAGS $CCDLFLAGS"
case "$host_os" in case "$target_os" in
sunos4*) sunos4*)
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so'
;; ;;
linux*) 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' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so'
;; ;;
freebsd*) freebsd*)
@ -683,7 +694,7 @@ if test "$enable_shared" = 'yes'; then
;; ;;
netbsd*) netbsd*)
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR)' LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR)'
case "$host_cpu" in case "$target_cpu" in
alpha|mipsel|mipseb|powerpc|sparc64) # ELF platforms alpha|mipsel|mipseb|powerpc|sparc64) # ELF platforms
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR) lib$(RUBY_INSTALL_NAME).so' ;; LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR) lib$(RUBY_INSTALL_NAME).so' ;;
*) LIBRUBY_ALIASES= ;; # a.out platforms *) LIBRUBY_ALIASES= ;; # a.out platforms
@ -716,13 +727,17 @@ if test "$enable_shared" = 'yes'; then
FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in
LIBOBJS="$LIBOBJS strftime.o" LIBOBJS="$LIBOBJS strftime.o"
CCDLFLAGS=-DUSEIMPORTLIB CCDLFLAGS=-DUSEIMPORTLIB
: ${NM=nm}
AC_SUBST(NM)
: ${DLLWRAP=dllwrap}
AC_SUBST(DLLWRAP)
;; ;;
*) *)
;; ;;
esac esac
fi fi
case "$host_os" in case "$target_os" in
nextstep*) nextstep*)
CFLAGS="$CFLAGS -pipe" CFLAGS="$CFLAGS -pipe"
;; ;;
@ -765,16 +780,16 @@ configure_args=$ac_configure_args
AC_SUBST(configure_args)dnl AC_SUBST(configure_args)dnl
if test "$fat_binary" = yes ; then if test "$fat_binary" = yes ; then
arch="fat-${host_os}" arch="fat-${target_os}"
AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB, 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, AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB,
"${RUBY_SITE_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}") "${RUBY_SITE_LIB_PATH}/" __ARCHITECTURE__ "-${target_os}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${host_os}") AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${target_os}")
else else
arch="${host_cpu}-${host_os}" arch="${target_cpu}-${target_os}"
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}") AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}")
fi fi
AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${RUBY_LIB_PATH}/${arch}") AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${RUBY_LIB_PATH}/${arch}")

View file

@ -4,6 +4,5 @@ RUBYCWDLL=rubycw.dll
miniruby$(EXEEXT): $(RUBYCWDLL) miniruby$(EXEEXT): $(RUBYCWDLL)
$(RUBYCWDLL): $(OBJS) dmyext.o $(LDSHARED) $(DLDFLAGS) -o $(RUBYCWDLL) --output-lib=$(LIBRUBY_SO) --dllname=$(RUBYCWDLL) -Wl,-e,__cygwin_noncygwin_dll_entry@12 --add-stdcall-alias $(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
nm --extern-only $(OBJS) dmyext.o | sed -n '/^........ [CD] _\(.*\)$$/s//#define \1 (*__imp_\1)/p' >import.h

View file

@ -14,7 +14,7 @@
/* define RUBY_USE_EUC/SJIS for default kanji-code */ /* define RUBY_USE_EUC/SJIS for default kanji-code */
#ifndef DEFAULT_KCODE #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 #define DEFAULT_KCODE KCODE_SJIS
#else #else
#define DEFAULT_KCODE KCODE_EUC #define DEFAULT_KCODE KCODE_EUC
@ -55,7 +55,7 @@
#endif #endif
#define PATH_SEP_CHAR PATH_SEP[0] #define PATH_SEP_CHAR PATH_SEP[0]
#if defined(__human68k__) || defined(__CYGWIN32__) #if defined(__human68k__) || defined(__CYGWIN__)
#undef HAVE_RANDOM #undef HAVE_RANDOM
#undef HAVE_SETITIMER #undef HAVE_SETITIMER
#endif #endif

2
dir.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Wed Jan 5 09:51:01 JST 1994 created at: Wed Jan 5 09:51:01 JST 1994
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

2
dln.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Jan 18 17:05:06 JST 1994 created at: Tue Jan 18 17:05:06 JST 1994
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

2
enum.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri Oct 1 15:15:19 JST 1993 created at: Fri Oct 1 15:15:19 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Mon Aug 9 16:11:34 JST 1993 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; char *s;
int len; int len;
s = str2cstr(str, &len); s = rb_str2cstr(str, &len);
return rb_exc_new(etype, s, len); return rb_exc_new(etype, s, len);
} }

255
eval.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Jun 10 14:22:17 JST 1993 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; \ ruby_dyna_vars = _old; \
} }
#define DVAR_DONT_RECYCLE FL_USER0
static struct RVarmap* static struct RVarmap*
new_dvar(id, value, prev) new_dvar(id, value, prev)
ID id; ID id;
@ -790,6 +792,7 @@ static VALUE massign _((VALUE,NODE*,VALUE,int));
static void assign _((VALUE,NODE*,VALUE,int)); static void assign _((VALUE,NODE*,VALUE,int));
static VALUE trace_func = 0; static VALUE trace_func = 0;
static int tracing = 0;
static void call_trace_func _((char*,char*,int,VALUE,ID,VALUE)); static void call_trace_func _((char*,char*,int,VALUE,ID,VALUE));
static void static void
@ -990,6 +993,7 @@ ruby_options(argc, argv)
POP_TAG(); POP_TAG();
if (state) { if (state) {
trace_func = 0; trace_func = 0;
tracing = 0;
error_print(); error_print();
exit(1); exit(1);
} }
@ -1110,7 +1114,7 @@ compile_error(at)
char *mesg; char *mesg;
int len; int len;
mesg = str2cstr(ruby_errinfo, &len); mesg = rb_str2cstr(ruby_errinfo, &len);
ruby_nerrs = 0; ruby_nerrs = 0;
str = rb_str_new2("compile error"); str = rb_str_new2("compile error");
if (at) { if (at) {
@ -1397,6 +1401,9 @@ rb_undef(klass, id)
VALUE origin; VALUE origin;
NODE *body; NODE *body;
if (ruby_class == rb_cObject) {
rb_secure(4);
}
if (safe_level >= 4 && !OBJ_TAINTED(klass)) { if (safe_level >= 4 && !OBJ_TAINTED(klass)) {
rb_raise(rb_eSecurityError, "Insecure: can't undef"); 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, \ (tmp__protect_tmp = rb_node_newnode(NODE_ALLOCA, \
ALLOC_N(VALUE,n),tmp__protect_tmp,n), \ ALLOC_N(VALUE,n),tmp__protect_tmp,n), \
(void*)tmp__protect_tmp->nd_head) (void*)tmp__protect_tmp->nd_head)
# define TMP_PROTECT_END do {\
rb_gc_force_recycle((VALUE)tmp__protect_tmp);\
alloca(0);\
} while (0)
#else #else
# define TMP_PROTECT typedef int foobazzz # define TMP_PROTECT typedef int foobazzz
# define TMP_ALLOC(n) ALLOCA_N(VALUE,n) # define TMP_ALLOC(n) ALLOCA_N(VALUE,n)
# define TMP_PROTECT_END
#endif #endif
#define SETUP_ARGS(anode) {\ #define SETUP_ARGS(anode) {\
@ -1766,18 +1778,15 @@ call_trace_func(event, file, line, self, id, klass)
VALUE klass; /* OK */ VALUE klass; /* OK */
{ {
int state; int state;
volatile VALUE trace;
struct FRAME *prev; struct FRAME *prev;
char *file_save = ruby_sourcefile; char *file_save = ruby_sourcefile;
int line_save = ruby_sourceline; int line_save = ruby_sourceline;
VALUE srcfile; VALUE srcfile;
if (!trace_func) return; if (!trace_func) return;
if (tracing) return;
trace = trace_func; tracing = 1;
trace_func = 0;
rb_thread_critical++;
prev = ruby_frame; prev = ruby_frame;
PUSH_FRAME(); PUSH_FRAME();
*ruby_frame = *prev; *ruby_frame = *prev;
@ -1795,7 +1804,7 @@ call_trace_func(event, file, line, self, id, klass)
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)"); srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)");
proc_call(trace, rb_ary_new3(6, rb_str_new2(event), proc_call(trace_func, rb_ary_new3(6, rb_str_new2(event),
srcfile, srcfile,
INT2FIX(ruby_sourceline), INT2FIX(ruby_sourceline),
INT2FIX(id), INT2FIX(id),
@ -1805,8 +1814,7 @@ call_trace_func(event, file, line, self, id, klass)
POP_TMPTAG(); /* do not propagate retval */ POP_TMPTAG(); /* do not propagate retval */
POP_FRAME(); POP_FRAME();
rb_thread_critical--; tracing = 0;
if (!trace_func) trace_func = trace;
ruby_sourceline = line_save; ruby_sourceline = line_save;
ruby_sourcefile = file_save; ruby_sourcefile = file_save;
if (state) JUMP_TAG(state); if (state) JUMP_TAG(state);
@ -2288,6 +2296,7 @@ rb_eval(self, node)
END_CALLARGS; END_CALLARGS;
result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0); result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0);
TMP_PROTECT_END;
} }
break; break;
@ -2301,6 +2310,7 @@ rb_eval(self, node)
END_CALLARGS; END_CALLARGS;
result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1); result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1);
TMP_PROTECT_END;
} }
break; break;
@ -2333,6 +2343,7 @@ rb_eval(self, node)
ruby_frame->self, ruby_frame->last_func, ruby_frame->self, ruby_frame->last_func,
argc, argv, 3); argc, argv, 3);
POP_ITER(); POP_ITER();
TMP_PROTECT_END;
} }
break; break;
@ -2394,6 +2405,7 @@ rb_eval(self, node)
argv[argc-1] = val; argv[argc-1] = val;
val = rb_funcall2(recv, aset, argc, argv); val = rb_funcall2(recv, aset, argc, argv);
result = val; result = val;
TMP_PROTECT_END;
} }
break; break;
@ -2767,9 +2779,6 @@ rb_eval(self, node)
if (NIL_P(ruby_class)) { if (NIL_P(ruby_class)) {
rb_raise(rb_eTypeError, "no class to undef method"); rb_raise(rb_eTypeError, "no class to undef method");
} }
if (ruby_class == rb_cObject) {
rb_secure(4);
}
rb_undef(ruby_class, node->nd_mid); rb_undef(ruby_class, node->nd_mid);
result = Qnil; result = Qnil;
break; break;
@ -3006,6 +3015,7 @@ module_setup(module, node)
call_trace_func("end", file, line, 0, call_trace_func("end", file, line, 0,
ruby_frame->last_func, ruby_frame->last_class); ruby_frame->last_func, ruby_frame->last_class);
} }
TMP_PROTECT_END;
if (state) JUMP_TAG(state); if (state) JUMP_TAG(state);
return result; return result;
@ -3319,6 +3329,15 @@ rb_yield_0(val, self, klass, acheck)
pop_state: pop_state:
POP_ITER(); POP_ITER();
POP_CLASS(); 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(); POP_VARS();
ruby_block = block; ruby_block = block;
ruby_frame = ruby_frame->prev; ruby_frame = ruby_frame->prev;
@ -3339,7 +3358,10 @@ rb_yield(val)
static VALUE static VALUE
rb_f_loop() rb_f_loop()
{ {
for (;;) { rb_yield_0(Qnil, 0, 0, Qfalse); } for (;;) {
rb_yield_0(Qnil, 0, 0, Qfalse);
CHECK_INTS;
}
return Qnil; /* dummy */ return Qnil; /* dummy */
} }
@ -3538,6 +3560,7 @@ handle_rescue(self, node)
if (rb_obj_is_kind_of(ruby_errinfo, argv[0])) return 1; if (rb_obj_is_kind_of(ruby_errinfo, argv[0])) return 1;
argv++; argv++;
} }
TMP_PROTECT_END;
return 0; return 0;
} }
@ -4075,6 +4098,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
} }
POP_FRAME(); POP_FRAME();
POP_ITER(); POP_ITER();
TMP_PROTECT_END;
return result; return result;
} }
@ -4638,84 +4662,6 @@ rb_mod_module_eval(argc, argv, mod)
VALUE rb_load_path; 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;i<RARRAY(rb_load_path)->len;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 void
rb_load(fname, wrap) rb_load(fname, wrap)
VALUE fname; VALUE fname;
@ -4734,7 +4680,7 @@ rb_load(fname, wrap)
else { else {
Check_SafeStr(fname); Check_SafeStr(fname);
} }
file = find_file(RSTRING(fname)->ptr); file = rb_find_file(RSTRING(fname)->ptr);
if (!file) { if (!file) {
rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr); rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
} }
@ -4755,6 +4701,7 @@ rb_load(fname, wrap)
} }
PUSH_FRAME(); PUSH_FRAME();
ruby_frame->last_func = 0; ruby_frame->last_func = 0;
ruby_frame->last_class = 0;
ruby_frame->self = ruby_top_self; ruby_frame->self = ruby_top_self;
ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_class,0,0); ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_class,0,0);
PUSH_SCOPE(); PUSH_SCOPE();
@ -4797,6 +4744,7 @@ rb_load(fname, wrap)
ruby_nerrs = 0; ruby_nerrs = 0;
rb_exc_raise(ruby_errinfo); rb_exc_raise(ruby_errinfo);
} }
TMP_PROTECT_END;
if (state) JUMP_TAG(state); if (state) JUMP_TAG(state);
} }
@ -4892,7 +4840,7 @@ rb_f_require(obj, fname)
if (ext) { if (ext) {
if (strcmp(".rb", ext) == 0) { if (strcmp(".rb", ext) == 0) {
feature = file = RSTRING(fname)->ptr; feature = file = RSTRING(fname)->ptr;
file = find_file(file); file = rb_find_file(file);
if (file) goto load_rb; if (file) goto load_rb;
} }
else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) { else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) {
@ -4905,19 +4853,19 @@ rb_f_require(obj, fname)
file = feature = buf; file = feature = buf;
if (rb_provided(feature)) return Qfalse; if (rb_provided(feature)) return Qfalse;
} }
file = find_file(file); file = rb_find_file(file);
if (file) goto load_dyna; if (file) goto load_dyna;
} }
else if (strcmp(DLEXT, ext) == 0) { else if (strcmp(DLEXT, ext) == 0) {
feature = RSTRING(fname)->ptr; feature = RSTRING(fname)->ptr;
file = find_file(feature); file = rb_find_file(feature);
if (file) goto load_dyna; if (file) goto load_dyna;
} }
} }
buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5); buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5);
strcpy(buf, RSTRING(fname)->ptr); strcpy(buf, RSTRING(fname)->ptr);
strcat(buf, ".rb"); strcat(buf, ".rb");
file = find_file(buf); file = rb_find_file(buf);
if (file) { if (file) {
fname = rb_str_new2(file); fname = rb_str_new2(file);
feature = buf; feature = buf;
@ -4925,7 +4873,7 @@ rb_f_require(obj, fname)
} }
strcpy(buf, RSTRING(fname)->ptr); strcpy(buf, RSTRING(fname)->ptr);
strcat(buf, DLEXT); strcat(buf, DLEXT);
file = find_file(buf); file = rb_find_file(buf);
if (file) { if (file) {
feature = buf; feature = buf;
goto load_dyna; goto load_dyna;
@ -5595,6 +5543,7 @@ rb_f_binding(self)
VALUE self; VALUE self;
{ {
struct BLOCK *data; struct BLOCK *data;
struct RVarmap *vars;
VALUE bind; VALUE bind;
PUSH_BLOCK(0,0); PUSH_BLOCK(0,0);
@ -5616,6 +5565,9 @@ rb_f_binding(self)
data->prev = 0; data->prev = 0;
} }
for (vars = data->d_vars; vars; vars = vars->next) {
FL_SET(vars, DVAR_DONT_RECYCLE);
}
scope_dup(data->scope); scope_dup(data->scope);
POP_BLOCK(); POP_BLOCK();
@ -5671,6 +5623,7 @@ proc_s_new(klass)
{ {
volatile VALUE proc; volatile VALUE proc;
struct BLOCK *data; struct BLOCK *data;
struct RVarmap *vars;
if (!rb_iterator_p() && !rb_f_iterator_p()) { if (!rb_iterator_p() && !rb_f_iterator_p()) {
rb_raise(rb_eArgError, "tried to create Procedure-Object out of iterator"); rb_raise(rb_eArgError, "tried to create Procedure-Object out of iterator");
@ -5691,6 +5644,9 @@ proc_s_new(klass)
} }
data->flags |= BLOCK_DYNAMIC; data->flags |= BLOCK_DYNAMIC;
for (vars = data->d_vars; vars; vars = vars->next) {
FL_SET(vars, DVAR_DONT_RECYCLE);
}
scope_dup(data->scope); scope_dup(data->scope);
proc_save_safe_level(proc); proc_save_safe_level(proc);
@ -6134,12 +6090,12 @@ struct thread {
VALUE klass; VALUE klass;
VALUE wrapper; VALUE wrapper;
VALUE trace;
int flags; /* misc. states (vmode/rb_trap_immediate/raised) */ int flags; /* misc. states (vmode/rb_trap_immediate/raised) */
char *file; char *file;
int line; int line;
int tracing;
VALUE errinfo; VALUE errinfo;
VALUE last_status; VALUE last_status;
VALUE last_line; VALUE last_line;
@ -6207,7 +6163,6 @@ thread_mark(th)
rb_gc_mark(th->errinfo); rb_gc_mark(th->errinfo);
rb_gc_mark(th->last_line); rb_gc_mark(th->last_line);
rb_gc_mark(th->last_match); rb_gc_mark(th->last_match);
rb_gc_mark(th->trace);
rb_mark_tbl(th->locals); rb_mark_tbl(th->locals);
/* mark data in copied stack */ /* mark data in copied stack */
@ -6302,13 +6257,13 @@ REALLOC_N(th->stk_ptr, VALUE, len);
th->flags = scope_vmode | (rb_trap_immediate<<8); th->flags = scope_vmode | (rb_trap_immediate<<8);
th->iter = ruby_iter; th->iter = ruby_iter;
th->tag = prot_tag; th->tag = prot_tag;
th->tracing = tracing;
th->errinfo = ruby_errinfo; th->errinfo = ruby_errinfo;
th->last_status = rb_last_status; th->last_status = rb_last_status;
th->last_line = rb_lastline_get(); th->last_line = rb_lastline_get();
th->last_match = rb_backref_get(); th->last_match = rb_backref_get();
th->safe = safe_level; th->safe = safe_level;
th->trace = trace_func;
th->file = ruby_sourcefile; th->file = ruby_sourcefile;
th->line = ruby_sourceline; th->line = ruby_sourceline;
} }
@ -6371,11 +6326,11 @@ rb_thread_restore_context(th, exit)
rb_trap_immediate = (th->flags&0x100)?1:0; rb_trap_immediate = (th->flags&0x100)?1:0;
ruby_iter = th->iter; ruby_iter = th->iter;
prot_tag = th->tag; prot_tag = th->tag;
tracing = th->tracing;
ruby_errinfo = th->errinfo; ruby_errinfo = th->errinfo;
rb_last_status = th->last_status; rb_last_status = th->last_status;
safe_level = th->safe; safe_level = th->safe;
trace_func = th->trace;
ruby_sourcefile = th->file; ruby_sourcefile = th->file;
ruby_sourceline = th->line; ruby_sourceline = th->line;
@ -6515,7 +6470,7 @@ rb_thread_schedule()
} }
FOREACH_THREAD_FROM(curr, th) { 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) if (!next || next->priority < th->priority)
next = th; next = th;
} }
@ -6885,6 +6840,26 @@ rb_thread_main()
return main_thread->thread; 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 VALUE
rb_thread_wakeup(thread) rb_thread_wakeup(thread)
VALUE thread; VALUE thread;
@ -7014,6 +6989,16 @@ rb_thread_priority_set(thread, prio)
return thread; 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 int thread_abort;
static VALUE static VALUE
@ -7074,6 +7059,7 @@ rb_thread_abort_exc_set(thread, val)
th->block = 0;\ th->block = 0;\
th->iter = 0;\ th->iter = 0;\
th->tag = 0;\ th->tag = 0;\
th->tracing = 0;\
th->errinfo = 0;\ th->errinfo = 0;\
th->last_status = 0;\ th->last_status = 0;\
th->last_line = 0;\ th->last_line = 0;\
@ -7280,6 +7266,18 @@ rb_thread_status(thread)
return Qnil; 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; return Qtrue;
} }
@ -7523,7 +7521,36 @@ rb_thread_key_p(thread, id)
return Qfalse; 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 static VALUE
rb_callcc(self) rb_callcc(self)
@ -7534,7 +7561,7 @@ rb_callcc(self)
struct tag *tag; struct tag *tag;
THREAD_ALLOC(th); 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); thread_free, th);
FL_SET(ruby_scope, SCOPE_DONT_RECYCLE); FL_SET(ruby_scope, SCOPE_DONT_RECYCLE);
@ -7551,7 +7578,7 @@ rb_callcc(self)
} }
static VALUE static VALUE
rb_continuation_call(argc, argv, cont) rb_cont_call(argc, argv, cont)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE cont; VALUE cont;
@ -7569,6 +7596,7 @@ rb_continuation_call(argc, argv, cont)
th->result = rb_ary_new4(argc, argv); th->result = rb_ary_new4(argc, argv);
break; break;
} }
rb_thread_restore_context(th, RESTORE_NORMAL); rb_thread_restore_context(th, RESTORE_NORMAL);
return Qnil; 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, "join", rb_thread_s_join, 1);
rb_define_singleton_method(rb_cThread, "current", rb_thread_current, 0); 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, "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_get, 0);
rb_define_singleton_method(rb_cThread, "critical=", rb_thread_critical_set, 1); 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, "run", rb_thread_run, 0);
rb_define_method(rb_cThread, "wakeup", rb_thread_wakeup, 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, "exit", rb_thread_kill, 0);
rb_define_method(rb_cThread, "value", rb_thread_value, 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, "status", rb_thread_status, 0);
rb_define_method(rb_cThread, "join", rb_thread_join, 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, "stop?", rb_thread_stop_p, 0);
rb_define_method(rb_cThread, "raise", rb_thread_raise, -1); 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, 0);
rb_define_method(rb_cThread, "priority=", rb_thread_priority_set, 1); 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_aref, 1);
rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2); 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, "key?", rb_thread_key_p, 1);
rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);
/* allocate main thread */ /* allocate main thread */
main_thread = rb_thread_alloc(rb_cThread); main_thread = rb_thread_alloc(rb_cThread);
rb_cContinuation = rb_define_class("Continuation", rb_cObject); rb_cCont = rb_define_class("Continuation", rb_cObject);
rb_undef_method(CLASS_OF(rb_cContinuation), "new"); rb_undef_method(CLASS_OF(rb_cCont), "new");
rb_define_method(rb_cContinuation, "call", rb_continuation_call, -1); rb_define_method(rb_cCont, "call", rb_cont_call, -1);
rb_define_global_function("callcc", rb_callcc, 0); rb_define_global_function("callcc", rb_callcc, 0);
} }
@ -7653,7 +7686,7 @@ static VALUE
catch_i(tag) catch_i(tag)
ID tag; ID tag;
{ {
return rb_f_catch(0, FIX2INT(tag)); return rb_funcall(Qnil, rb_intern("catch"), 0, FIX2INT(tag));
} }
VALUE VALUE

View file

@ -68,9 +68,9 @@ Win32API_initialize(self, dllname, proc, import, export)
rb_raise(rb_eRuntimeError, "GetProcAddress: %s or %s\n", rb_raise(rb_eRuntimeError, "GetProcAddress: %s or %s\n",
RSTRING(proc)->ptr, RSTRING(str)->ptr); 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, "__dllname__", dllname);
rb_iv_set(self, "__proc__", INT2NUM((int)hproc)); rb_iv_set(self, "__proc__", UINT2NUM((unsigned long)hproc));
a_import = rb_ary_new(); a_import = rb_ary_new();
ptr = RARRAY(import)->ptr; ptr = RARRAY(import)->ptr;
@ -165,7 +165,7 @@ Win32API_Call(argc, argv, obj)
mov eax, lParam mov eax, lParam
push eax push eax
} }
#elif defined(__CYGWIN32__) || defined(__MINGW32__) #elif defined(__CYGWIN__) || defined(__MINGW32__)
asm volatile ("pushl %0" :: "g" (lParam)); asm volatile ("pushl %0" :: "g" (lParam));
#else #else
#error #error
@ -184,10 +184,10 @@ Win32API_Call(argc, argv, obj)
} }
#if defined(_MSC_VER) || defined(__LCC__) #if defined(_MSC_VER) || defined(__LCC__)
_asm { _asm {
mov eax, dword ptr pParam mov eax, pParam
push eax push eax
} }
#elif defined(__CYGWIN32__) || defined(__MINGW32__) #elif defined(__CYGWIN__) || defined(__MINGW32__)
asm volatile ("pushl %0" :: "g" (pParam)); asm volatile ("pushl %0" :: "g" (pParam));
#else #else
#error #error
@ -195,7 +195,6 @@ Win32API_Call(argc, argv, obj)
break; break;
} }
} }
} }
switch (texport) { switch (texport) {

View file

@ -92,17 +92,10 @@ static void
sock_finalize(fptr) sock_finalize(fptr)
OpenFile *fptr; OpenFile *fptr;
{ {
SOCKET s;
extern int errno;
if (!fptr->f) return; if (!fptr->f) return;
myfdclose(fptr->f); myfdclose(fptr->f);
if(fptr->f2) myfdclose(fptr->f); if(fptr->f2) myfdclose(fptr->f2);
/*
s = get_osfhandle(fileno(fptr->f));
closesocket(s);
*/
} }
#endif #endif

View file

@ -1452,24 +1452,20 @@ module TkTreatFont
alias fontobj font_configinfo alias fontobj font_configinfo
def font_configure(slot) def font_configure(slot)
if (fnt = slot['font']) if (fnt = slot.delete('font'))
slot['font'] = nil
if fnt.kind_of? TkFont if fnt.kind_of? TkFont
return fnt.call_font_configure(self.path, self.path,'configure',slot) return fnt.call_font_configure(self.path, self.path,'configure',slot)
else else
latinfont_configure(fnt) if fnt latinfont_configure(fnt) if fnt
end end
end end
if (ltn = slot['latinfont']) if (ltn = slot.delete('latinfont'))
slot['latinfont'] = nil
latinfont_configure(ltn) if ltn latinfont_configure(ltn) if ltn
end end
if (ltn = slot['asciifont']) if (ltn = slot.delete('asciifont'))
slot['asciifont'] = nil
latinfont_configure(ltn) if ltn latinfont_configure(ltn) if ltn
end end
if (knj = slot['kanjifont']) if (knj = slot.delete('kanjifont'))
slot['kanjifont'] = nil
kanjifont_configure(knj) if knj kanjifont_configure(knj) if knj
end end
@ -1878,42 +1874,24 @@ class TkToplevel<TkWindow
@classname = classname @classname = classname
if keys.kind_of? Hash if keys.kind_of? Hash
keys = keys.dup keys = keys.dup
if keys['classname'] @classname = keys.delete('classname')
@classname = keys['classname'] @colormap = keys.delete('colormap')
keys['classname'] = nil @container = keys.delete('container')
end @screen = keys.delete('screen')
if keys['colormap'] @use = keys.delete('use')
@colormap = keys['colormap'] @visual = keys.delete('visual')
keys['colormap'] = nil
end
if keys['container']
@classname = keys['container']
keys['classname'] = nil
end
if keys['screen']
@screen = keys['screen']
keys['screen'] = nil
end
if keys['use']
@use = keys['use']
keys['use'] = nil
end
if keys['visual']
@screen = keys['visual']
keys['visual'] = nil
end
end end
super(parent, keys) super(parent, keys)
end end
def create_self def create_self
s = [] s = []
s.push << "-class" << @classname if @classname s << "-class" << @classname if @classname
s.push << "-colormap" << @colormap if @colormap s << "-colormap" << @colormap if @colormap
s.push << "-container" << @container if @container s << "-container" << @container if @container
s.push << "-screen" << @screen if @screen s << "-screen" << @screen if @screen
s.push << "-use" << @use if @use s << "-use" << @use if @use
s.push << "-visual" << @visual if @visual s << "-visual" << @visual if @visual
tk_call 'toplevel', @path, *s tk_call 'toplevel', @path, *s
end end
@ -1932,32 +1910,20 @@ class TkFrame<TkWindow
def initialize(parent=nil, keys=nil) def initialize(parent=nil, keys=nil)
if keys.kind_of? Hash if keys.kind_of? Hash
keys = keys.dup keys = keys.dup
if keys['classname'] @classname = keys.delete('classname')
@classname = keys['classname'] @colormap = keys.delete('colormap')
keys['classname'] = nil @container = keys.delete('container')
end @visual = keys.delete('visual')
if keys['colormap']
@colormap = keys['colormap']
keys['colormap'] = nil
end
if keys['container']
@classname = keys['container']
keys['classname'] = nil
end
if keys['visual']
@screen = keys['visual']
keys['visual'] = nil
end
end end
super(parent, keys) super(parent, keys)
end end
def create_self def create_self
s = [] s = []
s.push << "-class" << @classname if @classname s << "-class" << @classname if @classname
s.push << "-colormap" << @colormap if @colormap s << "-colormap" << @colormap if @colormap
s.push << "-container" << @container if @container s << "-container" << @container if @container
s.push << "-visual" << @visual if @visual s << "-visual" << @visual if @visual
tk_call 'frame', @path, *s tk_call 'frame', @path, *s
end end
end end
@ -2189,8 +2155,7 @@ module TkTreatMenuEntryFont
def tagfont_configure(index, slot) def tagfont_configure(index, slot)
pathname = self.path + ';' + index pathname = self.path + ';' + index
if (fnt = slot['font']) if (fnt = slot.delete('font'))
slot['font'] = nil
if fnt.kind_of? TkFont if fnt.kind_of? TkFont
return fnt.call_font_configure(pathname, return fnt.call_font_configure(pathname,
self.path,'entryconfigure',index,slot) self.path,'entryconfigure',index,slot)
@ -2198,16 +2163,13 @@ module TkTreatMenuEntryFont
latintagfont_configure(index, fnt) if fnt latintagfont_configure(index, fnt) if fnt
end end
end end
if (ltn = slot['latinfont']) if (ltn = slot.delete('latinfont'))
slot['latinfont'] = nil
latintagfont_configure(index, ltn) if ltn latintagfont_configure(index, ltn) if ltn
end end
if (ltn = slot['asciifont']) if (ltn = slot.delete('asciifont'))
slot['asciifont'] = nil
latintagfont_configure(index, ltn) if ltn latintagfont_configure(index, ltn) if ltn
end end
if (knj = slot['kanjifont']) if (knj = slot.delete('kanjifont'))
slot['kanjifont'] = nil
kanjitagfont_configure(index, knj) if knj kanjitagfont_configure(index, knj) if knj
end end

View file

@ -30,8 +30,7 @@ module TkTreatCItemFont
else else
pathname = self.path + ';' + tagOrId.to_s pathname = self.path + ';' + tagOrId.to_s
end end
if (fnt = slot['font']) if (fnt = slot.delete('font'))
slot['font'] = nil
if fnt.kind_of? TkFont if fnt.kind_of? TkFont
return fnt.call_font_configure(pathname, return fnt.call_font_configure(pathname,
self.path,'itemconfigure',tagOrId,slot) self.path,'itemconfigure',tagOrId,slot)
@ -39,16 +38,13 @@ module TkTreatCItemFont
latintagfont_configure(tagOrId, fnt) if fnt latintagfont_configure(tagOrId, fnt) if fnt
end end
end end
if (ltn = slot['latinfont']) if (ltn = slot.delete('latinfont'))
slot['latinfont'] = nil
latintagfont_configure(tagOrId, ltn) if ltn latintagfont_configure(tagOrId, ltn) if ltn
end end
if (ltn = slot['asciifont']) if (ltn = slot.delete('asciifont'))
slot['asciifont'] = nil
latintagfont_configure(tagOrId, ltn) if ltn latintagfont_configure(tagOrId, ltn) if ltn
end end
if (knj = slot['kanjifont']) if (knj = slot.delete('kanjifont'))
slot['kanjifont'] = nil
kanjitagfont_configure(tagOrId, knj) if knj kanjitagfont_configure(tagOrId, knj) if knj
end end

View file

@ -28,8 +28,7 @@ module TkTreatTextTagFont
else else
pathname = self.path + ';' + tag pathname = self.path + ';' + tag
end end
if (fnt = slot['font']) if (fnt = slot.delete('font'))
slot['font'] = nil
if fnt.kind_of? TkFont if fnt.kind_of? TkFont
return fnt.call_font_configure(pathname, return fnt.call_font_configure(pathname,
self.path,'tag','configure',tag,slot) self.path,'tag','configure',tag,slot)
@ -37,16 +36,13 @@ module TkTreatTextTagFont
latintagfont_configure(tag, fnt) if fnt latintagfont_configure(tag, fnt) if fnt
end end
end end
if (ltn = slot['latinfont']) if (ltn = slot.delete('latinfont'))
slot['latinfont'] = nil
latintagfont_configure(tag, ltn) if ltn latintagfont_configure(tag, ltn) if ltn
end end
if (ltn = slot['asciifont']) if (ltn = slot.delete('asciifont'))
slot['asciifont'] = nil
latintagfont_configure(tag, ltn) if ltn latintagfont_configure(tag, ltn) if ltn
end end
if (knj = slot['kanjifont']) if (knj = slot.delete('kanjifont'))
slot['kanjifont'] = nil
kanjitagfont_configure(tag, knj) if knj kanjitagfont_configure(tag, knj) if knj
end end

155
file.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Mon Nov 15 12:24:34 JST 1993 created at: Mon Nov 15 12:24:34 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/
@ -17,6 +17,7 @@
#include "ruby.h" #include "ruby.h"
#include "rubyio.h" #include "rubyio.h"
#include "rubysig.h" #include "rubysig.h"
#include "dln.h"
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -1179,10 +1180,11 @@ rb_file_s_expand_path(argc, argv)
VALUE fname, dname; VALUE fname, dname;
char *s, *p; char *s, *p;
char buf[MAXPATHLEN+2]; char buf[MAXPATHLEN+2];
int tainted = 0; int tainted;
rb_scan_args(argc, argv, "11", &fname, &dname); rb_scan_args(argc, argv, "11", &fname, &dname);
tainted = OBJ_TAINTED(fname);
s = STR2CSTR(fname); s = STR2CSTR(fname);
p = buf; p = buf;
if (s[0] == '~') { if (s[0] == '~') {
@ -1950,6 +1952,155 @@ rb_file_const(name, value)
rb_define_const(rb_mConst, 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;i<RARRAY(rb_load_path)->len;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 void
Init_File() Init_File()
{ {

8
gc.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Oct 5 09:44:46 JST 1993 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; void *mem;
if (size < 0) { 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; if (size == 0) size = 1;
malloc_memories += size; malloc_memories += size;
@ -422,6 +422,7 @@ rb_gc_mark(ptr)
Top: Top:
if (FIXNUM_P(obj)) return; /* fixnum not marked */ if (FIXNUM_P(obj)) return; /* fixnum not marked */
if (rb_special_const_p((VALUE)obj)) return; /* special const 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 == 0) return; /* free cell */
if (obj->as.basic.flags & FL_MARK) return; /* already marked */ if (obj->as.basic.flags & FL_MARK) return; /* already marked */
@ -878,6 +879,9 @@ _rb_setjmp:
movem.l d3-d7/a3-a5,(a0) movem.l d3-d7/a3-a5,(a0)
moveq.l #0,d0 moveq.l #0,d0
rts"); rts");
#ifdef setjmp
#undef setjmp
#endif
#else #else
#if defined(DJGPP) #if defined(DJGPP)
typedef unsigned long rb_jmp_buf[6]; typedef unsigned long rb_jmp_buf[6];

156
hash.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Mon Nov 22 18:51:18 JST 1993 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 "util.h"
#include "rubysig.h" #include "rubysig.h"
#include <sys/types.h>
#include <sys/stat.h>
#ifndef HAVE_STRING_H #ifndef HAVE_STRING_H
char *strchr _((char*,char)); char *strchr _((char*,char));
#endif #endif
@ -142,7 +139,7 @@ rb_hash_foreach_iter(key, value, arg)
st_table *tbl = RHASH(arg->hash)->tbl; st_table *tbl = RHASH(arg->hash)->tbl;
struct st_table_entry **bins = tbl->bins; 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); status = (*arg->func)(key, value, arg->arg);
if (RHASH(arg->hash)->tbl != tbl || RHASH(arg->hash)->tbl->bins != bins){ if (RHASH(arg->hash)->tbl != tbl || RHASH(arg->hash)->tbl->bins != bins){
rb_raise(rb_eIndexError, "rehash occurred during iteration"); rb_raise(rb_eIndexError, "rehash occurred during iteration");
@ -166,7 +163,7 @@ rb_hash_foreach_ensure(hash)
if (RHASH(hash)->iter_lev == 0) { if (RHASH(hash)->iter_lev == 0) {
if (FL_TEST(hash, HASH_DELETED)) { 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); FL_UNSET(hash, HASH_DELETED);
} }
} }
@ -275,30 +272,31 @@ static VALUE
rb_hash_clone(hash) rb_hash_clone(hash)
VALUE hash; VALUE hash;
{ {
NEWOBJ(hash2, struct RHash); NEWOBJ(clone, struct RHash);
CLONESETUP(hash2, hash); CLONESETUP(clone, hash);
hash2->iter_lev = 0; clone->iter_lev = 0;
hash2->ifnone = RHASH(hash)->ifnone; clone->ifnone = RHASH(hash)->ifnone;
hash2->tbl = 0; /* avoid GC crashing */ clone->tbl = 0; /* avoid GC crashing */
hash2->tbl = (st_table*)st_copy(RHASH(hash)->tbl); clone->tbl = (st_table*)st_copy(RHASH(hash)->tbl);
return (VALUE)hash2; return (VALUE)clone;
} }
static VALUE static VALUE
rb_hash_dup(hash) rb_hash_dup(hash)
VALUE hash; VALUE hash;
{ {
NEWOBJ(hash2, struct RHash); NEWOBJ(dup, struct RHash);
OBJSETUP(hash2, CLASS_OF(hash), T_HASH); OBJSETUP(dup, CLASS_OF(hash), T_HASH);
hash2->iter_lev = 0; dup->iter_lev = 0;
hash2->ifnone = RHASH(hash)->ifnone; dup->ifnone = RHASH(hash)->ifnone;
hash2->tbl = 0; /* avoid GC crashing */ dup->tbl = 0; /* avoid GC crashing */
hash2->tbl = (st_table*)st_copy(RHASH(hash)->tbl); dup->tbl = (st_table*)st_copy(RHASH(hash)->tbl);
return (VALUE)hash2; if (OBJ_TAINTED(hash)) OBJ_TAINT(dup);
return (VALUE)dup;
} }
static VALUE static VALUE
@ -313,9 +311,7 @@ rb_hash_rehash_i(key, value, tbl)
VALUE key, value; VALUE key, value;
st_table *tbl; st_table *tbl;
{ {
if (key != Qnil) { if (key != Qundef) st_insert(tbl, key, value);
st_insert(tbl, key, value);
}
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -405,7 +401,7 @@ rb_hash_index(hash, value)
VALUE args[2]; VALUE args[2];
args[0] = value; args[0] = value;
args[1] = Qnil; args[1] = RHASH(hash)->ifnone;
st_foreach(RHASH(hash)->tbl, index_i, args); st_foreach(RHASH(hash)->tbl, index_i, args);
@ -437,7 +433,7 @@ rb_hash_delete(hash, key)
rb_hash_modify(hash); rb_hash_modify(hash);
if (RHASH(hash)->iter_lev > 0 && 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); FL_SET(hash, HASH_DELETED);
return val; return val;
} }
@ -446,7 +442,7 @@ rb_hash_delete(hash, key)
if (rb_iterator_p()) { if (rb_iterator_p()) {
return rb_yield(key); return rb_yield(key);
} }
return Qnil; return RHASH(hash)->ifnone;
} }
struct shift_var { struct shift_var {
@ -460,7 +456,7 @@ shift_i(key, value, var)
VALUE key, value; VALUE key, value;
struct shift_var *var; struct shift_var *var;
{ {
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
if (var->stop) return ST_STOP; if (var->stop) return ST_STOP;
var->stop = 1; var->stop = 1;
var->key = key; var->key = key;
@ -478,7 +474,7 @@ rb_hash_shift(hash)
var.stop = 0; var.stop = 0;
st_foreach(RHASH(hash)->tbl, shift_i, &var); 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); return rb_assoc_new(var.key, var.val);
} }
@ -486,7 +482,7 @@ static int
delete_if_i(key, value) delete_if_i(key, value)
VALUE 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)))) if (RTEST(rb_yield(rb_assoc_new(key, value))))
return ST_DELETE; return ST_DELETE;
return ST_CONTINUE; return ST_CONTINUE;
@ -572,7 +568,7 @@ static int
each_value_i(key, value) each_value_i(key, value)
VALUE key, value; VALUE key, value;
{ {
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
rb_yield(value); rb_yield(value);
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -589,7 +585,7 @@ static int
each_key_i(key, value) each_key_i(key, value)
VALUE key, value; VALUE key, value;
{ {
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
rb_yield(key); rb_yield(key);
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -606,7 +602,7 @@ static int
each_pair_i(key, value) each_pair_i(key, value)
VALUE key, value; VALUE key, value;
{ {
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
rb_yield(rb_assoc_new(key, value)); rb_yield(rb_assoc_new(key, value));
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -623,7 +619,7 @@ static int
to_a_i(key, value, ary) to_a_i(key, value, ary)
VALUE 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)); rb_ary_push(ary, rb_assoc_new(key, value));
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -636,6 +632,7 @@ rb_hash_to_a(hash)
ary = rb_ary_new(); ary = rb_ary_new();
st_foreach(RHASH(hash)->tbl, to_a_i, ary); st_foreach(RHASH(hash)->tbl, to_a_i, ary);
if (OBJ_TAINTED(hash)) OBJ_TAINT(ary);
return ary; return ary;
} }
@ -653,7 +650,7 @@ inspect_i(key, value, str)
{ {
VALUE str2; VALUE str2;
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
if (RSTRING(str)->len > 1) { if (RSTRING(str)->len > 1) {
rb_str_cat(str, ", ", 2); rb_str_cat(str, ", ", 2);
} }
@ -689,23 +686,20 @@ rb_hash_inspect(hash)
} }
static VALUE static VALUE
hash_to_s(hash) to_s_hash(hash)
VALUE hash; VALUE hash;
{ {
VALUE str; return rb_ary_to_s(rb_hash_to_a(hash));
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;
} }
static VALUE static VALUE
rb_hash_to_s(hash) rb_hash_to_s(hash)
VALUE hash; VALUE hash;
{ {
VALUE str;
if (rb_inspecting_p(hash)) return rb_str_new2("{...}"); 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 static VALUE
@ -719,7 +713,7 @@ static int
keys_i(key, value, ary) keys_i(key, value, ary)
VALUE key, value, ary; VALUE key, value, ary;
{ {
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
rb_ary_push(ary, key); rb_ary_push(ary, key);
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -740,7 +734,7 @@ static int
values_i(key, value, ary) values_i(key, value, ary)
VALUE key, value, ary; VALUE key, value, ary;
{ {
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
rb_ary_push(ary, value); rb_ary_push(ary, value);
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -772,7 +766,7 @@ static int
rb_hash_search_value(key, value, data) rb_hash_search_value(key, value, data)
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])) { if (rb_equal(value, data[1])) {
data[0] = Qtrue; data[0] = Qtrue;
return ST_STOP; return ST_STOP;
@ -805,7 +799,7 @@ equal_i(key, val1, data)
{ {
VALUE val2; VALUE val2;
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
if (!st_lookup(data->tbl, key, &val2)) { if (!st_lookup(data->tbl, key, &val2)) {
data->result = Qfalse; data->result = Qfalse;
return ST_STOP; return ST_STOP;
@ -839,7 +833,7 @@ rb_hash_invert_i(key, value, hash)
VALUE key, value; VALUE key, value;
VALUE hash; VALUE hash;
{ {
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
rb_hash_aset(hash, value, key); rb_hash_aset(hash, value, key);
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -859,7 +853,7 @@ rb_hash_update_i(key, value, hash)
VALUE key, value; VALUE key, value;
VALUE hash; VALUE hash;
{ {
if (key == Qnil) return ST_CONTINUE; if (key == Qundef) return ST_CONTINUE;
rb_hash_aset(hash, key, value); rb_hash_aset(hash, key, value);
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -888,23 +882,25 @@ env_delete(obj, name)
char *nam, *val; char *nam, *val;
rb_secure(4); rb_secure(4);
nam = str2cstr(name, &len); nam = rb_str2cstr(name, &len);
if (strlen(nam) != len) { if (strlen(nam) != len) {
rb_raise(rb_eArgError, "bad environment variable name"); rb_raise(rb_eArgError, "bad environment variable name");
} }
val = getenv(nam); val = getenv(nam);
if (val) { if (val) {
VALUE value = rb_tainted_str_new2(val);
ruby_setenv(nam, 0); ruby_setenv(nam, 0);
if (strcmp(nam, "PATH") == 0 && !OBJ_TAINTED(name)) { if (strcmp(nam, "PATH") == 0 && !OBJ_TAINTED(name)) {
path_tainted = 0; path_tainted = 0;
} }
return rb_tainted_str_new2(val); return value;
} }
return Qnil; return Qnil;
} }
static VALUE static VALUE
env_delete_method(obj, name) env_delete_m(obj, name)
VALUE obj, name; VALUE obj, name;
{ {
VALUE val = env_delete(obj, name); VALUE val = env_delete(obj, name);
@ -919,7 +915,7 @@ rb_f_getenv(obj, name)
char *nam, *env; char *nam, *env;
int len; int len;
nam = str2cstr(name, &len); nam = rb_str2cstr(name, &len);
if (strlen(nam) != len) { if (strlen(nam) != len) {
rb_raise(rb_eArgError, "bad environment variable name"); rb_raise(rb_eArgError, "bad environment variable name");
} }
@ -932,54 +928,6 @@ rb_f_getenv(obj, name)
return Qnil; 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 static void
path_tainted_p(path) path_tainted_p(path)
char *path; char *path;
@ -1153,8 +1101,8 @@ rb_f_setenv(obj, nm, val)
return Qnil; return Qnil;
} }
name = str2cstr(nm, &nlen); name = rb_str2cstr(nm, &nlen);
value = str2cstr(val, &vlen); value = rb_str2cstr(val, &vlen);
if (strlen(name) != nlen) if (strlen(name) != nlen)
rb_raise(rb_eArgError, "bad environment variable name"); rb_raise(rb_eArgError, "bad environment variable name");
if (strlen(value) != vlen) if (strlen(value) != vlen)
@ -1371,7 +1319,7 @@ env_index(dmy, value)
char *s = strchr(*env, '=')+1; char *s = strchr(*env, '=')+1;
if (s) { if (s) {
if (strncmp(s, RSTRING(value)->ptr, strlen(s)) == 0) { 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++; env++;
@ -1497,7 +1445,7 @@ Init_Hash()
rb_define_singleton_method(envtbl,"each_pair", env_each, 0); 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_key", env_each_key, 0);
rb_define_singleton_method(envtbl,"each_value", env_each_value, 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,"delete_if", env_delete_if, 0);
rb_define_singleton_method(envtbl,"reject!", 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); rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Dec 28 16:01:58 JST 1993 created at: Tue Dec 28 16:01:58 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -25,7 +25,7 @@ VALUE rb_ary_reverse _((VALUE));
VALUE rb_ary_sort _((VALUE)); VALUE rb_ary_sort _((VALUE));
VALUE rb_ary_sort_bang _((VALUE)); VALUE rb_ary_sort_bang _((VALUE));
VALUE rb_ary_delete _((VALUE, 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_plus _((VALUE, VALUE));
VALUE rb_ary_concat _((VALUE, VALUE)); VALUE rb_ary_concat _((VALUE, VALUE));
VALUE rb_ary_assoc _((VALUE, VALUE)); VALUE rb_ary_assoc _((VALUE, VALUE));
@ -41,7 +41,8 @@ VALUE rb_uint2big _((unsigned long));
VALUE rb_int2big _((long)); VALUE rb_int2big _((long));
VALUE rb_uint2inum _((unsigned long)); VALUE rb_uint2inum _((unsigned long));
VALUE rb_int2inum _((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)); VALUE rb_big2str _((VALUE, int));
long rb_big2long _((VALUE)); long rb_big2long _((VALUE));
#define rb_big2int(x) rb_big2long(x) #define rb_big2int(x) rb_big2long(x)
@ -150,6 +151,7 @@ VALUE rb_thread_local_aset _((VALUE, ID, VALUE));
int eaccess _((const char*, int)); int eaccess _((const char*, int));
VALUE rb_file_s_expand_path _((int, VALUE *)); VALUE rb_file_s_expand_path _((int, VALUE *));
void rb_file_const _((const char*, VALUE)); void rb_file_const _((const char*, VALUE));
char *rb_find_file _((char*));
/* gc.c */ /* gc.c */
void rb_global_variable _((VALUE*)); void rb_global_variable _((VALUE*));
void rb_gc_mark_locations _((VALUE*, 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_untrace_var _((int, VALUE*));
VALUE rb_f_global_variables _((void)); VALUE rb_f_global_variables _((void));
void rb_alias_variable _((ID, ID)); void rb_alias_variable _((ID, ID));
struct st_table* rb_generic_ivar_table _((VALUE));
void rb_clone_generic_ivar _((VALUE,VALUE)); void rb_clone_generic_ivar _((VALUE,VALUE));
void rb_mark_generic_ivar _((VALUE)); void rb_mark_generic_ivar _((VALUE));
void rb_mark_generic_ivar_tbl _((void)); void rb_mark_generic_ivar_tbl _((void));

34
io.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri Oct 15 18:08:59 JST 1993 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; VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout;
static VALUE orig_stdin, orig_stdout, orig_stderr; static VALUE orig_stdin, orig_stdout, orig_stderr;
VALUE rb_fs;
VALUE rb_output_fs; VALUE rb_output_fs;
VALUE rb_rs; VALUE rb_rs;
VALUE rb_output_rs; VALUE rb_output_rs;
@ -701,7 +700,7 @@ rb_io_gets(io)
} }
static VALUE static VALUE
rb_io_gets_method(argc, argv, io) rb_io_gets_m(argc, argv, io)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE io; VALUE io;
@ -767,7 +766,7 @@ rb_io_readline(argc, argv, io)
VALUE *argv; VALUE *argv;
VALUE io; VALUE io;
{ {
VALUE line = rb_io_gets_method(argc, argv, io); VALUE line = rb_io_gets_m(argc, argv, io);
if (NIL_P(line)) { if (NIL_P(line)) {
rb_eof_error(); rb_eof_error();
@ -885,12 +884,12 @@ rb_io_ungetc(io, c)
VALUE io, c; VALUE io, c;
{ {
OpenFile *fptr; OpenFile *fptr;
int cc = NUM2INT(c);
Check_Type(c, T_FIXNUM);
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
rb_io_check_readable(fptr); rb_io_check_readable(fptr);
if (ungetc(FIX2INT(c), fptr->f) == EOF) if (ungetc(cc, fptr->f) == EOF)
rb_sys_fail(fptr->path); rb_sys_fail(fptr->path);
return Qnil; return Qnil;
} }
@ -966,7 +965,7 @@ rb_io_close(io)
} }
static VALUE static VALUE
rb_io_close_method(io) rb_io_close_m(io)
VALUE io; VALUE io;
{ {
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) { if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
@ -1260,6 +1259,9 @@ rb_fopen(fname, mode)
rb_sys_fail(fname); rb_sys_fail(fname);
} }
} }
#ifdef __human68k__
fmode(file, _IOTEXT);
#endif
return file; return file;
} }
@ -1809,11 +1811,11 @@ rb_io_clone(io)
int fd; int fd;
char *mode; char *mode;
NEWOBJ(obj, struct RFile); NEWOBJ(clone, struct RFile);
CLONESETUP(obj, io); CLONESETUP(clone, io);
GetOpenFile(io, orig); GetOpenFile(io, orig);
MakeOpenFile(obj, fptr); MakeOpenFile(clone, fptr);
if (orig->f2) { if (orig->f2) {
fflush(orig->f2); fflush(orig->f2);
@ -1847,10 +1849,10 @@ rb_io_clone(io)
fptr->f = rb_fdopen(fd, "w"); fptr->f = rb_fdopen(fd, "w");
} }
if (fptr->mode & FMODE_BINMODE) { if (fptr->mode & FMODE_BINMODE) {
rb_io_binmode((VALUE)obj); rb_io_binmode((VALUE)clone);
} }
return (VALUE)obj; return (VALUE)clone;
} }
static VALUE 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, "select", rb_f_select, -1);
rb_define_singleton_method(rb_cIO, "pipe", rb_io_s_pipe, 0); rb_define_singleton_method(rb_cIO, "pipe", rb_io_s_pipe, 0);
rb_fs = rb_output_fs = Qnil; 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_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter); rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter);
rb_rs = rb_default_rs = rb_str_new2("\n"); rb_output_rs = Qnil; 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, "read", io_read, -1);
rb_define_method(rb_cIO, "write", io_write, 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, "readline", rb_io_readline, -1);
rb_define_method(rb_cIO, "getc", rb_io_getc, 0); rb_define_method(rb_cIO, "getc", rb_io_getc, 0);
rb_define_method(rb_cIO, "readchar", rb_io_readchar, 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, "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, "closed?", rb_io_closed, 0);
rb_define_method(rb_cIO, "close_read", rb_io_close_read, 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); rb_define_method(rb_cIO, "close_write", rb_io_close_write, 0);

View file

@ -186,7 +186,7 @@ $-v = false
RELEASE_DATE = "$Date$" RELEASE_DATE = "$Date$"
$-v = v $-v = v
NEEDS_BINMODE = true if /WIN/ni === PLATFORM NEEDS_BINMODE = true if /WIN/ni === RUBY_PLATFORM
PATH_SEPARATOR = {'UNIX'=>'/', 'WINDOWS'=>'\\', 'MACINTOSH'=>':'} PATH_SEPARATOR = {'UNIX'=>'/', 'WINDOWS'=>'\\', 'MACINTOSH'=>':'}
HTTP_STATUS = { HTTP_STATUS = {

View file

@ -1,6 +1,52 @@
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__ class DEBUGGER__
class Mutex
def initialize
@locker = nil
@waiting = []
@locked = false;
end
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
end
MUTEX = Mutex.new
class Context
DEBUG_LAST_CMD = []
begin begin
require 'readline' require 'readline'
def readline(prompt, hist) def readline(prompt, hist)
@ -11,29 +57,40 @@ class DEBUGGER__
STDOUT.print prompt STDOUT.print prompt
STDOUT.flush STDOUT.flush
line = STDIN.gets line = STDIN.gets
exit unless line
line.chomp! line.chomp!
line line
end end
USE_READLINE = false USE_READLINE = false
end end
trap("INT") { DEBUGGER__::CONTEXT.interrupt }
$DEBUG = true
def initialize def initialize
@break_points = [] if Thread.current == Thread.main
@display = []
@stop_next = 1 @stop_next = 1
@frames = [nil] else
@stop_next = 0
end
@last_file = nil @last_file = nil
@last = [nil, nil] @last = [nil, nil]
@file = nil
@line = nil
@no_step = nil @no_step = nil
@frames = []
@finish_pos = 0 @finish_pos = 0
end end
DEBUG_LAST_CMD = [] def stop_next(n=1)
@stop_next = n
end
def interrupt def stdout
@stop_next = 1 DEBUGGER__.stdout
end
def break_points
DEBUGGER__.break_points
end
def display
DEBUGGER__.display
end end
def debug_eval(str, binding) def debug_eval(str, binding)
@ -41,37 +98,123 @@ class DEBUGGER__
val = eval(str, binding) val = eval(str, binding)
val val
rescue rescue
at = caller(0) at = eval("caller(0)", binding)
STDOUT.printf "%s:%s\n", at.shift, $! stdout.printf "%s:%s\n", at.shift, $!.to_s.sub(/\(eval\):1:(in `.*?':)?/, '') #`
for i in at for i in at
break if i =~ /`debug_(eval|command)'$/ #` stdout.printf "\tfrom %s\n", i
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 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) def debug_command(file, line, id, binding)
MUTEX.lock
DEBUGGER__.set_last_thread(Thread.current)
frame_pos = 0 frame_pos = 0
binding_file = file binding_file = file
binding_line = line binding_line = line
previus_line = nil previous_line = nil
if (ENV['EMACS'] == 't') if (ENV['EMACS'] == 't')
STDOUT.printf "\032\032%s:%d:\n", binding_file, binding_line stdout.printf "\032\032%s:%d:\n", binding_file, binding_line
else else
STDOUT.printf "%s:%d:%s", binding_file, binding_line, stdout.printf "%s:%d:%s", binding_file, binding_line,
line_at(binding_file, binding_line) line_at(binding_file, binding_line)
end end
@frames[0] = binding @frames[0] = [binding, file, line, id]
display_expressions(binding) display_expressions(binding)
while input = readline("(rdb:-) ", true) while input = readline("(rdb:%d) "%thnum(), true)
catch (:debug_error) do
if input == "" if input == ""
input = DEBUG_LAST_CMD[0] input = DEBUG_LAST_CMD[0]
stdout.print input, "\n"
else else
DEBUG_LAST_CMD[0] = input DEBUG_LAST_CMD[0] = input
end end
case input case input
when /^b(?:reak)?\s+((?:[^:\n]+:)?.+)$/ when /^\s*b(?:reak)?\s+((?:.*?+:)?.+)$/
pos = $1 pos = $1
if pos.index(":") if pos.index(":")
file, pos = pos.split(":") file, pos = pos.split(":")
@ -83,84 +226,93 @@ class DEBUGGER__
else else
pname = pos = pos.intern.id2name pname = pos = pos.intern.id2name
end end
@break_points.push [true, 0, file, pos] break_points.push [true, 0, file, pos]
STDOUT.printf "Set breakpoint %d at %s:%s\n", @break_points.size, file, stdout.printf "Set breakpoint %d at %s:%s\n", break_points.size, file,
pname pname
when /^wat(?:ch)?\s+(.+)$/ when /^\s*wat(?:ch)?\s+(.+)$/
exp = $1 exp = $1
@break_points.push [true, 1, exp] break_points.push [true, 1, exp]
STDOUT.printf "Set watchpoint %d\n", @break_points.size, exp stdout.printf "Set watchpoint %d\n", break_points.size, exp
when /^b(?:reak)?$/, /^info b(?:reak)?$/ when /^\s*b(?:reak)?$/
if break_points.find{|b| b[1] == 0}
n = 1 n = 1
STDOUT.print "breakpoints:\n" stdout.print "breakpoints:\n"
for b in @break_points for b in break_points
if b[0] and (b[1] == 0) if b[0] and b[1] == 0
STDOUT.printf " %d %s:%s\n", n, b[2], b[3] stdout.printf " %d %s:%s\n", n, b[2], b[3]
end end
n += 1 n += 1
end end
end
if break_points.find{|b| b[1] == 1}
n = 1 n = 1
STDOUT.print "\n" stdout.print "\n"
STDOUT.print "watchpoints:\n" stdout.print "watchpoints:\n"
for b in @break_points for b in break_points
if b[0] and (b[1] == 1) if b[0] and b[1] == 1
STDOUT.printf " %d %s\n", n, b[2] stdout.printf " %d %s\n", n, b[2]
end end
n += 1 n += 1
end end
STDOUT.print "\n" end
if break_points.size == 0
stdout.print "no breakpoints\n"
else
stdout.print "\n"
end
when /^del(?:ete)?(?:\s+(\d+))?$/ when /^\s*del(?:ete)?(?:\s+(\d+))?$/
pos = $1 pos = $1
unless pos unless pos
input = readline("clear all breakpoints? (y/n) ", false) input = readline("clear all breakpoints? (y/n) ", false)
if input == "y" if input == "y"
for b in @break_points for b in break_points
b[0] = false b[0] = false
end end
end end
else else
pos = pos.to_i pos = pos.to_i
if @break_points[pos-1] if break_points[pos-1]
@break_points[pos-1][0] = false break_points[pos-1][0] = false
else else
STDOUT.printf "Breakpoint %d is not defined\n", pos stdout.printf "Breakpoint %d is not defined\n", pos
end end
end end
when /^disp(?:lay)?\s+(.+)$/ when /^\s*disp(?:lay)?\s+(.+)$/
exp = $1 exp = $1
@display.push.push [true, exp] display.push.push [true, exp]
STDOUT.printf " %d: %s = %s\n", @display.size, exp, stdout.printf " %d: %s = %s\n", display.size, exp,
debug_eval(exp, binding).to_s eval(exp, binding) rescue "--"
when /^disp(?:lay)?$/, /^info disp(?:lay)?$/ when /^\s*disp(?:lay)?$/
display_expressions(binding) display_expressions(binding)
when /^undisp(?:lay)?(?:\s+(\d+))?$/ when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/
pos = $1 pos = $1
unless pos unless pos
input = readline("clear all expressions? (y/n) ", false) input = readline("clear all expressions? (y/n) ", false)
if input == "y" if input == "y"
for d in @display for d in display
d[0] = false d[0] = false
end end
end end
else else
pos = pos.to_i pos = pos.to_i
if @display[pos-1] if display[pos-1]
@display[pos-1][0] = false display[pos-1][0] = false
else else
STDOUT.printf "display expression %d is not defined\n", pos stdout.printf "display expression %d is not defined\n", pos
end end
end end
when /^c(?:ont)?$/ when /^\s*c(?:ont)?$/
MUTEX.unlock
return return
when /^s(?:tep)?(?:\s+(\d+))?$/ when /^\s*s(?:tep)?(?:\s+(\d+))?$/
if $1 if $1
lev = $1.to_i lev = $1.to_i
else else
@ -169,7 +321,7 @@ class DEBUGGER__
@stop_next = lev @stop_next = lev
return return
when /^n(?:ext)?(?:\s+(\d+))?$/ when /^\s*n(?:ext)?(?:\s+(\d+))?$/
if $1 if $1
lev = $1.to_i lev = $1.to_i
else else
@ -179,22 +331,15 @@ class DEBUGGER__
@no_step = @frames.size - frame_pos @no_step = @frames.size - frame_pos
return return
when /^w(?:here)?$/, /^f(?:rame)?$/ when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/
at = caller(0) display_frames(frame_pos)
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+(.+))?$/ when /^\s*l(?:ist)?(?:\s+(.+))?$/
if not $1 if not $1
b = previus_line ? previus_line + 10 : binding_line - 5 b = previous_line ? previous_line + 10 : binding_line - 5
e = b + 9 e = b + 9
elsif $1 == '-' elsif $1 == '-'
b = previus_line ? previus_line - 10 : binding_line - 5 b = previous_line ? previous_line - 10 : binding_line - 5
e = b + 9 e = b + 9
else else
b, e = $1.split(/[-,]/) b, e = $1.split(/[-,]/)
@ -206,26 +351,11 @@ class DEBUGGER__
e = b + 9 e = b + 9
end end
end end
previus_line = b previous_line = b
STDOUT.printf "[%d, %d] in %s\n", b, e, binding_file display_list(b, e, binding_file, binding_line)
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+))?$/ when /^\s*up(?:\s+(\d+))?$/
previus_line = nil previous_line = nil
if $1 if $1
lev = $1.to_i lev = $1.to_i
else else
@ -234,14 +364,13 @@ class DEBUGGER__
frame_pos += lev frame_pos += lev
if frame_pos >= @frames.size if frame_pos >= @frames.size
frame_pos = @frames.size - 1 frame_pos = @frames.size - 1
STDOUT.print "at toplevel\n" stdout.print "at toplevel\n"
end end
binding = @frames[frame_pos] binding, binding_file, binding_line = @frames[frame_pos]
info, binding_file, binding_line = frame_info(frame_pos) stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line
STDOUT.printf "#%d %s\n", frame_pos, info
when /^down(?:\s+(\d+))?$/ when /^\s*down(?:\s+(\d+))?$/
previus_line = nil previous_line = nil
if $1 if $1
lev = $1.to_i lev = $1.to_i
else else
@ -250,26 +379,37 @@ class DEBUGGER__
frame_pos -= lev frame_pos -= lev
if frame_pos < 0 if frame_pos < 0
frame_pos = 0 frame_pos = 0
STDOUT.print "at stack bottom\n" stdout.print "at stack bottom\n"
end end
binding = @frames[frame_pos] binding, binding_file, binding_line = @frames[frame_pos]
info, binding_file, binding_line = frame_info(frame_pos) stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line
STDOUT.printf "#%d %s\n", frame_pos, info
when /^fi(?:nish)?$/ when /^\s*fi(?:nish)?$/
if frame_pos == 0 if frame_pos == 0
STDOUT.print "\"finish\" not meaningful in the outermost frame.\n" stdout.print "\"finish\" not meaningful in the outermost frame.\n"
else else
@finish_pos = @frames.size - frame_pos @finish_pos = @frames.size - frame_pos
frame_pos = 0 frame_pos = 0
return return
end end
when /^q(?:uit)?$/ when /^\s*q(?:uit)?$/
input = readline("really quit? (y/n) ", false) input = readline("really quit? (y/n) ", false)
exit if input == "y" exit if input == "y"
when /^p\s+/ 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) p debug_eval($', binding)
else else
@ -278,25 +418,60 @@ class DEBUGGER__
end end
end end
end end
end
def display_expressions(binding) def display_expressions(binding)
n = 1 n = 1
for d in @display for d in display
if d[0] if d[0]
STDOUT.printf "%d: %s = %s\n", n, d[1], debug_eval(d[1], binding).to_s stdout.printf "%d: %s = %s\n", n, d[1], debug_eval(d[1], binding).to_s
end end
n += 1 n += 1
end end
end end
def frame_info(pos = 0) def frame_set_pos(file, line)
info = caller(0)[-(@frames.size - pos)] if @frames[0]
info.sub(/:in `.*'$/, "") =~ /^(.*):(\d+)$/ #` @frames[0][1] = file
[info, $1, $2.to_i] @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 end
def line_at(file, line) def line_at(file, line)
lines = LINES__[file] lines = SCRIPT_LINES__[file]
if lines if lines
return "\n" if lines == true return "\n" if lines == true
line = lines[line-1] line = lines[line-1]
@ -317,15 +492,15 @@ class DEBUGGER__
def check_break_points(file, pos, binding, id) def check_break_points(file, pos, binding, id)
file = File.basename(file) file = File.basename(file)
n = 1 n = 1
for b in @break_points for b in break_points
if b[0] if b[0]
if b[1] == 0 and b[2] == file and b[3] == pos 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), MUTEX.lock
file, pos stdout.printf "breakpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
return true return true
elsif b[1] == 1 and debug_eval(b[2], binding) elsif b[1] == 1 and debug_eval(b[2], binding)
STDOUT.printf "watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), MUTEX.lock
file, pos stdout.printf "watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
return true return true
end end
end end
@ -335,19 +510,29 @@ class DEBUGGER__
end end
def excn_handle(file, line, id, binding) def excn_handle(file, line, id, binding)
if $!.type <= SystemExit
set_trace_func nil
exit
end
MUTEX.lock
fs = @frames.size fs = @frames.size
tb = caller(0)[-fs..-1] tb = caller(0)[-fs..-1]
STDOUT.printf "%s\n", $! stdout.printf "%s\n", $!
if tb
for i in tb for i in tb
STDOUT.printf "\tfrom %s\n", i stdout.printf "\tfrom %s\n", i
end
end end
debug_command(file, line, id, binding) debug_command(file, line, id, binding)
end end
def trace_func(event, file, line, id, binding) def trace_func(event, file, line, id, binding, klass)
@file = file
@line = line
case event case event
when 'line' when 'line'
frame_set_pos(file, line)
if !@no_step or @frames.size == @no_step if !@no_step or @frames.size == @no_step
@stop_next -= 1 @stop_next -= 1
elsif @frames.size < @no_step elsif @frames.size < @no_step
@ -355,7 +540,7 @@ class DEBUGGER__
else else
# nothing to do. skipped. # nothing to do. skipped.
end end
if @stop_next == 0 if @stop_next == 0 or check_break_points(file, line, binding, id)
if [file, line] == @last if [file, line] == @last
@stop_next = 1 @stop_next = 1
else else
@ -364,18 +549,19 @@ class DEBUGGER__
@last = [file, line] @last = [file, line]
end end
end end
if check_break_points(file, line, binding, id)
debug_command(file, line, id, binding)
end
when 'call' when 'call'
@frames.unshift binding @frames.unshift [binding, file, line, id]
if check_break_points(file, id.id2name, binding, 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) debug_command(file, line, id, binding)
end end
when 'c-call'
frame_set_pos(file, line)
when 'class' when 'class'
@frames.unshift binding @frames.unshift [binding, file, line, id]
when 'return', 'end' when 'return', 'end'
@frames.shift @frames.shift
@ -383,17 +569,133 @@ class DEBUGGER__
@stop_next = 1 @stop_next = 1
end end
when 'end'
@frames.shift
when 'raise' when 'raise'
excn_handle(file, line, id, binding) excn_handle(file, line, id, binding)
end end
@last_file = file @last_file = file
end end
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 <<DEBUGGER__
def stdout
@stdout
end
def stdout=(s)
@stdout = s
end
set_trace_func proc{|event, file, line, id, binding,*rest| def display
DEBUGGER__::CONTEXT.trace_func event, file, line, id, binding @display
end
def break_points
@break_points
end
def set_last_thread(th)
@last_thread = th
end
def context(thread=Thread.current)
c = thread[:__debugger_data__]
unless c
thread[:__debugger_data__] = c = Context.new
end
c
end
def interrupt
context(@last_thread).stop_next
end
def get_thread(num)
th = @thread_list.index(num)
unless th
@stdout.print "no thread no.", num, "\n"
throw :debug_error
end
th
end
def thread_list(num)
th = get_thread(num)
if th == Thread.current
@stdout.print "+"
else
@stdout.print " "
end
@stdout.printf "%d ", num
@stdout.print th.inspect, "\t"
file = context(th).instance_eval{@file}
if file
@stdout.print file,":",context(th).instance_eval{@line}
end
@stdout.print "\n"
end
def thread_list_all
for th in @thread_list.values.sort
thread_list(th)
end
end
def make_thread_list
hash = {}
for th in Thread::list
if @thread_list.key? th
hash[th] = @thread_list[th]
else
@max_thread += 1
hash[th] = @max_thread
end
end
@thread_list = hash
end
def debug_thread_info(input, binding)
case input
when /^l(?:ist)?/
make_thread_list
thread_list_all
when /^c(?:ur(?:rent)?)?\s+(\d+)/, /^stop\s+(\d+)/, /^(\d+)/
make_thread_list
th = get_thread($1.to_i)
thread_list(@thread_list[th])
context(th).stop_next
th.run
return :cont
when /^c(?:ur(?:rent)?)?$/
make_thread_list
thread_list(@thread_list[Thread.current])
when /^resume\s+(\d+)/
make_thread_list
th = get_thread($1.to_i)
thread_list(@thread_list[th])
th.run
return :cont
end
end
end
@stdout.printf "Debug.rb\n"
@stdout.printf "Emacs support available.\n\n"
set_trace_func proc{|event, file, line, id, binding,klass,*rest|
DEBUGGER__.context.trace_func event, file, line, id, binding,klass
} }
end end

View file

@ -17,7 +17,9 @@ module Find
begin begin
for f in d for f in d
next if f =~ /^\.\.?$/ next if f =~ /^\.\.?$/
if file == "/" then if File::ALT_SEPARATOR and file =~ /^([\/\\]|[A-Za-z]:[\/\\]?)$/ then
f = file + f
elsif file == "/" then
f = "/" + f f = "/" + f
else else
f = file + "/" + f f = file + "/" + f

View file

@ -243,7 +243,7 @@ SRC
print "no\n" print "no\n"
return false return false
end end
header.tr!("a-z./\055", "A-Z___") header.tr!("a-z\055./", "A-Z___")
$defs.push(format("-DHAVE_%s", header)) $defs.push(format("-DHAVE_%s", header))
print "yes\n" print "yes\n"
return true return true
@ -367,6 +367,8 @@ CXXFLAGS = $(CFLAGS)
DLDFLAGS = #{$DLDFLAGS} #{$LDFLAGS} DLDFLAGS = #{$DLDFLAGS} #{$LDFLAGS}
LDSHARED = #{CONFIG["LDSHARED"]} #{defflag} LDSHARED = #{CONFIG["LDSHARED"]} #{defflag}
RUBY_INSTALL_NAME = #{CONFIG["RUBY_INSTALL_NAME"]}
prefix = #{CONFIG["prefix"]} prefix = #{CONFIG["prefix"]}
exec_prefix = #{CONFIG["exec_prefix"]} exec_prefix = #{CONFIG["exec_prefix"]}
libdir = #{$libdir} libdir = #{$libdir}

View file

@ -32,11 +32,11 @@ def timeout(sec)
x = Thread.current x = Thread.current
y = Thread.start { y = Thread.start {
sleep sec sleep sec
x.raise TimeoutError, "execution expired" if x.status x.raise TimeoutError, "execution expired" if x.alive?
} }
yield sec yield sec
return true return true
ensure ensure
Thread.kill y if y.status Thread.kill y if y.alive?
end end
end end

2
main.c
View file

@ -15,7 +15,7 @@ unsigned int _stklen = 0x180000;
#endif #endif
#ifdef __human68k__ #ifdef __human68k__
int _stacksize = 131072; int _stacksize = 262144;
#endif #endif
#if defined(__MACOS__) && defined(__MWERKS__) #if defined(__MACOS__) && defined(__MWERKS__)

View file

@ -17,7 +17,7 @@ double strtod();
#endif #endif
#define MARSHAL_MAJOR 4 #define MARSHAL_MAJOR 4
#define MARSHAL_MINOR 2 #define MARSHAL_MINOR 3
#define TYPE_NIL '0' #define TYPE_NIL '0'
#define TYPE_TRUE 'T' #define TYPE_TRUE 'T'
@ -42,6 +42,7 @@ double strtod();
#define TYPE_SYMBOL ':' #define TYPE_SYMBOL ':'
#define TYPE_SYMLINK ';' #define TYPE_SYMLINK ';'
#define TYPE_IVAR 'I'
#define TYPE_LINK '@' #define TYPE_LINK '@'
static ID s_dump, s_load; static ID s_dump, s_load;
@ -200,6 +201,22 @@ w_uclass(obj, klass, arg)
} }
} }
static void
w_ivar(tbl, arg)
st_table *tbl;
struct dump_call_arg *arg;
{
struct dump_call_arg c_arg;
if (tbl) {
w_long(tbl->num_entries, arg->arg);
st_foreach(tbl, obj_each, arg);
}
else {
w_long(0, arg->arg);
}
}
static void static void
w_object(obj, arg, limit) w_object(obj, arg, limit)
VALUE obj; VALUE obj;
@ -207,6 +224,7 @@ w_object(obj, arg, limit)
int limit; int limit;
{ {
struct dump_call_arg c_arg; struct dump_call_arg c_arg;
st_table *ivtbl = 0;;
if (limit == 0) { if (limit == 0) {
rb_raise(rb_eRuntimeError, "exceed depth limit"); rb_raise(rb_eRuntimeError, "exceed depth limit");
@ -262,6 +280,10 @@ w_object(obj, arg, limit)
return; return;
} }
if (ivtbl = rb_generic_ivar_table(obj)) {
w_byte(TYPE_IVAR, arg);
}
switch (BUILTIN_TYPE(obj)) { switch (BUILTIN_TYPE(obj)) {
case T_CLASS: case T_CLASS:
w_byte(TYPE_CLASS, arg); w_byte(TYPE_CLASS, arg);
@ -269,7 +291,7 @@ w_object(obj, arg, limit)
VALUE path = rb_class_path(obj); VALUE path = rb_class_path(obj);
w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg); w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
} }
return; break;
case T_MODULE: case T_MODULE:
w_byte(TYPE_MODULE, arg); w_byte(TYPE_MODULE, arg);
@ -277,12 +299,12 @@ w_object(obj, arg, limit)
VALUE path = rb_class_path(obj); VALUE path = rb_class_path(obj);
w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg); w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
} }
return; break;
case T_FLOAT: case T_FLOAT:
w_byte(TYPE_FLOAT, arg); w_byte(TYPE_FLOAT, arg);
w_float(RFLOAT(obj)->value, arg); w_float(RFLOAT(obj)->value, arg);
return; break;
case T_BIGNUM: case T_BIGNUM:
w_byte(TYPE_BIGNUM, arg); w_byte(TYPE_BIGNUM, arg);
@ -298,20 +320,20 @@ w_object(obj, arg, limit)
d++; d++;
} }
} }
return; break;
case T_STRING: case T_STRING:
w_uclass(obj, rb_cString, arg); w_uclass(obj, rb_cString, arg);
w_byte(TYPE_STRING, arg); w_byte(TYPE_STRING, arg);
w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg); w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg);
return; break;
case T_REGEXP: case T_REGEXP:
w_uclass(obj, rb_cRegexp, arg); w_uclass(obj, rb_cRegexp, arg);
w_byte(TYPE_REGEXP, arg); w_byte(TYPE_REGEXP, arg);
w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg); w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg);
w_byte(rb_reg_options(obj), arg); w_byte(rb_reg_options(obj), arg);
return; break;
case T_ARRAY: case T_ARRAY:
w_uclass(obj, rb_cArray, arg); w_uclass(obj, rb_cArray, arg);
@ -375,13 +397,7 @@ w_object(obj, arg, limit)
} }
path = rb_class2name(klass); path = rb_class2name(klass);
w_unique(path, arg); w_unique(path, arg);
if (ROBJECT(obj)->iv_tbl) { w_ivar(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);
}
} }
break; break;
@ -391,6 +407,9 @@ w_object(obj, arg, limit)
break; break;
} }
} }
if (ivtbl) {
w_ivar(ivtbl, &c_arg);
}
} }
static VALUE static VALUE
@ -471,6 +490,8 @@ struct load_arg {
VALUE proc; VALUE proc;
}; };
static VALUE r_object _((struct load_arg *arg));
static int static int
r_byte(arg) r_byte(arg)
struct load_arg *arg; struct load_arg *arg;
@ -624,6 +645,23 @@ r_regist(v, arg)
return v; 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 static VALUE
r_object(arg) r_object(arg)
struct load_arg *arg; struct load_arg *arg;
@ -642,6 +680,11 @@ r_object(arg)
return v; return v;
break; break;
case TYPE_IVAR:
v = r_object(arg);
r_ivar(v, arg);
return v;
case TYPE_UCLASS: case TYPE_UCLASS:
{ {
VALUE c = rb_path2class(r_unique(arg)); VALUE c = rb_path2class(r_unique(arg));
@ -793,19 +836,11 @@ r_object(arg)
case TYPE_OBJECT: case TYPE_OBJECT:
{ {
VALUE klass; VALUE klass;
int len;
klass = rb_path2class(r_unique(arg)); klass = rb_path2class(r_unique(arg));
len = r_long(arg);
v = rb_obj_alloc(klass); v = rb_obj_alloc(klass);
r_regist(v, arg); r_regist(v, arg);
if (len > 0) { r_ivar(v, arg);
while (len--) {
ID id = r_symbol(arg);
VALUE val = r_object(arg);
rb_ivar_set(v, id, val);
}
}
return v; return v;
} }
break; break;
@ -887,7 +922,7 @@ marshal_load(argc, argv)
int len; int len;
arg.fp = 0; arg.fp = 0;
arg.ptr = str2cstr(port, &len); arg.ptr = rb_str2cstr(port, &len);
arg.end = arg.ptr + len; arg.end = arg.ptr + len;
} }
else { else {

2
math.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Jan 25 14:12:56 JST 1994 created at: Tue Jan 25 14:12:56 JST 1994
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -189,7 +189,7 @@ The variable ruby-indent-level controls the amount of indentation.
(indent-to x) (indent-to x)
(move-to-column (+ x shift)))))) (move-to-column (+ x shift))))))
(defun ruby-expr-beg (&optional modifier) (defun ruby-expr-beg (&optional option)
(save-excursion (save-excursion
(if (looking-at "\\?") (if (looking-at "\\?")
(progn (progn
@ -201,15 +201,11 @@ The variable ruby-indent-level controls the amount of indentation.
(or (bolp) (or (bolp)
(looking-at ruby-operator-re) (looking-at ruby-operator-re)
(looking-at "[\\[({]") (looking-at "[\\[({]")
(and (not modifier) (looking-at "[!?]")) (and (not (eq option 'modifier))
(looking-at "[!?]"))
(and (looking-at ruby-symbol-re) (and (looking-at ruby-symbol-re)
(save-restriction (skip-chars-backward ruby-symbol-chars)
(let ((p (point))) (if (and (not (eq option 'modifier)) (bolp))
(beginning-of-line)
(narrow-to-region (point) p)
(goto-char p)
(forward-word -1)))
(if (and (not modifier) (bolp))
t t
(if (or (looking-at ruby-block-beg-re) (if (or (looking-at ruby-block-beg-re)
(looking-at ruby-block-op-re) (looking-at ruby-block-op-re)
@ -217,7 +213,8 @@ The variable ruby-indent-level controls the amount of indentation.
(progn (progn
(goto-char (match-end 0)) (goto-char (match-end 0))
(looking-at "\\>")) (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) (defun ruby-parse-region (start end)
(let ((indent-point end) (let ((indent-point end)
@ -252,7 +249,7 @@ The variable ruby-indent-level controls the amount of indentation.
(goto-char indent-point)))) (goto-char indent-point))))
((looking-at "/") ((looking-at "/")
(cond (cond
((and (not (eobp)) (ruby-expr-beg)) ((and (not (eobp)) (ruby-expr-beg 'expr-arg))
(if (re-search-forward "[^\\]/" indent-point t) (if (re-search-forward "[^\\]/" indent-point t)
nil nil
(setq in-string (point)) (setq in-string (point))
@ -261,7 +258,7 @@ The variable ruby-indent-level controls the amount of indentation.
(goto-char pnt)))) (goto-char pnt))))
((looking-at "%") ((looking-at "%")
(cond (cond
((and (not (eobp)) (ruby-expr-beg) ((and (not (eobp)) (ruby-expr-beg 'expr-arg)
(not (looking-at "%=")) (not (looking-at "%="))
(looking-at "%[Qqrxw]?\\(.\\)")) (looking-at "%[Qqrxw]?\\(.\\)"))
(setq w (buffer-substring (match-beginning 1) (setq w (buffer-substring (match-beginning 1)
@ -352,7 +349,7 @@ The variable ruby-indent-level controls the amount of indentation.
(progn (progn
(goto-char (match-beginning 0)) (goto-char (match-beginning 0))
(if (looking-at ruby-modifier-re) (if (looking-at ruby-modifier-re)
(ruby-expr-beg t) (ruby-expr-beg 'modifier)
t)) t))
t) t)
(goto-char pnt) (goto-char pnt)

View file

@ -18,6 +18,7 @@ link(const char *src, const char *dst)
return symlink(src, dst); return symlink(src, dst);
} }
#ifndef HAVE_GETTIMEOFDAY
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
@ -34,3 +35,4 @@ gettimeofday(struct timeval *tv, struct timezone *tz)
return 0; return 0;
} }
#endif

2
node.h
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri May 28 15:14:02 JST 1993 created at: Fri May 28 15:14:02 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri Aug 13 18:33:09 JST 1993 created at: Fri Aug 13 18:33:09 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Jul 15 12:01:24 JST 1993 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; return val;
case T_STRING: case T_STRING:
return rb_str2inum(RSTRING(val)->ptr, 0); return rb_str2inum(val, 0);
case T_NIL: case T_NIL:
return INT2FIX(0); return INT2FIX(0);
@ -827,8 +827,6 @@ rb_f_integer(obj, arg)
return rb_Integer(arg); return rb_Integer(arg);
} }
double rb_big2dbl _((VALUE));
VALUE VALUE
rb_Float(val) rb_Float(val)
VALUE val; VALUE val;

12
pack.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Feb 10 15:17:05 JST 1994 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 */ int natint; /* native integer */
#endif #endif
p = str2cstr(fmt, &plen); p = rb_str2cstr(fmt, &plen);
pend = p + plen; pend = p + plen;
res = rb_str_new(0, 0); res = rb_str_new(0, 0);
@ -379,7 +379,7 @@ pack_pack(ary, fmt)
plen = 0; plen = 0;
} }
else { else {
ptr = str2cstr(from, &plen); ptr = rb_str2cstr(from, &plen);
} }
if (p[-1] == '*') if (p[-1] == '*')
@ -813,7 +813,7 @@ pack_pack(ary, fmt)
case 'u': case 'u':
case 'm': case 'm':
ptr = str2cstr(NEXTFROM, &plen); ptr = rb_str2cstr(NEXTFROM, &plen);
if (len <= 1) if (len <= 1)
len = 45; len = 45;
@ -1030,9 +1030,9 @@ pack_unpack(str, fmt)
int natint; /* native integer */ int natint; /* native integer */
#endif #endif
s = str2cstr(str, &len); s = rb_str2cstr(str, &len);
send = s + len; send = s + len;
p = str2cstr(fmt, &len); p = rb_str2cstr(fmt, &len);
pend = p + len; pend = p + len;
ary = rb_ary_new(); ary = rb_ary_new();

42
parse.y
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri May 28 18:02:42 JST 1993 created at: Fri May 28 18:02:42 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/
@ -331,6 +331,7 @@ stmt : block_call
| stmt kWHILE_MOD expr | stmt kWHILE_MOD expr
{ {
value_expr($3); value_expr($3);
if ($1) {
if (nd_type($1) == NODE_BEGIN) { if (nd_type($1) == NODE_BEGIN) {
$$ = NEW_WHILE(cond($3), $1->nd_body, 0); $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
} }
@ -338,9 +339,14 @@ stmt : block_call
$$ = NEW_WHILE(cond($3), $1, 1); $$ = NEW_WHILE(cond($3), $1, 1);
} }
} }
else {
$$ = 0;
}
}
| stmt kUNTIL_MOD expr | stmt kUNTIL_MOD expr
{ {
value_expr($3); value_expr($3);
if ($1) {
if (nd_type($1) == NODE_BEGIN) { if (nd_type($1) == NODE_BEGIN) {
$$ = NEW_UNTIL(cond($3), $1->nd_body, 0); $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
} }
@ -348,6 +354,10 @@ stmt : block_call
$$ = NEW_UNTIL(cond($3), $1, 1); $$ = NEW_UNTIL(cond($3), $1, 1);
} }
} }
else {
$$ = 0;
}
}
| stmt kRESCUE_MOD expr | stmt kRESCUE_MOD expr
{ {
$$ = NEW_RESCUE($1, NEW_RESBODY(0,$3,0), 0); $$ = NEW_RESCUE($1, NEW_RESBODY(0,$3,0), 0);
@ -713,7 +723,7 @@ arg : lhs '=' arg
} }
| tUPLUS arg | tUPLUS arg
{ {
if (nd_type($2) == NODE_LIT) { if ($2 && nd_type($2) == NODE_LIT) {
$$ = $2; $$ = $2;
} }
else { else {
@ -722,7 +732,7 @@ arg : lhs '=' arg
} }
| tUMINUS 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); long i = FIX2LONG($2->nd_lit);
$2->nd_lit = INT2FIX(-i); $2->nd_lit = INT2FIX(-i);
@ -1781,16 +1791,17 @@ int ruby__end__seen;
static VALUE ruby_debug_lines; static VALUE ruby_debug_lines;
static NODE* static NODE*
yycompile(f) yycompile(f, line)
char *f; char *f;
int line;
{ {
int n; int n;
if (!ruby_in_eval && rb_safe_level() == 0 && 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; 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) { if (TYPE(hash) == T_HASH) {
fname = rb_str_new2(f); fname = rb_str_new2(f);
ruby_debug_lines = rb_hash_aref(hash, fname); ruby_debug_lines = rb_hash_aref(hash, fname);
@ -1799,6 +1810,13 @@ yycompile(f)
rb_hash_aset(hash, fname, ruby_debug_lines); 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; ruby__end__seen = 0;
@ -1864,7 +1882,7 @@ rb_compile_string(f, s, line)
ruby_sourceline = line - 1; ruby_sourceline = line - 1;
compile_for_eval = 1; compile_for_eval = 1;
return yycompile(f); return yycompile(f, line);
} }
NODE* NODE*
@ -1886,7 +1904,7 @@ rb_compile_file(f, file, start)
lex_pbeg = lex_p = lex_pend = 0; lex_pbeg = lex_p = lex_pend = 0;
ruby_sourceline = start - 1; ruby_sourceline = start - 1;
return yycompile(strdup(f)); return yycompile(strdup(f), start);
} }
#if defined(__GNUC__) && __GNUC__ >= 2 #if defined(__GNUC__) && __GNUC__ >= 2
@ -2873,7 +2891,7 @@ yylex()
} while (c = nextc()); } while (c = nextc());
pushback(c); pushback(c);
tokfix(); tokfix();
yylval.val = rb_str2inum(tok(), 16); yylval.val = rb_cstr2inum(tok(), 16);
return tINTEGER; return tINTEGER;
} }
if (c == 'b' || c == 'B') { if (c == 'b' || c == 'B') {
@ -2889,7 +2907,7 @@ yylex()
} while (c = nextc()); } while (c = nextc());
pushback(c); pushback(c);
tokfix(); tokfix();
yylval.val = rb_str2inum(tok(), 2); yylval.val = rb_cstr2inum(tok(), 2);
return tINTEGER; return tINTEGER;
} }
if (c >= '0' && c <= '7' || c == '_') { if (c >= '0' && c <= '7' || c == '_') {
@ -2901,7 +2919,7 @@ yylex()
} while (c = nextc()); } while (c = nextc());
pushback(c); pushback(c);
tokfix(); tokfix();
yylval.val = rb_str2inum(tok(), 8); yylval.val = rb_cstr2inum(tok(), 8);
return tINTEGER; return tINTEGER;
} }
if (c > '7' && c <= '9') { if (c > '7' && c <= '9') {
@ -2977,7 +2995,7 @@ yylex()
yylval.val = rb_float_new(d); yylval.val = rb_float_new(d);
return tFLOAT; return tFLOAT;
} }
yylval.val = rb_str2inum(tok(), 10); yylval.val = rb_cstr2inum(tok(), 10);
return tINTEGER; return tINTEGER;
} }

4
prec.c
View file

@ -4,9 +4,9 @@
$Author$ $Author$
$Date$ $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
*************************************************/ *************************************************/

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Aug 10 14:30:50 JST 1993 created at: Tue Aug 10 14:30:50 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri Dec 24 16:39:21 JST 1993 created at: Fri Dec 24 16:39:21 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Aug 19 17:46:47 JST 1993 created at: Thu Aug 19 17:46:47 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

59
re.c
View file

@ -5,7 +5,7 @@
$Author$ $Author$
created at: Mon Aug 9 18:24:49 JST 1993 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 static VALUE
rb_reg_kcode_method(re) rb_reg_kcode_m(re)
VALUE re; VALUE re;
{ {
char *kcode = "$KCODE"; char *kcode = "$KCODE";
@ -382,21 +382,21 @@ match_alloc()
} }
static VALUE static VALUE
match_clone(orig) match_clone(match)
VALUE orig; VALUE match;
{ {
NEWOBJ(match, struct RMatch); NEWOBJ(clone, struct RMatch);
OBJSETUP(match, rb_cMatch, T_MATCH); OBJSETUP(clone, rb_cMatch, T_MATCH);
match->str = RMATCH(orig)->str; clone->str = RMATCH(match)->str;
match->regs = 0; clone->regs = 0;
match->regs = ALLOC(struct re_registers); clone->regs = ALLOC(struct re_registers);
match->regs->allocated = 0; clone->regs->allocated = 0;
re_copy_registers(match->regs, RMATCH(orig)->regs); re_copy_registers(clone->regs, RMATCH(match)->regs);
CLONESETUP(match, orig); CLONESETUP(clone, match);
return (VALUE)match; return (VALUE)clone;
} }
static VALUE static VALUE
@ -587,6 +587,7 @@ rb_reg_search(reg, str, pos, reverse)
"Stack overfow in regexp matcher", reg); "Stack overfow in regexp matcher", reg);
} }
if (result < 0) { if (result < 0) {
FL_UNSET(match, FL_TAINT);
matchcache = match; matchcache = match;
rb_backref_set(Qnil); rb_backref_set(Qnil);
} }
@ -595,6 +596,8 @@ rb_reg_search(reg, str, pos, reverse)
rb_backref_set(match); rb_backref_set(match);
} }
OBJ_INFECT(match, reg);
OBJ_INFECT(match, str);
return result; return result;
} }
@ -616,6 +619,7 @@ rb_reg_nth_match(nth, match)
int nth; int nth;
VALUE match; VALUE match;
{ {
VALUE str;
int start, end, len; int start, end, len;
if (NIL_P(match)) return Qnil; if (NIL_P(match)) return Qnil;
@ -626,7 +630,9 @@ rb_reg_nth_match(nth, match)
if (start == -1) return Qnil; if (start == -1) return Qnil;
end = RMATCH(match)->END(nth); end = RMATCH(match)->END(nth);
len = end - start; 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 VALUE
@ -745,6 +751,7 @@ match_to_s(match)
if (NIL_P(str)) str = rb_str_new(0,0); if (NIL_P(str)) str = rb_str_new(0,0);
if (OBJ_TAINTED(match)) OBJ_TAINT(str); if (OBJ_TAINTED(match)) OBJ_TAINT(str);
if (OBJ_TAINTED(RMATCH(match)->str)) OBJ_TAINT(str);
return str; return str;
} }
@ -913,7 +920,7 @@ rb_reg_match2(re)
} }
static VALUE static VALUE
rb_reg_match_method(re, str) rb_reg_match_m(re, str)
VALUE re, str; VALUE re, str;
{ {
VALUE result = rb_reg_match(re, str); VALUE result = rb_reg_match(re, str);
@ -967,7 +974,7 @@ rb_reg_s_new(argc, argv, self)
char *p; char *p;
int len; int len;
p = str2cstr(src, &len); p = rb_str2cstr(src, &len);
return rb_reg_new_1(self, p, len, flag); return rb_reg_new_1(self, p, len, flag);
} }
} }
@ -989,7 +996,7 @@ rb_reg_s_quote(argc, argv)
curr_kcode = reg_kcode; curr_kcode = reg_kcode;
reg_kcode = kcode_saved; reg_kcode = kcode_saved;
} }
s = str2cstr(str, &len); s = rb_str2cstr(str, &len);
send = s + len; send = s + len;
tmp = ALLOCA_N(char, len*2); tmp = ALLOCA_N(char, len*2);
t = tmp; t = tmp;
@ -1072,15 +1079,15 @@ rb_reg_options(re)
} }
static VALUE static VALUE
rb_reg_clone(orig) rb_reg_clone(reg)
VALUE orig;
{
VALUE reg; VALUE reg;
{
VALUE clone;
reg = rb_reg_new_1(CLASS_OF(orig), RREGEXP(orig)->str, RREGEXP(orig)->len, clone = rb_reg_new_1(CLASS_OF(reg), RREGEXP(reg)->str, RREGEXP(reg)->len,
rb_reg_options(orig)); rb_reg_options(reg));
CLONESETUP(reg, orig); CLONESETUP(clone, reg);
return reg; return clone;
} }
VALUE 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_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, "~", 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, "inspect", rb_reg_inspect, 0);
rb_define_method(rb_cRegexp, "source", rb_reg_source, 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, "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, "IGNORECASE", INT2FIX(RE_OPTION_IGNORECASE));
rb_define_const(rb_cRegexp, "EXTENDED", INT2FIX(RE_OPTION_EXTENDED)); rb_define_const(rb_cRegexp, "EXTENDED", INT2FIX(RE_OPTION_EXTENDED));

2
re.h
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Sep 30 14:18:32 JST 1993 created at: Thu Sep 30 14:18:32 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

10
ruby.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Aug 10 12:47:31 JST 1993 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)", "-0[octal] specify record separator (\\0, if no argument)",
"-a autosplit mode with -n or -p (splits $_ into $F)", "-a autosplit mode with -n or -p (splits $_ into $F)",
"-c check syntax only", "-c check syntax only",
"-Cdirectory cd to directory, before executing your script",
"-d set debugging flags (set $DEBUG to true)", "-d set debugging flags (set $DEBUG to true)",
"-e 'command' one line of script. Several -e's allowed. Omit [programfile]", "-e 'command' one line of script. Several -e's allowed. Omit [programfile]",
"-Fpattern split() pattern for autosplit (-a)", "-Fpattern split() pattern for autosplit (-a)",
@ -95,7 +96,6 @@ usage(name)
"-v enables verbose mode", "-v enables verbose mode",
"-w turn warnings on for compilation of your script", "-w turn warnings on for compilation of your script",
"-x[directory] strip off text before #!ruby line and perhaps cd to directory", "-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", "--copyright print the copyright",
"--version print the version", "--version print the version",
"\n", "\n",
@ -441,13 +441,17 @@ proc_options(argc, argv)
} }
break; break;
case 'C':
case 'X': case 'X':
s++; s++;
if (!*s) { if (!*s) {
s = argv[1]; s = argv[1];
argc--,argv++; 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); rb_fatal("Can't chdir to %s", s);
} }
break; break;

30
ruby.h
View file

@ -5,7 +5,7 @@
$Author$ $Author$
created at: Thu Jun 10 14:26:32 JST 1993 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 Qfalse 0
#define Qtrue 2 #define Qtrue 2
#define Qnil 4 #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 NIL_P(v) ((VALUE)(v) == Qnil)
#define CLASS_OF(v) rb_class_of((VALUE)(v)) #define CLASS_OF(v) rb_class_of((VALUE)(v))
@ -306,7 +307,7 @@ struct RBignum {
struct RBasic basic; struct RBasic basic;
char sign; char sign;
long len; long len;
unsigned short *digits; void *digits;
}; };
#define R_CAST(st) (struct st*) #define R_CAST(st) (struct st*)
@ -343,14 +344,17 @@ struct RBignum {
#define FL_UMASK (0xff<<FL_USHIFT) #define FL_UMASK (0xff<<FL_USHIFT)
#define FL_ABLE(x) (!(FIXNUM_P(x)||rb_special_const_p((VALUE)(x)))) #define SPECIAL_CONST_P(x) (FIXNUM_P((VALUE)x) || (VALUE)(x) <= Qundef)
#define FL_ABLE(x) (!SPECIAL_CONST_P(x))
#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0) #define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)
#define FL_SET(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) if(FL_ABLE(x)){RBASIC(x)->flags &= ~(f);} #define FL_UNSET(x,f) (FL_ABLE(x) && (RBASIC(x)->flags &= ~(f)))
#define FL_REVERSE(x,f) if(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_TAINTED(x) FL_TEST((x), FL_TAINT)
#define OBJ_TAINT(x) FL_SET((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 *xmalloc _((size_t));
void *xcalloc _((size_t,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__ VALUE rb_class_of _((VALUE));
extern __inline__ int rb_type _((VALUE)); extern __inline__ int rb_type _((VALUE));
extern __inline__ int rb_special_const_p _((VALUE)); extern __inline__ int rb_special_const_p _((VALUE));
extern __inline__ int rb_test_false_or_nil _((VALUE));
extern __inline__ VALUE extern __inline__ VALUE
rb_class_of(VALUE obj) rb_class_of(VALUE obj)
@ -529,23 +532,14 @@ rb_type(VALUE obj)
extern __inline__ int extern __inline__ int
rb_special_const_p(VALUE obj) rb_special_const_p(VALUE obj)
{ {
if (FIXNUM_P(obj)) return Qtrue; if (SPECIAL_CONST_P(obj)) return Qtrue;
if (obj == Qnil) return Qtrue;
if (obj == Qfalse) return Qtrue;
if (obj == Qtrue) return Qtrue;;
return Qfalse; return Qfalse;
} }
extern __inline__ int
rb_test_false_or_nil(VALUE v)
{
return (v != Qnil) && (v != Qfalse);
}
#else #else
VALUE rb_class_of _((VALUE)); VALUE rb_class_of _((VALUE));
int rb_type _((VALUE)); int rb_type _((VALUE));
int rb_special_const_p _((VALUE)); int rb_special_const_p _((VALUE));
int rb_test_false_or_nil _((VALUE));
#endif #endif
#include "intern.h" #include "intern.h"

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri Nov 12 16:47:09 JST 1993 created at: Fri Nov 12 16:47:09 JST 1993
Copyright (C) 1993-1999 Yukihiro Matsumoto Copyright (C) 1993-2000 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -31,7 +31,7 @@ for i in ifp = open(basename)
end end
ofp.write(i) ofp.write(i)
line = line + 1 line = line + 1
if line >= lines if line >= lines and !ifp.eof?
ofp.write("END--cut here--cut here\n") ofp.write("END--cut here--cut here\n")
ofp.close ofp.close
part = part + 1 part = part + 1

View file

@ -317,7 +317,7 @@ signal_exec(sig)
case SIGINT: case SIGINT:
rb_thread_interrupt(); rb_thread_interrupt();
break; break;
#ifndef NT #if !defined(NT) && !defined(__human68k__)
case SIGHUP: case SIGHUP:
#endif #endif
#ifdef SIGQUIT #ifdef SIGQUIT
@ -498,7 +498,7 @@ trap(arg)
if (func == SIG_DFL) { if (func == SIG_DFL) {
switch (sig) { switch (sig) {
case SIGINT: case SIGINT:
#ifndef NT #if !defined(NT) && !defined(__human68k__)
case SIGHUP: case SIGHUP:
#endif #endif
#ifdef SIGQUIT #ifdef SIGQUIT

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri Oct 15 10:39:26 JST 1993 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; return str;
} }
double rb_big2dbl _((VALUE));
#define FNONE 0 #define FNONE 0
#define FSHARP 1 #define FSHARP 1
#define FMINUS 2 #define FMINUS 2
@ -178,7 +176,7 @@ rb_f_sprintf(argc, argv)
fmt = GETARG(); fmt = GETARG();
if (OBJ_TAINTED(fmt)) tainted = 1; if (OBJ_TAINTED(fmt)) tainted = 1;
p = str2cstr(fmt, &blen); p = rb_str2cstr(fmt, &blen);
end = p + blen; end = p + blen;
blen = 0; blen = 0;
bsiz = 120; bsiz = 120;
@ -397,22 +395,22 @@ rb_f_sprintf(argc, argv)
bin_retry: bin_retry:
switch (TYPE(val)) { switch (TYPE(val)) {
case T_FIXNUM:
v = FIX2LONG(val);
break;
case T_FLOAT: case T_FLOAT:
val = rb_dbl2big(RFLOAT(val)->value); val = rb_dbl2big(RFLOAT(val)->value);
if (FIXNUM_P(val)) goto bin_retry; if (FIXNUM_P(val)) goto bin_retry;
bignum = 1; bignum = 1;
break; break;
case T_STRING: case T_STRING:
val = rb_str2inum(RSTRING(val)->ptr, 10); val = rb_str2inum(val, 0);
goto bin_retry; goto bin_retry;
case T_BIGNUM: case T_BIGNUM:
bignum = 1; bignum = 1;
break; break;
default: default:
Check_Type(val, T_FIXNUM); v = NUM2LONG(val);
break;
case T_FIXNUM:
v = FIX2LONG(val);
break; break;
} }
@ -616,7 +614,7 @@ rb_f_sprintf(argc, argv)
fval = strtod(RSTRING(val)->ptr, 0); fval = strtod(RSTRING(val)->ptr, 0);
break; break;
default: default:
Check_Type(val, T_FLOAT); fval = NUM2DBL(val);
break; break;
} }

2
st.c
View file

@ -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"; static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible";

2
st.h
View file

@ -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 */ /* @(#) st.h 5.1 89/12/14 */

109
string.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Mon Aug 9 17:12:58 JST 1993 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 <unistd.h> #include <unistd.h>
#endif #endif
#ifndef atof
double strtod();
#endif
VALUE rb_cString; VALUE rb_cString;
#define STR_FREEZE FL_USER1 #define STR_FREEZE FL_USER1
#define STR_NO_ORIG FL_USER3 #define STR_NO_ORIG FL_USER3
extern VALUE rb_rs; VALUE rb_fs;
VALUE VALUE
rb_str_new(ptr, len) rb_str_new(ptr, len)
@ -167,19 +163,19 @@ rb_obj_as_string(obj)
} }
static VALUE static VALUE
rb_str_clone(orig) rb_str_clone(str)
VALUE orig;
{
VALUE str; VALUE str;
{
VALUE clone;
if (RSTRING(orig)->orig && !FL_TEST(orig, STR_NO_ORIG)) if (RSTRING(str)->orig && !FL_TEST(str, STR_NO_ORIG))
str = rb_str_new3(RSTRING(orig)->orig); clone = rb_str_new3(RSTRING(str)->orig);
else else
str = rb_str_new(RSTRING(orig)->ptr, RSTRING(orig)->len); clone = rb_str_new(RSTRING(str)->ptr, RSTRING(str)->len);
if (RSTRING(orig)->orig && FL_TEST(orig, STR_NO_ORIG)) if (RSTRING(str)->orig && FL_TEST(str, STR_NO_ORIG))
RSTRING(str)->orig = RSTRING(orig)->orig; RSTRING(str)->orig = RSTRING(str)->orig;
CLONESETUP(str, orig); CLONESETUP(clone, str);
return str; return clone;
} }
VALUE VALUE
@ -454,7 +450,7 @@ rb_str_hash(str)
} }
static VALUE static VALUE
rb_str_hash_method(str) rb_str_hash_m(str)
VALUE str; VALUE str;
{ {
int key = rb_str_hash(str); int key = rb_str_hash(str);
@ -501,7 +497,7 @@ rb_str_equal(str1, str2)
} }
static VALUE static VALUE
rb_str_cmp_method(str1, str2) rb_str_cmp_m(str1, str2)
VALUE str1, str2; VALUE str1, str2;
{ {
int result; int result;
@ -570,7 +566,7 @@ rb_str_index(str, sub, offset)
} }
static VALUE static VALUE
rb_str_index_method(argc, argv, str) rb_str_index_m(argc, argv, str)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE str; VALUE str;
@ -782,7 +778,7 @@ rb_str_upto(beg, end, excl)
} }
static VALUE static VALUE
rb_str_upto_method(beg, end) rb_str_upto_m(beg, end)
VALUE beg, end; VALUE beg, end;
{ {
return rb_str_upto(beg, end, 0); return rb_str_upto(beg, end, 0);
@ -835,7 +831,7 @@ rb_str_aref(str, indx)
} }
static VALUE static VALUE
rb_str_aref_method(argc, argv, str) rb_str_aref_m(argc, argv, str)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE str; VALUE str;
@ -936,7 +932,7 @@ rb_str_aset(str, indx, val)
} }
static VALUE static VALUE
rb_str_aset_method(argc, argv, str) rb_str_aset_m(argc, argv, str)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE str; VALUE str;
@ -1067,12 +1063,14 @@ rb_str_gsub_bang(argc, argv, str)
int iter = 0; int iter = 0;
char *buf, *bp, *cp; char *buf, *bp, *cp;
int offset, blen, len; int offset, blen, len;
int tainted = 0;
if (argc == 1 && rb_iterator_p()) { if (argc == 1 && rb_iterator_p()) {
iter = 1; iter = 1;
} }
else if (argc == 2) { 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 { else {
rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc); rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc);
@ -1101,6 +1099,7 @@ rb_str_gsub_bang(argc, argv, str)
else { else {
val = rb_reg_regsub(repl, str, regs); val = rb_reg_regsub(repl, str, regs);
} }
if (OBJ_TAINTED(val)) tainted = 1;
len = (bp - buf) + (beg - offset) + RSTRING(val)->len + 3; len = (bp - buf) + (beg - offset) + RSTRING(val)->len + 3;
if (blen < len) { if (blen < len) {
while (blen < len) blen *= 2; while (blen < len) blen *= 2;
@ -1146,6 +1145,7 @@ rb_str_gsub_bang(argc, argv, str)
RSTRING(str)->ptr = buf; RSTRING(str)->ptr = buf;
RSTRING(str)->len = len = bp - buf; RSTRING(str)->len = len = bp - buf;
RSTRING(str)->ptr[len] = '\0'; RSTRING(str)->ptr[len] = '\0';
if (tainted) OBJ_TAINT(str);
return str; return str;
} }
@ -1162,7 +1162,7 @@ rb_str_gsub(argc, argv, str)
} }
static VALUE static VALUE
rb_str_replace_method(str, str2) rb_str_replace_m(str, str2)
VALUE str, str2; VALUE str, str2;
{ {
if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2); if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2);
@ -1299,7 +1299,7 @@ static VALUE
rb_str_to_i(str) rb_str_to_i(str)
VALUE str; VALUE str;
{ {
return rb_str2inum(RSTRING(str)->ptr, 10); return rb_str2inum(str, 10);
} }
static VALUE static VALUE
@ -1977,7 +1977,7 @@ rb_str_count(argc, argv, str)
} }
static VALUE static VALUE
rb_str_split_method(argc, argv, str) rb_str_split_m(argc, argv, str)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE str; VALUE str;
@ -2004,9 +2004,9 @@ rb_str_split_method(argc, argv, str)
char_sep = ' '; char_sep = ' ';
} }
else { else {
fs_set:
switch (TYPE(spat)) { switch (TYPE(spat)) {
case T_STRING: case T_STRING:
fs_set:
if (RSTRING(spat)->len == 1) { if (RSTRING(spat)->len == 1) {
char_sep = (unsigned char)RSTRING(spat)->ptr[0]; 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); if (TYPE(str) != T_STRING) str = rb_str_to_str(str);
sep = rb_str_new2(sep0); sep = rb_str_new2(sep0);
return rb_str_split_method(1, &sep, str); return rb_str_split_m(1, &sep, str);
} }
static VALUE static VALUE
@ -2131,7 +2131,7 @@ rb_f_split(argc, argv)
int argc; int argc;
VALUE *argv; VALUE *argv;
{ {
return rb_str_split_method(argc, argv, uscore_get()); return rb_str_split_m(argc, argv, uscore_get());
} }
static VALUE static VALUE
@ -2193,6 +2193,32 @@ rb_str_each_line(argc, argv, str)
return 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 static VALUE
rb_str_each_byte(str) rb_str_each_byte(str)
VALUE str; VALUE str;
@ -2431,7 +2457,7 @@ static VALUE
rb_str_hex(str) rb_str_hex(str)
VALUE str; VALUE str;
{ {
return rb_str2inum(RSTRING(str)->ptr, 16); return rb_str2inum(str, 16);
} }
static VALUE static VALUE
@ -2452,7 +2478,7 @@ rb_str_oct(str)
break; break;
} }
} }
return rb_str2inum(RSTRING(str)->ptr, base); return rb_str2inum(str, base);
} }
static VALUE static VALUE
@ -2597,16 +2623,16 @@ Init_String()
rb_define_singleton_method(rb_cString, "new", rb_str_s_new, 1); 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, "clone", rb_str_clone, 0);
rb_define_method(rb_cString, "dup", rb_str_dup, 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, "===", 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, "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_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 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_format, 1);
rb_define_method(rb_cString, "[]", rb_str_aref_method, -1); rb_define_method(rb_cString, "[]", rb_str_aref_m, -1);
rb_define_method(rb_cString, "[]=", rb_str_aset_method, -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, "length", rb_str_length, 0);
rb_define_method(rb_cString, "size", rb_str_length, 0); rb_define_method(rb_cString, "size", rb_str_length, 0);
rb_define_method(rb_cString, "empty?", rb_str_empty, 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, "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, 0);
rb_define_method(rb_cString, "next!", rb_str_succ_bang, 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, "upto", rb_str_upto_m, 1);
rb_define_method(rb_cString, "index", rb_str_index_method, -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, "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, "freeze", rb_str_freeze, 0);
rb_define_method(rb_cString, "frozen?", rb_str_frozen_p, 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_i", rb_str_to_i, 0);
rb_define_method(rb_cString, "to_f", rb_str_to_f, 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_s", rb_str_to_s, 0);
rb_define_method(rb_cString, "to_str", 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); 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, "hex", rb_str_hex, 0);
rb_define_method(rb_cString, "oct", rb_str_oct, 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, 0);
rb_define_method(rb_cString, "reverse!", rb_str_reverse_bang, 0); rb_define_method(rb_cString, "reverse!", rb_str_reverse_bang, 0);
rb_define_method(rb_cString, "concat", rb_str_concat, 1); 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); rb_define_global_function("split", rb_f_split, -1);
to_str = rb_intern("to_s"); 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);
} }

View file

@ -407,14 +407,14 @@ static VALUE
rb_struct_clone(s) rb_struct_clone(s)
VALUE s; VALUE s;
{ {
NEWOBJ(st, struct RStruct); NEWOBJ(clone, struct RStruct);
CLONESETUP(st, s); CLONESETUP(clone, s);
st->len = 0; /* avoid GC crashing */ clone->len = 0; /* avoid GC crashing */
st->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len); clone->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len);
st->len = RSTRUCT(s)->len; clone->len = RSTRUCT(s)->len;
MEMCPY(st->ptr, RSTRUCT(s)->ptr, VALUE, st->len); MEMCPY(clone->ptr, RSTRUCT(s)->ptr, VALUE, clone->len);
return (VALUE)st; return (VALUE)clone;
} }
static VALUE static VALUE

20
time.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Dec 28 14:31:59 JST 1993 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; VALUE obj;
{ {
if (TYPE(obj) == T_STRING) { if (TYPE(obj) == T_STRING) {
obj = rb_str2inum(RSTRING(obj)->ptr, 10); obj = rb_str2inum(obj, 10);
} }
return NUM2LONG(obj); return NUM2LONG(obj);
@ -470,15 +470,15 @@ static VALUE
time_clone(time) time_clone(time)
VALUE time; VALUE time;
{ {
VALUE obj; VALUE clone;
struct time_object *tobj, *newtobj; struct time_object *tobj, *tclone;
GetTimeval(time, tobj); GetTimeval(time, tobj);
obj = Data_Make_Struct(0, struct time_object, 0, free, newtobj); clone = Data_Make_Struct(0, struct time_object, 0, free, tclone);
CLONESETUP(obj, time); CLONESETUP(clone, time);
MEMCPY(newtobj, tobj, struct time_object, 1); MEMCPY(tclone, tobj, struct time_object, 1);
return obj; return clone;
} }
static VALUE static VALUE
@ -838,7 +838,7 @@ time_strftime(time, format)
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_get_tm(time, tobj->gmt); time_get_tm(time, tobj->gmt);
} }
fmt = str2cstr(format, &len); fmt = rb_str2cstr(format, &len);
if (len == 0) { if (len == 0) {
rb_warning("strftime called with empty format string"); rb_warning("strftime called with empty format string");
} }
@ -948,7 +948,7 @@ time_load(klass, str)
struct tm tm; struct tm tm;
int i; int i;
buf = str2cstr(str, &i); buf = rb_str2cstr(str, &i);
if (i != 8) { if (i != 8) {
rb_raise(rb_eTypeError, "marshaled time format differ"); rb_raise(rb_eTypeError, "marshaled time format differ");
} }

14
util.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri Mar 10 17:22:34 JST 1995 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) rb_special_const_p(obj)
VALUE obj; VALUE obj;
{ {
if (FIXNUM_P(obj)) return Qtrue; if (SPECIAL_CONST_P(obj)) return Qtrue;
if (obj == Qnil) return Qtrue;
if (obj == Qfalse) return Qtrue;
if (obj == Qtrue) return Qtrue;
return Qfalse; return Qfalse;
} }
int
rb_test_false_or_nil(v)
VALUE v;
{
return (v != Qnil) && (v != Qfalse);
}
#include "util.h" #include "util.h"
#ifndef HAVE_STRING_H #ifndef HAVE_STRING_H
char *strchr _((char*,char)); char *strchr _((char*,char));

2
util.h
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Mar 9 11:55:53 JST 1995 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 #ifndef UTIL_H

View file

@ -714,6 +714,18 @@ rb_alias_variable(name1, name2)
static int special_generic_ivar = 0; static int special_generic_ivar = 0;
static st_table *generic_iv_tbl; 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 static VALUE
generic_ivar_get(obj, id) generic_ivar_get(obj, id)
VALUE obj; VALUE obj;

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Sep 30 20:08:01 JST 1993 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 void
ruby_show_copyright() ruby_show_copyright()
{ {
printf("ruby - Copyright (C) 1993-1999 Yukihiro Matsumoto\n"); printf("ruby - Copyright (C) 1993-2000 Yukihiro Matsumoto\n");
exit(0); exit(0);
} }

View file

@ -18,7 +18,7 @@ LDFLAGS = $(CFLAGS) -Fm
#LDFLAGS = $(CFLAGS) -Fm #LDFLAGS = $(CFLAGS) -Fm
XLDFLAGS = XLDFLAGS =
#EXTLIBS = #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 MISSING = crypt.obj alloca.obj win32.obj isinf.obj isnan.obj
LDSHARED = LDSHARED =
DLDFLAGS = DLDFLAGS =

View file

@ -7,7 +7,7 @@ s%@FFLAGS@%%g
s%@DEFS@% 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 -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%@LDFLAGS@%%g
s%@LIBS@%advapi32.lib wsock32.lib%g s%@LIBS@%user32.lib advapi32.lib wsock32.lib%g
s%@exec_prefix@%${prefix}%g s%@exec_prefix@%${prefix}%g
s%@prefix@%/usr/local%g s%@prefix@%/usr/local%g
s%@program_transform_name@%s,x,x,%g s%@program_transform_name@%s,x,x,%g

View file

@ -495,7 +495,7 @@ mypopen (char *cmd, char *mode)
int p[2]; int p[2];
BOOL fRet; BOOL fRet;
HANDLE hInFile, hOutFile, hStdin, hStdout; HANDLE hInFile, hOutFile;
LPCSTR lpApplicationName = NULL; LPCSTR lpApplicationName = NULL;
LPTSTR lpCommandLine; LPTSTR lpCommandLine;
LPTSTR lpCmd2 = NULL; LPTSTR lpCmd2 = NULL;
@ -533,35 +533,14 @@ mypopen (char *cmd, char *mode)
aStartupInfo.dwFlags = STARTF_USESTDHANDLES; aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
if (reading) { if (reading) {
aStartupInfo.hStdInput = GetStdHandle(STD_OUTPUT_HANDLE);//hStdin; aStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
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.hStdOutput = hOutFile; aStartupInfo.hStdOutput = hOutFile;
} }
else { 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); dwCreationFlags = (NORMAL_PRIORITY_CLASS);
@ -587,24 +566,12 @@ mypopen (char *cmd, char *mode)
CloseHandle(aProcessInformation.hThread); CloseHandle(aProcessInformation.hThread);
if (reading) { if (reading) {
HANDLE hDummy;
fd = _open_osfhandle((long)hInFile, (_O_RDONLY | pipemode)); fd = _open_osfhandle((long)hInFile, (_O_RDONLY | pipemode));
CloseHandle(hOutFile); CloseHandle(hOutFile);
DuplicateHandle(GetCurrentProcess(), hStdout,
GetCurrentProcess(), &hDummy,
0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)
);
} }
else { else {
HANDLE hDummy;
fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode)); fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode));
CloseHandle(hInFile); CloseHandle(hInFile);
DuplicateHandle(GetCurrentProcess(), hStdin,
GetCurrentProcess(), &hDummy,
0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)
);
} }
if (fd == -1) if (fd == -1)
@ -1245,8 +1212,10 @@ opendir(char *filename)
// check to see if we\'ve got a directory // check to see if we\'ve got a directory
// //
if (stat (filename, &sbuf) < 0 || if ((stat (filename, &sbuf) < 0 ||
sbuf.st_mode & _S_IFDIR == 0) { sbuf.st_mode & _S_IFDIR == 0) &&
(!isalpha(filename[0]) || filename[1] != ':' || filename[2] != '\0' ||
((1 << (filename[0] & 0x5f) - 'A') & GetLogicalDrives()) == 0)) {
return NULL; return NULL;
} }
@ -1264,7 +1233,7 @@ opendir(char *filename)
strcpy(scanname, filename); strcpy(scanname, filename);
if (index("/\\", *(scanname + strlen(scanname) - 1)) == NULL) if (index("/\\:", *CharPrev(scanname, scanname + strlen(scanname))) == NULL)
strcat(scanname, "/*"); strcat(scanname, "/*");
else else
strcat(scanname, "*"); strcat(scanname, "*");
@ -1802,6 +1771,10 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
if (!NtSocketsInitialized++) { if (!NtSocketsInitialized++) {
StartSockets(); 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) { if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
errno = WSAGetLastError(); errno = WSAGetLastError();
switch (errno) { switch (errno) {

View file

@ -87,7 +87,7 @@
#undef leave #undef leave
#if defined(__cplusplus) #if defined(__cplusplus)
} extern "C++" {
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -103,7 +103,7 @@
#include <malloc.h> #include <malloc.h>
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { }
#endif #endif
#define UIDTYPE int #define UIDTYPE int