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/branches/ruby_1_3@409 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1999-03-24 08:52:35 +00:00
parent 1727010a3a
commit 35247a52ef
77 changed files with 6223 additions and 6114 deletions

249
ChangeLog
View file

@ -1,5 +1,254 @@
Wed Mar 24 13:06:43 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* io.c (next_argv): need to check type for ARGV.shift.
* eval.c (blk_copy_prev): need to preverse outer scope as well as
outer frames.
* parse.y (rb_compile_string): return can appear within eval().
Tue Mar 23 10:15:07 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
* configure.in: AC_C_CONST check added.
Tue Mar 23 02:07:35 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* time.c (time_plus): preserve gmt-mode for result.
Mon Mar 22 01:32:37 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (rb_eval): adjust line numbers before expression
interpolation within strings.
* eval.c (rb_eval): defined? returns nil for false condition.
* numeric.c (num_nonzero_p): returns nil for false condition.
Sat Mar 20 13:07:43 1999 Keiju Ishitsuka <keiju@rational.com>
* lib/weakref.rb: avoid leak for two weakrefs for one object.
Fri Mar 19 11:26:45 1999 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
* eval.c (ruby_run): needed to eval END{} on exit.
* eval.c (rb_exit): ditto.
Fri Mar 19 02:17:27 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* signal.c (Init_signal): handles terminating signals HUP, TERM,
QUIT, PIPE, etc.
Thu Mar 18 15:47:18 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* bignum.c (rb_big_and): bug in sign calculation.
* bignum.c (rb_big_or): ditto.
* io.c (rb_f_select): forgot to use to_io to retrieve IO, after
calling select(2).
Tue Mar 16 19:54:31 1999 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
* ext/extmk.rb.in: static linking cause infinite make loop.
Tue Mar 16 18:50:04 1999 Yoshida Masato <yoshidam@yoshidam.net>
* ext/socket/socket.c (tcp_s_gethostbyname): typo, not NUM2INT(),
but INT2NUM().
* ext/socket/socket.c (mkhostent): ditto.
Tue Mar 16 12:31:44 1999 Ryo HAYASAKA <hayasaka@cheer.u-aizu.ac.jp>
* file.c (utime_internal): suppress warning by const.
* time.c (time_gmtime): ditto.
Tue Mar 16 10:23:05 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* time.c (time_clone): Time object can be cloned.
Tue Mar 16 03:13:10 1999 Koji Arai <JCA02266@nifty.ne.jp>
* ruby.c (load_file): argv[argc] should be NULL.
Mon Mar 15 22:12:08 1999 Tadayoshi Funaba <tadf@kt.rim.or.jp>
* sprintf.c (rb_f_sprintf): typo in arg_num check at exit.
Mon Mar 15 16:42:22 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* array.c (rb_ary_dup): dup2 should copy class too.
Mon Mar 15 15:12:53 1999 Yasuhiro Fukuma <yasuf@big.or.jp>
* lib/mkmf.rb: install program relative path check.
Mon Mar 15 14:05:25 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* re.c (rb_reg_s_new): 2nd argument is now option.
Regexp::EXTENDED can be specified.
Fri Mar 12 10:47:49 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* string.c (rb_str_index): str.index("") should always match at
offset point.
* string.c (rb_str_upto): can specify end point exclusion.
* string.c (rb_str_index): negative offset.
* regex.c (re_match): begline should not match at the point
between a newline and end-of-string. endline neither.
* regex.c (re_compile_pattern): context_indep_anchors .
* parse.y (parse_regx): need not to push backslashes before
escaped characters.
* eval.c (rb_thread_join): re-raises exception within target.
Fri Mar 12 01:09:36 1999 Koji Arai <JCA02266@nifty.ne.jp>
* ext/readline/readline.c (readline_s_vi_editing_mode): wrong
number of arguments.
Fri Mar 12 02:12:50 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* pack.c (PACK_ITEM_ADJUST): "a".unpack("C3") => [97, nil, nil]
Thu Mar 11 18:23:50 1999 WATANABE Tetsuya <tetsu@jpn.hp.com>
* ext/socket/socket.c (Init_socket): UDPsocket was ommited.
Thu Mar 11 16:43:30 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* pack.c (PACK_LENGTH_ADJUST): push fixed number of items per
template to result array.
* pack.c (pack_unpack): I/N/C etc. push nil in the array for "".
Tue Mar 9 00:19:21 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* hash.c (ruby_unsetenv): use ruby_setenv(name, 0).
* hash.c (env_delete): ditto.
* string.c (rb_str_upto): do not check `beg<end' to generate
strings for the pattern like "a".upto("#a").
* range.c (range_each): treat strings as special case.
* range.c (range_each): no longer use upto for generic cases.
Sun Mar 7 14:21:32 1999 IKARASHI Akira <ikarashi@itlb.te.noda.sut.ac.jp>
* string.c (rb_str_index): wrong end point calculation.
Sat Mar 6 02:19:12 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* re.c (match_index): MatchingData#index(n) added.
* array.c (rb_ary_subseq): ary[n..-1] returns an sub-array unless
n is too small negative index.
* re.c (rb_reg_match_method): Regexp#match(str) added.
* array.c (rb_ary_indexes): understands ranges as indexes.
* re.c (match_size): MatchingData#size added.
Fri Mar 5 01:04:57 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* array.c (rb_ary_fill): modified for range.
* array.c (rb_ary_aset): a[n..m] revisited.
Thu Mar 4 14:23:29 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* string.c (rb_str_subseq): a[n..m] revisited.
* parse.y (method_call): allow Const::method{}.
* array.c (rb_ary_replace_method): should replace original array.
Thu Mar 4 02:30:22 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* configure.in: remove --disable-thread, thread feature is no
longer optional.
Thu Mar 4 00:32:17 1999 Yasuhiro Fukuma <yasuf@big.or.jp>
* parse.y (read_escape): wrong arguments for scan_oct,scan_hex.
Wed Mar 3 11:51:53 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* ext/socket/socket.c (Init_socket): rename class names as
TCPsocket -> TCPSocket etc.
Tue Mar 2 19:46:42 1999 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
* configure.in (LDSHARED): use gcc -Wl,-G for solaris with gcc.
Tue Mar 2 17:04:19 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (yylex): backslashes do not concatenate comment lines
anymore.
Mon Mar 1 14:05:12 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (rb_call0): adjust argv for optional arguments. super
without arguments emit superclasse method with the value from
optinal arguments. enabled as experiment.
Sun Feb 28 14:04:07 1999 WATANABE Hirofumi <eban@os.rim.or.jp>
* parse.y (nextc): backslash at the eof cause infinite loop
Sun Feb 28 11:01:26 1999 Tadayoshi Funaba <tadf@kt.rim.or.jp>
* time.c (make_time_t): month range check added.
Sat Feb 27 02:36:05 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* re.c (Init_Regexp): add escape as alias of quote.
* re.c (rb_reg_s_quote): char-code can be specified now.
Fri Feb 26 18:45:36 1999 Yasuhiro Fukuma <yasuf@big.or.jp>
* eval.c (error_print): bug for error message with newlines.
Fri Feb 26 12:00:04 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* time.c (make_time_t): future check modified to allow 1969-12-31
at certain timezone.
* time.c (time_arg): year >= 1000 should be past.
* version.c (Init_version): constant RELEASE_DATE added.
Fri Feb 26 01:08:30 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* string.c (rb_str_substr): returns nil for out-of-range access.
* array.c (rb_ary_subseq): returns nil for out-of-range access.
* array.c (rb_ary_store): negative index message has changed.
* string.c (rb_str_aset): reallocation needed.
* string.c (rb_str_aset): allow char append to the string.
Thu Feb 25 23:30:17 1999 Tadayoshi Funaba <tadf@kt.rim.or.jp>
* time.c (time_load): tm_year should be packed in 17 bits, not 18.
Thu Feb 25 12:50:25 1999 Yukihiro Matsumoto <matz@netlab.co.jp> Thu Feb 25 12:50:25 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* missing/dup2.c: replaced by public domain version.
* time.c (make_time_t): add `future check' in loops. * time.c (make_time_t): add `future check' in loops.
* object.c (rb_num2dbl): forbid implicit conversion from nil, or * object.c (rb_num2dbl): forbid implicit conversion from nil, or

View file

@ -148,9 +148,18 @@ crypt.o: @srcdir@/missing/crypt.c
dup2.o: @srcdir@/missing/dup2.c dup2.o: @srcdir@/missing/dup2.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/dup2.c $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/dup2.c
finite.o: @srcdir@/missing/finite.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/finite.c
flock.o: @srcdir@/missing/flock.c flock.o: @srcdir@/missing/flock.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/flock.c $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/flock.c
isinf.o: @srcdir@/missing/isinf.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/isinf.c
isnan.o: @srcdir@/missing/isnan.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/isnan.c
fnmatch.o: @srcdir@/missing/fnmatch.c fnmatch.o: @srcdir@/missing/fnmatch.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/fnmatch.c $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/fnmatch.c

View file

@ -1,6 +1,6 @@
.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995 .\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
This document explains how to make extention modules for Ruby. This document explains how to make extention libraries for Ruby.
1Basic knowledge 1Basic knowledge
@ -184,11 +184,6 @@ interpreter. Useful functions are listed below (not all):
2. Extend Ruby with C 2. Extend Ruby with C
原理的にRubyで書けることはCでも書けますRubyそのものがCで記
述されているんですから,当然といえば当然なんですけど.ここで
はRubyの拡張に使うことが多いだろうと予測される機能を中心に紹
介します.
2.1 Add new features to Ruby 2.1 Add new features to Ruby
You can add new features (classes, methods, etc.) to the Ruby You can add new features (classes, methods, etc.) to the Ruby
@ -422,7 +417,7 @@ The pointer to the structure will be assigned to the variable sval.
See example below for detail. See example below for detail.
4Example - Create dbm module 4¡¥Example - Creating dbm extension
OK, here's the example to make extension library. This is the OK, here's the example to make extension library. This is the
extension to access dbm. The full source is included in ext/ extension to access dbm. The full source is included in ext/
@ -448,17 +443,17 @@ You need to design the library features, before making it.
(4) write C code. (4) write C code.
拡張ライブラリ本体となるC言語のソースを書きますC言語のソー You need to write C code for your extension library. If your library
スがひとつの時には「モジュール名.c」を選ぶと良いでしょうC has only one source file, choosing ``LIBRARY.c'' as a file name is
言語のソースが複数の場合には逆に「モジュール名.c」というファ preferred. On the other hand, in case your library has prural source
イル名は避ける必要があります.オブジェクトファイルとモジュー files, avoid chooing ``LIBRARY.c'' for a file name. It may conflict
ル生成時に中間的に生成される「モジュール名.o」というファイル with intermediate file ``LIBRARY.o'' on some platforms.
とが衝突するからです.
Rubyは拡張ライブラリをロードする時に「Init_モジュール名」と Ruby will execute the initializing function named ``Init_LIBRARY'' in
いう関数を自動的に実行しますdbmモジュールの場合「Init_dbm」 the library. For exapmle, ``Init_dbm()'' will be executed when loading
です.この関数の中でクラス,モジュール,メソッド,定数などの the library.
定義を行いますdbm.cから一部引用します
Here's the example of an initializing function.
-- --
Init_dbm() Init_dbm()
@ -480,11 +475,7 @@ Init_dbm()
} }
-- --
DBMモジュールはdbmのデータと対応するオブジェクトになるはずで The dbm extension wrap dbm struct in C world using Data_Make_Struct.
すからCの世界のdbmをRubyの世界に取り込む必要があります
dbm.cではData_Make_Structを以下のように使っています
-- --
struct dbmdata { struct dbmdata {
@ -593,23 +584,27 @@ If there exists the file named extconf.rb, it will be executed to
generate Makefile. If not, compilation scheme try to generate generate Makefile. If not, compilation scheme try to generate
Makefile anyway. Makefile anyway.
extconf.rbはモジュールのコンパイルに必要な条件のチェックなど The extconf.rb is the file to check compilation condition etc. You
を行うことが目的ですextconf.rbの中では以下のRuby関数を使う need to put
ことが出来ます.
have_library(lib, func): ライブラリの存在チェック require 'mkmf'
have_func(func): 関数の存在チェック
have_header(header): ヘッダファイルの存在チェック
create_makefile(target): Makefileの生成
以下の変数を使うことができます. at the top of the file. You can use the funcitons below to check the
condition.
$CFLAGS: コンパイル時に追加的に指定するフラグ(-Iなど) have_library(lib, func): check whether library containing function exists.
$LDFLAGS: リンク時に追加的に指定するフラグ(-Lなど) have_func(func): check whether function exists
have_header(header): check whether header file exists
create_makefile(target): generate Makefile
モジュールをコンパイルする条件が揃わなず,そのモジュールはコ The value of variables below will affect Makefile.
ンパイルしない時にはcreate_makefileを呼ばなければMakefileは
生成されず,コンパイルも行われません. $CFLAGS: included in CFLAGS make variable (such as -I)
$LDFLAGS: included in LDFLAGS make variable (such as -L)
If compilation condition is not fulfilled, you do not call
``create_makefile''. Makefile will not generated, compilation will
not be done.
(6) prepare depend (optional) (6) prepare depend (optional)
@ -620,7 +615,7 @@ check dependency. You can make this file by invoking
It's no harm. Prepare it. It's no harm. Prepare it.
(7) MANIFESTファイルにファイル名を入れる (7) put file names into MANIFEST (optional)
% find * -type f -print > MANIFEST % find * -type f -print > MANIFEST
% vi MANIFEST % vi MANIFEST
@ -629,18 +624,30 @@ Append file names into MANIFEST. The compilation scheme requires
MANIFEST only to be exist. But, you'd better take this step to MANIFEST only to be exist. But, you'd better take this step to
distinguish required files. distinguish required files.
(8) make (8) generate Makefile
Rubyのディレクトリでmakeを実行するとMakefileを生成からmake Try generate Makefile by:
必要によってはそのモジュールのRubyへのリンクまで自動的に実行
してくれますextconf.rbを書き換えるなどしてMakefileの再生成 ruby extconf.rb
が必要な時はまたRubyディレクトリでmakeしてください
You don't need this step, if you put extension library under ext
directory of the ruby source tree. In that case, compilation of the
interpreter will do this step for you.
(9) make
Type
make
to compile your extension. You don't need this step neither, if you
put extension library under ext directory of the ruby source tree.
(9) debug (9) debug
You may need to rb_debug the module. The modules can be linked You may need to rb_debug the extension. The extensions can be linked
statically by adding directory name in the ext/Setup file, statically by adding directory name in the ext/Setup file, so that you
so that you can inspect the module by the debugger. can inspect the extension with the debugger.
(10) done, now you have the extension library (10) done, now you have the extension library
@ -648,12 +655,7 @@ You can do anything you want with your library. The author of Ruby
will not claim any restriction about your code depending Ruby API. will not claim any restriction about your code depending Ruby API.
Feel free to use, modify, distribute or sell your program. Feel free to use, modify, distribute or sell your program.
Appendix A. Rubyのソースコードの分類 Appendix A. Ruby source files overview
Rubyのソースはいくつかに分類することが出来ますこのうちクラ
スライブラリの部分は基本的に拡張ライブラリと同じ作り方になっ
ています.これらのソースは今までの説明でほとんど理解できると
思います.
ruby language core ruby language core
@ -865,7 +867,7 @@ argc,argv
数に対応する引数が与えられていない場合は変数にQnilが代入され 数に対応する引数が与えられていない場合は変数にQnilが代入され
る. る.
** Rubyメソッド呼び出し ** Invoking Ruby method
VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)

View file

@ -505,7 +505,7 @@ C
4例題 - dbmパッケージを作る 4例題 - dbmパッケージを作る
ここまでの説明でとりあえず拡張ライブラリは作れるはずです. ここまでの説明でとりあえず拡張ライブラリは作れるはずです.
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に Rubyのextディレクトリにすでに含まれているdbmライブラリを例に
して段階的に説明します. して段階的に説明します.
(1) ディレクトリを作る (1) ディレクトリを作る
@ -515,7 +515,7 @@ Ruby
Ruby 1.1からは任意のディレクトリでダイナミックライブラリを作 Ruby 1.1からは任意のディレクトリでダイナミックライブラリを作
ることができるようになりましたRubyに静的にリンクする場合に ることができるようになりましたRubyに静的にリンクする場合に
はRubyを展開したディレクトリの下extディレクトリの中に拡張 はRubyを展開したディレクトリの下extディレクトリの中に拡張
モジュール用のディレクトリを作る必要があります.名前は適当に ライブラリ用のディレクトリを作る必要があります.名前は適当に
選んで構いません. 選んで構いません.
(2) MANIFESTファイルを作る (2) MANIFESTファイルを作る
@ -542,14 +542,14 @@ MANIFEST
(4) Cコードを書く (4) Cコードを書く
拡張ライブラリ本体となるC言語のソースを書きますC言語のソー 拡張ライブラリ本体となるC言語のソースを書きますC言語のソー
スがひとつの時には「モジュール名.c」を選ぶと良いでしょうC スがひとつの時には「ライブラリ名.c」を選ぶと良いでしょうC
言語のソースが複数の場合には逆に「モジュール名.c」というファ 言語のソースが複数の場合には逆に「ライブラリ名.c」というファ
イル名は避ける必要があります.オブジェクトファイルとモジュー イル名は避ける必要があります.オブジェクトファイルとモジュー
ル生成時に中間的に生成される「モジュール名.o」というファイル ル生成時に中間的に生成される「ライブラリ名.o」というファイル
とが衝突するからです. とが衝突するからです.
Rubyは拡張ライブラリをロードする時に「Init_モジュール名」と Rubyは拡張ライブラリをロードする時に「Init_ライブラリ名」と
いう関数を自動的に実行しますdbmモジュールの場合「Init_dbm」 いう関数を自動的に実行しますdbmライブラリの場合「Init_dbm」
です.この関数の中でクラス,モジュール,メソッド,定数などの です.この関数の中でクラス,モジュール,メソッド,定数などの
定義を行いますdbm.cから一部引用します 定義を行いますdbm.cから一部引用します
@ -575,7 +575,7 @@ Init_dbm()
} }
-- --
DBMモジュールはdbmのデータと対応するオブジェクトになるはずで DBMライブラリはdbmのデータと対応するオブジェクトになるはずで
すからCの世界のdbmをRubyの世界に取り込む必要があります すからCの世界のdbmをRubyの世界に取り込む必要があります
@ -627,7 +627,7 @@ fdbm_delete(obj, keystr)
の引数となります. の引数となります.
引数の数が不定のものはCの配列で受けるものとRubyの配列で受け 引数の数が不定のものはCの配列で受けるものとRubyの配列で受け
るものとがありますdbmモジュールの中でCの配列で受けるもの るものとがありますdbmライブラリの中でCの配列で受けるもの
はDBMのクラスメソッドであるopen()です.これを実装している関 はDBMのクラスメソッドであるopen()です.これを実装している関
数fdbm_s_open()はこうなっています. 数fdbm_s_open()はこうなっています.
@ -685,9 +685,13 @@ C
(5) extconf.rbを用意する (5) extconf.rbを用意する
Makefileを作る場合の雛型になるextconf.rbというファイルを作り Makefileを作る場合の雛型になるextconf.rbというファイルを作り
ますextconf.rbはモジュールのコンパイルに必要な条件のチェッ ますextconf.rbはライブラリのコンパイルに必要な条件のチェッ
クなどを行うことが目的ですextconf.rbの中では以下のRuby関数 クなどを行うことが目的です.まず,
を使うことが出来ます.
require 'mkmf'
をextconf.rbの先頭に置きますextconf.rbの中では以下のRuby関
数を使うことが出来ます.
have_library(lib, func): ライブラリの存在チェック have_library(lib, func): ライブラリの存在チェック
have_func(func): 関数の存在チェック have_func(func): 関数の存在チェック
@ -699,15 +703,9 @@ Makefile
$CFLAGS: コンパイル時に追加的に指定するフラグ(-Iなど) $CFLAGS: コンパイル時に追加的に指定するフラグ(-Iなど)
$LDFLAGS: リンク時に追加的に指定するフラグ(-Lなど) $LDFLAGS: リンク時に追加的に指定するフラグ(-Lなど)
モジュールをコンパイルする条件が揃わなず,そのモジュールはコ ライブラリをコンパイルする条件が揃わず,そのライブラリをコン
ンパイルしない時にはcreate_makefileを呼ばなければMakefileは パイルしない時にはcreate_makefileを呼ばなければMakefileは生
生成されず,コンパイルも行われません. 成されず,コンパイルも行われません.
モジュールがRuby 1.1専用である場合には
require 'mkmf'
をextconf.rbの先頭に置くと便利でしょう
(6) dependを用意する (6) dependを用意する
@ -756,9 +754,9 @@ make
extconf.rbを書き換えるなどしてMakefileの再生成が必要な時はま extconf.rbを書き換えるなどしてMakefileの再生成が必要な時はま
たRubyディレクトリでmakeしてください たRubyディレクトリでmakeしてください
動的リンクライブラリはmake installでRubyライブラリのディレク 拡張ライブラリはmake installでRubyライブラリのディレクトリの
トリの下にコピーされますもしモジュールと協調して使うRubyで 下にコピーされますもし拡張ライブラリと協調して使うRubyで記
述されたプログラムがありRubyライブラリに置きたい場合には 述されたプログラムがありRubyライブラリに置きたい場合には
拡張ライブラリ用のディレクトリの下に lib というディレクトリ 拡張ライブラリ用のディレクトリの下に lib というディレクトリ
を作り,そこに 拡張子 .rb のファイルを置いておけば同時にイン を作り,そこに 拡張子 .rb のファイルを置いておけば同時にイン
ストールされます. ストールされます.
@ -1134,7 +1132,7 @@ extconf.rb
create_makefile(target) create_makefile(target)
拡張ライブラリ用のMakefileを生成するこの関数を呼ばなければ 拡張ライブラリ用のMakefileを生成するこの関数を呼ばなければ
そのモジュールはコンパイルされないtargetはモジュール名を表 そのライブラリはコンパイルされないtargetはモジュール名を表
す. す.
/* /*

1
ToDo
View file

@ -6,6 +6,7 @@ Language Spec.
* multiple return values, yield values. maybe imcompatible * multiple return values, yield values. maybe imcompatible
* cascading method invocation. * cascading method invocation.
* def Class#method .. end * def Class#method .. end
* exclusive range n...m (means n<=x<m).
Hacking Interpreter Hacking Interpreter

149
array.c
View file

@ -229,9 +229,10 @@ rb_ary_store(ary, idx, val)
{ {
rb_ary_modify(ary); rb_ary_modify(ary);
if (idx < 0) { if (idx < 0) {
idx = RARRAY(ary)->len + idx; idx += RARRAY(ary)->len;
if (idx < 0) { if (idx < 0) {
rb_raise(rb_eIndexError, "negative index of array"); rb_raise(rb_eIndexError, "index %d out of array",
idx - RARRAY(ary)->len);
} }
} }
@ -349,26 +350,22 @@ rb_ary_entry(ary, offset)
} }
static VALUE static VALUE
rb_ary_subseq(ary, beg, len) rb_ary_subary(ary, beg, len)
VALUE ary; VALUE ary;
int beg, len; int beg, len;
{ {
VALUE ary2; VALUE ary2;
if (len == 0) return rb_ary_new2(0); if (len < 0) return Qnil;
if (len < 0) { if (beg > RARRAY(ary)->len) return Qnil;
rb_raise(rb_eIndexError, "negative length %d", len); if (beg < 0) return Qnil;
}
if (beg < 0) {
len += beg;
beg = 0;
}
if (beg + len > RARRAY(ary)->len) { if (beg + len > RARRAY(ary)->len) {
len = RARRAY(ary)->len - beg; len = RARRAY(ary)->len - beg;
} }
if (len < 0) { if (len < 0) {
len = 0; len = 0;
} }
if (len == 0) return rb_ary_new2(0);
ary2 = rb_ary_new2(len); ary2 = rb_ary_new2(len);
MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr+beg, VALUE, len); MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr+beg, VALUE, len);
@ -377,41 +374,6 @@ rb_ary_subseq(ary, beg, len)
return ary2; return ary2;
} }
static VALUE
beg_len(range, begp, lenp, len)
VALUE range;
int *begp, *lenp, len;
{
int beg, end;
int b, e;
if (!rb_range_beg_end(range, &beg, &end)) return Qfalse;
b = beg; e = end;
if (beg < 0) {
beg = len + beg;
}
if (end < 0) {
end = len + end;
}
*begp = beg;
if (beg > end) {
if (e == -1) {
*lenp = 0;
return Qtrue;
}
rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", b, e);
}
if (beg > len) {
*lenp = 0;
}
else {
*lenp = end - beg + 1;
}
return Qtrue;
}
VALUE VALUE
rb_ary_aref(argc, argv, ary) rb_ary_aref(argc, argv, ary)
int argc; int argc;
@ -427,7 +389,7 @@ rb_ary_aref(argc, argv, ary)
if (beg < 0) { if (beg < 0) {
beg = RARRAY(ary)->len + beg; beg = RARRAY(ary)->len + beg;
} }
return rb_ary_subseq(ary, beg, len); return rb_ary_subary(ary, beg, len);
} }
/* special case - speeding up */ /* special case - speeding up */
@ -437,9 +399,16 @@ rb_ary_aref(argc, argv, ary)
else if (TYPE(arg1) == T_BIGNUM) { else if (TYPE(arg1) == T_BIGNUM) {
rb_raise(rb_eIndexError, "index too big"); rb_raise(rb_eIndexError, "index too big");
} }
else if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) { else {
/* check if idx is Range */ /* check if idx is Range */
return rb_ary_subseq(ary, beg, len); switch (rb_range_beg_len(arg1, &beg, &len, RARRAY(ary)->len, 0)) {
case Qfalse:
break;
case Qnil:
return Qnil;
default:
return rb_ary_subary(ary, beg, len);
}
} }
return rb_ary_entry(ary, NUM2INT(arg1)); return rb_ary_entry(ary, NUM2INT(arg1));
} }
@ -483,7 +452,12 @@ rb_ary_indexes(argc, argv, ary)
new_ary = rb_ary_new2(argc); new_ary = rb_ary_new2(argc);
for (i=0; i<argc; i++) { for (i=0; i<argc; i++) {
#if 0
rb_ary_store(new_ary, i, rb_ary_entry(ary, NUM2INT(argv[i]))); rb_ary_store(new_ary, i, rb_ary_entry(ary, NUM2INT(argv[i])));
#else
VALUE v = argv[i];
rb_ary_concat(new_ary, rb_ary_aref(1, &v, ary));
#endif
} }
return new_ary; return new_ary;
@ -494,22 +468,22 @@ rb_ary_replace(ary, beg, len, rpl)
VALUE ary, rpl; VALUE ary, rpl;
int beg, len; int beg, len;
{ {
if (len < 0) { if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len);
rb_raise(rb_eIndexError, "negative length %d", len); if (beg < 0) {
beg += RARRAY(ary)->len;
}
if (beg < 0) {
beg -= RARRAY(ary)->len;
rb_raise(rb_eIndexError, "index %d out of array", beg);
}
if (beg + len > RARRAY(ary)->len) {
len = RARRAY(ary)->len - beg;
} }
if (TYPE(rpl) != T_ARRAY) { if (TYPE(rpl) != T_ARRAY) {
rpl = rb_Array(rpl); rpl = rb_Array(rpl);
} }
if (beg + len < 0 || (beg < 0 && beg <= -len)) {
rb_raise(rb_eIndexError, "index %d out of range", beg);
}
if (beg < 0) {
len += beg;
beg = 0;
}
rb_ary_modify(ary); rb_ary_modify(ary);
if (beg >= RARRAY(ary)->len) { if (beg >= RARRAY(ary)->len) {
len = beg + RARRAY(rpl)->len; len = beg + RARRAY(rpl)->len;
@ -550,30 +524,18 @@ rb_ary_aset(argc, argv, ary)
VALUE ary; VALUE ary;
{ {
VALUE arg1, arg2, arg3; VALUE arg1, arg2, arg3;
int offset, beg, len; int offset, beg, end, len;
if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) { if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) {
beg = NUM2INT(arg1); rb_ary_replace(ary, NUM2INT(arg1), NUM2INT(arg2), arg3);
len = NUM2INT(arg2);
if (beg < 0) {
beg = RARRAY(ary)->len + beg;
}
#ifdef INABA
if (len < 0) return Qnil;
#endif
rb_ary_replace(ary, beg, len, arg3);
return arg3; return arg3;
} }
else if (FIXNUM_P(arg1)) { else if (FIXNUM_P(arg1)) {
offset = FIX2INT(arg1); offset = FIX2INT(arg1);
goto fixnum; goto fixnum;
} }
else if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) { else if (rb_range_beg_len(arg1, &beg, &len, RARRAY(ary)->len, 1)) {
/* check if idx is Range */ /* check if idx is Range */
#ifdef INABA
if (len < 0) return Qnil;
#endif
rb_ary_replace(ary, beg, len, arg2); rb_ary_replace(ary, beg, len, arg2);
return arg2; return arg2;
} }
@ -655,7 +617,7 @@ static VALUE
rb_ary_dup(ary) rb_ary_dup(ary)
VALUE ary; VALUE ary;
{ {
return rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr); return rb_ary_s_create(RARRAY(ary)->len, RARRAY(ary)->ptr, CLASS_OF(ary));
} }
static VALUE static VALUE
@ -758,11 +720,7 @@ rb_ary_to_s(ary)
return str; return str;
} }
#ifdef USE_THREAD
static ID inspect_key; static ID inspect_key;
#else
static VALUE inspect_tbl;
#endif
struct inspect_arg { struct inspect_arg {
VALUE (*func)(); VALUE (*func)();
@ -780,11 +738,9 @@ static VALUE
inspect_ensure(obj) inspect_ensure(obj)
VALUE obj; VALUE obj;
{ {
#ifdef USE_THREAD
VALUE inspect_tbl; VALUE inspect_tbl;
inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key); inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key);
#endif
rb_ary_pop(inspect_tbl); rb_ary_pop(inspect_tbl);
return 0; return 0;
} }
@ -796,7 +752,6 @@ rb_protect_inspect(func, obj, arg)
{ {
struct inspect_arg iarg; struct inspect_arg iarg;
#ifdef USE_THREAD
VALUE inspect_tbl; VALUE inspect_tbl;
if (!inspect_key) { if (!inspect_key) {
@ -807,12 +762,6 @@ 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);
} }
#else
if (!inspect_tbl) {
inspect_tbl = rb_ary_new();
rb_global_variable(&inspect_tbl);
}
#endif
rb_ary_push(inspect_tbl, obj); rb_ary_push(inspect_tbl, obj);
iarg.func = func; iarg.func = func;
iarg.arg1 = obj; iarg.arg1 = obj;
@ -824,15 +773,11 @@ VALUE
rb_inspecting_p(obj) rb_inspecting_p(obj)
VALUE obj; VALUE obj;
{ {
#ifdef USE_THREAD
VALUE inspect_tbl; VALUE inspect_tbl;
if (!inspect_key) return Qfalse; if (!inspect_key) return Qfalse;
inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key); inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key);
if (NIL_P(inspect_tbl)) return Qfalse; if (NIL_P(inspect_tbl)) return Qfalse;
#else
if (!inspect_tbl) return Qfalse;
#endif
return rb_ary_includes(inspect_tbl, obj); return rb_ary_includes(inspect_tbl, obj);
} }
@ -1054,7 +999,7 @@ rb_ary_replace_method(ary, ary2)
VALUE ary, ary2; VALUE ary, ary2;
{ {
ary2 = to_ary(ary2); ary2 = to_ary(ary2);
rb_ary_replace(ary, 0, RARRAY(ary2)->len, ary2); rb_ary_replace(ary, 0, RARRAY(ary)->len, ary2);
return ary; return ary;
} }
@ -1080,17 +1025,25 @@ rb_ary_fill(argc, argv, ary)
int beg, end, len; int beg, end, len;
VALUE *p, *pend; VALUE *p, *pend;
if (rb_scan_args(argc, argv, "12", &item, &arg1, &arg2) == 2 && rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
beg_len(arg1, &beg, &len, RARRAY(ary)->len)) { switch (argc) {
/* beg and len set already */ case 1:
} beg = 0;
else { len = RARRAY(ary)->len - beg;
break;
case 2:
if (rb_range_beg_len(arg1, &beg, &len, RARRAY(ary)->len, 1)) {
break;
}
/* fall through */
case 3:
beg = NIL_P(arg1)?0:NUM2INT(arg1); beg = NIL_P(arg1)?0:NUM2INT(arg1);
if (beg < 0) { if (beg < 0) {
beg = RARRAY(ary)->len + beg; beg = RARRAY(ary)->len + beg;
if (beg < 0) beg = 0; if (beg < 0) beg = 0;
} }
len = NIL_P(arg2)?RARRAY(ary)->len - beg:NUM2INT(arg2); len = NIL_P(arg2)?RARRAY(ary)->len - beg:NUM2INT(arg2);
break;
} }
rb_ary_modify(ary); rb_ary_modify(ary);
end = beg + len; end = beg + len;

View file

@ -165,7 +165,7 @@ rb_int2inum(n)
VALUE VALUE
rb_str2inum(str, base) rb_str2inum(str, base)
char *str; const char *str;
int base; int base;
{ {
char sign = 1, c; char sign = 1, c;
@ -1000,7 +1000,7 @@ rb_big_and(x, y)
ds2 = BDIGITS(y); ds2 = BDIGITS(y);
sign = RBIGNUM(x)->sign; sign = RBIGNUM(x)->sign;
} }
z = bignew(l2, RBIGNUM(x)->sign && RBIGNUM(y)->sign); z = bignew(l2, RBIGNUM(x)->sign || RBIGNUM(y)->sign);
zds = BDIGITS(z); zds = BDIGITS(z);
for (i=0; i<l1; i++) { for (i=0; i<l1; i++) {
@ -1051,7 +1051,7 @@ rb_big_or(x, y)
ds2 = BDIGITS(y); ds2 = BDIGITS(y);
sign = RBIGNUM(x)->sign; sign = RBIGNUM(x)->sign;
} }
z = bignew(l2, RBIGNUM(x)->sign || RBIGNUM(y)->sign); z = bignew(l2, RBIGNUM(x)->sign && RBIGNUM(y)->sign);
zds = BDIGITS(z); zds = BDIGITS(z);
for (i=0; i<l1; i++) { for (i=0; i<l1; i++) {

32
class.c
View file

@ -105,7 +105,7 @@ rb_define_class_id(id, super)
VALUE VALUE
rb_define_class(name, super) rb_define_class(name, super)
char *name; const char *name;
VALUE super; VALUE super;
{ {
VALUE klass; VALUE klass;
@ -122,7 +122,7 @@ rb_define_class(name, super)
VALUE VALUE
rb_define_class_under(outer, name, super) rb_define_class_under(outer, name, super)
VALUE outer; VALUE outer;
char *name; const char *name;
VALUE super; VALUE super;
{ {
VALUE klass; VALUE klass;
@ -164,7 +164,7 @@ rb_define_module_id(id)
VALUE VALUE
rb_define_module(name) rb_define_module(name)
char *name; const char *name;
{ {
VALUE module; VALUE module;
ID id; ID id;
@ -179,7 +179,7 @@ rb_define_module(name)
VALUE VALUE
rb_define_module_under(outer, name) rb_define_module_under(outer, name)
VALUE outer; VALUE outer;
char *name; const char *name;
{ {
VALUE module; VALUE module;
ID id; ID id;
@ -462,7 +462,7 @@ rb_define_method_id(klass, name, func, argc)
void void
rb_define_method(klass, name, func, argc) rb_define_method(klass, name, func, argc)
VALUE klass; VALUE klass;
char *name; const char *name;
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
@ -476,7 +476,7 @@ rb_define_method(klass, name, func, argc)
void void
rb_define_protected_method(klass, name, func, argc) rb_define_protected_method(klass, name, func, argc)
VALUE klass; VALUE klass;
char *name; const char *name;
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
@ -487,7 +487,7 @@ rb_define_protected_method(klass, name, func, argc)
void void
rb_define_private_method(klass, name, func, argc) rb_define_private_method(klass, name, func, argc)
VALUE klass; VALUE klass;
char *name; const char *name;
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
@ -498,7 +498,7 @@ rb_define_private_method(klass, name, func, argc)
void void
rb_undef_method(klass, name) rb_undef_method(klass, name)
VALUE klass; VALUE klass;
char *name; const char *name;
{ {
rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF); rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
} }
@ -521,7 +521,7 @@ rb_singleton_class(obj)
void void
rb_define_singleton_method(obj, name, func, argc) rb_define_singleton_method(obj, name, func, argc)
VALUE obj; VALUE obj;
char *name; const char *name;
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
@ -531,7 +531,7 @@ rb_define_singleton_method(obj, name, func, argc)
void void
rb_define_module_function(module, name, func, argc) rb_define_module_function(module, name, func, argc)
VALUE module; VALUE module;
char *name; const char *name;
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
@ -541,7 +541,7 @@ rb_define_module_function(module, name, func, argc)
void void
rb_define_global_function(name, func, argc) rb_define_global_function(name, func, argc)
char *name; const char *name;
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
@ -551,7 +551,7 @@ rb_define_global_function(name, func, argc)
void void
rb_define_alias(klass, name1, name2) rb_define_alias(klass, name1, name2)
VALUE klass; VALUE klass;
char *name1, *name2; const char *name1, *name2;
{ {
rb_alias(klass, rb_intern(name1), rb_intern(name2)); rb_alias(klass, rb_intern(name1), rb_intern(name2));
} }
@ -559,7 +559,7 @@ rb_define_alias(klass, name1, name2)
void void
rb_define_attr(klass, name, read, write) rb_define_attr(klass, name, read, write)
VALUE klass; VALUE klass;
char *name; const char *name;
int read, write; int read, write;
{ {
rb_attr(klass, rb_intern(name), read, write, Qfalse); rb_attr(klass, rb_intern(name), read, write, Qfalse);
@ -575,17 +575,17 @@ rb_define_attr(klass, name, read, write)
int int
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_scan_args(int argc, VALUE *argv, char *fmt, ...) rb_scan_args(int argc, VALUE *argv, const char *fmt, ...)
#else #else
rb_scan_args(argc, argv, fmt, va_alist) rb_scan_args(argc, argv, fmt, va_alist)
int argc; int argc;
VALUE *argv; VALUE *argv;
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
int n, i; int n, i;
char *p = fmt; const char *p = fmt;
VALUE *var; VALUE *var;
va_list vargs; va_list vargs;

564
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -25,15 +25,6 @@ then
(it is also a good idea to do 'make clean' before compiling)) (it is also a good idea to do 'make clean' before compiling))
fi fi
dnl checks for thread
rb_thread=yes
AC_ARG_ENABLE(thread, [--disable-thread never use user-level thread], [
rb_thread=$enableval
])
if test $rb_thread = yes; then
AC_DEFINE(USE_THREAD)
fi
AC_CANONICAL_HOST AC_CANONICAL_HOST
dnl checks for fat-binary dnl checks for fat-binary
@ -194,8 +185,8 @@ AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd\
setruid seteuid setreuid setrgid setegid setregid\ setruid seteuid setreuid setrgid setegid setregid\
getpgrp setpgrp getpgid setpgid getgroups getpriority\ getpgrp setpgrp getpgid setpgid getgroups getpriority\
dlopen sigprocmask sigaction _setjmp setsid) dlopen sigprocmask sigaction _setjmp setsid)
AC_STRUCT_TIMEZONE
if test "$ac_cv_func_strftime" = no; then if test "$ac_cv_func_strftime" = no; then
AC_STRUCT_TIMEZONE
AC_TRY_LINK([], AC_TRY_LINK([],
[extern int daylight; int i = daylight;], AC_DEFINE(HAVE_DAYLIGHT)) [extern int daylight; int i = daylight;], AC_DEFINE(HAVE_DAYLIGHT))
fi fi
@ -265,6 +256,7 @@ main()
test $rb_cv_func_strtod = no && LIBOBJS="$LIBOBJS strtod.o" test $rb_cv_func_strtod = no && LIBOBJS="$LIBOBJS strtod.o"
AC_C_BIGENDIAN AC_C_BIGENDIAN
AC_C_CONST
AC_CHAR_UNSIGNED AC_CHAR_UNSIGNED
AC_CACHE_CHECK(whether right shift preserve sign bit, rb_cv_rshift_sign, AC_CACHE_CHECK(whether right shift preserve sign bit, rb_cv_rshift_sign,
@ -384,8 +376,12 @@ if test "$with_dln_a_out" != yes; then
LDSHARED='ld -b' LDSHARED='ld -b'
LDFLAGS="-Wl,-E" LDFLAGS="-Wl,-E"
rb_cv_dlopen=yes;; rb_cv_dlopen=yes;;
solaris*) LDSHARED='ld -G' solaris*) if test "$GCC" = yes; then
test "$GCC" = yes && `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E" LDSHARED='gcc -Wl,-G'
`$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E"
else
LDSHARED='ld -G'
fi
rb_cv_dlopen=yes;; rb_cv_dlopen=yes;;
sunos*) LDSHARED='ld -assert nodefinitions' sunos*) LDSHARED='ld -assert nodefinitions'
rb_cv_dlopen=yes;; rb_cv_dlopen=yes;;
@ -395,6 +391,8 @@ if test "$with_dln_a_out" != yes; then
rb_cv_dlopen=yes;; rb_cv_dlopen=yes;;
esix*|uxpds*) LDSHARED="ld -G" esix*|uxpds*) LDSHARED="ld -G"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
osf*) LDSHARED="gcc -shared"
rb_cv_dlopen=yes ;;
linux*) LDSHARED="gcc -shared" linux*) LDSHARED="gcc -shared"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
freebsd*) LDSHARED="gcc -shared" freebsd*) LDSHARED="gcc -shared"
@ -433,7 +431,8 @@ if test "$with_dln_a_out" != yes; then
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
human*) DLDFLAGS='' human*) DLDFLAGS=''
LDSHARED='' LDSHARED=''
LDFLAGS='' ;; LDFLAGS=''
rb_cv_dlopen=yes ;;
beos*) case "$host_cpu" in beos*) case "$host_cpu" in
powerpc*) powerpc*)
LDSHARED="ld -xms" LDSHARED="ld -xms"
@ -445,10 +444,10 @@ 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='../../miniruby ../cygwin32_ld.rb' ;; cygwin*) LDSHARED='../../miniruby ../cygwin32_ld.rb'
rb_cv_dlopen=yes ;;
*) LDSHARED='ld' ;; *) LDSHARED='ld' ;;
esac esac
AC_MSG_RESULT($rb_cv_dlopen) AC_MSG_RESULT($rb_cv_dlopen)
@ -678,26 +677,27 @@ test "$program_suffix" != NONE &&
ri_suffix=$program_suffix ri_suffix=$program_suffix
RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}" RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}"
#RUBY_LIB_PATH="${prefix}/lib/${RUBY_INSTALL_NAME}/${MAJOR}.${MINOR}"
RUBY_LIB_PATH="${prefix}/lib/ruby/${MAJOR}.${MINOR}" RUBY_LIB_PATH="${prefix}/lib/ruby/${MAJOR}.${MINOR}"
AC_DEFINE_UNQUOTED(RUBY_LIB, "${RUBY_LIB_PATH}") AC_DEFINE_UNQUOTED(RUBY_LIB, "${RUBY_LIB_PATH}")
AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${RUBY_LIB_PATH}/site_ruby") RUBY_SITE_LIB_PATH="${RUBY_LIB_PATH}/site_ruby"
AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${RUBY_SITE_LIB_PATH}")
AC_SUBST(arch)dnl AC_SUBST(arch)dnl
if test "$fat_binary" = yes ; then if test "$fat_binary" = yes ; then
arch="fat-${host_os}" arch="fat-${host_os}"
AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB, AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB,
"${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}" ) "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}")
AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB, AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB,
"${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}" ) "${RUBY_SITE_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${host_os}")
else else
arch="${host_cpu}-${host_os}" arch="${host_cpu}-${host_os}"
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}")
AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${RUBY_LIB_PATH}/site_ruby/${arch}") AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${RUBY_SITE_LIB_PATH}/${arch}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}")
echo "creating config.h" echo "creating config.h"
cat confdefs.h > config.h cat confdefs.h > config.h

45
dln.c
View file

@ -56,7 +56,9 @@ void *xrealloc();
#endif #endif
#ifndef NT #ifndef NT
# ifndef strdup
char *strdup(); char *strdup();
# endif
char *getenv(); char *getenv();
#endif #endif
@ -88,7 +90,8 @@ int eaccess();
static void static void
init_funcname(buf, file) init_funcname(buf, file)
char *buf, *file; char *buf;
char *file;
{ {
char *p, *slash; char *p, *slash;
@ -316,7 +319,7 @@ sym_hash(hdrp, syms)
static int static int
dln_init(prog) dln_init(prog)
char *prog; const char *prog;
{ {
char *file; char *file;
int fd; int fd;
@ -424,7 +427,7 @@ load_text_data(fd, hdrp, bss, disp)
} }
static int static int
underb_f_print(key, value) undef_print(key, value)
char *key, *value; char *key, *value;
{ {
fprintf(stderr, " %s\n", key); fprintf(stderr, " %s\n", key);
@ -435,7 +438,7 @@ static void
dln_print_undef() dln_print_undef()
{ {
fprintf(stderr, " Undefined symbols:\n"); fprintf(stderr, " Undefined symbols:\n");
st_foreach(undef_tbl, underb_f_print, NULL); st_foreach(undef_tbl, undef_print, NULL);
} }
static void static void
@ -463,7 +466,7 @@ struct undef {
static st_table *reloc_tbl = NULL; static st_table *reloc_tbl = NULL;
static void static void
link_undef(name, base, reloc) link_undef(name, base, reloc)
char *name; const char *name;
long base; long base;
struct relocation_info *reloc; struct relocation_info *reloc;
{ {
@ -563,7 +566,7 @@ reloc_undef(no, undef, arg)
static void static void
unlink_undef(name, value) unlink_undef(name, value)
char *name; const char *name;
long value; long value;
{ {
struct reloc_arg arg; struct reloc_arg arg;
@ -596,7 +599,7 @@ static int
load_1(fd, disp, need_init) load_1(fd, disp, need_init)
int fd; int fd;
long disp; long disp;
char *need_init; const char *need_init;
{ {
static char *libc = LIBC_NAME; static char *libc = LIBC_NAME;
struct exec hdr; struct exec hdr;
@ -874,7 +877,7 @@ load_1(fd, disp, need_init)
static int target_offset; static int target_offset;
static int static int
search_undef(key, value, lib_tbl) search_undef(key, value, lib_tbl)
char *key; const char *key;
int value; int value;
st_table *lib_tbl; st_table *lib_tbl;
{ {
@ -894,7 +897,7 @@ char *dln_librrb_ary_path = DLN_DEFAULT_LIB_PATH;
static int static int
load_lib(lib) load_lib(lib)
char *lib; const char *lib;
{ {
char *path, *file; char *path, *file;
char armagic[SARMAG]; char armagic[SARMAG];
@ -1031,7 +1034,7 @@ load_lib(lib)
static int static int
load(file) load(file)
char *file; const char *file;
{ {
int fd; int fd;
int result; int result;
@ -1057,7 +1060,7 @@ load(file)
void* void*
dln_sym(name) dln_sym(name)
char *name; const char *name;
{ {
struct nlist *sym; struct nlist *sym;
@ -1100,7 +1103,7 @@ dln_sym(name)
#include <windows.h> #include <windows.h>
#endif #endif
static char * static const char *
dln_strerror() dln_strerror()
{ {
#ifdef USE_DLN_A_OUT #ifdef USE_DLN_A_OUT
@ -1153,7 +1156,7 @@ dln_strerror()
#if defined(_AIX) #if defined(_AIX)
static void static void
aix_loaderror(char *pathname) aix_loaderror(const char *pathname)
{ {
char *message[8], errbuf[1024]; char *message[8], errbuf[1024];
int i,j; int i,j;
@ -1201,7 +1204,7 @@ aix_loaderror(char *pathname)
void void
dln_load(file) dln_load(file)
char *file; const char *file;
{ {
#ifdef _WIN32 #ifdef _WIN32
HINSTANCE handle; HINSTANCE handle;
@ -1497,8 +1500,8 @@ static char *dln_find_1();
char * char *
dln_find_exe(fname, path) dln_find_exe(fname, path)
char *fname; const char *fname;
char *path; const char *path;
{ {
if (!path) { if (!path) {
#if defined(__human68k__) #if defined(__human68k__)
@ -1520,8 +1523,8 @@ dln_find_exe(fname, path)
char * char *
dln_find_file(fname, path) dln_find_file(fname, path)
char *fname; const char *fname;
char *path; const char *path;
{ {
#ifndef __MACOS__ #ifndef __MACOS__
if (!path) path = "."; if (!path) path = ".";
@ -1533,10 +1536,10 @@ dln_find_file(fname, path)
} }
#if defined(__CYGWIN32__) #if defined(__CYGWIN32__)
char * const char *
conv_to_posix_path(win32, posix) conv_to_posix_path(win32, posix)
char *win32; const char *win32;
char *posix; const char *posix;
{ {
char *first = win32; char *first = win32;
char *p = win32; char *p = win32;

7
dln.h
View file

@ -14,17 +14,18 @@
#ifndef _ #ifndef _
#ifndef __STDC__ #ifndef __STDC__
# define _(args) () # define _(args) ()
# define const
#else #else
# define _(args) args # define _(args) args
#endif #endif
#endif #endif
char *dln_find_exe _((char*,char*)); char *dln_find_exe _((const char*,const char*));
char *dln_find_file _((char*,char*)); char *dln_find_file _((const char*,const char*));
#ifdef USE_DLN_A_OUT #ifdef USE_DLN_A_OUT
extern char *dln_argv0; extern char *dln_argv0;
#endif #endif
void dln_load _((char*)); void dln_load _((const char*));
#endif #endif

57
error.c
View file

@ -45,10 +45,10 @@ err_snprintf(buf, len, fmt, args)
} }
} }
static void err_append _((char*)); static void err_append _((const char*));
static void static void
err_print(fmt, args) err_print(fmt, args)
char *fmt; const char *fmt;
va_list args; va_list args;
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
@ -59,10 +59,10 @@ err_print(fmt, args)
void void
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_compile_error(char *fmt, ...) rb_compile_error(const char *fmt, ...)
#else #else
rb_compile_error(fmt, va_alist) rb_compile_error(fmt, va_alist)
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
@ -76,10 +76,10 @@ rb_compile_error(fmt, va_alist)
void void
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_compile_error_append(char *fmt, ...) rb_compile_error_append(const char *fmt, ...)
#else #else
rb_compile_error_append(fmt, va_alist) rb_compile_error_append(fmt, va_alist)
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
@ -94,10 +94,10 @@ rb_compile_error_append(fmt, va_alist)
void void
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_warn(char *fmt, ...) rb_warn(const char *fmt, ...)
#else #else
rb_warn(fmt, va_alist) rb_warn(fmt, va_alist)
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
@ -114,10 +114,10 @@ rb_warn(fmt, va_alist)
/* rb_warning() reports only in verbose mode */ /* rb_warning() reports only in verbose mode */
void void
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_warning(char *fmt, ...) rb_warning(const char *fmt, ...)
#else #else
rb_warning(fmt, va_alist) rb_warning(fmt, va_alist)
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
@ -135,10 +135,10 @@ rb_warning(fmt, va_alist)
void void
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_bug(char *fmt, ...) rb_bug(const char *fmt, ...)
#else #else
rb_bug(fmt, va_alist) rb_bug(fmt, va_alist)
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
@ -156,7 +156,7 @@ rb_bug(fmt, va_alist)
static struct types { static struct types {
int type; int type;
char *name; const char *name;
} builtin_types[] = { } builtin_types[] = {
T_NIL, "nil", T_NIL, "nil",
T_OBJECT, "Object", T_OBJECT, "Object",
@ -220,7 +220,10 @@ rb_check_type(x, t)
#include <errno.h> #include <errno.h>
VALUE rb_eException; VALUE rb_eException;
VALUE rb_eSystemExit, rb_eInterrupt, rb_eFatal; VALUE rb_eSystemExit;
VALUE rb_eInterrupt;
VALUE rb_eSignal;
VALUE rb_eFatal;
VALUE rb_eStandardError; VALUE rb_eStandardError;
VALUE rb_eRuntimeError; VALUE rb_eRuntimeError;
VALUE rb_eSyntaxError; VALUE rb_eSyntaxError;
@ -238,7 +241,7 @@ VALUE rb_mErrno;
VALUE VALUE
rb_exc_new(etype, ptr, len) rb_exc_new(etype, ptr, len)
VALUE etype; VALUE etype;
char *ptr; const char *ptr;
int len; int len;
{ {
VALUE exc = rb_obj_alloc(etype); VALUE exc = rb_obj_alloc(etype);
@ -250,7 +253,7 @@ rb_exc_new(etype, ptr, len)
VALUE VALUE
rb_exc_new2(etype, s) rb_exc_new2(etype, s)
VALUE etype; VALUE etype;
char *s; const char *s;
{ {
return rb_exc_new(etype, s, strlen(s)); return rb_exc_new(etype, s, strlen(s));
} }
@ -436,7 +439,7 @@ extern int sys_nerr;
static VALUE static VALUE
set_syserr(i, name) set_syserr(i, name)
int i; int i;
char *name; const char *name;
{ {
#ifdef __BEOS__ #ifdef __BEOS__
VALUE *list; VALUE *list;
@ -509,8 +512,10 @@ Init_Exception()
rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1); rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
rb_eSystemExit = rb_define_class("SystemExit", rb_eException); rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
rb_eFatal = rb_define_class("fatal", rb_eException); rb_eFatal = rb_define_class("fatal", rb_eException);
rb_eInterrupt = rb_define_class("Interrupt", rb_eException); rb_eInterrupt = rb_define_class("Interrupt", rb_eException);
rb_eInterrupt = rb_define_class("Interrupt", rb_eException);
rb_eSignal = rb_define_class("SignalException", rb_eException);
rb_eStandardError = rb_define_class("StandardError", rb_eException); rb_eStandardError = rb_define_class("StandardError", rb_eException);
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eStandardError); rb_eSyntaxError = rb_define_class("SyntaxError", rb_eStandardError);
@ -529,11 +534,11 @@ Init_Exception()
void void
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_raise(VALUE exc, char *fmt, ...) rb_raise(VALUE exc, const char *fmt, ...)
#else #else
rb_raise(exc, fmt, va_alist) rb_raise(exc, fmt, va_alist)
VALUE exc; VALUE exc;
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
@ -548,10 +553,10 @@ rb_raise(exc, fmt, va_alist)
void void
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_loaderror(char *fmt, ...) rb_loaderror(const char *fmt, ...)
#else #else
rb_loaderror(fmt, va_alist) rb_loaderror(fmt, va_alist)
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
@ -574,10 +579,10 @@ rb_notimplement()
void void
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_fatal(char *fmt, ...) rb_fatal(const char *fmt, ...)
#else #else
rb_fatal(fmt, va_alist) rb_fatal(fmt, va_alist)
char *fmt; const char *fmt;
va_dcl va_dcl
#endif #endif
{ {
@ -594,7 +599,7 @@ rb_fatal(fmt, va_alist)
void void
rb_sys_fail(mesg) rb_sys_fail(mesg)
char *mesg; const char *mesg;
{ {
#ifndef NT #ifndef NT
char *strerror(); char *strerror();
@ -1043,7 +1048,7 @@ init_syserr()
static void static void
err_append(s) err_append(s)
char *s; const char *s;
{ {
extern VALUE ruby_errinfo; extern VALUE ruby_errinfo;

281
eval.c
View file

@ -21,7 +21,7 @@
#include "dln.h" #include "dln.h"
#ifndef HAVE_STRING_H #ifndef HAVE_STRING_H
char *strrchr _((char*,char)); char *strrchr _((const char*,const char));
#endif #endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
@ -236,7 +236,7 @@ remove_method(klass, mid)
void void
rb_remove_method(klass, name) rb_remove_method(klass, name)
VALUE klass; VALUE klass;
char *name; const char *name;
{ {
remove_method(klass, rb_intern(name)); remove_method(klass, rb_intern(name));
} }
@ -244,7 +244,7 @@ rb_remove_method(klass, name)
void void
rb_disable_super(klass, name) rb_disable_super(klass, name)
VALUE klass; VALUE klass;
char *name; const char *name;
{ {
VALUE origin; VALUE origin;
NODE *body; NODE *body;
@ -267,7 +267,7 @@ rb_disable_super(klass, name)
void void
rb_enable_super(klass, name) rb_enable_super(klass, name)
VALUE klass; VALUE klass;
char *name; const char *name;
{ {
VALUE origin; VALUE origin;
NODE *body; NODE *body;
@ -334,7 +334,7 @@ rb_attr(klass, id, read, write, ex)
ID id; ID id;
int read, write, ex; int read, write, ex;
{ {
char *name; const char *name;
char *buf; char *buf;
ID attriv; ID attriv;
int noex; int noex;
@ -412,9 +412,7 @@ struct BLOCK {
int iter; int iter;
int vmode; int vmode;
struct RVarmap *d_vars; struct RVarmap *d_vars;
#ifdef USE_THREAD
VALUE orig_thread; VALUE orig_thread;
#endif
struct BLOCK *prev; struct BLOCK *prev;
}; };
static struct BLOCK *ruby_block; static struct BLOCK *ruby_block;
@ -633,7 +631,6 @@ static VALUE ruby_wrapper; /* security wrapper */
ruby_scope = _scope; \ ruby_scope = _scope; \
scope_vmode = SCOPE_PUBLIC; scope_vmode = SCOPE_PUBLIC;
#ifdef USE_THREAD
#define SCOPE_DONT_RECYCLE FL_USER2 #define SCOPE_DONT_RECYCLE FL_USER2
#define POP_SCOPE() \ #define POP_SCOPE() \
if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) {\ if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) {\
@ -653,25 +650,10 @@ static VALUE ruby_wrapper; /* security wrapper */
ruby_scope = _old;\ ruby_scope = _old;\
scope_vmode = _vmode;\ scope_vmode = _vmode;\
} }
#else /* not USE_THREAD */
#define POP_SCOPE() \
if (ruby_scope->flag == SCOPE_ALLOCA) {\
ruby_scope->local_vars = 0;\
ruby_scope->local_tbl = 0;\
if (ruby_scope != top_scope)\
rb_gc_force_recycle((VALUE)ruby_scope);\
}\
else {\
ruby_scope->flag |= SCOPE_NOSTACK;\
}\
ruby_scope = _old;\
scope_vmode = _vmode;\
}
#endif /* USE_THREAD */
static VALUE rb_eval _((VALUE,NODE*)); static VALUE rb_eval _((VALUE,NODE*));
static VALUE eval _((VALUE,VALUE,VALUE,char*,int)); static VALUE eval _((VALUE,VALUE,VALUE,char*,int));
static NODE *compile _((VALUE,char*)); static NODE *compile _((VALUE));
static VALUE rb_yield_0 _((VALUE, VALUE, VALUE)); static VALUE rb_yield_0 _((VALUE, VALUE, VALUE));
static VALUE rb_call _((VALUE,VALUE,ID,int,VALUE*,int)); static VALUE rb_call _((VALUE,VALUE,ID,int,VALUE*,int));
@ -840,7 +822,7 @@ error_print()
tail++; /* skip newline */ tail++; /* skip newline */
} }
fprintf(stderr, ": "); fprintf(stderr, ": ");
fwrite(einfo, 1, elen, stderr); fwrite(einfo, 1, len, stderr);
if (epath) { if (epath) {
fprintf(stderr, " ("); fprintf(stderr, " (");
fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr); fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
@ -978,10 +960,8 @@ eval_node(self)
int ruby_in_eval; int ruby_in_eval;
#ifdef USE_THREAD
static void rb_thread_cleanup _((void)); static void rb_thread_cleanup _((void));
static void rb_thread_wait_other_threads _((void)); static void rb_thread_wait_other_threads _((void));
#endif
static int exit_status; static int exit_status;
@ -1011,10 +991,8 @@ ruby_run()
PUSH_ITER(ITER_NOT); PUSH_ITER(ITER_NOT);
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
rb_trap_exit(); rb_trap_exit();
#ifdef USE_THREAD
rb_thread_cleanup(); rb_thread_cleanup();
rb_thread_wait_other_threads(); rb_thread_wait_other_threads();
#endif
} }
else { else {
ex = state; ex = state;
@ -1055,6 +1033,7 @@ ruby_run()
case TAG_RAISE: case TAG_RAISE:
case TAG_FATAL: case TAG_FATAL:
if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) { if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
exec_end_proc();
exit(exit_status); exit(exit_status);
} }
error_print(); error_print();
@ -1071,7 +1050,7 @@ ruby_run()
static void static void
compile_error(at) compile_error(at)
char *at; const char *at;
{ {
VALUE str; VALUE str;
char *mesg; char *mesg;
@ -1091,7 +1070,7 @@ compile_error(at)
VALUE VALUE
rb_eval_string(str) rb_eval_string(str)
char *str; const char *str;
{ {
VALUE v; VALUE v;
char *oldsrc = ruby_sourcefile; char *oldsrc = ruby_sourcefile;
@ -1105,7 +1084,7 @@ rb_eval_string(str)
VALUE VALUE
rb_eval_string_protect(str, state) rb_eval_string_protect(str, state)
char *str; const char *str;
int *state; int *state;
{ {
VALUE result; /* OK */ VALUE result; /* OK */
@ -1154,10 +1133,8 @@ rb_eval_cmd(cmd, arg)
val = eval(ruby_top_self, cmd, Qnil, 0, 0); val = eval(ruby_top_self, cmd, Qnil, 0, 0);
} }
#ifdef USE_THREAD
if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE))
FL_SET(saved_scope, SCOPE_DONT_RECYCLE); FL_SET(saved_scope, SCOPE_DONT_RECYCLE);
#endif
ruby_scope = saved_scope; ruby_scope = saved_scope;
safe_level = safe; safe_level = safe;
POP_TAG(); POP_TAG();
@ -1188,7 +1165,7 @@ rb_eval_cmd(cmd, arg)
return val; return val;
} }
VALUE static VALUE
rb_trap_eval(cmd, sig) rb_trap_eval(cmd, sig)
VALUE cmd; VALUE cmd;
int sig; int sig;
@ -1341,11 +1318,11 @@ rb_mod_alias_method(mod, newname, oldname)
} }
#ifdef C_ALLOCA #ifdef C_ALLOCA
# define TMP_PROTECT NODE * volatile __protect_tmp=0 # define TMP_PROTECT NODE * volatile tmp__protect_tmp=0
# define TMP_ALLOC(n) \ # define TMP_ALLOC(n) \
(__protect_tmp = rb_node_newnode(NODE_ALLOCA, \ (tmp__protect_tmp = rb_node_newnode(NODE_ALLOCA, \
ALLOC_N(VALUE,n),__protect_tmp,n), \ ALLOC_N(VALUE,n),tmp__protect_tmp,n), \
(void*)__protect_tmp->nd_head) (void*)tmp__protect_tmp->nd_head)
#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)
@ -1639,9 +1616,7 @@ call_trace_func(event, file, line, self, id, klass)
trace = trace_func; trace = trace_func;
trace_func = 0; trace_func = 0;
#ifdef USE_THREAD
rb_thread_critical++; rb_thread_critical++;
#endif
prev = ruby_frame; prev = ruby_frame;
PUSH_FRAME(); PUSH_FRAME();
@ -1669,9 +1644,7 @@ call_trace_func(event, file, line, self, id, klass)
POP_TAG(); POP_TAG();
POP_FRAME(); POP_FRAME();
#ifdef USE_THREAD
rb_thread_critical--; rb_thread_critical--;
#endif
if (!trace_func) trace_func = trace; if (!trace_func) trace_func = trace;
ruby_sourceline = line_save; ruby_sourceline = line_save;
ruby_sourcefile = file_save; ruby_sourcefile = file_save;
@ -2067,8 +2040,9 @@ rb_eval(self, node)
case NODE_DOT2: case NODE_DOT2:
case NODE_DOT3: case NODE_DOT3:
result = rb_range_new(rb_eval(self, node->nd_beg), rb_eval(self, node->nd_end)); result = rb_range_new(rb_eval(self, node->nd_beg),
result = rb_range_new(rb_eval(self, node->nd_beg), rb_eval(self, node->nd_end)); rb_eval(self, node->nd_end),
nd_type(node) == NODE_DOT3);
if (node->nd_state) break; if (node->nd_state) break;
if (nd_type(node->nd_beg) == NODE_LIT && FIXNUM_P(node->nd_beg->nd_lit) && if (nd_type(node->nd_beg) == NODE_LIT && FIXNUM_P(node->nd_beg->nd_lit) &&
nd_type(node->nd_end) == NODE_LIT && FIXNUM_P(node->nd_end->nd_lit)) nd_type(node->nd_end) == NODE_LIT && FIXNUM_P(node->nd_end->nd_lit))
@ -2478,8 +2452,9 @@ rb_eval(self, node)
str2 = list->nd_head->nd_lit; str2 = list->nd_head->nd_lit;
break; break;
case NODE_EVSTR: case NODE_EVSTR:
ruby_sourceline = nd_line(node);
ruby_in_eval++; ruby_in_eval++;
list->nd_head = compile(list->nd_head->nd_lit,0); list->nd_head = compile(list->nd_head->nd_lit);
ruby_eval_tree = 0; ruby_eval_tree = 0;
ruby_in_eval--; ruby_in_eval--;
if (ruby_nerrs > 0) { if (ruby_nerrs > 0) {
@ -2801,7 +2776,7 @@ rb_eval(self, node)
char *desc = is_defined(self, node->nd_head, buf); char *desc = is_defined(self, node->nd_head, buf);
if (desc) result = rb_str_new2(desc); if (desc) result = rb_str_new2(desc);
else result = Qfalse; else result = Qnil;
} }
break; break;
@ -2935,6 +2910,7 @@ rb_exit(status)
exit_status = status; exit_status = status;
rb_exc_raise(rb_exc_new(rb_eSystemExit, 0, 0)); rb_exc_raise(rb_exc_new(rb_eSystemExit, 0, 0));
} }
exec_end_proc();
exit(status); exit(status);
} }
@ -3182,10 +3158,8 @@ rb_yield_0(val, self, klass)
POP_VARS(); POP_VARS();
ruby_block = block; ruby_block = block;
ruby_frame = ruby_frame->prev; ruby_frame = ruby_frame->prev;
#ifdef USE_THREAD
if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE))
FL_SET(old_scope, SCOPE_DONT_RECYCLE); FL_SET(old_scope, SCOPE_DONT_RECYCLE);
#endif
ruby_scope = old_scope; ruby_scope = old_scope;
if (state) JUMP_TAG(state); if (state) JUMP_TAG(state);
return result; return result;
@ -3518,7 +3492,7 @@ rb_f_missing(argc, argv, obj)
format = "undefined iterator `%s' for %s"; format = "undefined iterator `%s' for %s";
} }
else if (last_call_status & CSTAT_VCALL) { else if (last_call_status & CSTAT_VCALL) {
char *mname = rb_id2name(id); const char *mname = rb_id2name(id);
if (('a' <= mname[0] && mname[0] <= 'z') || mname[0] == '_') { if (('a' <= mname[0] && mname[0] <= 'z') || mname[0] == '_') {
format = "undefined local variable or method `%s' for %s"; format = "undefined local variable or method `%s' for %s";
@ -3803,17 +3777,21 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
argc, i); argc, i);
} }
if (node->nd_rest == -1) { if (node->nd_rest == -1) {
int opt = argc - i; int opt = i;
NODE *optnode = node->nd_opt; NODE *optnode = node->nd_opt;
while (optnode) { while (optnode) {
opt--; opt++;
optnode = optnode->nd_next; optnode = optnode->nd_next;
} }
if (opt > 0) { if (opt < argc) {
rb_raise(rb_eArgError, "wrong # of arguments(%d for %d)", rb_raise(rb_eArgError, "wrong # of arguments(%d for %d)",
argc, argc-opt); argc, opt);
} }
#if 1
ruby_frame->argc = opt;
ruby_frame->argv = local_vars+2;
#endif
} }
if (local_vars) { if (local_vars) {
@ -4111,15 +4089,13 @@ rb_frame_last_func()
} }
static NODE* static NODE*
compile(src, place) compile(src)
VALUE src; VALUE src;
char *place;
{ {
NODE *node; NODE *node;
Check_Type(src, T_STRING); Check_Type(src, T_STRING);
if (place == 0) place = ruby_sourcefile; node = rb_compile_string(ruby_sourcefile, src);
node = rb_compile_string(place, src);
if (ruby_nerrs == 0) return node; if (ruby_nerrs == 0) return node;
return 0; return 0;
@ -4190,7 +4166,7 @@ eval(self, src, scope, file, line)
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
ruby_sourcefile = file; ruby_sourcefile = file;
ruby_sourceline = line; ruby_sourceline = line;
compile(src, file); compile(src);
if (ruby_nerrs > 0) { if (ruby_nerrs > 0) {
compile_error(0); compile_error(0);
} }
@ -4201,10 +4177,8 @@ eval(self, src, scope, file, line)
ruby_in_eval--; ruby_in_eval--;
if (!NIL_P(scope)) { if (!NIL_P(scope)) {
ruby_frame = ruby_frame->prev; ruby_frame = ruby_frame->prev;
#ifdef USE_THREAD
if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE))
FL_SET(old_scope, SCOPE_DONT_RECYCLE); FL_SET(old_scope, SCOPE_DONT_RECYCLE);
#endif
ruby_scope = old_scope; ruby_scope = old_scope;
ruby_block = old_block; ruby_block = old_block;
ruby_calling_block = old_call_block; ruby_calling_block = old_call_block;
@ -4252,7 +4226,7 @@ rb_f_eval(argc, argv, self)
{ {
VALUE src, scope, vfile, vline; VALUE src, scope, vfile, vline;
char *file = "(eval)"; char *file = "(eval)";
int line = 0; int line = 1;
rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline); rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
if (argc >= 3) { if (argc >= 3) {
@ -4311,7 +4285,7 @@ eval_under_i(args)
static VALUE static VALUE
eval_under(under, self, src, file, line) eval_under(under, self, src, file, line)
VALUE under, self, src; VALUE under, self, src;
char *file; const char *file;
int line; int line;
{ {
VALUE args[4]; VALUE args[4];
@ -4340,44 +4314,54 @@ yield_under(under, self)
return exec_under(yield_under_i, under, self); return exec_under(yield_under_i, under, self);
} }
static VALUE
specific_eval(argc, argv, klass, self)
int argc;
VALUE *argv;
VALUE klass, self;
{
char *file = 0;
int line = 1;
int iter = rb_iterator_p();
if (argc > 0) {
Check_SafeStr(argv[0]);
if (argc > 3) {
rb_raise(rb_eArgError, "wrong # of arguments: %s(src) or %s{..}",
rb_id2name(ruby_frame->last_func),
rb_id2name(ruby_frame->last_func));
}
if (argc > 1) file = STR2CSTR(argv[1]);
if (argc > 2) line = NUM2INT(argv[2]);
}
else if (!iter) {
rb_raise(rb_eArgError, "block not supplied");
}
if (iter) {
return yield_under(klass, self);
}
else {
return eval_under(klass, self, argv[0], file, line);
}
}
VALUE VALUE
rb_obj_instance_eval(argc, argv, self) rb_obj_instance_eval(argc, argv, self)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE self; VALUE self;
{ {
char *file = 0;
int line = 0;
VALUE klass; VALUE klass;
if (argc == 0) {
if (!rb_iterator_p()) {
rb_raise(rb_eArgError, "block not supplied");
}
}
else if (argc < 4) {
Check_SafeStr(argv[0]);
if (argc > 1) file = STR2CSTR(argv[1]);
if (argc > 2) line = NUM2INT(argv[2]);
}
else {
rb_raise(rb_eArgError, "wrong # of arguments: %s(src) or %s{..}",
rb_id2name(ruby_frame->last_func),
rb_id2name(ruby_frame->last_func));
}
if (rb_special_const_p(self)) { if (rb_special_const_p(self)) {
klass = Qnil; klass = Qnil;
} }
else { else {
klass = rb_singleton_class(self); klass = rb_singleton_class(self);
} }
if (argc == 0) {
return yield_under(klass, self); return specific_eval(argc, argv, klass, self);
}
else {
return eval_under(klass, self, argv[0], file, line);
}
} }
static VALUE static VALUE
@ -4386,38 +4370,14 @@ rb_mod_module_eval(argc, argv, mod)
VALUE *argv; VALUE *argv;
VALUE mod; VALUE mod;
{ {
char *file = 0; return specific_eval(argc, argv, mod, mod);
int line = 0;
if (argc == 0) {
if (!rb_iterator_p()) {
rb_raise(rb_eArgError, "block not supplied");
}
}
else if (argc < 4) {
Check_SafeStr(argv[0]);
if (argc > 1) file = STR2CSTR(argv[1]);
if (argc > 2) line = NUM2INT(argv[2]);
}
else {
rb_raise(rb_eArgError, "wrong # of arguments: %s(src) or %s{..}",
rb_id2name(ruby_frame->last_func),
rb_id2name(ruby_frame->last_func));
}
if (argc == 0) {
return yield_under(mod, mod);
}
else {
return eval_under(mod, mod, argv[0], file, line);
}
} }
VALUE rb_load_path; VALUE rb_load_path;
static int static int
is_absolute_path(path) is_absolute_path(path)
char *path; const char *path;
{ {
if (path[0] == '/') return 1; if (path[0] == '/') return 1;
# if defined(MSDOS) || defined(NT) || defined(__human68k__) # if defined(MSDOS) || defined(NT) || defined(__human68k__)
@ -4430,7 +4390,7 @@ is_absolute_path(path)
#ifdef __MACOS__ #ifdef __MACOS__
static int static int
is_macos_native_path(path) is_macos_native_path(path)
char *path; const char *path;
{ {
if (strchr(path, ':')) return 1; if (strchr(path, ':')) return 1;
return 0; return 0;
@ -4601,7 +4561,7 @@ static VALUE rb_features;
static int static int
rb_provided(feature) rb_provided(feature)
char *feature; const char *feature;
{ {
VALUE *p, *pend; VALUE *p, *pend;
char *f; char *f;
@ -4622,14 +4582,12 @@ rb_provided(feature)
return Qfalse; return Qfalse;
} }
#ifdef USE_THREAD static int rb_thread_loading _((const char*));
static int rb_thread_loading _((char*));
static void rb_thread_loading_done _((void)); static void rb_thread_loading_done _((void));
#endif
void void
rb_provide(feature) rb_provide(feature)
char *feature; const char *feature;
{ {
char *buf, *ext; char *buf, *ext;
@ -4703,43 +4661,35 @@ rb_f_require(obj, fname)
RSTRING(fname)->ptr); RSTRING(fname)->ptr);
load_dyna: load_dyna:
#ifdef USE_THREAD
if (rb_thread_loading(feature)) return Qfalse; if (rb_thread_loading(feature)) return Qfalse;
else { else {
int state; int state;
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
#endif
load = rb_str_new2(file); load = rb_str_new2(file);
file = RSTRING(load)->ptr; file = RSTRING(load)->ptr;
dln_load(file); dln_load(file);
rb_provide(feature); rb_provide(feature);
#ifdef USE_THREAD
} }
POP_TAG(); POP_TAG();
rb_thread_loading_done(); rb_thread_loading_done();
if (state) JUMP_TAG(state); if (state) JUMP_TAG(state);
} }
#endif
return Qtrue; return Qtrue;
load_rb: load_rb:
#ifdef USE_THREAD
if (rb_thread_loading(feature)) return Qfalse; if (rb_thread_loading(feature)) return Qfalse;
else { else {
int state; int state;
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
#endif
rb_load(fname, 0); rb_load(fname, 0);
rb_provide(feature); rb_provide(feature);
#ifdef USE_THREAD
} }
POP_TAG(); POP_TAG();
rb_thread_loading_done(); rb_thread_loading_done();
if (state) JUMP_TAG(state); if (state) JUMP_TAG(state);
} }
#endif
return Qtrue; return Qtrue;
} }
@ -5268,6 +5218,7 @@ blk_copy_prev(block)
tmp = ALLOC_N(struct BLOCK, 1); tmp = ALLOC_N(struct BLOCK, 1);
MEMCPY(tmp, block->prev, struct BLOCK, 1); MEMCPY(tmp, block->prev, struct BLOCK, 1);
tmp->frame.argv = ALLOC_N(VALUE, tmp->frame.argc); tmp->frame.argv = ALLOC_N(VALUE, tmp->frame.argc);
scope_dup(tmp->scope);
MEMCPY(tmp->frame.argv, block->frame.argv, VALUE, tmp->frame.argc); MEMCPY(tmp->frame.argv, block->frame.argv, VALUE, tmp->frame.argc);
block->prev = tmp; block->prev = tmp;
block = tmp; block = tmp;
@ -5309,9 +5260,7 @@ rb_f_binding(self)
bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data); bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data);
*data = *ruby_block; *data = *ruby_block;
#ifdef USE_THREAD
data->orig_thread = rb_thread_current(); data->orig_thread = rb_thread_current();
#endif
data->iter = rb_f_iterator_p(); data->iter = rb_f_iterator_p();
if (ruby_frame->prev) { if (ruby_frame->prev) {
data->frame.last_func = ruby_frame->prev->last_func; data->frame.last_func = ruby_frame->prev->last_func;
@ -5389,9 +5338,7 @@ proc_s_new(klass)
proc = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data); proc = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data);
*data = *ruby_block; *data = *ruby_block;
#ifdef USE_THREAD
data->orig_thread = rb_thread_current(); data->orig_thread = rb_thread_current();
#endif
data->iter = data->prev?Qtrue:Qfalse; data->iter = data->prev?Qtrue:Qfalse;
data->frame.argv = ALLOC_N(VALUE, data->frame.argc); data->frame.argv = ALLOC_N(VALUE, data->frame.argc);
MEMCPY(data->frame.argv, ruby_block->frame.argv, VALUE, data->frame.argc); MEMCPY(data->frame.argv, ruby_block->frame.argv, VALUE, data->frame.argc);
@ -5423,11 +5370,9 @@ blk_orphan(data)
(data->scope->flag & SCOPE_NOSTACK)) { (data->scope->flag & SCOPE_NOSTACK)) {
return 1; return 1;
} }
#ifdef USE_THREAD
if (data->orig_thread != rb_thread_current()) { if (data->orig_thread != rb_thread_current()) {
return 1; return 1;
} }
#endif
return 0; return 0;
} }
@ -5662,7 +5607,7 @@ method_inspect(method)
{ {
struct METHOD *data; struct METHOD *data;
VALUE str; VALUE str;
char *s; const char *s;
Data_Get_Struct(method, struct METHOD, data); Data_Get_Struct(method, struct METHOD, data);
str = rb_str_new2("#<"); str = rb_str_new2("#<");
@ -5739,8 +5684,6 @@ Init_Proc()
rb_define_method(rb_mKernel, "method", rb_obj_method, 1); rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
} }
#ifdef USE_THREAD
static VALUE rb_eThreadError; static VALUE rb_eThreadError;
int rb_thread_pending = 0; int rb_thread_pending = 0;
@ -5995,12 +5938,14 @@ static char *th_raise_file;
static int th_raise_line; static int th_raise_line;
static VALUE th_cmd; static VALUE th_cmd;
static int th_sig; static int th_sig;
static char *th_signm;
#define RESTORE_NORMAL 0 #define RESTORE_NORMAL 0
#define RESTORE_FATAL 1 #define RESTORE_FATAL 1
#define RESTORE_INTERRUPT 2 #define RESTORE_INTERRUPT 2
#define RESTORE_TRAP 3 #define RESTORE_TRAP 3
#define RESTORE_RAISE 4 #define RESTORE_RAISE 4
#define RESTORE_SIGNAL 5
static void static void
rb_thread_restore_context(th, exit) rb_thread_restore_context(th, exit)
@ -6063,6 +6008,10 @@ rb_thread_restore_context(th, exit)
errno = EINTR; errno = EINTR;
break; break;
case RESTORE_SIGNAL:
rb_raise(rb_eSignal, "SIG%s", th_signm);
break;
case RESTORE_RAISE: case RESTORE_RAISE:
ruby_frame->last_func = 0; ruby_frame->last_func = 0;
ruby_sourcefile = th_raise_file; ruby_sourcefile = th_raise_file;
@ -6160,7 +6109,9 @@ rb_thread_schedule()
select_err: select_err:
rb_thread_pending = 0; rb_thread_pending = 0;
if (curr_thread == curr_thread->next) return; if (curr_thread == curr_thread->next
&& curr_thread->status == THREAD_RUNNABLE)
return;
next = 0; next = 0;
curr = curr_thread; /* starting thread */ curr = curr_thread; /* starting thread */
@ -6493,6 +6444,8 @@ rb_thread_join(thread)
thread_t th = rb_thread_check(thread); thread_t th = rb_thread_check(thread);
if (rb_thread_dead(th)) return thread; if (rb_thread_dead(th)) return thread;
if (th == curr_thread)
rb_raise(rb_eThreadError, "recursive join");
if ((th->wait_for & WAIT_JOIN) && th->join == curr_thread) if ((th->wait_for & WAIT_JOIN) && th->join == curr_thread)
rb_raise(rb_eThreadError, "Thread#join: deadlock"); rb_raise(rb_eThreadError, "Thread#join: deadlock");
curr_thread->status = THREAD_STOPPED; curr_thread->status = THREAD_STOPPED;
@ -6501,6 +6454,15 @@ rb_thread_join(thread)
curr_thread->wait_for |= WAIT_JOIN; curr_thread->wait_for |= WAIT_JOIN;
rb_thread_schedule(); rb_thread_schedule();
if (!NIL_P(th->errinfo)) {
VALUE oldbt = get_backtrace(th->errinfo);
VALUE errat = make_backtrace();
rb_ary_unshift(errat, rb_ary_entry(oldbt, 0));
set_backtrace(th->errinfo, errat);
rb_exc_raise(th->errinfo);
}
return thread; return thread;
} }
@ -6588,10 +6550,10 @@ static VALUE
rb_thread_stop() rb_thread_stop()
{ {
rb_thread_critical = 0; rb_thread_critical = 0;
curr_thread->status = THREAD_STOPPED;
if (curr_thread == curr_thread->next) { if (curr_thread == curr_thread->next) {
rb_raise(rb_eThreadError, "stopping only thread"); rb_raise(rb_eThreadError, "stopping only thread");
} }
curr_thread->status = THREAD_STOPPED;
rb_thread_schedule(); rb_thread_schedule();
return Qnil; return Qnil;
@ -6874,14 +6836,6 @@ rb_thread_value(thread)
thread_t th = rb_thread_check(thread); thread_t th = rb_thread_check(thread);
rb_thread_join(thread); rb_thread_join(thread);
if (!NIL_P(th->errinfo)) {
VALUE oldbt = get_backtrace(th->errinfo);
VALUE errat = make_backtrace();
rb_ary_unshift(errat, rb_ary_entry(oldbt, 0));
set_backtrace(th->errinfo, errat);
rb_exc_raise(th->errinfo);
}
return th->result; return th->result;
} }
@ -6970,6 +6924,26 @@ rb_thread_interrupt()
rb_thread_restore_context(curr_thread, RESTORE_INTERRUPT); rb_thread_restore_context(curr_thread, RESTORE_INTERRUPT);
} }
void
rb_thread_signal_raise(sig)
char *sig;
{
if (sig == 0) return; /* should not happen */
rb_thread_critical = 0;
if (curr_thread == main_thread) {
rb_thread_ready(curr_thread);
rb_raise(rb_eSignal, "SIG%s", sig);
}
rb_thread_ready(main_thread);
rb_thread_save_context(curr_thread);
if (setjmp(curr_thread->context)) {
return;
}
th_signm = sig;
curr_thread = main_thread;
rb_thread_restore_context(curr_thread, RESTORE_SIGNAL);
}
void void
rb_thread_trap_eval(cmd, sig) rb_thread_trap_eval(cmd, sig)
VALUE cmd; VALUE cmd;
@ -7027,7 +7001,7 @@ static int loading_nest;
static int static int
rb_thread_loading(feature) rb_thread_loading(feature)
char *feature; const char *feature;
{ {
if (curr_thread != curr_thread->next && loading_thread) { if (curr_thread != curr_thread->next && loading_thread) {
while (loading_thread != curr_thread) { while (loading_thread != curr_thread) {
@ -7211,7 +7185,6 @@ Init_Thread()
rb_define_method(rb_cContinuation, "call", rb_continuation_call, -1); rb_define_method(rb_cContinuation, "call", rb_continuation_call, -1);
rb_define_method(rb_mKernel, "callcc", rb_callcc, 0); rb_define_method(rb_mKernel, "callcc", rb_callcc, 0);
} }
#endif
static VALUE static VALUE
rb_f_catch(dmy, tag) rb_f_catch(dmy, tag)
@ -7245,7 +7218,7 @@ catch_i(tag)
VALUE VALUE
rb_catch(tag, proc, data) rb_catch(tag, proc, data)
char *tag; const char *tag;
VALUE (*proc)(); VALUE (*proc)();
VALUE data; VALUE data;
{ {
@ -7269,13 +7242,11 @@ rb_f_throw(argc, argv)
tt->dst = t; tt->dst = t;
break; break;
} }
#ifdef USE_THREAD
if (tt->tag == PROT_THREAD) { if (tt->tag == PROT_THREAD) {
rb_raise(rb_eThreadError, "uncaught throw `%s' in thread 0x%x", rb_raise(rb_eThreadError, "uncaught throw `%s' in thread 0x%x",
rb_id2name(t), rb_id2name(t),
curr_thread); curr_thread);
} }
#endif
tt = tt->prev; tt = tt->prev;
} }
if (!tt) { if (!tt) {
@ -7289,7 +7260,7 @@ rb_f_throw(argc, argv)
void void
rb_throw(tag, val) rb_throw(tag, val)
char *tag; const char *tag;
VALUE val; VALUE val;
{ {
VALUE argv[2]; VALUE argv[2];
@ -7303,7 +7274,6 @@ rb_throw(tag, val)
static void static void
return_check() return_check()
{ {
#ifdef USE_THREAD
struct tag *tt = prot_tag; struct tag *tt = prot_tag;
while (tt) { while (tt) {
@ -7316,6 +7286,5 @@ return_check()
} }
tt = tt->prev; tt = tt->prev;
} }
#endif
} }

View file

@ -561,7 +561,7 @@ if $extlist.size > 0
if PLATFORM =~ /m68k-human|beos/ if PLATFORM =~ /m68k-human|beos/
$extlibs.gsub!("-L/usr/local/lib", "") if $extlibs $extlibs.gsub!("-L/usr/local/lib", "") if $extlibs
end end
system format('make #{ruby} EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs) system format(%[make #{ruby} EXTOBJS="%s" EXTLIBS="%s"], $extobjs, $extlibs)
else else
Dir.chdir ".." Dir.chdir ".."
if older(ruby, miniruby) if older(ruby, miniruby)

View file

@ -3,5 +3,5 @@ depend
extconf.rb extconf.rb
lib/kconv.rb lib/kconv.rb
nkf.c nkf.c
orig/nkf.c 1.7/nkf.c
test.rb test.rb

View file

@ -43,7 +43,7 @@ printf("[[%c][%c][%d]]\n", c, output[output_ctr - 1], output_ctr);
} }
#define PERL_XS 1 #define PERL_XS 1
#include "orig/nkf.c" #include "1.7/nkf.c"
static VALUE static VALUE
rb_nkf_kconv(obj, opt, src) rb_nkf_kconv(obj, opt, src)
@ -61,12 +61,12 @@ rb_nkf_kconv(obj, opt, src)
} }
arguments(opt_ptr); arguments(opt_ptr);
} }
dst = rb_str_new(0, RSTRING(src)->len*3 + 10); /* large enough? */
incsize = INCSIZE; incsize = INCSIZE;
input_ctr = 0; input_ctr = 0;
input = str2cstr(src, &i_len); input = str2cstr(src, &i_len);
dst = rb_str_new(0, i_len*3 + 10); /* large enough? */
output_ctr = 0; output_ctr = 0;
output = RSTRING(dst)->ptr; output = RSTRING(dst)->ptr;
@ -106,12 +106,13 @@ rb_nkf_guess(obj, src)
{ {
unsigned char *p; unsigned char *p;
unsigned char *pend; unsigned char *pend;
int plen;
int sequence_counter = 0; int sequence_counter = 0;
Check_Type(src, T_STRING); Check_Type(src, T_STRING);
p = RSTRING(src)->ptr; p = str2cstr(src, &plen);
pend = p + RSTRING(src)->len; pend = p + plen;
#define INCR do {\ #define INCR do {\
p++;\ p++;\

View file

@ -19,9 +19,7 @@ static int
readline_event() readline_event()
{ {
CHECK_INTS; CHECK_INTS;
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
} }
static VALUE static VALUE
@ -135,14 +133,14 @@ readline_attempted_completion_function(char *text, int start, int end)
static VALUE static VALUE
readline_s_vi_editing_mode(VALUE self) readline_s_vi_editing_mode(VALUE self)
{ {
rl_vi_editing_mode(); rl_vi_editing_mode(1,0);
return Qnil; return Qnil;
} }
static VALUE static VALUE
readline_s_emacs_editing_mode(VALUE self) readline_s_emacs_editing_mode(VALUE self)
{ {
rl_emacs_editing_mode(); rl_emacs_editing_mode(1,0);
return Qnil; return Qnil;
} }

View file

@ -30,7 +30,7 @@ extern int rb_thread_select(int, fd_set*, fd_set*, fd_set*, struct timeval*); /*
# include <GUSI.h> # include <GUSI.h>
#endif #endif
#if defined(USE_THREAD) && defined(HAVE_FCNTL) #if defined(HAVE_FCNTL)
#ifdef HAVE_SYS_SELECT_H #ifdef HAVE_SYS_SELECT_H
#include <sys/select.h> #include <sys/select.h>
#endif #endif
@ -43,20 +43,20 @@ extern int rb_thread_select(int, fd_set*, fd_set*, fd_set*, struct timeval*); /*
#endif #endif
VALUE rb_cBasicSocket; VALUE rb_cBasicSocket;
VALUE rb_cIPsocket; VALUE rb_cIPSocket;
VALUE rb_cTCPsocket; VALUE rb_cTCPSocket;
VALUE rb_cTCPserver; VALUE rb_cTCPServer;
VALUE rb_cUDPsocket; VALUE rb_cUDPSocket;
#ifdef AF_UNIX #ifdef AF_UNIX
VALUE rb_cUNIXsocket; VALUE rb_cUNIXSocket;
VALUE rb_cUNIXserver; VALUE rb_cUNIXServer;
#endif #endif
VALUE rb_cSocket; VALUE rb_cSocket;
static VALUE rb_eSocket; static VALUE rb_eSocket;
#ifdef SOCKS #ifdef SOCKS
VALUE rb_cSOCKSsocket; VALUE rb_cSOCKSSocket;
void SOCKSinit(); void SOCKSinit();
int Rconnect(); int Rconnect();
#endif #endif
@ -146,9 +146,7 @@ bsock_close_read(sock)
if (fptr->f2 == 0) { if (fptr->f2 == 0) {
return rb_io_close(sock); return rb_io_close(sock);
} }
#ifdef USE_THREAD
rb_thread_fd_close(fileno(fptr->f)); rb_thread_fd_close(fileno(fptr->f));
#endif
fptr->mode &= ~FMODE_READABLE; fptr->mode &= ~FMODE_READABLE;
#ifdef NT #ifdef NT
free(fptr->f); free(fptr->f);
@ -293,9 +291,7 @@ bsock_send(argc, argv, sock)
f = GetWriteFile(fptr); f = GetWriteFile(fptr);
fd = fileno(f); fd = fileno(f);
retry: retry:
#ifdef USE_THREAD
rb_thread_fd_writable(fd); rb_thread_fd_writable(fd);
#endif
m = rb_str2cstr(msg, &mlen); m = rb_str2cstr(msg, &mlen);
if (RTEST(to)) { if (RTEST(to)) {
t = rb_str2cstr(to, &tlen); t = rb_str2cstr(to, &tlen);
@ -312,9 +308,7 @@ bsock_send(argc, argv, sock)
#if EAGAIN != EWOULDBLOCK #if EAGAIN != EWOULDBLOCK
case EAGAIN: case EAGAIN:
#endif #endif
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
goto retry; goto retry;
} }
rb_sys_fail("send(2)"); rb_sys_fail("send(2)");
@ -329,9 +323,9 @@ static VALUE unixaddr _((struct sockaddr_un*));
enum sock_recv_type { enum sock_recv_type {
RECV_RECV, /* BasicSocket#recv(no from) */ RECV_RECV, /* BasicSocket#recv(no from) */
RECV_TCP, /* TCPsocket#recvfrom */ RECV_TCP, /* TCPSocket#recvfrom */
RECV_UDP, /* UDPsocket#recvfrom */ RECV_UDP, /* UDPSocket#recvfrom */
RECV_UNIX, /* UNIXsocket#recvfrom */ RECV_UNIX, /* UNIXSocket#recvfrom */
RECV_SOCKET, /* Socket#recvfrom */ RECV_SOCKET, /* Socket#recvfrom */
}; };
@ -358,9 +352,7 @@ s_recv(sock, argc, argv, from)
GetOpenFile(sock, fptr); GetOpenFile(sock, fptr);
fd = fileno(fptr->f); fd = fileno(fptr->f);
#ifdef USE_THREAD
rb_thread_wait_fd(fd); rb_thread_wait_fd(fd);
#endif
TRAP_BEG; TRAP_BEG;
retry: retry:
RSTRING(str)->len = recvfrom(fd, RSTRING(str)->ptr, RSTRING(str)->len, flags, RSTRING(str)->len = recvfrom(fd, RSTRING(str)->ptr, RSTRING(str)->len, flags,
@ -374,9 +366,7 @@ s_recv(sock, argc, argv, from)
#if EAGAIN != EWOULDBLOCK #if EAGAIN != EWOULDBLOCK
case EAGAIN: case EAGAIN:
#endif #endif
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
goto retry; goto retry;
} }
rb_sys_fail("recvfrom(2)"); rb_sys_fail("recvfrom(2)");
@ -504,7 +494,7 @@ setipaddr(name, addr)
} }
} }
#if defined(USE_THREAD) && defined(HAVE_FCNTL) #if defined(HAVE_FCNTL)
static int static int
thread_connect(fd, sockaddr, len, type) thread_connect(fd, sockaddr, len, type)
int fd; int fd;
@ -661,7 +651,7 @@ open_inet(class, h, serv, type)
syscall = "bind(2)"; syscall = "bind(2)";
} }
else { else {
#if defined(USE_THREAD) && defined(HAVE_FCNTL) #if defined(HAVE_FCNTL)
status = thread_connect(fd, (struct sockaddr*)&sockaddr, status = thread_connect(fd, (struct sockaddr*)&sockaddr,
sizeof(sockaddr), type); sizeof(sockaddr), type);
#else #else
@ -742,7 +732,7 @@ tcp_s_gethostbyname(obj, host)
for (pch = h->h_aliases; *pch; pch++) { for (pch = h->h_aliases; *pch; pch++) {
rb_ary_push(names, rb_str_new2(*pch)); rb_ary_push(names, rb_str_new2(*pch));
} }
rb_ary_push(ary, NUM2INT(h->h_addrtype)); rb_ary_push(ary, INT2NUM(h->h_addrtype));
#ifdef h_addr #ifdef h_addr
for (pch = h->h_addr_list; *pch; pch++) { for (pch = h->h_addr_list; *pch; pch++) {
memcpy((char *) &addr.sin_addr, *pch, h->h_length); memcpy((char *) &addr.sin_addr, *pch, h->h_length);
@ -780,9 +770,7 @@ s_accept(class, fd, sockaddr, len)
int fd2; int fd2;
retry: retry:
#ifdef USE_THREAD
rb_thread_wait_fd(fd); rb_thread_wait_fd(fd);
#endif
TRAP_BEG; TRAP_BEG;
fd2 = accept(fd, sockaddr, len); fd2 = accept(fd, sockaddr, len);
TRAP_END; TRAP_END;
@ -793,9 +781,7 @@ s_accept(class, fd, sockaddr, len)
#if EAGAIN != EWOULDBLOCK #if EAGAIN != EWOULDBLOCK
case EAGAIN: case EAGAIN:
#endif #endif
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
goto retry; goto retry;
} }
rb_sys_fail(0); rb_sys_fail(0);
@ -813,7 +799,7 @@ tcp_accept(sock)
GetOpenFile(sock, fptr); GetOpenFile(sock, fptr);
fromlen = sizeof(struct sockaddr_in); fromlen = sizeof(struct sockaddr_in);
return s_accept(rb_cTCPsocket, fileno(fptr->f), return s_accept(rb_cTCPSocket, fileno(fptr->f),
(struct sockaddr*)&from, &fromlen); (struct sockaddr*)&from, &fromlen);
} }
@ -981,9 +967,7 @@ udp_connect(sock, host, port)
#if EAGAIN != EWOULDBLOCK #if EAGAIN != EWOULDBLOCK
case EAGAIN: case EAGAIN:
#endif #endif
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
goto retry; goto retry;
} }
rb_sys_fail("connect(2)"); rb_sys_fail("connect(2)");
@ -1040,9 +1024,7 @@ udp_send(argc, argv, sock)
#if EAGAIN != EWOULDBLOCK #if EAGAIN != EWOULDBLOCK
case EAGAIN: case EAGAIN:
#endif #endif
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
goto retry; goto retry;
} }
rb_sys_fail("sendto(2)"); rb_sys_fail("sendto(2)");
@ -1110,7 +1092,7 @@ unix_accept(sock)
GetOpenFile(sock, fptr); GetOpenFile(sock, fptr);
fromlen = sizeof(struct sockaddr_un); fromlen = sizeof(struct sockaddr_un);
return s_accept(rb_cUNIXsocket, fileno(fptr->f), return s_accept(rb_cUNIXSocket, fileno(fptr->f),
(struct sockaddr*)&from, &fromlen); (struct sockaddr*)&from, &fromlen);
} }
@ -1293,9 +1275,7 @@ sock_connect(sock, addr)
#if EAGAIN != EWOULDBLOCK #if EAGAIN != EWOULDBLOCK
case EAGAIN: case EAGAIN:
#endif #endif
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
goto retry; goto retry;
} }
rb_sys_fail("connect(2)"); rb_sys_fail("connect(2)");
@ -1416,7 +1396,7 @@ mkhostent(h)
for (pch = h->h_aliases; *pch; pch++) { for (pch = h->h_aliases; *pch; pch++) {
rb_ary_push(names, rb_str_new2(*pch)); rb_ary_push(names, rb_str_new2(*pch));
} }
rb_ary_push(ary, NUM2INT(h->h_addrtype)); rb_ary_push(ary, INT2NUM(h->h_addrtype));
#ifdef h_addr #ifdef h_addr
for (pch = h->h_addr_list; *pch; pch++) { for (pch = h->h_addr_list; *pch; pch++) {
rb_ary_push(ary, rb_str_new(*pch, h->h_length)); rb_ary_push(ary, rb_str_new(*pch, h->h_length));
@ -1533,49 +1513,56 @@ Init_socket()
rb_define_method(rb_cBasicSocket, "send", bsock_send, -1); rb_define_method(rb_cBasicSocket, "send", bsock_send, -1);
rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1); rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1);
rb_cIPsocket = rb_define_class("IPsocket", rb_cBasicSocket); rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket);
rb_define_method(rb_cIPsocket, "addr", ip_addr, 0); rb_define_global_const("IPsocket", rb_cIPSocket);
rb_define_method(rb_cIPsocket, "peeraddr", ip_peeraddr, 0); rb_define_method(rb_cIPSocket, "addr", ip_addr, 0);
rb_define_singleton_method(rb_cIPsocket, "getaddress", ip_s_getaddress, 1); rb_define_method(rb_cIPSocket, "peeraddr", ip_peeraddr, 0);
rb_define_singleton_method(rb_cIPSocket, "getaddress", ip_s_getaddress, 1);
rb_cTCPsocket = rb_define_class("TCPsocket", rb_cIPsocket); rb_cTCPSocket = rb_define_class("TCPSocket", rb_cIPSocket);
rb_define_singleton_method(rb_cTCPsocket, "open", tcp_s_open, 2); rb_define_global_const("TCPsocket", rb_cTCPSocket);
rb_define_singleton_method(rb_cTCPsocket, "new", tcp_s_open, 2); rb_define_singleton_method(rb_cTCPSocket, "open", tcp_s_open, 2);
rb_define_singleton_method(rb_cTCPsocket, "gethostbyname", tcp_s_gethostbyname, 1); rb_define_singleton_method(rb_cTCPSocket, "new", tcp_s_open, 2);
rb_define_method(rb_cTCPsocket, "recvfrom", tcp_recvfrom, -1); rb_define_singleton_method(rb_cTCPSocket, "gethostbyname", tcp_s_gethostbyname, 1);
rb_define_method(rb_cTCPSocket, "recvfrom", tcp_recvfrom, -1);
#ifdef SOCKS #ifdef SOCKS
rb_cSOCKSsocket = rb_define_class("SOCKSsocket", rb_cTCPsocket); rb_cSOCKSSocket = rb_define_class("SOCKSSocket", rb_cTCPSocket);
rb_define_singleton_method(rb_cSOCKSsocket, "open", socks_s_open, 2); rb_define_global_const("SOCKSsocket", rb_cSOCKSSocket);
rb_define_singleton_method(rb_cSOCKSsocket, "new", socks_s_open, 2); rb_define_singleton_method(rb_cSOCKSSocket, "open", socks_s_open, 2);
rb_define_singleton_method(rb_cSOCKSSocket, "new", socks_s_open, 2);
#endif #endif
rb_cTCPserver = rb_define_class("TCPserver", rb_cTCPsocket); rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket);
rb_define_singleton_method(rb_cTCPserver, "open", tcp_svr_s_open, -1); rb_define_global_const("TCPserver", rb_cTCPServer);
rb_define_singleton_method(rb_cTCPserver, "new", tcp_svr_s_open, -1); rb_define_singleton_method(rb_cTCPServer, "open", tcp_svr_s_open, -1);
rb_define_method(rb_cTCPserver, "accept", tcp_accept, 0); rb_define_singleton_method(rb_cTCPServer, "new", tcp_svr_s_open, -1);
rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0);
rb_cUDPsocket = rb_define_class("UDPsocket", rb_cIPsocket); rb_cUDPSocket = rb_define_class("UDPSocket", rb_cIPSocket);
rb_define_singleton_method(rb_cUDPsocket, "open", udp_s_open, 0); rb_define_global_const("UDPsocket", rb_cUDPSocket);
rb_define_singleton_method(rb_cUDPsocket, "new", udp_s_open, 0); rb_define_singleton_method(rb_cUDPSocket, "open", udp_s_open, 0);
rb_define_method(rb_cUDPsocket, "connect", udp_connect, 2); rb_define_singleton_method(rb_cUDPSocket, "new", udp_s_open, 0);
rb_define_method(rb_cUDPsocket, "bind", udp_bind, 2); rb_define_method(rb_cUDPSocket, "connect", udp_connect, 2);
rb_define_method(rb_cUDPsocket, "send", udp_send, -1); rb_define_method(rb_cUDPSocket, "bind", udp_bind, 2);
rb_define_method(rb_cUDPsocket, "recvfrom", udp_recvfrom, -1); rb_define_method(rb_cUDPSocket, "send", udp_send, -1);
rb_define_method(rb_cUDPSocket, "recvfrom", udp_recvfrom, -1);
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
rb_cUNIXsocket = rb_define_class("UNIXsocket", rb_cBasicSocket); rb_cUNIXSocket = rb_define_class("UNIXSocket", rb_cBasicSocket);
rb_define_singleton_method(rb_cUNIXsocket, "open", unix_s_sock_open, 1); rb_define_global_const("UNIXsocket", rb_cUNIXSocket);
rb_define_singleton_method(rb_cUNIXsocket, "new", unix_s_sock_open, 1); rb_define_singleton_method(rb_cUNIXSocket, "open", unix_s_sock_open, 1);
rb_define_method(rb_cUNIXsocket, "path", unix_path, 0); rb_define_singleton_method(rb_cUNIXSocket, "new", unix_s_sock_open, 1);
rb_define_method(rb_cUNIXsocket, "addr", unix_addr, 0); rb_define_method(rb_cUNIXSocket, "path", unix_path, 0);
rb_define_method(rb_cUNIXsocket, "peeraddr", unix_peeraddr, 0); rb_define_method(rb_cUNIXSocket, "addr", unix_addr, 0);
rb_define_method(rb_cUNIXsocket, "recvfrom", unix_recvfrom, -1); rb_define_method(rb_cUNIXSocket, "peeraddr", unix_peeraddr, 0);
rb_define_method(rb_cUNIXSocket, "recvfrom", unix_recvfrom, -1);
rb_cUNIXserver = rb_define_class("UNIXserver", rb_cUNIXsocket); rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
rb_define_singleton_method(rb_cUNIXserver, "open", unix_svr_s_open, 1); rb_define_global_const("UNIXserver", rb_cUNIXServer);
rb_define_singleton_method(rb_cUNIXserver, "new", unix_svr_s_open, 1); rb_define_singleton_method(rb_cUNIXServer, "open", unix_svr_s_open, 1);
rb_define_method(rb_cUNIXserver, "accept", unix_accept, 0); rb_define_singleton_method(rb_cUNIXServer, "new", unix_svr_s_open, 1);
rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0);
#endif #endif
rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);

View file

@ -55,9 +55,7 @@ void _timer_for_tcl (ClientData clientData)
timer->flag = 0; timer->flag = 0;
CHECK_INTS; CHECK_INTS;
#ifdef USE_THREAD
if (!rb_thread_critical) rb_thread_schedule(); if (!rb_thread_critical) rb_thread_schedule();
#endif
timer->token = Tk_CreateTimerHandler(200, _timer_for_tcl, timer->token = Tk_CreateTimerHandler(200, _timer_for_tcl,
(ClientData)timer); (ClientData)timer);
@ -82,11 +80,9 @@ lib_mainloop(VALUE self)
} }
DUMP1("stop Tk_Mainloop"); DUMP1("stop Tk_Mainloop");
#ifdef USE_THREAD
if (timer->flag) { if (timer->flag) {
Tk_DeleteTimerHandler(timer->token); Tk_DeleteTimerHandler(timer->token);
} }
#endif
return Qnil; return Qnil;
} }

View file

@ -228,7 +228,7 @@ module TkComm
return '' if cmd == '' return '' if cmd == ''
id = _next_cmd_id id = _next_cmd_id
Tk_CMDTBL[id] = cmd Tk_CMDTBL[id] = cmd
@cmdtbl = [] if not @cmdtbl @cmdtbl = [] unless @cmdtbl
@cmdtbl.push id @cmdtbl.push id
return format("rb_out %s", id); return format("rb_out %s", id);
end end
@ -711,14 +711,14 @@ class TkVariable
elsif val.kind_of?(Array) elsif val.kind_of?(Array)
a = [] a = []
val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
s = '"' + a.join(" ").gsub(/[][$"]/, '\\\\\&') + '"' #' s = '"' + a.join(" ").gsub(/[][$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
elsif val.kind_of?(Hash) elsif val.kind_of?(Hash)
s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
.gsub(/[][$"]/, '\\\\\&') + '"' #' .gsub(/[][$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
else else
s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"' #' s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; set %s %s', @id, @id, s)) INTERP._eval(format('global %s; set %s %s', @id, @id, s))
end end
end end
@ -738,16 +738,15 @@ class TkVariable
if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1" if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
raise raise
else else
Hash[*tk_split_simplelist(INTERP\ Hash[*tk_split_simplelist(INTERP._eval(format('global %s; array get %s',
._eval(format('global %s; array get %s', @id, @id)))]
@id, @id)))]
end end
end end
end end
def value=(val) def value=(val)
begin begin
s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"' #' s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; set %s %s', @id, @id, s)) INTERP._eval(format('global %s; set %s %s', @id, @id, s))
rescue rescue
if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1" if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
@ -760,12 +759,12 @@ class TkVariable
elsif val.kind_of?(Array) elsif val.kind_of?(Array)
a = [] a = []
val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
s = '"' + a.join(" ").gsub(/[][$"]/, '\\\\\&') + '"' #' s = '"' + a.join(" ").gsub(/[][$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; unset %s; array set %s %s', INTERP._eval(format('global %s; unset %s; array set %s %s',
@id, @id, @id, s)) @id, @id, @id, s))
elsif val.kind_of?(Hash) elsif val.kind_of?(Hash)
s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
.gsub(/[][$"]/, '\\\\\&') + '"' #' .gsub(/[][$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; unset %s; array set %s %s', INTERP._eval(format('global %s; unset %s; array set %s %s',
@id, @id, @id, s)) @id, @id, @id, s))
else else
@ -972,7 +971,7 @@ class TkVarAccess<TkVariable
def initialize(varname, val=nil) def initialize(varname, val=nil)
@id = varname @id = varname
if val if val
s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"' #' s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; set %s %s', @id, @id, s)) INTERP._eval(format('global %s; set %s %s', @id, @id, s))
end end
end end
@ -1600,17 +1599,21 @@ class TkObject<TkKernel
def configure(slot, value=None) def configure(slot, value=None)
if slot.kind_of? Hash if slot.kind_of? Hash
if ( slot['font'] || slot['kanjifont'] \ if (slot['font'] || slot['kanjifont'] ||
|| slot['latinfont'] || slot['asciifont'] ) slot['latinfont'] || slot['asciifont'] )
font_configure(slot.dup) font_configure(slot.dup)
else else
tk_call path, 'configure', *hash_kv(slot) tk_call path, 'configure', *hash_kv(slot)
end end
else else
if ( slot == 'font' || slot == 'kanjifont' \ if (slot == 'font' || slot == 'kanjifont' ||
|| slot == 'latinfont' || slot == 'asciifont' ) slot == 'latinfont' || slot == 'asciifont')
font_configure({slot=>value}) if value == None
fontobj
else
font_configure({slot=>value})
end
else else
tk_call path, 'configure', "-#{slot}", value tk_call path, 'configure', "-#{slot}", value
end end
@ -1624,13 +1627,11 @@ class TkObject<TkKernel
def configinfo(slot = nil) def configinfo(slot = nil)
if slot == 'font' || slot == 'kanjifont' if slot == 'font' || slot == 'kanjifont'
fontobj fontobj
else else
if slot if slot
conf = tk_split_list(tk_send('configure', "-#{slot}") ) conf = tk_split_list(tk_send('configure', "-#{slot}") )
conf[0] = conf[0][1..-1] conf[0] = conf[0][1..-1]
conf conf
else else
ret = tk_split_list(tk_send('configure') ).collect{|conf| ret = tk_split_list(tk_send('configure') ).collect{|conf|
conf[0] = conf[0][1..-1] conf[0] = conf[0][1..-1]
@ -2360,27 +2361,21 @@ class TkMenu<TkWindow
def yposition(index) def yposition(index)
number(tk_send('yposition', index)) number(tk_send('yposition', index))
end end
def entryconfigure(index, keys=nil)
tk_send 'entryconfigure', index, *hash_kv(keys)
end
# def entryconfigure(index, keys=nil)
# tk_send 'entryconfigure', index, *hash_kv(keys)
# end
def entrycget(index, key) def entrycget(index, key)
tk_tcl2ruby tk_send 'entrycget', index, "-#{key}" tk_tcl2ruby tk_send 'entrycget', index, "-#{key}"
end end
def entryconfigure(index, key, val=None) def entryconfigure(index, key, val=None)
if key.kind_of? Hash if key.kind_of? Hash
if ( key['font'] || key['kanjifont'] \ if (key['font'] || key['kanjifont'] ||
|| key['latinfont'] || key['asciifont'] ) key['latinfont'] || key['asciifont'])
tagfont_configure(index, key.dup) tagfont_configure(index, key.dup)
else else
tk_send 'entryconfigure', index, *hash_kv(key) tk_send 'entryconfigure', index, *hash_kv(key)
end end
else else
if ( key == 'font' || key == 'kanjifont' \ if (key == 'font' || key == 'kanjifont' ||
|| key == 'latinfont' || key == 'asciifont' ) key == 'latinfont' || key == 'asciifont' )
tagfont_configure({key=>val}) tagfont_configure({key=>val})
else else
tk_call 'entryconfigure', index, "-#{key}", val tk_call 'entryconfigure', index, "-#{key}", val

View file

@ -153,8 +153,8 @@ class TkFont
charset = (info = font['charset'] .to_s)? info: '*' charset = (info = font['charset'] .to_s)? info: '*'
encoding = (info = font['encoding'].to_s)? info: '*' encoding = (info = font['encoding'].to_s)? info: '*'
Array([foundry, family, weight, slant, swidth, adstyle, [foundry, family, weight, slant, swidth, adstyle,
pixels, points, resx, resy, space, avgWidth, charset, encoding]) pixels, points, resx, resy, space, avgWidth, charset, encoding]
end end
def create_latinfont_tk4x(font) def create_latinfont_tk4x(font)
@ -238,13 +238,10 @@ class TkFont
} }
@kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' @kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-'
elsif font.kind_of? TkFont elsif font.kind_of? TkFont
@kanjifont = font.kanji_font @kanjifont = font.kanji_font
else else
@kanjifont = font @kanjifont = font
end end
end end
@ -309,11 +306,9 @@ class TkFont
elsif font.kind_of? TkFont elsif font.kind_of? TkFont
tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font) tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font)
else else
tk_call('font', 'create', @kanjifont, '-copy', font, tk_call('font', 'create', @kanjifont, '-copy', font,
'-charset', 'jisx0208.1983') '-charset', 'jisx0208.1983')
end end
end end
@ -397,9 +392,9 @@ class TkFont
if option if option
"" ""
else else
Array([ ['family',[]], ['size',[]], ['weight',[]], ['slant',[]], [['family',[]], ['size',[]], ['weight',[]], ['slant',[]],
['underline',[]], ['overstrike',[]], ['charset',[]], ['underline',[]], ['overstrike',[]], ['charset',[]],
['pointadjust',[]] ]) ['pointadjust',[]]]
end end
end end
@ -440,9 +435,9 @@ class TkFont
if option if option
"" ""
else else
Array([ ['family',[]], ['size',[]], ['weight',[]], ['slant',[]], [['family',[]], ['size',[]], ['weight',[]], ['slant',[]],
['underline',[]], ['overstrike',[]], ['charset',[]], ['underline',[]], ['overstrike',[]], ['charset',[]],
['pointadjust',[]] ]) ['pointadjust',[]]]
end end
end end
@ -583,15 +578,15 @@ class TkFont
def kanji_replace_core_tk81(knj) def kanji_replace_core_tk81(knj)
if font.kind_of? Hash if font.kind_of? Hash
tk_call('font', 'configure', @compoundfont, *hash_kv(font)) tk_call('font', 'configure', @compoundfont, *hash_kv(knj))
else else
keys = {} keys = {}
if font.kind_of? Array if knj.kind_of? Array
actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} actual_core(array2tk_list(knj)).each{|key,val| keys[key] = val}
elsif font.kind_of? TkFont elsif knj.kind_of? TkFont
actual_core(font.latin_font).each{|key,val| keys[key] = val} actual_core(knj.latin_font).each{|key,val| keys[key] = val}
else else
actual_core(font).each{|key,val| keys[key] = val} actual_core(knj).each{|key,val| keys[key] = val}
end end
tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) tk_call('font', 'configure', @compoundfont, *hash_kv(keys))
end end
@ -616,7 +611,7 @@ class TkFont
if option if option
"" ""
else else
Array([ ['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]] ]) [['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]]]
end end
end end

20
file.c
View file

@ -51,7 +51,7 @@ VALUE rb_time_new _((time_t, time_t));
#endif #endif
#ifndef HAVE_STRING_H #ifndef HAVE_STRING_H
char *strrchr _((char*,char)); char *strrchr _((const char*,const char));
#endif #endif
#include <sys/types.h> #include <sys/types.h>
@ -256,7 +256,7 @@ group_member(gid)
int int
eaccess(path, mode) eaccess(path, mode)
char *path; const char *path;
int mode; int mode;
{ {
#ifndef NT #ifndef NT
@ -560,7 +560,7 @@ test_grpowned(obj, fname)
#if defined(S_ISUID) || defined(S_ISGID) || defined(S_ISVTX) #if defined(S_ISUID) || defined(S_ISGID) || defined(S_ISVTX)
static VALUE static VALUE
check3rdbyte(file, mode) check3rdbyte(file, mode)
char *file; const char *file;
int mode; int mode;
{ {
struct stat st; struct stat st;
@ -745,7 +745,7 @@ rb_file_ctime(obj)
static void static void
chmod_internal(path, mode) chmod_internal(path, mode)
char *path; const char *path;
int mode; int mode;
{ {
if (chmod(path, mode) == -1) if (chmod(path, mode) == -1)
@ -796,7 +796,7 @@ struct chown_args {
static void static void
chown_internal(path, args) chown_internal(path, args)
char *path; const char *path;
struct chown_args *args; struct chown_args *args;
{ {
if (chown(path, args->owner, args->group) < 0) if (chown(path, args->owner, args->group) < 0)
@ -902,7 +902,7 @@ struct utimbuf {
static void static void
utime_internal(path, utp) utime_internal(path, utp)
char *path; const char *path;
struct utimbuf *utp; struct utimbuf *utp;
{ {
if (utime(path, utp) < 0) if (utime(path, utp) < 0)
@ -987,7 +987,7 @@ rb_file_s_readlink(obj, path)
static void static void
unlink_internal(path) unlink_internal(path)
char *path; const char *path;
{ {
if (unlink(path) < 0) if (unlink(path) < 0)
rb_sys_fail(path); rb_sys_fail(path);
@ -1147,7 +1147,7 @@ rb_file_s_expand_path(argc, argv)
static int static int
rmext(p, e) rmext(p, e)
char *p, *e; const char *p, *e;
{ {
int l1, l2; int l1, l2;
@ -1303,7 +1303,7 @@ rb_file_truncate(obj, len)
# define LOCK_UN 8 # define LOCK_UN 8
# endif # endif
#if defined(USE_THREAD) && defined(EWOULDBLOCK) #if defined(EWOULDBLOCK)
static int static int
rb_thread_flock(fd, op, fptr) rb_thread_flock(fd, op, fptr)
int fd, op; int fd, op;
@ -1515,7 +1515,7 @@ static VALUE rb_mConst;
void void
rb_file_const(name, value) rb_file_const(name, value)
char *name; const char *name;
VALUE value; VALUE value;
{ {
rb_define_const(rb_cFile, name, value); rb_define_const(rb_cFile, name, value);

3
gc.c
View file

@ -911,10 +911,7 @@ rb_gc()
rb_gc_mark_locations((VALUE*)((char*)rb_gc_stack_start + 2), rb_gc_mark_locations((VALUE*)((char*)rb_gc_stack_start + 2),
(VALUE*)((char*)&stack_end + 2)); (VALUE*)((char*)&stack_end + 2));
#endif #endif
#ifdef USE_THREAD
rb_gc_mark_threads(); rb_gc_mark_threads();
#endif
/* mark protected global variables */ /* mark protected global variables */
for (list = Global_List; list; list = list->next) { for (list = Global_List; list; list = list->next) {

54
hash.c
View file

@ -847,48 +847,24 @@ extern char **environ;
#endif #endif
static char **origenviron; static char **origenviron;
void
ruby_unsetenv(name)
char *name;
{
int i, len;
len = strlen(name);
for(i=0; environ[i]; i++) {
if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
break;
}
}
while (environ[i]) {
environ[i] = environ[i+1];
i++;
}
}
static VALUE static VALUE
env_delete(obj, name) env_delete(obj, name)
VALUE obj, name; VALUE obj, name;
{ {
int i, len; int i, len;
char *nam, *val = 0; char *nam, *val;
rb_secure(4); rb_secure(4);
nam = STR2CSTR(name); nam = str2cstr(name, &len);
if (strcmp(nam, "PATH") == 0 && !OBJ_TAINTED(name)) { if (strlen(nam) != len) {
path_tainted = 0; rb_raise(rb_eArgError, "bad environment variable name");
}
len = strlen(nam);
for(i=0; environ[i]; i++) {
if (strncmp(environ[i], nam, len) == 0 && environ[i][len] == '=') {
val = environ[i]+len+1;
break;
}
}
while (environ[i]) {
environ[i] = environ[i+1];
i++;
} }
val = getenv(nam);
if (val) { if (val) {
ruby_setenv(nam, 0);
if (strcmp(nam, "PATH") == 0 && !OBJ_TAINTED(name)) {
path_tainted = 0;
}
return rb_str_new2(val); return rb_str_new2(val);
} }
return Qnil; return Qnil;
@ -1011,7 +987,7 @@ ruby_setenv(name, value)
char *name; char *name;
char *value; char *value;
{ {
#ifdef WIN32 #if defined(WIN32) && !defined(__CYGWIN32__)
#ifdef USE_WIN32_RTL_ENV #ifdef USE_WIN32_RTL_ENV
register char *envstr; register char *envstr;
STRLEN namlen = strlen(name); STRLEN namlen = strlen(name);
@ -1069,7 +1045,7 @@ ruby_setenv(name, value)
#else /* WIN32 */ #else /* WIN32 */
register int i=envix(name); /* where does it go? */ int i=envix(name); /* where does it go? */
if (environ == origenviron) { /* need we copy environment? */ if (environ == origenviron) { /* need we copy environment? */
int j; int j;
@ -1084,6 +1060,7 @@ ruby_setenv(name, value)
environ = tmpenv; /* tell exec where it is now */ environ = tmpenv; /* tell exec where it is now */
} }
if (!value) { if (!value) {
free(environ[i]);
while (environ[i]) { while (environ[i]) {
environ[i] = environ[i+1]; environ[i] = environ[i+1];
i++; i++;
@ -1113,6 +1090,13 @@ ruby_setenv(name, value)
#endif /* WIN32 */ #endif /* WIN32 */
} }
void
ruby_unsetenv(name)
char *name;
{
ruby_setenv(name, 0);
}
static VALUE static VALUE
rb_f_setenv(obj, nm, val) rb_f_setenv(obj, nm, val)
VALUE obj, nm, val; VALUE obj, nm, val;

View file

@ -56,9 +56,7 @@ rb_call_inits()
Init_eval(); Init_eval();
Init_String(); Init_String();
Init_Exception(); Init_Exception();
#ifdef USE_THREAD
Init_Thread(); Init_Thread();
#endif
Init_Numeric(); Init_Numeric();
Init_Bignum(); Init_Bignum();
Init_Array(); Init_Array();

View file

@ -7,6 +7,7 @@ destdir = ARGV[0] || ''
$:.unshift CONFIG["srcdir"]+"/lib" $:.unshift CONFIG["srcdir"]+"/lib"
require "ftools" require "ftools"
require "find"
binsuffix = CONFIG["binsuffix"] binsuffix = CONFIG["binsuffix"]
if ENV["prefix"] if ENV["prefix"]
@ -51,8 +52,12 @@ File.makedirs archdir, true
Dir.chdir "ext" Dir.chdir "ext"
system "../miniruby#{binsuffix} extmk.rb install #{destdir}" system "../miniruby#{binsuffix} extmk.rb install #{destdir}"
Dir.chdir CONFIG["srcdir"] Dir.chdir CONFIG["srcdir"]
for f in Dir["lib/*.rb"]
File.install f, pkglibdir, 0644, true Find.find("lib") do |f|
next unless /\.rb$/ =~ f
dir = pkglibdir+"/"+File.dirname(f[4..-1])
File.makedirs dir, true unless File.directory? dir
File.install f, dir, 0644, true
end end
for f in Dir["*.h"] for f in Dir["*.h"]

View file

@ -41,7 +41,7 @@ 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 _((char*, int)); VALUE rb_str2inum _((const char*, 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)
@ -73,28 +73,28 @@ VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE)); VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
VALUE rb_obj_singleton_methods _((VALUE)); VALUE rb_obj_singleton_methods _((VALUE));
void rb_define_method_id _((VALUE, ID, VALUE (*)(), int)); void rb_define_method_id _((VALUE, ID, VALUE (*)(), int));
void rb_undef_method _((VALUE, char*)); void rb_undef_method _((VALUE, const char*));
void rb_define_protected_method _((VALUE, char*, VALUE (*)(), int)); void rb_define_protected_method _((VALUE, const char*, VALUE (*)(), int));
void rb_define_private_method _((VALUE, char*, VALUE (*)(), int)); void rb_define_private_method _((VALUE, const char*, VALUE (*)(), int));
void rb_define_singleton_method _((VALUE,char*,VALUE(*)(),int)); void rb_define_singleton_method _((VALUE,const char*,VALUE(*)(),int));
void rb_define_private_method _((VALUE,char*,VALUE(*)(),int)); void rb_define_private_method _((VALUE,const char*,VALUE(*)(),int));
VALUE rb_singleton_class _((VALUE)); VALUE rb_singleton_class _((VALUE));
/* enum.c */ /* enum.c */
VALUE rb_enum_length _((VALUE)); VALUE rb_enum_length _((VALUE));
/* error.c */ /* error.c */
extern int ruby_nerrs; extern int ruby_nerrs;
VALUE rb_exc_new _((VALUE, char*, int)); VALUE rb_exc_new _((VALUE, const char*, int));
VALUE rb_exc_new2 _((VALUE, char*)); VALUE rb_exc_new2 _((VALUE, const char*));
VALUE rb_exc_new3 _((VALUE, VALUE)); VALUE rb_exc_new3 _((VALUE, VALUE));
void rb_loaderror __((char*, ...)) NORETURN; void rb_loaderror __((const char*, ...)) NORETURN;
void rb_compile_error __((char*, ...)); void rb_compile_error __((const char*, ...));
void rb_compile_error_append __((char*, ...)); void rb_compile_error_append __((const char*, ...));
/* eval.c */ /* eval.c */
void rb_exc_raise _((VALUE)) NORETURN; void rb_exc_raise _((VALUE)) NORETURN;
void rb_exc_fatal _((VALUE)) NORETURN; void rb_exc_fatal _((VALUE)) NORETURN;
void rb_remove_method _((VALUE, char*)); void rb_remove_method _((VALUE, const char*));
void rb_disable_super _((VALUE, char*)); void rb_disable_super _((VALUE, const char*));
void rb_enable_super _((VALUE, char*)); void rb_enable_super _((VALUE, const char*));
void rb_clear_cache _((void)); void rb_clear_cache _((void));
void rb_alias _((VALUE, ID, ID)); void rb_alias _((VALUE, ID, ID));
void rb_attr _((VALUE,ID,int,int,int)); void rb_attr _((VALUE,ID,int,int,int));
@ -104,7 +104,6 @@ VALUE rb_dvar_ref _((ID));
void rb_dvar_asgn _((ID, VALUE)); void rb_dvar_asgn _((ID, VALUE));
void rb_dvar_push _((ID, VALUE)); void rb_dvar_push _((ID, VALUE));
VALUE rb_eval_cmd _((VALUE, VALUE)); VALUE rb_eval_cmd _((VALUE, VALUE));
VALUE rb_trap_eval _((VALUE, int));
int rb_respond_to _((VALUE, ID)); int rb_respond_to _((VALUE, ID));
void rb_interrupt _((void)); void rb_interrupt _((void));
VALUE rb_apply _((VALUE, ID, VALUE)); VALUE rb_apply _((VALUE, ID, VALUE));
@ -115,7 +114,7 @@ VALUE rb_obj_instance_eval _((int, VALUE*, VALUE));
void rb_load _((VALUE, int)); void rb_load _((VALUE, int));
void rb_load_protect _((VALUE, int, int*)); void rb_load_protect _((VALUE, int, int*));
void rb_jump_tag _((int)) NORETURN; void rb_jump_tag _((int)) NORETURN;
void rb_provide _((char*)); void rb_provide _((const char*));
VALUE rb_f_require _((VALUE, VALUE)); VALUE rb_f_require _((VALUE, VALUE));
void rb_obj_call_init _((VALUE, int, VALUE*)); void rb_obj_call_init _((VALUE, int, VALUE*));
VALUE rb_class_new_instance _((int, VALUE*, VALUE)); VALUE rb_class_new_instance _((int, VALUE*, VALUE));
@ -135,6 +134,7 @@ VALUE rb_thread_create _((VALUE (*)(), void*));
int rb_thread_scope_shared_p _((void)); int rb_thread_scope_shared_p _((void));
void rb_thread_interrupt _((void)); void rb_thread_interrupt _((void));
void rb_thread_trap_eval _((VALUE, int)); void rb_thread_trap_eval _((VALUE, int));
void rb_thread_signal_raise _((char*));
int rb_thread_select(); int rb_thread_select();
void rb_thread_wait_for(); void rb_thread_wait_for();
VALUE rb_thread_current _((void)); VALUE rb_thread_current _((void));
@ -142,9 +142,9 @@ VALUE rb_thread_main _((void));
VALUE rb_thread_local_aref _((VALUE, ID)); VALUE rb_thread_local_aref _((VALUE, ID));
VALUE rb_thread_local_aset _((VALUE, ID, VALUE)); VALUE rb_thread_local_aset _((VALUE, ID, VALUE));
/* file.c */ /* file.c */
int eaccess _((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 _((char*, VALUE)); void rb_file_const _((const char*, VALUE));
/* 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*));
@ -176,7 +176,7 @@ VALUE rb_io_ungetc _((VALUE, VALUE));
VALUE rb_io_close _((VALUE)); VALUE rb_io_close _((VALUE));
VALUE rb_io_eof _((VALUE)); VALUE rb_io_eof _((VALUE));
VALUE rb_io_binmode _((VALUE)); VALUE rb_io_binmode _((VALUE));
VALUE rb_file_open _((char*, char*)); VALUE rb_file_open _((const char*, const char*));
VALUE rb_gets _((void)); VALUE rb_gets _((void));
void rb_str_setter _((VALUE, ID, VALUE*)); void rb_str_setter _((VALUE, ID, VALUE*));
/* numeric.c */ /* numeric.c */
@ -198,7 +198,7 @@ VALUE rb_obj_taint _((VALUE));
VALUE rb_obj_tainted _((VALUE)); VALUE rb_obj_tainted _((VALUE));
VALUE rb_obj_untaint _((VALUE)); VALUE rb_obj_untaint _((VALUE));
VALUE rb_obj_id _((VALUE)); VALUE rb_obj_id _((VALUE));
VALUE rb_convert_type _((VALUE,int,char*,char*)); VALUE rb_convert_type _((VALUE,int,const char*,const char*));
VALUE rb_Integer _((VALUE)); VALUE rb_Integer _((VALUE));
VALUE rb_Float _((VALUE)); VALUE rb_Float _((VALUE));
VALUE rb_String _((VALUE)); VALUE rb_String _((VALUE));
@ -217,11 +217,11 @@ void rb_backref_set _((VALUE));
VALUE rb_lastline_get _((void)); VALUE rb_lastline_get _((void));
void rb_lastline_set _((VALUE)); void rb_lastline_set _((VALUE));
/* process.c */ /* process.c */
int rb_proc_exec _((char*)); int rb_proc_exec _((const char*));
void rb_syswait _((int)); void rb_syswait _((int));
/* range.c */ /* range.c */
VALUE rb_range_new _((VALUE, VALUE)); VALUE rb_range_new _((VALUE, VALUE, int));
VALUE rb_range_beg_end _((VALUE, int*, int*)); VALUE rb_range_beg_len _((VALUE, int*, int*, int, int));
/* re.c */ /* re.c */
VALUE rb_reg_nth_defined _((int, VALUE)); VALUE rb_reg_nth_defined _((int, VALUE));
VALUE rb_reg_nth_match _((int, VALUE)); VALUE rb_reg_nth_match _((int, VALUE));
@ -229,12 +229,12 @@ VALUE rb_reg_last_match _((VALUE));
VALUE rb_reg_match_pre _((VALUE)); VALUE rb_reg_match_pre _((VALUE));
VALUE rb_reg_match_post _((VALUE)); VALUE rb_reg_match_post _((VALUE));
VALUE rb_reg_match_last _((VALUE)); VALUE rb_reg_match_last _((VALUE));
VALUE rb_reg_new _((char*, int, int)); VALUE rb_reg_new _((const char*, int, int));
VALUE rb_reg_match _((VALUE, VALUE)); VALUE rb_reg_match _((VALUE, VALUE));
VALUE rb_reg_match2 _((VALUE)); VALUE rb_reg_match2 _((VALUE));
int rb_reg_options _((VALUE)); int rb_reg_options _((VALUE));
char*rb_get_kcode _((void)); const char* rb_get_kcode _((void));
void rb_set_kcode _((char*)); void rb_set_kcode _((const char*));
int rb_ignorecase_p _((void)); int rb_ignorecase_p _((void));
/* ruby.c */ /* ruby.c */
extern VALUE rb_argv0; extern VALUE rb_argv0;
@ -257,12 +257,12 @@ void rb_trap_exec _((void));
/* sprintf.c */ /* sprintf.c */
VALUE rb_f_sprintf _((int, VALUE*)); VALUE rb_f_sprintf _((int, VALUE*));
/* string.c */ /* string.c */
VALUE rb_str_new _((char*, int)); VALUE rb_str_new _((const char*, int));
VALUE rb_str_new2 _((char*)); VALUE rb_str_new2 _((const char*));
VALUE rb_str_new3 _((VALUE)); VALUE rb_str_new3 _((VALUE));
VALUE rb_str_new4 _((VALUE)); VALUE rb_str_new4 _((VALUE));
VALUE rb_tainted_str_new _((char*, int)); VALUE rb_tainted_str_new _((const char*, int));
VALUE rb_tainted_str_new2 _((char*)); VALUE rb_tainted_str_new2 _((const char*));
VALUE rb_obj_as_string _((VALUE)); VALUE rb_obj_as_string _((VALUE));
VALUE rb_str_to_str _((VALUE)); VALUE rb_str_to_str _((VALUE));
VALUE rb_str_dup _((VALUE)); VALUE rb_str_dup _((VALUE));
@ -272,32 +272,34 @@ VALUE rb_str_substr _((VALUE, int, int));
void rb_str_modify _((VALUE)); void rb_str_modify _((VALUE));
VALUE rb_str_freeze _((VALUE)); VALUE rb_str_freeze _((VALUE));
VALUE rb_str_resize _((VALUE, int)); VALUE rb_str_resize _((VALUE, int));
VALUE rb_str_cat _((VALUE, char*, int)); VALUE rb_str_cat _((VALUE, const char*, int));
VALUE rb_str_concat _((VALUE, VALUE)); VALUE rb_str_concat _((VALUE, VALUE));
int rb_str_hash _((VALUE)); int rb_str_hash _((VALUE));
int rb_str_cmp _((VALUE, VALUE)); int rb_str_cmp _((VALUE, VALUE));
VALUE rb_str_upto _((VALUE, VALUE)); VALUE rb_str_upto _((VALUE, VALUE, int));
VALUE rb_str_inspect _((VALUE)); VALUE rb_str_inspect _((VALUE));
VALUE rb_str_split _((VALUE, char*)); VALUE rb_str_split _((VALUE, const char*));
/* struct.c */ /* struct.c */
VALUE rb_struct_new __((VALUE, ...)); VALUE rb_struct_new __((VALUE, ...));
VALUE rb_struct_define __((char*, ...)); VALUE rb_struct_define __((const char*, ...));
VALUE rb_struct_alloc _((VALUE, VALUE)); VALUE rb_struct_alloc _((VALUE, VALUE));
VALUE rb_struct_aref _((VALUE, VALUE)); VALUE rb_struct_aref _((VALUE, VALUE));
VALUE rb_struct_aset _((VALUE, VALUE, VALUE)); VALUE rb_struct_aset _((VALUE, VALUE, VALUE));
VALUE rb_struct_getmember _((VALUE, ID)); VALUE rb_struct_getmember _((VALUE, ID));
/* time.c */
VALUE rb_time_new();
/* variable.c */ /* variable.c */
VALUE rb_mod_name _((VALUE)); VALUE rb_mod_name _((VALUE));
VALUE rb_class_path _((VALUE)); VALUE rb_class_path _((VALUE));
void rb_set_class_path _((VALUE, VALUE, char*)); void rb_set_class_path _((VALUE, VALUE, const char*));
VALUE rb_path2class _((char*)); VALUE rb_path2class _((const char*));
void rb_name_class _((VALUE, ID)); void rb_name_class _((VALUE, ID));
void rb_autoload _((char*, char*)); void rb_autoload _((const char*, const char*));
VALUE rb_f_autoload _((VALUE, VALUE, VALUE)); VALUE rb_f_autoload _((VALUE, VALUE, VALUE));
void rb_gc_mark_global_tbl _((void)); void rb_gc_mark_global_tbl _((void));
VALUE rb_f_trace_var _((int, VALUE*)); VALUE rb_f_trace_var _((int, VALUE*));
VALUE rb_f_untrace_var _((int, VALUE*)); VALUE rb_f_untrace_var _((int, VALUE*));
VALUE rb_gvar_set2 _((char*, VALUE)); VALUE rb_gvar_set2 _((const char*, 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));
void rb_mark_generic_ivar _((VALUE)); void rb_mark_generic_ivar _((VALUE));

93
io.c
View file

@ -110,16 +110,12 @@ extern int ReadDataPending();
# define READ_DATA_PENDING(fp) ReadDataPending(fp) # define READ_DATA_PENDING(fp) ReadDataPending(fp)
#endif #endif
#ifndef USE_THREAD #define READ_CHECK(fp) do {\
# define READ_CHECK(fp) 0
#else
# define READ_CHECK(fp) do {\
if (!READ_DATA_PENDING(fp)) {\ if (!READ_DATA_PENDING(fp)) {\
rb_thread_wait_fd(fileno(fp));\ rb_thread_wait_fd(fileno(fp));\
rb_io_check_closed(fptr);\ rb_io_check_closed(fptr);\
}\ }\
} while(0) } while(0)
#endif
void void
rb_eof_error() rb_eof_error()
@ -154,8 +150,8 @@ rb_io_check_writable(fptr)
} }
/* writing functions */ /* writing functions */
VALUE static VALUE
rb_io_write(io, str) io_write(io, str)
VALUE io, str; VALUE io, str;
{ {
OpenFile *fptr; OpenFile *fptr;
@ -200,6 +196,13 @@ rb_io_write(io, str)
return INT2FIX(n); return INT2FIX(n);
} }
VALUE
rb_io_write(io, str)
VALUE io, str;
{
return rb_funcall(io, id_write, 1, str);
}
static VALUE static VALUE
rb_io_addstr(io, str) rb_io_addstr(io, str)
VALUE io, str; VALUE io, str;
@ -419,7 +422,7 @@ read_all(port)
} }
static VALUE static VALUE
rb_io_read(argc, argv, io) io_read(argc, argv, io)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE io; VALUE io;
@ -850,10 +853,7 @@ rb_io_fptr_close(fptr)
int fd; int fd;
if (fptr->f == NULL && fptr->f2 == NULL) return; if (fptr->f == NULL && fptr->f2 == NULL) return;
#ifdef USE_THREAD
rb_thread_fd_close(fileno(fptr->f)); rb_thread_fd_close(fileno(fptr->f));
#endif
if (fptr->finalize) { if (fptr->finalize) {
(*fptr->finalize)(fptr); (*fptr->finalize)(fptr);
@ -911,6 +911,7 @@ rb_io_close_read(io)
VALUE io; VALUE io;
{ {
OpenFile *fptr; OpenFile *fptr;
int n;
rb_secure(4); rb_secure(4);
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
@ -920,10 +921,11 @@ rb_io_close_read(io)
if (fptr->f2 == 0) { if (fptr->f2 == 0) {
return rb_io_close(io); return rb_io_close(io);
} }
fclose(fptr->f); n = fclose(fptr->f);
fptr->mode &= ~FMODE_READABLE; fptr->mode &= ~FMODE_READABLE;
fptr->f = fptr->f2; fptr->f = fptr->f2;
fptr->f2 = 0; fptr->f2 = 0;
if (n != 0) rb_sys_fail(fptr->path);
return Qnil; return Qnil;
} }
@ -933,6 +935,7 @@ rb_io_close_write(io)
VALUE io; VALUE io;
{ {
OpenFile *fptr; OpenFile *fptr;
int n;
rb_secure(4); rb_secure(4);
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
@ -942,9 +945,10 @@ rb_io_close_write(io)
if (fptr->f2 == 0) { if (fptr->f2 == 0) {
return rb_io_close(io); return rb_io_close(io);
} }
fclose(fptr->f2); n = fclose(fptr->f2);
fptr->f2 = 0; fptr->f2 = 0;
fptr->mode &= ~FMODE_WRITABLE; fptr->mode &= ~FMODE_WRITABLE;
if (n != 0) rb_sys_fail(fptr->path);
return Qnil; return Qnil;
} }
@ -965,11 +969,9 @@ rb_io_syswrite(io, str)
rb_io_check_writable(fptr); rb_io_check_writable(fptr);
f = GetWriteFile(fptr); f = GetWriteFile(fptr);
#ifdef USE_THREAD
if (!rb_thread_fd_writable(fileno(f))) { if (!rb_thread_fd_writable(fileno(f))) {
rb_io_check_closed(fptr); rb_io_check_closed(fptr);
} }
#endif
n = write(fileno(f), RSTRING(str)->ptr, RSTRING(str)->len); n = write(fileno(f), RSTRING(str)->ptr, RSTRING(str)->len);
if (n == -1) rb_sys_fail(fptr->path); if (n == -1) rb_sys_fail(fptr->path);
@ -991,9 +993,7 @@ rb_io_sysread(io, len)
str = rb_str_new(0, ilen); str = rb_str_new(0, ilen);
#ifdef USE_THREAD
rb_thread_wait_fd(fileno(fptr->f)); rb_thread_wait_fd(fileno(fptr->f));
#endif
TRAP_BEG; TRAP_BEG;
n = read(fileno(fptr->f), RSTRING(str)->ptr, RSTRING(str)->len); n = read(fileno(fptr->f), RSTRING(str)->ptr, RSTRING(str)->len);
TRAP_END; TRAP_END;
@ -1158,8 +1158,8 @@ rb_open(fname, flag, mode)
FILE * FILE *
rb_fopen(fname, mode) rb_fopen(fname, mode)
char *fname; const char *fname;
char *mode; const char *mode;
{ {
FILE *file; FILE *file;
@ -1179,7 +1179,7 @@ rb_fopen(fname, mode)
FILE * FILE *
rb_fdopen(fd, mode) rb_fdopen(fd, mode)
int fd; int fd;
char *mode; const char *mode;
{ {
FILE *file; FILE *file;
@ -1198,7 +1198,7 @@ rb_fdopen(fd, mode)
VALUE VALUE
rb_file_open(fname, mode) rb_file_open(fname, mode)
char *fname, *mode; const char *fname, *mode;
{ {
OpenFile *fptr; OpenFile *fptr;
NEWOBJ(port, struct RFile); NEWOBJ(port, struct RFile);
@ -1388,8 +1388,6 @@ pipe_open(pname, mode)
} }
if (doexec) { if (doexec) {
extern char *ruby_sourcefile;
extern int ruby_sourceline;
int fd; int fd;
for (fd = 3; fd < NOFILE; fd++) for (fd = 3; fd < NOFILE; fd++)
@ -1403,11 +1401,7 @@ pipe_open(pname, mode)
case -1: /* fork failed */ case -1: /* fork failed */
if (errno == EAGAIN) { if (errno == EAGAIN) {
#ifdef USE_THREAD
rb_thread_sleep(1); rb_thread_sleep(1);
#else
sleep(1);
#endif
goto retry; goto retry;
} }
close(pr[0]); close(pw[1]); close(pr[0]); close(pw[1]);
@ -1603,9 +1597,7 @@ rb_io_reopen(io, nfile)
else if (orig->mode & FMODE_WRITABLE) { else if (orig->mode & FMODE_WRITABLE) {
fflush(orig->f); fflush(orig->f);
} }
#ifdef USE_THREAD
rb_thread_fd_close(fileno(fptr->f)); rb_thread_fd_close(fileno(fptr->f));
#endif
/* copy OpenFile structure */ /* copy OpenFile structure */
fptr->mode = orig->mode; fptr->mode = orig->mode;
@ -2060,8 +2052,8 @@ next_argv()
next_p = 0; next_p = 0;
if (RARRAY(rb_argv)->len > 0) { if (RARRAY(rb_argv)->len > 0) {
filename = rb_ary_shift(rb_argv); filename = rb_ary_shift(rb_argv);
fn = RSTRING(filename)->ptr; fn = STR2CSTR(filename);
if (RSTRING(filename)->len == 1 && fn[0] == '-') { if (strlen(fn) == 1 && fn[0] == '-') {
file = rb_stdin; file = rb_stdin;
if (ruby_inplace_mode) { if (ruby_inplace_mode) {
rb_defout = rb_stdout; rb_defout = rb_stdout;
@ -2282,6 +2274,7 @@ rb_f_select(argc, argv, obj)
int i, max = 0, n; int i, max = 0, n;
int interrupt_flag = 0; int interrupt_flag = 0;
int pending = 0; int pending = 0;
VALUE io;
rb_scan_args(argc, argv, "13", &read, &write, &except, &timeout); rb_scan_args(argc, argv, "13", &read, &write, &except, &timeout);
if (NIL_P(timeout)) { if (NIL_P(timeout)) {
@ -2298,9 +2291,7 @@ rb_f_select(argc, argv, obj)
rp = &rset; rp = &rset;
FD_ZERO(rp); FD_ZERO(rp);
for (i=0; i<RARRAY(read)->len; i++) { for (i=0; i<RARRAY(read)->len; i++) {
VALUE io = rb_io_get_io(RARRAY(read)->ptr[i]); GetOpenFile(rb_io_get_io(RARRAY(read)->ptr[i]), fptr);
GetOpenFile(io, fptr);
FD_SET(fileno(fptr->f), rp); FD_SET(fileno(fptr->f), rp);
if (READ_DATA_PENDING(fptr->f)) { /* check for buffered data */ if (READ_DATA_PENDING(fptr->f)) { /* check for buffered data */
pending++; pending++;
@ -2321,9 +2312,7 @@ rb_f_select(argc, argv, obj)
wp = &wset; wp = &wset;
FD_ZERO(wp); FD_ZERO(wp);
for (i=0; i<RARRAY(write)->len; i++) { for (i=0; i<RARRAY(write)->len; i++) {
VALUE io = rb_io_get_io(RARRAY(write)->ptr[i]); GetOpenFile(rb_io_get_io(RARRAY(write)->ptr[i]), fptr);
GetOpenFile(io, fptr);
FD_SET(fileno(fptr->f), wp); FD_SET(fileno(fptr->f), wp);
if (max < fileno(fptr->f)) max = fileno(fptr->f); if (max < fileno(fptr->f)) max = fileno(fptr->f);
if (fptr->f2) { if (fptr->f2) {
@ -2340,9 +2329,7 @@ rb_f_select(argc, argv, obj)
ep = &eset; ep = &eset;
FD_ZERO(ep); FD_ZERO(ep);
for (i=0; i<RARRAY(except)->len; i++) { for (i=0; i<RARRAY(except)->len; i++) {
VALUE io = rb_io_get_io(RARRAY(except)->ptr[i]); GetOpenFile(rb_io_get_io(RARRAY(except)->ptr[i]), fptr);
GetOpenFile(io, fptr);
FD_SET(fileno(fptr->f), ep); FD_SET(fileno(fptr->f), ep);
if (max < fileno(fptr->f)) max = fileno(fptr->f); if (max < fileno(fptr->f)) max = fileno(fptr->f);
if (fptr->f2) { if (fptr->f2) {
@ -2356,24 +2343,10 @@ rb_f_select(argc, argv, obj)
max++; max++;
#ifdef USE_THREAD
n = rb_thread_select(max, rp, wp, ep, tp); n = rb_thread_select(max, rp, wp, ep, tp);
if (n < 0) { if (n < 0) {
rb_sys_fail(0); rb_sys_fail(0);
} }
#else
retry:
TRAP_BEG;
n = select(max, rp, wp, ep, tp);
TRAP_END;
if (n < 0) {
if (errno != EINTR) {
rb_sys_fail(0);
}
if (tp == NULL) goto retry;
interrupt_flag = 1;
}
#endif
if (!pending && n == 0) return Qnil; /* returns nil on timeout */ if (!pending && n == 0) return Qnil; /* returns nil on timeout */
res = rb_ary_new2(3); res = rb_ary_new2(3);
@ -2385,7 +2358,7 @@ rb_f_select(argc, argv, obj)
if (rp) { if (rp) {
list = RARRAY(res)->ptr[0]; list = RARRAY(res)->ptr[0];
for (i=0; i< RARRAY(read)->len; i++) { for (i=0; i< RARRAY(read)->len; i++) {
GetOpenFile(RARRAY(read)->ptr[i], fptr); GetOpenFile(rb_io_get_io(RARRAY(read)->ptr[i]), fptr);
if (FD_ISSET(fileno(fptr->f), rp) if (FD_ISSET(fileno(fptr->f), rp)
|| FD_ISSET(fileno(fptr->f), &pset)) { || FD_ISSET(fileno(fptr->f), &pset)) {
rb_ary_push(list, RARRAY(read)->ptr[i]); rb_ary_push(list, RARRAY(read)->ptr[i]);
@ -2396,7 +2369,7 @@ rb_f_select(argc, argv, obj)
if (wp) { if (wp) {
list = RARRAY(res)->ptr[1]; list = RARRAY(res)->ptr[1];
for (i=0; i< RARRAY(write)->len; i++) { for (i=0; i< RARRAY(write)->len; i++) {
GetOpenFile(RARRAY(write)->ptr[i], fptr); GetOpenFile(rb_io_get_io(RARRAY(write)->ptr[i]), fptr);
if (FD_ISSET(fileno(fptr->f), wp)) { if (FD_ISSET(fileno(fptr->f), wp)) {
rb_ary_push(list, RARRAY(write)->ptr[i]); rb_ary_push(list, RARRAY(write)->ptr[i]);
} }
@ -2409,7 +2382,7 @@ rb_f_select(argc, argv, obj)
if (ep) { if (ep) {
list = RARRAY(res)->ptr[2]; list = RARRAY(res)->ptr[2];
for (i=0; i< RARRAY(except)->len; i++) { for (i=0; i< RARRAY(except)->len; i++) {
GetOpenFile(RARRAY(except)->ptr[i], fptr); GetOpenFile(rb_io_get_io(RARRAY(except)->ptr[i]), fptr);
if (FD_ISSET(fileno(fptr->f), ep)) { if (FD_ISSET(fileno(fptr->f), ep)) {
rb_ary_push(list, RARRAY(except)->ptr[i]); rb_ary_push(list, RARRAY(except)->ptr[i]);
} }
@ -2787,7 +2760,7 @@ arg_read(argc, argv)
retry: retry:
if (!next_argv()) return str; if (!next_argv()) return str;
tmp = rb_io_read(argc, argv, file); tmp = io_read(argc, argv, file);
if (NIL_P(tmp) && next_p != -1) { if (NIL_P(tmp) && next_p != -1) {
rb_io_close(file); rb_io_close(file);
next_p = 1; next_p = 1;
@ -3017,8 +2990,8 @@ Init_IO()
rb_define_method(rb_cIO, "readlines", rb_io_readlines, -1); rb_define_method(rb_cIO, "readlines", rb_io_readlines, -1);
rb_define_method(rb_cIO, "read", rb_io_read, -1); rb_define_method(rb_cIO, "read", io_read, -1);
rb_define_method(rb_cIO, "write", rb_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_method, -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);

View file

@ -27,14 +27,14 @@ and query.cookie has Hash class methods
== print HTTP header and HTML string to $> == print HTTP header and HTML string to $>
require "cgi-lib.rb" require "cgi-lib.rb"
CGI.print{ CGI::print{
CGI.tag("HTML"){ CGI::tag("HTML"){
CGI.tag("HEAD"){ CGI.tag("TITLE"){"TITLE"} } + CGI::tag("HEAD"){ CGI::tag("TITLE"){"TITLE"} } +
CGI.tag("BODY"){ CGI::tag("BODY"){
CGI.tag("FORM", {"ACTION"=>"test.rb", "METHOD"=>"POST"}){ CGI::tag("FORM", {"ACTION"=>"test.rb", "METHOD"=>"POST"}){
CGI.tag("INPUT", {"TYPE"=>"submit", "VALUE"=>"submit"}) CGI::tag("INPUT", {"TYPE"=>"submit", "VALUE"=>"submit"})
} + } +
CGI.tag("HR") CGI::tag("HR")
} }
} }
} }
@ -43,68 +43,68 @@ and query.cookie has Hash class methods
== make raw cookie string == make raw cookie string
require "cgi-lib.rb" require "cgi-lib.rb"
cookie1 = CGI.cookie({'name' => 'name', cookie1 = CGI::cookie({'name' => 'name',
'value' => 'value', 'value' => 'value',
'path' => 'path', # optional 'path' => 'path', # optional
'domain' => 'domain', # optional 'domain' => 'domain', # optional
'expires' => Time.now, # optional 'expires' => Time.now, # optional
'secure' => true # optional 'secure' => true # optional
}) })
CGI.print("Content-Type: text/html", cookie1, cookie2){ "string" } CGI::print("Content-Type: text/html", cookie1, cookie2){ "string" }
== print HTTP header and string to $> == print HTTP header and string to $>
require "cgi-lib.rb" require "cgi-lib.rb"
CGI.print{ "string" } CGI::print{ "string" }
# == CGI.print("Content-Type: text/html"){ "string" } # == CGI::print("Content-Type: text/html"){ "string" }
CGI.print("Content-Type: text/html", cookie1, cookie2){ "string" } CGI::print("Content-Type: text/html", cookie1, cookie2){ "string" }
=== NPH (no-parse-header) mode === NPH (no-parse-header) mode
require "cgi-lib.rb" require "cgi-lib.rb"
CGI.print("nph"){ "string" } CGI::print("nph"){ "string" }
# == CGI.print("nph", "Content-Type: text/html"){ "string" } # == CGI::print("nph", "Content-Type: text/html"){ "string" }
CGI.print("nph", "Content-Type: text/html", cookie1, cookie2){ "string" } CGI::print("nph", "Content-Type: text/html", cookie1, cookie2){ "string" }
== make HTML tag string == make HTML tag string
require "cgi-lib.rb" require "cgi-lib.rb"
CGI.tag("element", {"attribute_name"=>"attribute_value"}){"content"} CGI::tag("element", {"attribute_name"=>"attribute_value"}){"content"}
== make HTTP header string == make HTTP header string
require "cgi-lib.rb" require "cgi-lib.rb"
CGI.header # == CGI.header("Content-Type: text/html") CGI::header # == CGI::header("Content-Type: text/html")
CGI.header("Content-Type: text/html", cookie1, cookie2) CGI::header("Content-Type: text/html", cookie1, cookie2)
=== NPH (no-parse-header) mode === NPH (no-parse-header) mode
CGI.header("nph") # == CGI.header("nph", "Content-Type: text/html") CGI::header("nph") # == CGI::header("nph", "Content-Type: text/html")
CGI.header("nph", "Content-Type: text/html", cookie1, cookie2) CGI::header("nph", "Content-Type: text/html", cookie1, cookie2)
== escape url encode == escape url encode
require "cgi-lib.rb" require "cgi-lib.rb"
url_encoded_string = CGI.escape("string") url_encoded_string = CGI::escape("string")
== unescape url encoded == unescape url encoded
require "cgi-lib.rb" require "cgi-lib.rb"
string = CGI.unescape("url encoded string") string = CGI::unescape("url encoded string")
== escape HTML &"<> == escape HTML &"<>
require "cgi-lib.rb" require "cgi-lib.rb"
CGI.escapeHTML("string") CGI::escapeHTML("string")
=end =end
@ -117,11 +117,6 @@ class CGI < SimpleDelegator
LF = "\012" LF = "\012"
EOL = CR + LF EOL = CR + LF
# if running on Windows(IIS or PWS) then change cwd.
if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/
Dir.chdir(ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, ''))
end
# escape url encode # escape url encode
def escape(str) def escape(str)
str.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) } str.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
@ -160,12 +155,8 @@ class CGI < SimpleDelegator
case ENV['REQUEST_METHOD'] case ENV['REQUEST_METHOD']
when "GET" when "GET"
# exception messages should be printed to stdout.
STDERR.reopen($>)
ENV['QUERY_STRING'] or "" ENV['QUERY_STRING'] or ""
when "POST" when "POST"
# exception messages should be printed to stdout.
STDERR.reopen($>)
input.read Integer(ENV['CONTENT_LENGTH']) input.read Integer(ENV['CONTENT_LENGTH'])
else else
read_from_cmdline read_from_cmdline
@ -198,7 +189,7 @@ class CGI < SimpleDelegator
attr("cookie") attr("cookie")
# make HTML tag string # make HTML tag string
def CGI.tag(element, attributes = {}) def CGI::tag(element, attributes = {})
"<" + escapeHTML(element) + attributes.collect{|name, value| "<" + escapeHTML(element) + attributes.collect{|name, value|
" " + escapeHTML(name) + '="' + escapeHTML(value) + '"' " " + escapeHTML(name) + '="' + escapeHTML(value) + '"'
}.to_s + ">" + }.to_s + ">" +
@ -206,7 +197,7 @@ class CGI < SimpleDelegator
end end
# make raw cookie string # make raw cookie string
def CGI.cookie(options) def CGI::cookie(options)
"Set-Cookie: " + options['name'] + '=' + escape(options['value']) + "Set-Cookie: " + options['name'] + '=' + escape(options['value']) +
(options['domain'] ? '; domain=' + options['domain'] : '') + (options['domain'] ? '; domain=' + options['domain'] : '') +
(options['path'] ? '; path=' + options['path'] : '') + (options['path'] ? '; path=' + options['path'] : '') +
@ -215,7 +206,7 @@ class CGI < SimpleDelegator
end end
# make HTTP header string # make HTTP header string
def CGI.header(*options) def CGI::header(*options)
if ENV['MOD_RUBY'] if ENV['MOD_RUBY']
options.each{|option| options.each{|option|
option.sub(/(.*?): (.*)/){ option.sub(/(.*?): (.*)/){
@ -238,32 +229,31 @@ class CGI < SimpleDelegator
end end
# print HTTP header and string to $> # print HTTP header and string to $>
def CGI.print(*options) def CGI::print(*options)
$>.print CGI.header(*options) + yield.to_s $>.print CGI::header(*options) + yield.to_s
end end
# print message to $> # print message to $>
def CGI.message(message, title = "", header = ["Content-Type: text/html"]) def CGI::message(message, title = "", header = ["Content-Type: text/html"])
if message.kind_of?(Hash) if message.kind_of?(Hash)
title = message['title'] title = message['title']
header = message['header'] header = message['header']
message = message['body'] message = message['body']
end end
CGI.print(*header){ CGI::print(*header){
CGI.tag("HTML"){ CGI::tag("HTML"){
CGI.tag("HEAD"){ CGI.tag("TITLE"){ title } } + CGI::tag("HEAD"){ CGI.tag("TITLE"){ title } } +
CGI.tag("BODY"){ message } CGI::tag("BODY"){ message }
} }
} }
TRUE TRUE
end end
# print error message to $> and exit # print error message to $> and exit
def CGI.error def CGI::error
CGI.message({'title'=>'ERROR', 'body'=> CGI::message({'title'=>'ERROR', 'body'=>
CGI.tag("PRE"){ CGI::tag("PRE"){
"ERROR: " + CGI.tag("STRONG"){ escapeHTML($!.to_s) } + "\n" + "ERROR: " + CGI::tag("STRONG"){ escapeHTML($!.to_s) } + "\n" + escapeHTML($@.join("\n"))
escapeHTML($@.join("\n"))
} }
}) })
exit exit

View file

@ -1,107 +1,138 @@
# date.rb: Written by Tadayoshi Funaba 1998, 1999 # date.rb: Written by Tadayoshi Funaba 1998, 1999
# $Id: date.rb,v 1.5 1999/02/06 08:51:56 tadf Exp $ # $Id: date.rb,v 1.7 1999/03/06 02:05:59 tadf Exp $
class Date class Date
include Comparable include Comparable
MONTHNAMES = [ nil, 'January', 'February', 'March', 'April', 'May', 'June', MONTHNAMES = [ nil, 'January', 'February', 'March',
'July', 'August', 'September', 'October', 'November', 'December' ] 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December' ]
DAYNAMES = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', DAYNAMES = [ 'Sunday', 'Monday', 'Tuesday',
'Friday', 'Saturday' ] 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]
ITALY = 2299161 # Oct 15, 1582 ITALY = 2299161 # Oct 15, 1582
ENGLAND = 2361222 # Sept 14, 1752 ENGLAND = 2361222 # Sept 14, 1752
def Date.civil_to_jd(y, m, d, gs = true) class << self
if m <= 2 then
y -= 1
m += 12
end
a = (y / 100).to_i
b = 2 - a + (a / 4).to_i
jd = (365.25 * (y + 4716)).to_i +
(30.6001 * (m + 1)).to_i +
d + b - 1524
unless
(if gs.kind_of? Numeric then jd >= gs else gs end) then
jd -= b
end
jd
end
def Date.jd_to_civil(jd, gs = true) def civil_to_jd(y, m, d, gs=true)
unless if m <= 2
(if gs.kind_of? Numeric then jd >= gs else gs end) then y -= 1
a = jd m += 12
else end
x = ((jd - 1867216.25) / 36524.25).to_i a = (y / 100).to_i
a = jd + 1 + x - (x / 4).to_i b = 2 - a + (a / 4).to_i
end jd = (365.25 * (y + 4716)).to_i +
b = a + 1524 (30.6001 * (m + 1)).to_i +
c = ((b - 122.1) / 365.25).to_i d + b - 1524
d = (365.25 * c).to_i unless
e = ((b - d) / 30.6001).to_i (if gs.kind_of? Numeric then jd >= gs else gs end)
dom = b - d - (30.6001 * e).to_i jd -= b
if e <= 13 then end
m = e - 1
y = c - 4716
else
m = e - 13
y = c - 4715
end
return y, m, dom
end
def Date.mjd_to_jd(mjd)
mjd + 2400000.5
end
def Date.jd_to_mjd(jd)
jd - 2400000.5
end
def Date.tjd_to_jd(tjd)
tjd + 2440000.5
end
def Date.jd_to_tjd(jd)
jd - 2440000.5
end
def Date.julian_leap? (y)
y % 4 == 0
end
def Date.gregorian_leap? (y)
y % 4 == 0 and y % 100 != 0 or y % 400 == 0
end
def Date.leap? (y)
Date.gregorian_leap?(y)
end
def initialize(jd = 0, gs = ITALY)
@jd, @gs = jd, gs
end
def Date.exist? (y, m, d, gs = true)
jd = Date.civil_to_jd(y, m, d, gs)
if [y, m, d] == Date.jd_to_civil(jd, gs) then
jd jd
end end
end
def Date.new3(y = -4712, m = 1, d = 1, gs = ITALY) def jd_to_civil(jd, gs=true)
unless jd = Date.exist?(y, m, d, gs) then unless
fail ArgumentError, 'invalid date' (if gs.kind_of? Numeric then jd >= gs else gs end)
a = jd
else
x = ((jd - 1867216.25) / 36524.25).to_i
a = jd + 1 + x - (x / 4).to_i
end
b = a + 1524
c = ((b - 122.1) / 365.25).to_i
d = (365.25 * c).to_i
e = ((b - d) / 30.6001).to_i
dom = b - d - (30.6001 * e).to_i
if e <= 13
m = e - 1
y = c - 4716
else
m = e - 13
y = c - 4715
end
return y, m, dom
end end
Date.new(jd, gs)
def ordinal_to_jd(y, d, gs=true)
civil_to_jd(y, 1, d, gs)
end
def jd_to_ordinal(jd, gs=true)
y, *_ = jd_to_civil(jd, gs)
ns = if gs.kind_of? Numeric then jd >= gs else gs end
pl = civil_to_jd(y - 1, 12, 31, ns)
doy = jd - pl
return y, doy
end
def mjd_to_jd(mjd)
mjd + 2400000.5
end
def jd_to_mjd(jd)
jd - 2400000.5
end
def tjd_to_jd(tjd)
tjd + 2440000.5
end
def jd_to_tjd(jd)
jd - 2440000.5
end
def julian_leap? (y)
y % 4 == 0
end
def gregorian_leap? (y)
y % 4 == 0 and y % 100 != 0 or y % 400 == 0
end
alias_method :leap?, :gregorian_leap?
def exist3? (y, m, d, gs=true)
jd = civil_to_jd(y, m, d, gs)
if [y, m, d] == jd_to_civil(jd, gs)
jd
end
end
alias_method :exist?, :exist3?
def new3(y=-4712, m=1, d=1, gs=ITALY)
unless jd = exist3?(y, m, d, gs)
fail ArgumentError, 'invalid date'
end
new(jd, gs)
end
def exist2? (y, d, gs=true)
jd = ordinal_to_jd(y, d, gs)
if [y, d] == jd_to_ordinal(jd, gs)
jd
end
end
def new2(y=-4712, d=1, gs=ITALY)
unless jd = exist2?(y, d, gs)
fail ArgumentError, 'invalid date'
end
new(jd, gs)
end
def today(gs=ITALY)
new(civil_to_jd(*(Time.now.to_a[3..5].reverse << gs)), gs)
end
end end
def Date.today(gs = ITALY) def initialize(jd=0, gs=ITALY)
Date.new(Date.civil_to_jd(*(Time.now.to_a[3..5].reverse << gs)), gs) @jd, @gs = jd, gs
end end
def jd def jd
@ -109,19 +140,19 @@ class Date
end end
def mjd def mjd
def self.mjd; @mjd end def self.mjd() @mjd end
@mjd = Date.jd_to_mjd(@jd) @mjd = Date.jd_to_mjd(@jd)
end end
def tjd def tjd
def self.tjd; @tjd end def self.tjd() @tjd end
@tjd = Date.jd_to_tjd(@jd) @tjd = Date.jd_to_tjd(@jd)
end end
def civil def civil
def self.year; @year end def self.year() @year end
def self.mon; @mon end def self.mon() @mon end
def self.mday; @mday end def self.mday() @mday end
@year, @mon, @mday = Date.jd_to_civil(@jd, @gs) @year, @mon, @mday = Date.jd_to_civil(@jd, @gs)
end end
@ -133,10 +164,9 @@ class Date
end end
def yday def yday
def self.yday; @yday end def self.yday() @yday end
ns = if @gs.kind_of? Numeric then @jd >= @gs else @gs end _, @yday = Date.jd_to_ordinal(@jd, @gs)
jd = Date.civil_to_jd(year - 1, 12, 31, ns) @yday
@yday = @jd - jd
end end
def mon def mon
@ -150,12 +180,12 @@ class Date
end end
def wday def wday
def self.wday; @wday end def self.wday() @wday end
@wday = (@jd + 1) % 7 @wday = (@jd + 1) % 7
end end
def leap? def leap?
def self.leap?; @leap_p end def self.leap?() @leap_p end
ns = if @gs.kind_of? Numeric then @jd >= @gs else @gs end ns = if @gs.kind_of? Numeric then @jd >= @gs else @gs end
jd = Date.civil_to_jd(year, 2, 28, ns) jd = Date.civil_to_jd(year, 2, 28, ns)
@leap_p = Date.jd_to_civil(jd + 1, ns)[1] == 2 @leap_p = Date.jd_to_civil(jd + 1, ns)[1] == 2
@ -214,4 +244,12 @@ class Date
format('%04d-%02d-%02d', year, mon, mday) format('%04d-%02d-%02d', year, mon, mday)
end end
def _dump(limit)
Marshal.dump([@jd, @gs], -1)
end
def Date._load(str)
Date.new(*Marshal.load(str))
end
end end

View file

@ -34,14 +34,8 @@ class Delegator
begin begin
__getobj__.__send__(:#{method}, *args, &block) __getobj__.__send__(:#{method}, *args, &block)
rescue Exception rescue Exception
c = -caller(0).size $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
if /:in `__getobj__'$/ =~ $@[c-1] #` $@.delete_if{|s| /^\\(eval\\):/ =~ s}
n = 1
else
c -= 1
n = 2
end
$@[c,n] = nil
raise raise
end end
end end

View file

@ -37,7 +37,7 @@ $libdir += "/"+CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
$archdir = $libdir+"/"+CONFIG["arch"] $archdir = $libdir+"/"+CONFIG["arch"]
$install = CONFIG["INSTALL_PROGRAM"] $install = CONFIG["INSTALL_PROGRAM"]
$install_data = CONFIG["INSTALL_DATA"] $install_data = CONFIG["INSTALL_DATA"]
if $install !~ /^\// then if $install =~ %r!^[^\s/]+/! then
$install = CONFIG["srcdir"]+"/"+$install $install = CONFIG["srcdir"]+"/"+$install
$install_data = CONFIG["srcdir"]+"/"+$install_data $install_data = CONFIG["srcdir"]+"/"+$install_data
end end

View file

@ -1,271 +1,96 @@
## monitor.rb =begin
# Author: Shugo Maeda <shugo@po.aianet.ne.jp> monitor.rb
# Version: $Revision: 0.1 $ Author: Shugo Maeda <shugo@netlab.co.jp>
Version: 1.2.1
# USAGE: USAGE:
#
# foo = Foo.new
# foo.extend(MonitorMixin)
# cond = foo.new_cond
#
# thread1:
# foo.synchronize {
# ...
# cond.wait_until { foo.done? }
# ...
# }
#
# thread2:
# foo.synchronize {
# foo.do_something
# cond.signal
# }
# ATTENTION: foo = Foo.new
# foo.extend(MonitorMixin)
# If you include MonitorMixin and override `initialize', you should cond = foo.new_cond
# call `super'.
# If you include MonitorMixin to built-in classes, you should override
# `new' to call `mon_initialize'.
## Code: thread1:
foo.synchronize {
...
cond.wait_until { foo.done? }
...
}
thread2:
foo.synchronize {
foo.do_something
cond.signal
}
=end
require "final"
module MonitorMixin module MonitorMixin
module Accessible
RCS_ID = %q$Id: monitor.rb,v 0.1 1998/03/01 08:40:18 shugo Exp shugo $ protected
attr_accessor :mon_owner, :mon_count
module Primitive attr_reader :mon_entering_queue, :mon_waiting_queue
include MonitorMixin
MON_OWNER_TABLE = {}
MON_COUNT_TABLE = {}
MON_ENTERING_QUEUE_TABLE = {}
MON_WAITING_QUEUE_TABLE = {}
FINALIZER = Proc.new { |id|
MON_OWNER_TABLE.delete(id)
MON_COUNT_TABLE.delete(id)
MON_ENTERING_QUEUE_TABLE.delete(id)
MON_WAITING_QUEUE_TABLE.delete(id)
}
def self.extend_object(obj)
super(obj)
obj.mon_initialize
end
def mon_initialize
MON_OWNER_TABLE[id] = nil
MON_COUNT_TABLE[id] = 0
MON_ENTERING_QUEUE_TABLE[id] = []
MON_WAITING_QUEUE_TABLE[id] = []
ObjectSpace.define_finalizer(self, FINALIZER)
end
def mon_owner
return MON_OWNER_TABLE[id]
end
def mon_count
return MON_COUNT_TABLE[id]
end
def mon_entering_queue
return MON_ENTERING_QUEUE_TABLE[id]
end
def mon_waiting_queue
return MON_WAITING_QUEUE_TABLE[id]
end
def set_mon_owner(val)
return MON_OWNER_TABLE[id] = val
end
def set_mon_count(val)
return MON_COUNT_TABLE[id] = val
end
private :mon_count, :mon_entering_queue, :mon_waiting_queue,
:set_mon_owner, :set_mon_count
end end
module NonPrimitive module Initializable
protected
include MonitorMixin
attr_reader :mon_owner, :mon_count,
:mon_entering_queue, :mon_waiting_queue
def self.extend_object(obj)
super(obj)
obj.mon_initialize
end
def mon_initialize def mon_initialize
@mon_owner = nil @mon_owner = nil
@mon_count = 0 @mon_count = 0
@mon_entering_queue = [] @mon_entering_queue = []
@mon_waiting_queue = [] @mon_waiting_queue = []
end end
def set_mon_owner(val)
@mon_owner = val
end
def set_mon_count(val)
@mon_count = val
end
private :mon_count, :mon_entering_queue, :mon_waiting_queue,
:set_mon_owner, :set_mon_count
end end
def self.extendable_module(obj)
if Fixnum === obj or TrueClass === obj or FalseClass === obj or
NilClass === obj
raise TypeError, "MonitorMixin can't extend #{obj.type}"
else
begin
obj.instance_eval("@mon_owner")
return NonPrimitive
rescue TypeError
return Primitive
end
end
end
def self.extend_object(obj)
obj.extend(extendable_module(obj))
end
def self.includable_module(klass)
if klass.instance_of?(Module)
return NonPrimitive
end
begin
dummy = klass.new
return extendable_module(dummy)
rescue ArgumentError
if klass.singleton_methods.include?("new")
return Primitive
else
return NonPrimitive
end
rescue NameError
raise TypeError, "#{klass} can't include MonitorMixin"
end
end
def self.append_features(klass)
mod = includable_module(klass)
klass.module_eval("include mod")
end
def initialize(*args)
super
mon_initialize
end
def try_mon_enter
result = false
Thread.critical = true
if mon_owner.nil?
set_mon_owner(Thread.current)
end
if mon_owner == Thread.current
set_mon_count(mon_count + 1)
result = true
end
Thread.critical = false
return result
end
def mon_enter
Thread.critical = true
while mon_owner != nil && mon_owner != Thread.current
mon_entering_queue.push(Thread.current)
Thread.stop
Thread.critical = true
end
set_mon_owner(Thread.current)
set_mon_count(mon_count + 1)
Thread.critical = false
end
def mon_exit
if mon_owner != Thread.current
raise ThreadError, "current thread not owner"
end
Thread.critical = true
set_mon_count(mon_count - 1)
if mon_count == 0
set_mon_owner(nil)
if mon_waiting_queue.empty?
t = mon_entering_queue.shift
else
t = mon_waiting_queue.shift
end
end
t.wakeup if t
Thread.critical = false
Thread.pass
end
def mon_synchronize
mon_enter
begin
yield
ensure
mon_exit
end
end
alias synchronize mon_synchronize
class ConditionVariable class ConditionVariable
def initialize(monitor) class Timeout < Exception; end
@monitor = monitor
@waiters = []
end
def wait include Accessible
def wait(timeout = nil)
if @monitor.mon_owner != Thread.current if @monitor.mon_owner != Thread.current
raise ThreadError, "current thread not owner" raise ThreadError, "current thread not owner"
end end
@monitor.instance_eval(<<MON_EXIT)
Thread.critical = true Thread.critical = true
_count = mon_count count = @monitor.mon_count
set_mon_count(0) @monitor.mon_count = 0
set_mon_owner(nil) @monitor.mon_owner = nil
if mon_waiting_queue.empty? if @monitor.mon_waiting_queue.empty?
t = mon_entering_queue.shift t = @monitor.mon_entering_queue.shift
else else
t = mon_waiting_queue.shift t = @monitor.mon_waiting_queue.shift
end end
t.wakeup if t t.wakeup if t
Thread.critical = false
MON_EXIT
Thread.critical = true
@waiters.push(Thread.current) @waiters.push(Thread.current)
Thread.stop
@monitor.instance_eval(<<MON_ENTER) if timeout
t = Thread.current
timeout_thread = Thread.start {
sleep(timeout)
t.raise(Timeout.new)
}
end
begin
Thread.stop
rescue Timeout
@waiters.delete(Thread.current)
ensure
if timeout && timeout_thread.alive?
Thread.kill(timeout_thread)
end
end
Thread.critical = true Thread.critical = true
while mon_owner != nil && mon_owner != Thread.current while @monitor.mon_owner &&
mon_waiting_queue.push(Thread.current) @monitor.mon_owner != Thread.current
@monitor.mon_waiting_queue.push(Thread.current)
Thread.stop Thread.stop
Thread.critical = true Thread.critical = true
end end
set_mon_owner(Thread.current) @monitor.mon_owner = Thread.current
set_mon_count(_count) @monitor.mon_count = count
Thread.critical = false Thread.critical = false
MON_ENTER
end end
def wait_while def wait_while
@ -307,11 +132,87 @@ MON_ENTER
def count_waiters def count_waiters
return @waiters.length return @waiters.length
end end
private
def initialize(monitor)
@monitor = monitor
@waiters = []
end
end end
include Accessible
include Initializable
extend Initializable
def self.extend_object(obj)
super(obj)
obj.mon_initialize
end
def try_mon_enter
result = false
Thread.critical = true
if mon_owner.nil?
self.mon_owner = Thread.current
end
if mon_owner == Thread.current
self.mon_count += 1
result = true
end
Thread.critical = false
return result
end
def mon_enter
Thread.critical = true
while mon_owner != nil && mon_owner != Thread.current
mon_entering_queue.push(Thread.current)
Thread.stop
Thread.critical = true
end
self.mon_owner = Thread.current
self.mon_count += 1
Thread.critical = false
end
def mon_exit
if mon_owner != Thread.current
raise ThreadError, "current thread not owner"
end
Thread.critical = true
self.mon_count -= 1
if mon_count == 0
self.mon_owner = nil
if mon_waiting_queue.empty?
t = mon_entering_queue.shift
else
t = mon_waiting_queue.shift
end
end
t.wakeup if t
Thread.critical = false
Thread.pass
end
def mon_synchronize
mon_enter
begin
yield
ensure
mon_exit
end
end
alias synchronize mon_synchronize
def new_cond def new_cond
return ConditionVariable.new(self) return ConditionVariable.new(self)
end end
private
def initialize(*args)
super
mon_initialize
end
end end
class Monitor class Monitor
@ -322,4 +223,7 @@ class Monitor
alias owner mon_owner alias owner mon_owner
end end
## monitor.rb ends here # Local variables:
# mode: Ruby
# tab-width: 8
# End:

View file

@ -15,51 +15,24 @@
# extended object can be handled like Mutex # extended object can be handled like Mutex
# #
require "finalize"
module Mutex_m module Mutex_m
def Mutex_m.extendable_module(obj) def Mutex_m.append_features(cl)
if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj super
raise TypeError, "Mutex_m can't extend to this class(#{obj.type})" unless cl.instance_of?(Module)
else cl.module_eval %q{
begin alias locked? mu_locked?
obj.instance_eval "@mu_locked" alias lock mu_lock
For_general_object alias unlock mu_unlock
rescue TypeError alias try_lock mu_try_lock
For_primitive_object alias synchronize mu_synchronize
end }
end end
end return self
def Mutex_m.includable_module(cl)
begin
dummy = cl.new
Mutex_m.extendable_module(dummy)
rescue NameError
# if new is not defined, cl must be Data.
For_primitive_object
end
end
def Mutex_m.extend_class(cl)
return super if cl.instance_of?(Module)
# do nothing for Modules
# make aliases and include the proper module.
real = includable_module(cl)
cl.module_eval %q{
include real
alias locked? mu_locked?
alias lock mu_lock
alias unlock mu_unlock
alias try_lock mu_try_lock
alias synchronize mu_synchronize
}
end end
def Mutex_m.extend_object(obj) def Mutex_m.extend_object(obj)
obj.extend(Mutex_m.extendable_module(obj)) super
obj.mu_extended
end end
def mu_extended def mu_extended
@ -76,6 +49,7 @@ module Mutex_m
alias synchronize mu_synchronize alias synchronize mu_synchronize
end" end"
end end
initialize
end end
# locking # locking
@ -88,131 +62,50 @@ module Mutex_m
end end
end end
# internal class def mu_locked?
module For_general_object @mu_locked
include Mutex_m
def For_general_object.extend_object(obj)
super
obj.mu_extended
end
def mu_extended
super
@mu_waiting = []
@mu_locked = FALSE;
end
def mu_locked?
@mu_locked
end
def mu_try_lock
result = FALSE
Thread.critical = TRUE
unless @mu_locked
@mu_locked = TRUE
result = TRUE
end
Thread.critical = FALSE
result
end
def mu_lock
while (Thread.critical = TRUE; @mu_locked)
@mu_waiting.push Thread.current
Thread.stop
end
@mu_locked = TRUE
Thread.critical = FALSE
self
end
def mu_unlock
return unless @mu_locked
Thread.critical = TRUE
wait = @mu_waiting
@mu_waiting = []
@mu_locked = FALSE
Thread.critical = FALSE
for w in wait
w.run
end
self
end
end end
module For_primitive_object def mu_try_lock
include Mutex_m result = FALSE
Mu_Locked = Hash.new Thread.critical = TRUE
unless @mu_locked
def For_primitive_object.extend_object(obj) @mu_locked = TRUE
super result = TRUE
obj.mu_extended
Finalizer.add(obj, For_primitive_object, :mu_finalize)
end end
Thread.critical = FALSE
def mu_extended result
super end
initialize
def mu_lock
while (Thread.critical = TRUE; @mu_locked)
@mu_waiting.push Thread.current
Thread.stop
end end
@mu_locked = TRUE
def For_primitive_object.mu_finalize(id) Thread.critical = FALSE
Thread.critical = TRUE self
if wait = Mu_Locked.delete(id) end
Thread.critical = FALSE
for w in wait def mu_unlock
w.run return unless @mu_locked
end Thread.critical = TRUE
else wait = @mu_waiting
Thread.critical = FALSE @mu_waiting = []
end @mu_locked = FALSE
self Thread.critical = FALSE
end for w in wait
w.run
def mu_locked?
Mu_Locked.key?(self.id)
end
def mu_try_lock
Thread.critical = TRUE
if Mu_Locked.key?(self.id)
ret = FALSE
else
Mu_Locked[self.id] = []
Finalizer.add(self, For_primitive_object, :mu_finalize)
ret = TRUE
end
Thread.critical = FALSE
ret
end
def mu_lock
while (Thread.critical = TRUE; w = Mu_Locked[self.id])
w.push Thread.current
Thread.stop
end
Mu_Locked[self.id] = []
Finalizer.add(self, For_primitive_object, :mu_finalize)
Thread.critical = FALSE
self
end
def mu_unlock
Thread.critical = TRUE
if wait = Mu_Locked.delete(self.id)
Finalizer.delete(self, For_primitive_object, :mu_finalize)
Thread.critical = FALSE
for w in wait
w.run
end
else
Thread.critical = FALSE
end
self
end end
self
end
private
def initialize(*args)
ret = super
@mu_waiting = []
@mu_locked = FALSE;
return ret
end end
end end

View file

@ -22,7 +22,7 @@ module Profiler__
else else
name += "." name += "."
end end
data = [0, 0, 0, name+id.id2name] data = [0.0, 0.0, 0.0, name+id.id2name]
MAP[id] = data MAP[id] = data
end end
data[0] += 1 data[0] += 1

View file

@ -77,7 +77,7 @@ class Rational < Numeric
@denominator = den @denominator = den
else else
@numerator = num.to_i @numerator = num.to_i
@denoninator = den.to_i @denominator = den.to_i
end end
end end

View file

@ -44,8 +44,6 @@ unless defined? Thread
fail "Thread not available for this ruby interpreter" fail "Thread not available for this ruby interpreter"
end end
require "final"
module Sync_m module Sync_m
RCS_ID='-$Header$-' RCS_ID='-$Header$-'
@ -78,51 +76,27 @@ module Sync_m
end end
end end
# include and extend initialize methods. def Sync_m.append_features(cl)
def Sync_m.extendable_module(obj) super
if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj unless cl.instance_of?(Module)
raise TypeError, "Sync_m can't extend to this class(#{obj.type})" # do nothing for Modules
else # make aliases and include the proper module.
begin cl.module_eval %q{
obj.instance_eval "@sync_locked" alias locked? sync_locked?
For_general_object alias shared? sync_shared?
rescue TypeError alias exclusive? sync_exclusive?
For_primitive_object alias lock sync_lock
end alias unlock sync_unlock
alias try_lock sync_try_lock
alias synchronize sync_synchronize
}
end end
end return self
def Sync_m.includable_module(cl)
begin
dummy = cl.new
Sync_m.extendable_module(dummy)
rescue NameError
# if new is not defined, cl must be Data.
For_primitive_object
end
end
def Sync_m.extend_class(cl)
return super if cl.instance_of?(Module)
# do nothing for Modules
# make aliases and include the proper module.
real = includable_module(cl)
cl.module_eval %q{
include real
alias locked? sync_locked?
alias shared? sync_shared?
alias exclusive? sync_exclusive?
alias lock sync_lock
alias unlock sync_unlock
alias try_lock sync_try_lock
alias synchronize sync_synchronize
}
end end
def Sync_m.extend_object(obj) def Sync_m.extend_object(obj)
obj.extend(Sync_m.extendable_module(obj)) super
obj.sync_extended
end end
def sync_extended def sync_extended
@ -143,6 +117,7 @@ module Sync_m
alias synchronize sync_synchronize alias synchronize sync_synchronize
end" end"
end end
initialize
end end
# accessing # accessing
@ -162,16 +137,16 @@ module Sync_m
def sync_try_lock(mode = EX) def sync_try_lock(mode = EX)
return unlock if sync_mode == UN return unlock if sync_mode == UN
Thread.critical = TRUE Thread.critical = true
ret = sync_try_lock_sub(sync_mode) ret = sync_try_lock_sub(sync_mode)
Thread.critical = FALSE Thread.critical = false
ret ret
end end
def sync_lock(m = EX) def sync_lock(m = EX)
return unlock if m == UN return unlock if m == UN
until (Thread.critical = TRUE; sync_try_lock_sub(m)) until (Thread.critical = true; sync_try_lock_sub(m))
if sync_sh_locker[Thread.current] if sync_sh_locker[Thread.current]
sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]] sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
sync_sh_locker.delete(Thread.current) sync_sh_locker.delete(Thread.current)
@ -180,23 +155,23 @@ module Sync_m
end end
Thread.stop Thread.stop
end end
Thread.critical = FALSE Thread.critical = false
self self
end end
def sync_unlock(m = EX) def sync_unlock(m = EX)
Thread.critical = TRUE Thread.critical = true
if sync_mode == UN if sync_mode == UN
Thread.critical = FALSE Thread.critical = false
Err::UnknownLocker.Fail(Thread.current) Err::UnknownLocker.Fail(Thread.current)
end end
m = sync_mode if m == EX and sync_mode == SH m = sync_mode if m == EX and sync_mode == SH
runnable = FALSE runnable = false
case m case m
when UN when UN
Thread.critical = FALSE Thread.critical = false
Err::UnknownLocker.Fail(Thread.current) Err::UnknownLocker.Fail(Thread.current)
when EX when EX
@ -208,7 +183,7 @@ module Sync_m
else else
self.sync_mode = UN self.sync_mode = UN
end end
runnable = TRUE runnable = true
end end
else else
Err::UnknownLocker.Fail(Thread.current) Err::UnknownLocker.Fail(Thread.current)
@ -222,7 +197,7 @@ module Sync_m
sync_sh_locker.delete(Thread.current) sync_sh_locker.delete(Thread.current)
if sync_sh_locker.empty? and sync_ex_count == 0 if sync_sh_locker.empty? and sync_ex_count == 0
self.sync_mode = UN self.sync_mode = UN
runnable = TRUE runnable = true
end end
end end
end end
@ -235,7 +210,7 @@ module Sync_m
end end
wait = sync_upgrade_waiting wait = sync_upgrade_waiting
self.sync_upgrade_waiting = [] self.sync_upgrade_waiting = []
Thread.critical = FALSE Thread.critical = false
for w, v in wait for w, v in wait
w.run w.run
@ -243,59 +218,17 @@ module Sync_m
else else
wait = sync_waiting wait = sync_waiting
self.sync_waiting = [] self.sync_waiting = []
Thread.critical = FALSE Thread.critical = false
for w in wait for w in wait
w.run w.run
end end
end end
end end
Thread.critical = FALSE Thread.critical = false
self self
end end
def sync_try_lock_sub(m)
case m
when SH
case sync_mode
when UN
self.sync_mode = m
sync_sh_locker[Thread.current] = 1
ret = TRUE
when SH
count = 0 unless count = sync_sh_locker[Thread.current]
sync_sh_locker[Thread.current] = count + 1
ret = TRUE
when EX
# in EX mode, lock will upgrade to EX lock
if sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1
ret = TRUE
else
ret = FALSE
end
end
when EX
if sync_mode == UN or
sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
self.sync_mode = m
self.sync_ex_locker = Thread.current
self.sync_ex_count = 1
ret = TRUE
elsif sync_mode == EX && sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1
ret = TRUE
else
ret = FALSE
end
else
Thread.critical = FALSE
Err::LockModeFailer.Fail mode
end
return ret
end
private :sync_try_lock_sub
def sync_synchronize(mode = EX) def sync_synchronize(mode = EX)
sync_lock(mode) sync_lock(mode)
begin begin
@ -305,133 +238,76 @@ module Sync_m
end end
end end
# internal class attr :sync_mode, true
module For_primitive_object attr :sync_waiting, true
include Sync_m attr :sync_upgrade_waiting, true
attr :sync_sh_locker, true
LockState = Struct.new("LockState", attr :sync_ex_locker, true
:mode, attr :sync_ex_count, true
:waiting,
:upgrade_waiting,
:sh_locker,
:ex_locker,
:ex_count)
Sync_Locked = Hash.new
def For_primitive_object.extend_object(obj)
super
obj.sync_extended
# Changed to use `final.rb'.
# Finalizer.add(obj, For_primitive_object, :sync_finalize)
ObjectSpace.define_finalizer(obj) do |id|
For_primitive_object.sync_finalize(id)
end
end
def initialize
super
Sync_Locked[id] = LockState.new(UN, [], [], Hash.new, nil, 0 )
self
end
def sync_extended
super
initialize
end
def For_primitive_object.sync_finalize(id)
wait = Sync_Locked.delete(id)
# need not to free waiting
end
def sync_mode
Sync_Locked[id].mode
end
def sync_mode=(value)
Sync_Locked[id].mode = value
end
def sync_waiting private
Sync_Locked[id].waiting
end def initialize(*args)
def sync_waiting=(v) ret = super
Sync_Locked[id].waiting = v @sync_mode = UN
end @sync_waiting = []
@sync_upgrade_waiting = []
def sync_upgrade_waiting @sync_sh_locker = Hash.new
Sync_Locked[id].upgrade_waiting @sync_ex_locker = nil
end @sync_ex_count = 0
def sync_upgrade_waiting=(v) return ret
Sync_Locked[id].upgrade_waiting = v
end
def sync_sh_locker
Sync_Locked[id].sh_locker
end
def sync_sh_locker=(v)
Sync_Locked[id].sh_locker = v
end
def sync_ex_locker
Sync_Locked[id].ex_locker
end
def sync_ex_locker=(value)
Sync_Locked[id].ex_locker = value
end
def sync_ex_count
Sync_Locked[id].ex_count
end
def sync_ex_count=(value)
Sync_Locked[id].ex_count = value
end
end end
module For_general_object def sync_try_lock_sub(m)
include Sync_m case m
when SH
def For_general_object.extend_object(obj) case sync_mode
super when UN
obj.sync_extended self.sync_mode = m
sync_sh_locker[Thread.current] = 1
ret = true
when SH
count = 0 unless count = sync_sh_locker[Thread.current]
sync_sh_locker[Thread.current] = count + 1
ret = true
when EX
# in EX mode, lock will upgrade to EX lock
if sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1
ret = true
else
ret = false
end
end
when EX
if sync_mode == UN or
sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
self.sync_mode = m
self.sync_ex_locker = Thread.current
self.sync_ex_count = 1
ret = true
elsif sync_mode == EX && sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1
ret = true
else
ret = false
end
else
Thread.critical = false
Err::LockModeFailer.Fail mode
end end
return ret
def initialize
super
@sync_mode = UN
@sync_waiting = []
@sync_upgrade_waiting = []
@sync_sh_locker = Hash.new
@sync_ex_locker = nil
@sync_ex_count = 0
self
end
def sync_extended
super
initialize
end
attr :sync_mode, TRUE
attr :sync_waiting, TRUE
attr :sync_upgrade_waiting, TRUE
attr :sync_sh_locker, TRUE
attr :sync_ex_locker, TRUE
attr :sync_ex_count, TRUE
end end
end end
Synchronizer_m = Sync_m Synchronizer_m = Sync_m
class Sync class Sync
Sync_m.extend_class self include Sync_m
#include Sync_m
private
def initialize def initialize
super super
end end
end end
Synchronizer = Sync Synchronizer = Sync

View file

@ -1,8 +1,142 @@
=begin =begin
telnet.rb ver0.161 1999/02/03 = simple telnet cliant library
telnet.rb ver0.162 1999/03/18
Wakou Aoyama <wakou@fsinet.or.jp> Wakou Aoyama <wakou@fsinet.or.jp>
= methods
== new (make new Telnet object)
host = Telnet.new({"Binmode" => FALSE, # default: FALSE
"Host" => "localhost", # default: "localhost"
"Output_log" => "output_log", # default: not output
"Dump_log" => "dump_log", # default: not output
"Port" => 23, # default: 23
"Prompt" => /[$%#>] \Z/, # default: /[$%#>] \Z/
"Telnetmode" => TRUE, # default: TRUE
"Timeout" => 10, # default: 10
"Waittime" => 0, # default: 0
"Proxy" => proxy}) # default: nil
# proxy is Telnet or TCPsocket object
Telnet object has socket class methods.
if set "Telnetmode" option FALSE. not TELNET command interpretation.
"Waittime" is time to confirm "Prompt". There is a possibility that
the same character as "Prompt" is included in the data, and, when
the network or the host is very heavy, the value is enlarged.
== waitfor (wait for match)
line = host.waitfor(/match/)
line = host.waitfor({"Match" => /match/,
"String" => "string",
"Timeout" => secs})
if set "String" option. Match = Regexp.new(quote(string))
=== realtime output
host.waitfor(/match/){|c| print c }
host.waitfor({"Match" => /match/,
"String" => "string",
"Timeout" => secs}){|c| print c}
of cource, set sync=TRUE or flush is necessary.
== cmd (send string and wait prompt)
line = host.cmd("string")
line = host.cmd({"String" => "string",
"Prompt" => /[$%#>] \Z/,
"Timeout" => 10})
=== realtime output
host.cmd("string"){|c| print c }
host.cmd({"String" => "string",
"Prompt" => /[$%#>] \Z/,
"Timeout" => 10}){|c| print c }
of cource, set sync=TRUE or flush is necessary.
== print (send string)
host.print("string")
== telnetmode (turn telnet command interpretation)
host.telnetmode # turn on/off
host.telnetmode(TRUE) # on
host.telnetmode(FALSE) # off
== binmode (toggle newline translation)
host.binmode # turn TRUE/FALSE
host.binmode(TRUE) # no translate newline
host.binmode(FALSE) # translate newline
== login
host.login("username", "password")
host.login({"Name" => "username",
"Password" => "password",
"Prompt" => /[$%#>] \Z/,
"Timeout" => 10})
=== realtime output
host.login("username", "password"){|c| print c }
host.login({"Name" => "username",
"Password" => "password",
"Prompt" => /[$%#>] \Z/,
"Timeout" => 10}){|c| print c }
of cource, set sync=TRUE or flush is necessary.
= sample
== login and send command
localhost = Telnet.new({"Host" => "localhost",
"Timeout" => 10,
"Prompt" => /[$%#>] \Z/})
localhost.login("username", "password"){|c| print c }
localhost.cmd("command"){|c| print c }
localhost.close
== checks a POP server to see if you have mail
pop = Telnet.new({"Host" => "your_destination_host_here",
"Port" => 110,
"Telnetmode" => FALSE,
"Prompt" => /^\+OK/})
pop.cmd("user " + "your_username_here"){|c| print c}
pop.cmd("pass " + "your_password_here"){|c| print c}
pop.cmd("list"){|c| print c}
= history
ver0.162 1999/03/17
add "Proxy" option
required timeout.rb
ver0.161 1999/02/03 ver0.161 1999/02/03
select --> IO::select select --> IO::select
@ -44,128 +178,16 @@ add realtime output.
ver0.10 1998/04/13 ver0.10 1998/04/13
first release. first release.
== make new Telnet object
host = Telnet.new({"Binmode" => FALSE, default: FALSE
"Host" => "localhost", default: "localhost"
"Output_log" => "output_log", default: not output
"Dump_log" => "dump_log", default: not output
"Port" => 23, default: 23
"Prompt" => /[$%#>] \Z/, default: /[$%#>] \Z/
"Telnetmode" => TRUE, default: TRUE
"Timeout" => 10, default: 10
"Waittime" => 0}) default: 0
if set "Telnetmode" option FALSE. not TELNET command interpretation.
"Waittime" is time to confirm "Prompt". There is a possibility that
the same character as "Prompt" is included in the data, and, when
the network or the host is very heavy, the value is enlarged.
== wait for match
line = host.waitfor(/match/)
line = host.waitfor({"Match" => /match/,
"String" => "string",
"Timeout" => secs})
if set "String" option. Match = Regexp.new(quote(string))
realtime output. of cource, set sync=TRUE or flush is necessary.
host.waitfor(/match/){|c| print c }
host.waitfor({"Match" => /match/,
"String" => "string",
"Timeout" => secs}){|c| print c}
== send string and wait prompt
line = host.cmd("string")
line = host.cmd({"String" => "string",
"Prompt" => /[$%#>] \Z/,
"Timeout" => 10})
realtime output. of cource, set sync=TRUE or flush is necessary.
host.cmd("string"){|c| print c }
host.cmd({"String" => "string",
"Prompt" => /[$%#>] \Z/,
"Timeout" => 10}){|c| print c }
== send string
host.print("string")
== turn telnet command interpretation
host.telnetmode # turn on/off
host.telnetmode(TRUE) # on
host.telnetmode(FALSE) # off
== toggle newline translation
host.binmode # turn TRUE/FALSE
host.binmode(TRUE) # no translate newline
host.binmode(FALSE) # translate newline
== login
host.login("username", "password")
host.login({"Name" => "username",
"Password" => "password",
"Prompt" => /[$%#>] \Z/,
"Timeout" => 10})
realtime output. of cource, set sync=TRUE or flush is necessary.
host.login("username", "password"){|c| print c }
host.login({"Name" => "username",
"Password" => "password",
"Prompt" => /[$%#>] \Z/,
"Timeout" => 10}){|c| print c }
and Telnet object has socket class methods
== sample
localhost = Telnet.new({"Host" => "localhost",
"Timeout" => 10,
"Prompt" => /[$%#>] \Z/})
localhost.login("username", "password"){|c| print c }
localhost.cmd("command"){|c| print c }
localhost.close
== sample 2
checks a POP server to see if you have mail.
pop = Telnet.new({"Host" => "your_destination_host_here",
"Port" => 110,
"Telnetmode" => FALSE,
"Prompt" => /^\+OK/})
pop.cmd("user " + "your_username_here"){|c| print c}
pop.cmd("pass " + "your_password_here"){|c| print c}
pop.cmd("list"){|c| print c}
=end =end
require "socket" require "socket"
require "delegate" require "delegate"
require "thread" require "thread"
require "timeout"
class TimeOut < Exception TimeOut = TimeoutError
end
class Telnet < SimpleDelegator class Telnet < SimpleDelegator
def timeout(sec)
is_timeout = FALSE
begin
x = Thread.current
y = Thread.start {
sleep sec
if x.alive?
#print "timeout!\n"
x.raise TimeOut, "timeout"
end
}
begin
yield
rescue TimeOut
is_timeout = TRUE
end
ensure
Thread.kill y if y && y.alive?
end
is_timeout
end
IAC = 255.chr # interpret as command: IAC = 255.chr # interpret as command:
DONT = 254.chr # you are not to use option DONT = 254.chr # you are not to use option
DO = 253.chr # please, you use option DO = 253.chr # please, you use option
@ -259,32 +281,45 @@ class Telnet < SimpleDelegator
@dumplog.binmode @dumplog.binmode
end end
message = "Trying " + @options["Host"] + "...\n" if @options.include?("Proxy")
STDOUT.write(message) if @options["Proxy"].kind_of?(Telnet)
@log.write(message) if @options.include?("Output_log") @sock = @options["Proxy"].sock
@dumplog.write(message) if @options.include?("Dump_log") elsif @options["Proxy"].kind_of?(TCPsocket)
@sock = @options["Proxy"]
else
raise "Error; Proxy is Telnet or TCPSocket object."
end
else
message = "Trying " + @options["Host"] + "...\n"
STDOUT.write(message)
@log.write(message) if @options.include?("Output_log")
@dumplog.write(message) if @options.include?("Dump_log")
is_timeout = timeout(@options["Timeout"]){
begin begin
@sock = TCPsocket.open(@options["Host"], @options["Port"]) timeout(@options["Timeout"]){
@sock = TCPsocket.open(@options["Host"], @options["Port"])
}
rescue TimeoutError
raise TimeOut, "timed-out; opening of the host"
rescue rescue
@log.write($! + "\n") if @options.include?("Output_log") @log.write($! + "\n") if @options.include?("Output_log")
@dumplog.write($! + "\n") if @options.include?("Dump_log") @dumplog.write($! + "\n") if @options.include?("Dump_log")
raise raise
end end
} @sock.sync = TRUE
raise TimeOut, "timed-out; opening of the host" if is_timeout @sock.binmode
@sock.sync = TRUE
@sock.binmode
message = "Connected to " + @options["Host"] + ".\n" message = "Connected to " + @options["Host"] + ".\n"
STDOUT.write(message) STDOUT.write(message)
@log.write(message) if @options.include?("Output_log") @log.write(message) if @options.include?("Output_log")
@dumplog.write(message) if @options.include?("Dump_log") @dumplog.write(message) if @options.include?("Dump_log")
end
super(@sock) super(@sock)
end end
attr :sock
def telnetmode(mode = 'turn') def telnetmode(mode = 'turn')
if 'turn' == mode if 'turn' == mode
@options["Telnetmode"] = @options["Telnetmode"] ? FALSE : TRUE @options["Telnetmode"] = @options["Telnetmode"] ? FALSE : TRUE
@ -347,12 +382,12 @@ class Telnet < SimpleDelegator
end end
def waitfor(options) def waitfor(options)
timeout = @options["Timeout"] time_out = @options["Timeout"]
waittime = @options["Waittime"] waittime = @options["Waittime"]
if options.kind_of?(Hash) if options.kind_of?(Hash)
prompt = options["Prompt"] if options.include?("Prompt") prompt = options["Prompt"] if options.include?("Prompt")
timeout = options["Timeout"] if options.include?("Timeout") time_out = options["Timeout"] if options.include?("Timeout")
waittime = options["Waittime"] if options.include?("Waittime") waittime = options["Waittime"] if options.include?("Waittime")
prompt = Regexp.new( Regexp.quote(options["String"]) ) if prompt = Regexp.new( Regexp.quote(options["String"]) ) if
options.include?("String") options.include?("String")
@ -363,7 +398,7 @@ class Telnet < SimpleDelegator
line = '' line = ''
until(not IO::select([@sock], nil, nil, waittime) and prompt === line) until(not IO::select([@sock], nil, nil, waittime) and prompt === line)
raise TimeOut, "timed-out; wait for the next data" if raise TimeOut, "timed-out; wait for the next data" if
not IO::select([@sock], nil, nil, timeout) not IO::select([@sock], nil, nil, time_out)
buf = '' buf = ''
begin begin
buf = @sock.sysread(1024 * 1024) buf = @sock.sysread(1024 * 1024)
@ -399,13 +434,13 @@ class Telnet < SimpleDelegator
end end
def cmd(options) def cmd(options)
match = @options["Prompt"] match = @options["Prompt"]
timeout = @options["Timeout"] time_out = @options["Timeout"]
if options.kind_of?(Hash) if options.kind_of?(Hash)
string = options["String"] string = options["String"]
match = options["Match"] if options.include?("Match") match = options["Match"] if options.include?("Match")
timeout = options["Timeout"] if options.include?("Timeout") time_out = options["Timeout"] if options.include?("Timeout")
else else
string = options string = options
end end
@ -413,9 +448,9 @@ class Telnet < SimpleDelegator
IO::select(nil, [@sock]) IO::select(nil, [@sock])
print(string) print(string)
if iterator? if iterator?
waitfor({"Prompt" => match, "Timeout" => timeout}){|c| yield c } waitfor({"Prompt" => match, "Timeout" => time_out}){|c| yield c }
else else
waitfor({"Prompt" => match, "Timeout" => timeout}) waitfor({"Prompt" => match, "Timeout" => time_out})
end end
end end

View file

@ -144,6 +144,10 @@ class Queue
@que.length == 0 @que.length == 0
end end
def clear
@que.replace([])
end
def length def length
@que.length @que.length
end end

View file

@ -2,11 +2,12 @@
# #
# Usage: # Usage:
# foo = Object.new # foo = Object.new
# foo.hash # foo = Object.new
# p foo.to_s # original's class
# foo = WeakRef.new(foo) # foo = WeakRef.new(foo)
# foo.hash # p foo.to_s # should be same class
# ObjectSpace.garbage_collect # ObjectSpace.garbage_collect
# foo.hash # => Raises WeakRef::RefError (because original GC'ed) # p foo.to_s # should raise exception (recycled)
require "delegate" require "delegate"
@ -18,9 +19,11 @@ class WeakRef<Delegator
ID_MAP = {} ID_MAP = {}
ID_REV_MAP = {} ID_REV_MAP = {}
ObjectSpace.add_finalizer(lambda{|id| ObjectSpace.add_finalizer(lambda{|id|
rid = ID_MAP[id] rids = ID_MAP[id]
if rid if rids
ID_REV_MAP[rid] = nil for rid in rids
ID_REV_MAP[rid] = nil
end
ID_MAP[id] = nil ID_MAP[id] = nil
end end
rid = ID_REV_MAP[id] rid = ID_REV_MAP[id]
@ -35,7 +38,8 @@ class WeakRef<Delegator
@__id = orig.__id__ @__id = orig.__id__
ObjectSpace.call_finalizer orig ObjectSpace.call_finalizer orig
ObjectSpace.call_finalizer self ObjectSpace.call_finalizer self
ID_MAP[@__id] = self.__id__ ID_MAP[@__id] = [] unless ID_MAP[@__id]
ID_MAP[@__id].concat self.__id__
ID_REV_MAP[self.id] = @__id ID_REV_MAP[self.id] = @__id
end end

2
main.c
View file

@ -31,7 +31,7 @@ main(argc, argv, envp)
NtInitialize(&argc, &argv); NtInitialize(&argc, &argv);
#endif #endif
#if defined(__MACOS__) && defined(__MWERKS__) #if defined(__MACOS__) && defined(__MWERKS__)
argc = ccommand(&argv); argc = ccommand(&argv);
#endif #endif
ruby_init(); ruby_init();

View file

@ -41,8 +41,6 @@ double strtod();
#define TYPE_LINK '@' #define TYPE_LINK '@'
VALUE rb_path2class _((char*));
static ID s_dump, s_load; static ID s_dump, s_load;
struct dump_arg { struct dump_arg {

View file

@ -261,6 +261,7 @@ The variable ruby-indent-level controls the amount of indentation.
((looking-at "%") ((looking-at "%")
(cond (cond
((and (not (eobp)) (ruby-expr-beg) ((and (not (eobp)) (ruby-expr-beg)
(not (looking-at "%="))
(looking-at "%[Qqrxw]?\\(.\\)")) (looking-at "%[Qqrxw]?\\(.\\)"))
(setq w (buffer-substring (match-beginning 1) (setq w (buffer-substring (match-beginning 1)
(match-end 1))) (match-end 1)))

View file

@ -1,36 +1,61 @@
/* /*
* Copyright (c) 1991, Larry Wall * Public domain dup2() lookalike
* by Curtis Jackson @ AT&T Technologies, Burlington, NC
* electronic address: burl!rcj
* *
* You may distribute under the terms of either the GNU General Public * dup2 performs the following functions:
* License or the Artistic License, as specified in the README file. *
* Check to make sure that fd1 is a valid open file descriptor.
* Check to see if fd2 is already open; if so, close it.
* Duplicate fd1 onto fd2; checking to make sure fd2 is a valid fd.
* Return fd2 if all went well; return BADEXIT otherwise.
*/ */
#include "defines.h" #include "config.h"
#if defined(HAVE_FCNTL) && defined(F_DUPFD) #if defined(HAVE_FCNTL)
# include <fcntl.h> # include <fcntl.h>
#endif #endif
#if !defined(HAVE_FCNTL) || !defined(F_DUPFD)
# include <errno.h>
#endif
#define BADEXIT -1
int int
dup2(oldfd,newfd) dup2(fd1, fd2)
int oldfd; int fd1, fd2;
int newfd;
{ {
#if defined(HAVE_FCNTL) && defined(F_DUPFD) #if defined(HAVE_FCNTL) && defined(F_DUPFD)
close(newfd); if (fd1 != fd2) {
return fcntl(oldfd, F_DUPFD, newfd); #ifdef F_GETFL
if (fcntl(fd1, F_GETFL) < 0)
return BADEXIT;
if (fcntl(fd2, F_GETFL) >= 0)
close(fd2);
#else #else
int fdtmp[256]; close(fd2);
int fdx = 0; #endif
int fd; if (fcntl(fd1, F_DUPFD, fd2) < 0)
return BADEXIT;
}
return fd2;
#else
extern int errno;
int i, fd, fds[256];
if (oldfd == newfd) if (fd1 == fd2) return 0;
return 0; close(fd2);
close(newfd); for (i=0; i<256; i++) {
while ((fd = dup(oldfd)) != newfd) /* good enough for low fd's */ fd = fds[i] = dup(fd1);
fdtmp[fdx++] = fd; if (fd == fd2) break;
while (fdx > 0) }
close(fdtmp[--fdx]); while (i) {
return 0; close(fds[i--]);
}
if (fd == fd2) return 0;
errno = EMFILE;
return BADEXIT;
#endif #endif
} }

View file

@ -48,7 +48,7 @@ static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
#define EOS '\0' #define EOS '\0'
static char *rangematch(const char *, int, int); static char *rangematch();
int int
fnmatch(pattern, string, flags) fnmatch(pattern, string, flags)

6
node.h
View file

@ -331,9 +331,9 @@ VALUE rb_method_booundp();
#define NOEX_PRIVATE 2 #define NOEX_PRIVATE 2
#define NOEX_PROTECTED 4 #define NOEX_PROTECTED 4
NODE *rb_compile_cstr _((char *, char *, int)); NODE *rb_compile_cstr _((const char*, const char*, int));
NODE *rb_compile_string _((char *, VALUE)); NODE *rb_compile_string _((const char*, VALUE));
NODE *rb_compile_file _((char *, VALUE, int)); NODE *rb_compile_file _((const char*, VALUE, int));
void rb_add_method _((VALUE, ID, NODE *, int)); void rb_add_method _((VALUE, ID, NODE *, int));
NODE *rb_node_newnode(); NODE *rb_node_newnode();

View file

@ -167,7 +167,7 @@ num_nonzero_p(num)
VALUE num; VALUE num;
{ {
if (RTEST(rb_funcall(num, rb_intern("zero?"), 0, 0))) { if (RTEST(rb_funcall(num, rb_intern("zero?"), 0, 0))) {
return Qfalse; return Qnil;
} }
return num; return num;
} }

View file

@ -740,7 +740,7 @@ rb_obj_private_methods(obj)
struct arg_to { struct arg_to {
VALUE val; VALUE val;
char *s; const char *s;
}; };
static VALUE static VALUE
@ -766,7 +766,7 @@ VALUE
rb_convert_type(val, type, tname, method) rb_convert_type(val, type, tname, method)
VALUE val; VALUE val;
int type; int type;
char *tname, *method; const char *tname, *method;
{ {
struct arg_to arg1, arg2; struct arg_to arg1, arg2;

84
pack.c
View file

@ -914,6 +914,16 @@ hex2num(c)
} }
} }
#define PACK_LENGTH_ADJUST(type) do { \
tmp = 0; \
if (len > (send - s)/sizeof(type)) { \
tmp = len - (send - s) / sizeof(type); \
len = (send - s) / sizeof(type); \
} \
} while (0)
#define PACK_ITEM_ADJUST() while (tmp--) rb_ary_push(ary, Qnil);
static VALUE static VALUE
pack_unpack(str, fmt) pack_unpack(str, fmt)
VALUE str, fmt; VALUE str, fmt;
@ -923,7 +933,7 @@ pack_unpack(str, fmt)
char *p, *pend; char *p, *pend;
VALUE ary; VALUE ary;
char type; char type;
int len; int len, tmp;
s = rb_str2cstr(str, &len); s = rb_str2cstr(str, &len);
send = s + len; send = s + len;
@ -1052,93 +1062,92 @@ pack_unpack(str, fmt)
break; break;
case 'c': case 'c':
if (len > send - s) PACK_LENGTH_ADJUST(char);
len = send - s;
while (len-- > 0) { while (len-- > 0) {
int c = *s++; int c = *s++;
if (c > (char)127) c-=256; if (c > (char)127) c-=256;
rb_ary_push(ary, INT2FIX(c)); rb_ary_push(ary, INT2FIX(c));
} }
PACK_ITEM_ADJUST();
break; break;
case 'C': case 'C':
if (len > send - s) PACK_LENGTH_ADJUST(char);
len = send - s;
while (len-- > 0) { while (len-- > 0) {
unsigned char c = *s++; unsigned char c = *s++;
rb_ary_push(ary, INT2FIX(c)); rb_ary_push(ary, INT2FIX(c));
} }
PACK_ITEM_ADJUST();
break; break;
case 's': case 's':
if (len >= (send - s) / sizeof(short)) PACK_LENGTH_ADJUST(short);
len = (send - s) / sizeof(short);
while (len-- > 0) { while (len-- > 0) {
short tmp; short tmp;
memcpy(&tmp, s, sizeof(short)); memcpy(&tmp, s, sizeof(short));
s += sizeof(short); s += sizeof(short);
rb_ary_push(ary, INT2FIX(tmp)); rb_ary_push(ary, INT2FIX(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'S': case 'S':
if (len >= (send - s) / sizeof(short)) PACK_LENGTH_ADJUST(short);
len = (send - s) / sizeof(short);
while (len-- > 0) { while (len-- > 0) {
unsigned short tmp; unsigned short tmp;
memcpy(&tmp, s, sizeof(short)); memcpy(&tmp, s, sizeof(short));
s += sizeof(short); s += sizeof(short);
rb_ary_push(ary, INT2FIX(tmp)); rb_ary_push(ary, INT2FIX(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'i': case 'i':
if (len >= (send - s) / sizeof(int)) PACK_LENGTH_ADJUST(int);
len = (send - s) / sizeof(int);
while (len-- > 0) { while (len-- > 0) {
int tmp; int tmp;
memcpy(&tmp, s, sizeof(int)); memcpy(&tmp, s, sizeof(int));
s += sizeof(int); s += sizeof(int);
rb_ary_push(ary, rb_int2inum(tmp)); rb_ary_push(ary, rb_int2inum(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'I': case 'I':
if (len >= (send - s) / sizeof(int)) PACK_LENGTH_ADJUST(int);
len = (send - s) / sizeof(int);
while (len-- > 0) { while (len-- > 0) {
unsigned int tmp; unsigned int tmp;
memcpy(&tmp, s, sizeof(int)); memcpy(&tmp, s, sizeof(int));
s += sizeof(int); s += sizeof(int);
rb_ary_push(ary, rb_uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'l': case 'l':
if (len >= (send - s) / sizeof(long)) PACK_LENGTH_ADJUST(long);
len = (send - s) / sizeof(long);
while (len-- > 0) { while (len-- > 0) {
long tmp; long tmp;
memcpy(&tmp, s, sizeof(long)); memcpy(&tmp, s, sizeof(long));
s += sizeof(long); s += sizeof(long);
rb_ary_push(ary, rb_int2inum(tmp)); rb_ary_push(ary, rb_int2inum(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'L': case 'L':
if (len >= (send - s) / sizeof(long)) PACK_LENGTH_ADJUST(long);
len = (send - s) / sizeof(long);
while (len-- > 0) { while (len-- > 0) {
unsigned long tmp; unsigned long tmp;
memcpy(&tmp, s, sizeof(long)); memcpy(&tmp, s, sizeof(long));
s += sizeof(long); s += sizeof(long);
rb_ary_push(ary, rb_uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'n': case 'n':
if (len >= (send - s) / sizeof(short)) PACK_LENGTH_ADJUST(short);
len = (send - s) / sizeof(short);
while (len-- > 0) { while (len-- > 0) {
unsigned short tmp; unsigned short tmp;
memcpy(&tmp, s, sizeof(short)); memcpy(&tmp, s, sizeof(short));
@ -1146,11 +1155,11 @@ pack_unpack(str, fmt)
tmp = ntohs(tmp); tmp = ntohs(tmp);
rb_ary_push(ary, rb_uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'N': case 'N':
if (len >= (send - s) / sizeof(long)) PACK_LENGTH_ADJUST(long);
len = (send - s) / sizeof(long);
while (len-- > 0) { while (len-- > 0) {
unsigned long tmp; unsigned long tmp;
memcpy(&tmp, s, sizeof(long)); memcpy(&tmp, s, sizeof(long));
@ -1158,11 +1167,11 @@ pack_unpack(str, fmt)
tmp = ntohl(tmp); tmp = ntohl(tmp);
rb_ary_push(ary, rb_uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'v': case 'v':
if (len >= (send - s) / sizeof(short)) PACK_LENGTH_ADJUST(short);
len = (send - s) / sizeof(short);
while (len-- > 0) { while (len-- > 0) {
unsigned short tmp; unsigned short tmp;
memcpy(&tmp, s, sizeof(short)); memcpy(&tmp, s, sizeof(short));
@ -1170,11 +1179,11 @@ pack_unpack(str, fmt)
tmp = vtohs(tmp); tmp = vtohs(tmp);
rb_ary_push(ary, rb_uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'V': case 'V':
if (len >= (send - s) / sizeof(long)) PACK_LENGTH_ADJUST(long);
len = (send - s) / sizeof(long);
while (len-- > 0) { while (len-- > 0) {
unsigned long tmp; unsigned long tmp;
memcpy(&tmp, s, sizeof(long)); memcpy(&tmp, s, sizeof(long));
@ -1182,23 +1191,23 @@ pack_unpack(str, fmt)
tmp = vtohl(tmp); tmp = vtohl(tmp);
rb_ary_push(ary, rb_uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'f': case 'f':
case 'F': case 'F':
if (len >= (send - s) / sizeof(float)) PACK_LENGTH_ADJUST(float);
len = (send - s) / sizeof(float);
while (len-- > 0) { while (len-- > 0) {
float tmp; float tmp;
memcpy(&tmp, s, sizeof(float)); memcpy(&tmp, s, sizeof(float));
s += sizeof(float); s += sizeof(float);
rb_ary_push(ary, rb_float_new((double)tmp)); rb_ary_push(ary, rb_float_new((double)tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'e': case 'e':
if (len >= (send - s) / sizeof(float)) PACK_LENGTH_ADJUST(float);
len = (send - s) / sizeof(float);
while (len-- > 0) { while (len-- > 0) {
float tmp; float tmp;
FLOAT_CONVWITH(ftmp); FLOAT_CONVWITH(ftmp);
@ -1208,11 +1217,11 @@ pack_unpack(str, fmt)
tmp = VTOHF(tmp,ftmp); tmp = VTOHF(tmp,ftmp);
rb_ary_push(ary, rb_float_new((double)tmp)); rb_ary_push(ary, rb_float_new((double)tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'E': case 'E':
if (len >= (send - s) / sizeof(double)) PACK_LENGTH_ADJUST(double);
len = (send - s) / sizeof(double);
while (len-- > 0) { while (len-- > 0) {
double tmp; double tmp;
DOUBLE_CONVWITH(dtmp); DOUBLE_CONVWITH(dtmp);
@ -1222,23 +1231,23 @@ pack_unpack(str, fmt)
tmp = VTOHD(tmp,dtmp); tmp = VTOHD(tmp,dtmp);
rb_ary_push(ary, rb_float_new(tmp)); rb_ary_push(ary, rb_float_new(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'D': case 'D':
case 'd': case 'd':
if (len >= (send - s) / sizeof(double)) PACK_LENGTH_ADJUST(double);
len = (send - s) / sizeof(double);
while (len-- > 0) { while (len-- > 0) {
double tmp; double tmp;
memcpy(&tmp, s, sizeof(double)); memcpy(&tmp, s, sizeof(double));
s += sizeof(double); s += sizeof(double);
rb_ary_push(ary, rb_float_new(tmp)); rb_ary_push(ary, rb_float_new(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'g': case 'g':
if (len >= (send - s) / sizeof(float)) PACK_LENGTH_ADJUST(float);
len = (send - s) / sizeof(float);
while (len-- > 0) { while (len-- > 0) {
float tmp; float tmp;
FLOAT_CONVWITH(ftmp;) FLOAT_CONVWITH(ftmp;)
@ -1248,11 +1257,11 @@ pack_unpack(str, fmt)
tmp = NTOHF(tmp,ftmp); tmp = NTOHF(tmp,ftmp);
rb_ary_push(ary, rb_float_new((double)tmp)); rb_ary_push(ary, rb_float_new((double)tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'G': case 'G':
if (len >= (send - s) / sizeof(double)) PACK_LENGTH_ADJUST(double);
len = (send - s) / sizeof(double);
while (len-- > 0) { while (len-- > 0) {
double tmp; double tmp;
DOUBLE_CONVWITH(dtmp); DOUBLE_CONVWITH(dtmp);
@ -1262,6 +1271,7 @@ pack_unpack(str, fmt)
tmp = NTOHD(tmp,dtmp); tmp = NTOHD(tmp,dtmp);
rb_ary_push(ary, rb_float_new(tmp)); rb_ary_push(ary, rb_float_new(tmp));
} }
PACK_ITEM_ADJUST();
break; break;
case 'u': case 'u':

3041
parse.c

File diff suppressed because it is too large Load diff

139
parse.y
View file

@ -176,7 +176,7 @@ static void top_local_setup();
%type <node> array assoc_list assocs assoc undef_list backref %type <node> array assoc_list assocs assoc undef_list backref
%type <node> iter_var opt_iter_var iter_block iter_do_block %type <node> iter_var opt_iter_var iter_block iter_do_block
%type <node> mlhs mlhs_head mlhs_tail mlhs_basic mlhs_entry mlhs_item lhs %type <node> mlhs mlhs_head mlhs_tail mlhs_basic mlhs_entry mlhs_item lhs
%type <id> variable symbol operation %type <id> variable symbol operation operation2
%type <id> cname fname op f_rest_arg %type <id> cname fname op f_rest_arg
%type <num> f_arg %type <num> f_arg
%token tUPLUS /* unary+ */ %token tUPLUS /* unary+ */
@ -935,11 +935,6 @@ primary : literal
value_expr($1); value_expr($1);
$$ = NEW_COLON2($1, $3); $$ = NEW_COLON2($1, $3);
} }
| primary tCOLON2 tIDENTIFIER
{
value_expr($1);
$$ = new_call($1, $3, 0);
}
| tCOLON3 cname | tCOLON3 cname
{ {
$$ = NEW_COLON3($2); $$ = NEW_COLON3($2);
@ -1313,6 +1308,11 @@ method_call : operation '(' opt_call_args ')'
$$ = new_call($1, $3, $5); $$ = new_call($1, $3, $5);
fixpos($$, $1); fixpos($$, $1);
} }
| primary tCOLON2 operation2
{
value_expr($1);
$$ = new_call($1, $3, 0);
}
| kSUPER '(' opt_call_args ')' | kSUPER '(' opt_call_args ')'
{ {
if (!cur_mid && !in_single && !in_defined) if (!cur_mid && !in_single && !in_defined)
@ -1579,6 +1579,9 @@ operation : tIDENTIFIER
| tCONSTANT | tCONSTANT
| tFID | tFID
operation2 : tIDENTIFIER
| tFID
dot_or_colon : '.' dot_or_colon : '.'
| tCOLON2 | tCOLON2
@ -1608,7 +1611,9 @@ terms : term
static char *tokenbuf = NULL; static char *tokenbuf = NULL;
static int tokidx, toksiz = 0; static int tokidx, toksiz = 0;
#ifndef strdup
char *strdup(); char *strdup();
#endif
static NODE *rb_str_extend(); static NODE *rb_str_extend();
@ -1664,7 +1669,6 @@ yyerror(msg)
return 0; return 0;
} }
static int newline_seen;
static int heredoc_end; static int heredoc_end;
int ruby_in_compile = 0; int ruby_in_compile = 0;
@ -1678,7 +1682,6 @@ yycompile(f)
ruby__end__seen = 0; ruby__end__seen = 0;
ruby_eval_tree = 0; ruby_eval_tree = 0;
newline_seen = 0;
heredoc_end = 0; heredoc_end = 0;
ruby_sourcefile = f; ruby_sourcefile = f;
ruby_in_compile = 1; ruby_in_compile = 1;
@ -1713,7 +1716,7 @@ lex_get_str(s)
NODE* NODE*
rb_compile_string(f, s) rb_compile_string(f, s)
char *f; const char *f;
VALUE s; VALUE s;
{ {
lex_gets = lex_get_str; lex_gets = lex_get_str;
@ -1721,14 +1724,16 @@ rb_compile_string(f, s)
lex_input = s; lex_input = s;
lex_pbeg = lex_p = lex_pend = 0; lex_pbeg = lex_p = lex_pend = 0;
if (!ruby_sourcefile || strcmp(f, ruby_sourcefile)) /* not in eval() */ if (!ruby_sourcefile || strcmp(f, ruby_sourcefile)) /* not in eval() */
ruby_sourceline = 1; ruby_sourceline = 0;
else if (ruby_frame) /* in eval() */
cur_mid = ruby_frame->last_func;
return yycompile(f); return yycompile(f);
} }
NODE* NODE*
rb_compile_cstr(f, s, len) rb_compile_cstr(f, s, len)
char *f, *s; const char *f, *s;
int len; int len;
{ {
return rb_compile_string(f, rb_str_new(s, len)); return rb_compile_string(f, rb_str_new(s, len));
@ -1736,14 +1741,14 @@ rb_compile_cstr(f, s, len)
NODE* NODE*
rb_compile_file(f, file, start) rb_compile_file(f, file, start)
char *f; const char *f;
VALUE file; VALUE file;
int start; int start;
{ {
lex_gets = rb_io_gets; lex_gets = rb_io_gets;
lex_input = file; lex_input = file;
lex_pbeg = lex_p = lex_pend = 0; lex_pbeg = lex_p = lex_pend = 0;
ruby_sourceline = start; ruby_sourceline = start - 1;
return yycompile(strdup(f)); return yycompile(strdup(f));
} }
@ -1777,22 +1782,11 @@ nextc()
if (NIL_P(v)) return -1; if (NIL_P(v)) return -1;
if (heredoc_end > 0) { if (heredoc_end > 0) {
ruby_sourceline = heredoc_end+1; ruby_sourceline = heredoc_end;
heredoc_end = 0; heredoc_end = 0;
} }
normalize_newline(v); normalize_newline(v);
while (RSTRING(v)->len >= 2 && ruby_sourceline++;
RSTRING(v)->ptr[RSTRING(v)->len-1] == '\n' &&
RSTRING(v)->ptr[RSTRING(v)->len-2] == '\\' &&
(RSTRING(v)->len == 2 ||
RSTRING(v)->ptr[RSTRING(v)->len-3] != '\\')) {
VALUE v2 = (*lex_gets)(lex_input);
if (!NIL_P(v2)) {
normalize_newline(v2);
rb_str_cat(v, RSTRING(v2)->ptr, RSTRING(v2)->len);
}
}
lex_pbeg = lex_p = RSTRING(v)->ptr; lex_pbeg = lex_p = RSTRING(v)->ptr;
lex_pend = lex_p + RSTRING(v)->len; lex_pend = lex_p + RSTRING(v)->len;
if (strncmp(lex_pbeg, "__END__", 7) == 0 && lex_pbeg[7] == '\n') { if (strncmp(lex_pbeg, "__END__", 7) == 0 && lex_pbeg[7] == '\n') {
@ -1897,7 +1891,7 @@ read_escape()
} }
buf[i] = c; buf[i] = c;
} }
c = scan_oct(buf, i+1, &i); c = scan_oct(buf, i, &i);
} }
return c; return c;
@ -1914,7 +1908,7 @@ read_escape()
break; break;
} }
} }
c = scan_hex(buf, i+1, &i); c = scan_hex(buf, i, &i);
} }
return c; return c;
@ -1983,9 +1977,6 @@ parse_regx(term, paren)
} }
switch (c) { switch (c) {
case '\n':
ruby_sourceline++;
break;
case '[': case '[':
in_brack = 1; in_brack = 1;
break; break;
@ -2006,7 +1997,6 @@ parse_regx(term, paren)
return 0; return 0;
case '\n': case '\n':
ruby_sourceline++;
break; break;
case '\\': case '\\':
@ -2036,16 +2026,20 @@ parse_regx(term, paren)
if (c == paren) nest++; if (c == paren) nest++;
if (c == term) nest--; if (c == term) nest--;
} }
if (c == '\n') { if (c == term) {
ruby_sourceline++;
}
else if (c == term) {
tokadd(c); tokadd(c);
} }
else { else {
int c1;
pushback(c); pushback(c);
tokadd('\\'); c1 = read_escape();
tokadd(read_escape()); if (c1 != c) {
tokadd(c1);
}
else {
tokadd('\\');
tokadd(c);
}
} }
} }
continue; continue;
@ -2099,6 +2093,7 @@ parse_regx(term, paren)
tokfix(); tokfix();
lex_state = EXPR_END; lex_state = EXPR_END;
if (list) { if (list) {
nd_set_line(list, re_start-1);
if (toklen() > 0) { if (toklen() > 0) {
VALUE ss = rb_str_new(tok(), toklen()); VALUE ss = rb_str_new(tok(), toklen());
list_append(list, NEW_STR(ss)); list_append(list, NEW_STR(ss));
@ -2134,9 +2129,9 @@ parse_string(func, term, paren)
return parse_qstring(term, paren); return parse_qstring(term, paren);
} }
if (func == 0) { /* read 1 line for heredoc */ if (func == 0) { /* read 1 line for heredoc */
ruby_sourceline++;
/* -1 for chomp */ /* -1 for chomp */
yylval.val = rb_str_new(lex_pbeg, lex_pend - lex_pbeg - 1); yylval.val = rb_str_new(lex_pbeg, lex_pend - lex_pbeg - 1);
lex_p = lex_pend;
return tSTRING; return tSTRING;
} }
strstart = ruby_sourceline; strstart = ruby_sourceline;
@ -2156,9 +2151,6 @@ parse_string(func, term, paren)
c = nextc(); c = nextc();
} }
} }
else if (c == '\n') {
ruby_sourceline++;
}
else if (c == '#') { else if (c == '#') {
list = rb_str_extend(list, term); list = rb_str_extend(list, term);
if (list == (NODE*)-1) goto unterm_str; if (list == (NODE*)-1) goto unterm_str;
@ -2166,10 +2158,7 @@ parse_string(func, term, paren)
} }
else if (c == '\\') { else if (c == '\\') {
c = nextc(); c = nextc();
if (c == '\n') { if (c == term) {
ruby_sourceline++;
}
else if (c == term) {
tokadd(c); tokadd(c);
} }
else { else {
@ -2191,7 +2180,9 @@ parse_string(func, term, paren)
tokfix(); tokfix();
lex_state = EXPR_END; lex_state = EXPR_END;
if (list) { if (list) {
nd_set_line(list, strstart-1);
if (toklen() > 0) { if (toklen() > 0) {
VALUE ss = rb_str_new(tok(), toklen()); VALUE ss = rb_str_new(tok(), toklen());
list_append(list, NEW_STR(ss)); list_append(list, NEW_STR(ss));
@ -2235,16 +2226,9 @@ parse_qstring(term, paren)
c = nextc(); c = nextc();
} }
} }
else if (c == '\n') {
ruby_sourceline++;
}
else if (c == '\\') { else if (c == '\\') {
c = nextc(); c = nextc();
switch (c) { switch (c) {
case '\n':
ruby_sourceline++;
continue;
case '\\': case '\\':
c = '\\'; c = '\\';
break; break;
@ -2403,6 +2387,7 @@ here_document(term, indent)
ruby_sourceline = linesave; ruby_sourceline = linesave;
if (list) { if (list) {
nd_set_line(list, linesave);
yylval.node = list; yylval.node = list;
} }
switch (term) { switch (term) {
@ -2438,12 +2423,7 @@ yylex()
int space_seen = 0; int space_seen = 0;
struct kwtable *kw; struct kwtable *kw;
if (newline_seen) { retry:
ruby_sourceline += newline_seen;
newline_seen = 0;
}
retry:
switch (c = nextc()) { switch (c = nextc()) {
case '\0': /* NUL */ case '\0': /* NUL */
case '\004': /* ^D */ case '\004': /* ^D */
@ -2461,26 +2441,6 @@ retry:
while ((c = nextc()) != '\n') { while ((c = nextc()) != '\n') {
if (c == -1) if (c == -1)
return 0; return 0;
if (ismbchar(c)) {
int i, len = mbclen(c)-1;
for (i = 0; i < len; i++) {
c = nextc();
if (c == '\n') {
pushback(c);
break;
}
}
}
else if (c == ' ') {
if ((c = nextc()) == '\\') {
c = nextc();
if (c == '\n') ruby_sourceline++;
}
else {
pushback(c);
}
}
} }
/* fall through */ /* fall through */
case '\n': case '\n':
@ -2488,12 +2448,10 @@ retry:
case EXPR_BEG: case EXPR_BEG:
case EXPR_FNAME: case EXPR_FNAME:
case EXPR_DOT: case EXPR_DOT:
ruby_sourceline++;
goto retry; goto retry;
default: default:
break; break;
} }
newline_seen++;
lex_state = EXPR_BEG; lex_state = EXPR_BEG;
return '\n'; return '\n';
@ -2541,7 +2499,6 @@ retry:
/* skip embedded rd document */ /* skip embedded rd document */
if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) { if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
for (;;) { for (;;) {
ruby_sourceline++;
lex_p = lex_pend; lex_p = lex_pend;
c = nextc(); c = nextc();
if (c == -1) { if (c == -1) {
@ -2553,7 +2510,6 @@ retry:
break; break;
} }
} }
ruby_sourceline++;
lex_p = lex_pend; lex_p = lex_pend;
goto retry; goto retry;
} }
@ -2715,10 +2671,12 @@ retry:
yylval.id = '+'; yylval.id = '+';
return tOP_ASGN; return tOP_ASGN;
} }
if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
(lex_state == EXPR_ARG && space_seen && !ISSPACE(c))) {
if (ISDIGIT(c)) { if (ISDIGIT(c)) {
goto start_num; goto start_num;
} }
if (lex_state == EXPR_ARG) arg_ambiguous();
pushback(c); pushback(c);
lex_state = EXPR_BEG; lex_state = EXPR_BEG;
return tUPLUS; return tUPLUS;
@ -2741,12 +2699,14 @@ retry:
yylval.id = '-'; yylval.id = '-';
return tOP_ASGN; return tOP_ASGN;
} }
if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
(lex_state == EXPR_ARG && space_seen && !ISSPACE(c))) {
if (ISDIGIT(c)) { if (ISDIGIT(c)) {
pushback(c); pushback(c);
c = '-'; c = '-';
goto start_num; goto start_num;
} }
if (lex_state == EXPR_ARG) arg_ambiguous();
lex_state = EXPR_BEG; lex_state = EXPR_BEG;
pushback(c); pushback(c);
return tUMINUS; return tUMINUS;
@ -3021,7 +2981,6 @@ retry:
case '\\': case '\\':
c = nextc(); c = nextc();
if (c == '\n') { if (c == '\n') {
ruby_sourceline++;
space_seen = 1; space_seen = 1;
goto retry; /* skip \\n */ goto retry; /* skip \\n */
} }
@ -3721,6 +3680,9 @@ aryset(recv, idx, val)
idx = arg_add(idx, val); idx = arg_add(idx, val);
} }
} }
else {
idx = val;
}
return NEW_CALL(recv, tASET, idx); return NEW_CALL(recv, tASET, idx);
} }
@ -4205,9 +4167,6 @@ static struct {
0, 0, 0, 0,
}; };
char *rb_id2name();
char *rb_class2name();
static st_table *sym_tbl; static st_table *sym_tbl;
static st_table *sym_rev_tbl; static st_table *sym_rev_tbl;
@ -4222,7 +4181,7 @@ Init_sym()
ID ID
rb_intern(name) rb_intern(name)
char *name; const char *name;
{ {
static ID last_id = LAST_TOKEN; static ID last_id = LAST_TOKEN;
int id; int id;

View file

@ -79,12 +79,10 @@ rb_waitpid(pid, flags, st)
{ {
int result; int result;
#ifndef NO_WAITPID #ifndef NO_WAITPID
#if defined(USE_THREAD)
int oflags = flags; int oflags = flags;
if (!rb_thread_alone()) { /* there're other threads to run */ if (!rb_thread_alone()) { /* there're other threads to run */
flags |= WNOHANG; flags |= WNOHANG;
} }
#endif
retry: retry:
#ifdef HAVE_WAITPID #ifdef HAVE_WAITPID
@ -94,21 +92,17 @@ rb_waitpid(pid, flags, st)
#endif #endif
if (result < 0) { if (result < 0) {
if (errno == EINTR) { if (errno == EINTR) {
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
goto retry; goto retry;
} }
return -1; return -1;
} }
#ifdef USE_THREAD
if (result == 0) { if (result == 0) {
if (oflags & WNOHANG) return 0; if (oflags & WNOHANG) return 0;
rb_thread_schedule(); rb_thread_schedule();
if (rb_thread_alone()) flags = oflags; if (rb_thread_alone()) flags = oflags;
goto retry; goto retry;
} }
#endif
#else /* NO_WAITPID */ #else /* NO_WAITPID */
if (pid_tbl && st_lookup(pid_tbl, pid, st)) { if (pid_tbl && st_lookup(pid_tbl, pid, st)) {
rb_last_status = INT2FIX(*st); rb_last_status = INT2FIX(*st);
@ -124,9 +118,7 @@ rb_waitpid(pid, flags, st)
result = wait(st); result = wait(st);
if (result < 0) { if (result < 0) {
if (errno == EINTR) { if (errno == EINTR) {
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
continue; continue;
} }
return -1; return -1;
@ -137,9 +129,7 @@ rb_waitpid(pid, flags, st)
if (!pid_tbl) if (!pid_tbl)
pid_tbl = st_init_numtable(); pid_tbl = st_init_numtable();
st_insert(pid_tbl, pid, st); st_insert(pid_tbl, pid, st);
#ifdef USE_THREAD
if (!rb_thread_alone()) rb_thread_schedule(); if (!rb_thread_alone()) rb_thread_schedule();
#endif
} }
#endif #endif
rb_last_status = INT2FIX(*st); rb_last_status = INT2FIX(*st);
@ -181,9 +171,7 @@ rb_f_wait()
while ((pid = wait(&state)) < 0) { while ((pid = wait(&state)) < 0) {
if (errno == EINTR) { if (errno == EINTR) {
#ifdef USE_THREAD
rb_thread_schedule(); rb_thread_schedule();
#endif
continue; continue;
} }
rb_sys_fail(0); rb_sys_fail(0);
@ -212,7 +200,7 @@ rb_f_waitpid(obj, vpid, vflags)
char *strtok(); char *strtok();
#if defined(USE_THREAD) && defined(HAVE_SETITIMER) #ifdef HAVE_SETITIMER
#define before_exec() rb_thread_stop_timer() #define before_exec() rb_thread_stop_timer()
#define after_exec() rb_thread_start_timer() #define after_exec() rb_thread_start_timer()
#else #else
@ -320,10 +308,11 @@ proc_exec_n(argc, argv, progv)
int int
rb_proc_exec(str) rb_proc_exec(str)
char *str; const char *str;
{ {
#ifndef USE_CWGUSI #ifndef USE_CWGUSI
char *s = str, *t; const char *s = str;
char *ss, *t;
char **argv, **a; char **argv, **a;
security(str); security(str);
@ -358,9 +347,9 @@ rb_proc_exec(str)
} }
} }
a = argv = ALLOCA_N(char*, (s-str)/2+2); a = argv = ALLOCA_N(char*, (s-str)/2+2);
s = ALLOCA_N(char, s-str+1); ss = ALLOCA_N(char, s-str+1);
strcpy(s, str); strcpy(ss, str);
if (*a++ = strtok(s, " \t")) { if (*a++ = strtok(ss, " \t")) {
while (t = strtok(NULL, " \t")) { while (t = strtok(NULL, " \t")) {
*a++ = t; *a++ = t;
} }
@ -712,11 +701,7 @@ rb_f_system(argc, argv)
case -1: case -1:
if (errno == EAGAIN) { if (errno == EAGAIN) {
#ifdef USE_THREAD
rb_thread_sleep(1); rb_thread_sleep(1);
#else
sleep(1);
#endif
goto retry; goto retry;
} }
rb_sys_fail(0); rb_sys_fail(0);
@ -742,30 +727,12 @@ rb_f_sleep(argc, argv)
int beg, end; int beg, end;
beg = time(0); beg = time(0);
#ifdef USE_THREAD
if (argc == 0) { if (argc == 0) {
rb_thread_sleep_forever(); rb_thread_sleep_forever();
} }
else if (argc == 1) { else if (argc == 1) {
rb_thread_wait_for(rb_time_timeval(argv[0])); rb_thread_wait_for(rb_time_timeval(argv[0]));
} }
#else
if (argc == 0) {
TRAP_BEG;
sleep((32767<<16)+32767);
TRAP_END;
}
else if (argc == 1) {
struct timeval tv;
int n;
tv = rb_time_timeval(argv[0]);
TRAP_BEG;
n = select(0, 0, 0, 0, &tv);
TRAP_END;
if (n<0) rb_sys_fail(0);
}
#endif
else { else {
rb_raise(rb_eArgError, "wrong # of arguments"); rb_raise(rb_eArgError, "wrong # of arguments");
} }

189
range.c
View file

@ -13,8 +13,10 @@
#include "ruby.h" #include "ruby.h"
VALUE rb_cRange; VALUE rb_cRange;
static ID id_upto, id_cmp; static ID id_cmp, id_beg, id_end;
static ID id_beg, id_end;
#define EXCL(r) FL_TEST((r), FL_USER1)
#define SET_EXCL(r) FL_SET((r), FL_USER1)
static VALUE static VALUE
range_check(args) range_check(args)
@ -31,8 +33,9 @@ range_failed()
} }
static VALUE static VALUE
range_s_new(klass, beg, end) range_new(klass, beg, end, exclude_end)
VALUE klass, beg, end; VALUE klass, beg, end;
int exclude_end;
{ {
VALUE obj; VALUE obj;
VALUE args[2]; VALUE args[2];
@ -43,6 +46,9 @@ range_s_new(klass, beg, end)
} }
obj = rb_obj_alloc(klass); obj = rb_obj_alloc(klass);
if (exclude_end) {
SET_EXCL(obj);
}
rb_ivar_set(obj, id_beg, beg); rb_ivar_set(obj, id_beg, beg);
rb_ivar_set(obj, id_end, end); rb_ivar_set(obj, id_end, end);
@ -52,67 +58,97 @@ range_s_new(klass, beg, end)
} }
VALUE VALUE
rb_range_new(beg, end) rb_range_new(beg, end, exclude_end)
VALUE beg, end; VALUE beg, end;
int exclude_end;
{ {
return range_s_new(rb_cRange, beg, end); return range_new(rb_cRange, beg, end, exclude_end);
} }
static VALUE static VALUE
range_eqq(rng, obj) range_s_new(argc, argv, klass)
VALUE rng, obj; int argc;
VALUE *argv;
VALUE klass;
{
VALUE beg, end, flag, range;
rb_scan_args(argc, argv, "21", &beg, &end, &flag);
if (argc == 2) flag == Qtrue;
return range_new(klass, beg, end, RTEST(flag));
}
static VALUE
range_exclude_end_p(range)
VALUE range;
{
return EXCL(range)?Qtrue:Qfalse;;
}
static VALUE
range_eqq(range, obj)
VALUE range, obj;
{ {
VALUE beg, end; VALUE beg, end;
beg = rb_ivar_get(rng, id_beg); beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(rng, id_end); end = rb_ivar_get(range, id_end);
if (FIXNUM_P(beg) && FIXNUM_P(obj) && FIXNUM_P(end)) { if (FIXNUM_P(beg) && FIXNUM_P(obj) && FIXNUM_P(end)) {
if (FIX2INT(beg) <= FIX2INT(obj) && FIX2INT(obj) <= FIX2INT(end)) { if (FIX2INT(beg) <= FIX2INT(obj)) {
return Qtrue; if (EXCL(range)) {
if (FIX2INT(obj) <= FIX2INT(end)) return Qtrue;
}
else {
if (FIX2INT(obj) < FIX2INT(end)) return Qtrue;
}
} }
return Qfalse; return Qfalse;
} }
else { else if (RTEST(rb_funcall(beg, rb_intern("<="), 1, obj))) {
if (RTEST(rb_funcall(beg, rb_intern("<="), 1, obj)) && if (EXCL(range)) {
RTEST(rb_funcall(end, rb_intern(">="), 1, obj))) { if (RTEST(rb_funcall(end, rb_intern(">="), 1, obj)))
return Qtrue; return Qtrue;
}
else {
if (RTEST(rb_funcall(end, rb_intern(">"), 1, obj)))
return Qtrue;
if (FIX2INT(obj) < FIX2INT(end)) return Qtrue;
} }
return Qfalse;
} }
} return Qfalse;
struct upto_data {
VALUE beg;
VALUE end;
};
static VALUE
range_upto(data)
struct upto_data *data;
{
return rb_funcall(data->beg, id_upto, 1, data->end);
} }
static VALUE static VALUE
range_each(obj) range_each(range)
VALUE obj; VALUE range;
{ {
VALUE b, e; VALUE b, e;
b = rb_ivar_get(obj, id_beg); b = rb_ivar_get(range, id_beg);
e = rb_ivar_get(obj, id_end); e = rb_ivar_get(range, id_end);
if (FIXNUM_P(b)) { /* fixnum is a special case(for performance) */ if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
rb_fix_upto(b, e); long end = FIX2LONG(e);
long i;
if (!EXCL(range)) end += 1;
for (i=FIX2LONG(b); i<end; i++) {
rb_yield(INT2FIX(i));
}
} }
else { else if (TYPE(b) == T_STRING) {
struct upto_data data; rb_str_upto(b, e, EXCL(range));
}
else { /* generic each */
VALUE v = b;
ID le = EXCL(range)?'<':rb_intern("<=");
ID succ = rb_intern("succ");
data.beg = b; while (rb_funcall(v, le, 1, e)) {
data.end = e; rb_yield(v);
v = rb_funcall(v, succ, 0, 0);
rb_iterate(range_upto, (VALUE)&data, rb_yield, 0); }
} }
return Qnil; return Qnil;
@ -139,17 +175,49 @@ range_last(obj)
} }
VALUE VALUE
rb_range_beg_end(range, begp, endp) rb_range_beg_len(range, begp, lenp, len, err)
VALUE range; VALUE range;
int *begp, *endp; int *begp, *lenp;
int len, err;
{ {
VALUE beg, end; int beg, end, b, e;
if (!rb_obj_is_kind_of(range, rb_cRange)) return Qfalse; if (!rb_obj_is_kind_of(range, rb_cRange)) return Qfalse;
beg = rb_ivar_get(range, id_beg); *begp = NUM2INT(beg); beg = b = NUM2INT(rb_ivar_get(range, id_beg));
end = rb_ivar_get(range, id_end); *endp = NUM2INT(end); end = e = NUM2INT(rb_ivar_get(range, id_end));
if (beg < 0) {
beg += len;
if (beg < 0) goto out_of_range;
}
if (err == 2 && beg > len) goto out_of_range;
if (end < 0) {
end += len;
if (end < 0) {
if (err == 1 && e == -1 && !EXCL(range)) {
len = 0;
goto length_set;
}
goto out_of_range;
}
}
len = end - beg;
if (!EXCL(range)) len++; /* include end point */
if (len < 0) goto out_of_range;
length_set:
*begp = beg;
*lenp = len;
return Qtrue; return Qtrue;
out_of_range:
if (err) {
rb_raise(rb_eIndexError, "%d..%s%d out of range",
b, EXCL(range)?".":"", e);
}
return Qnil;
} }
static VALUE static VALUE
@ -160,7 +228,7 @@ range_to_s(range)
str = rb_obj_as_string(rb_ivar_get(range, id_beg)); str = rb_obj_as_string(rb_ivar_get(range, id_beg));
str2 = rb_obj_as_string(rb_ivar_get(range, id_end)); str2 = rb_obj_as_string(rb_ivar_get(range, id_end));
rb_str_cat(str, "..", 2); rb_str_cat(str, "...", EXCL(range)?3:2);
rb_str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); rb_str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
return str; return str;
@ -174,30 +242,40 @@ range_inspect(range)
str = rb_inspect(rb_ivar_get(range, id_beg)); str = rb_inspect(rb_ivar_get(range, id_beg));
str2 = rb_inspect(rb_ivar_get(range, id_end)); str2 = rb_inspect(rb_ivar_get(range, id_end));
rb_str_cat(str, "..", 2); rb_str_cat(str, "...", EXCL(range)?3:2);
rb_str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); rb_str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
return str; return str;
} }
static VALUE static VALUE
range_length(rng) range_length(range)
VALUE rng; VALUE range;
{ {
VALUE beg, end; VALUE beg, end;
VALUE size; VALUE size;
beg = rb_ivar_get(rng, id_beg); beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(rng, id_end); end = rb_ivar_get(range, id_end);
if (RTEST(rb_funcall(beg, '>', 1, end))) { if (RTEST(rb_funcall(beg, '>', 1, end))) {
return INT2FIX(0); return INT2FIX(0);
} }
if (FIXNUM_P(beg) && FIXNUM_P(end)) {
if (EXCL(range)) {
return INT2FIX(FIX2INT(end) - FIX2INT(beg));
}
else {
return INT2FIX(FIX2INT(end) - FIX2INT(beg) + 1);
}
}
if (!rb_obj_is_kind_of(beg, rb_cNumeric)) { if (!rb_obj_is_kind_of(beg, rb_cNumeric)) {
return rb_enum_length(rng); return rb_enum_length(range);
} }
size = rb_funcall(end, '-', 1, beg); size = rb_funcall(end, '-', 1, beg);
size = rb_funcall(size, '+', 1, INT2FIX(1)); if (!EXCL(range)) {
size = rb_funcall(size, '+', 1, INT2FIX(1));
}
return size; return size;
} }
@ -207,7 +285,7 @@ Init_Range()
{ {
rb_cRange = rb_define_class("Range", rb_cObject); rb_cRange = rb_define_class("Range", rb_cObject);
rb_include_module(rb_cRange, rb_mEnumerable); rb_include_module(rb_cRange, rb_mEnumerable);
rb_define_singleton_method(rb_cRange, "new", range_s_new, 2); rb_define_singleton_method(rb_cRange, "new", range_s_new, -1);
rb_define_method(rb_cRange, "===", range_eqq, 1); rb_define_method(rb_cRange, "===", range_eqq, 1);
rb_define_method(rb_cRange, "each", range_each, 0); rb_define_method(rb_cRange, "each", range_each, 0);
rb_define_method(rb_cRange, "first", range_first, 0); rb_define_method(rb_cRange, "first", range_first, 0);
@ -217,10 +295,11 @@ Init_Range()
rb_define_method(rb_cRange, "to_s", range_to_s, 0); rb_define_method(rb_cRange, "to_s", range_to_s, 0);
rb_define_method(rb_cRange, "inspect", range_inspect, 0); rb_define_method(rb_cRange, "inspect", range_inspect, 0);
rb_define_method(rb_cRange, "exclude_end?", range_exclude_end_p, 0);
rb_define_method(rb_cRange, "length", range_length, 0); rb_define_method(rb_cRange, "length", range_length, 0);
rb_define_method(rb_cRange, "size", range_length, 0); rb_define_method(rb_cRange, "size", range_length, 0);
id_upto = rb_intern("upto");
id_cmp = rb_intern("<=>"); id_cmp = rb_intern("<=>");
id_beg = rb_intern("begin"); id_beg = rb_intern("begin");
id_end = rb_intern("end"); id_end = rb_intern("end");

190
re.c
View file

@ -18,7 +18,7 @@ static VALUE rb_eRegxpError;
#define END(no) regs->end[no] #define END(no) regs->end[no]
#if 'a' == 97 /* it's ascii */ #if 'a' == 97 /* it's ascii */
static char casetable[] = { static const char casetable[] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
@ -198,10 +198,10 @@ extern int ruby_in_compile;
static void static void
rb_reg_expr_str(str, s, len) rb_reg_expr_str(str, s, len)
VALUE str; VALUE str;
char *s; const char *s;
int len; int len;
{ {
char *p, *pend; const char *p, *pend;
int slash = 0; int slash = 0;
p = s; pend = p + len; p = s; pend = p + len;
@ -233,7 +233,7 @@ rb_reg_expr_str(str, s, len)
static VALUE static VALUE
rb_reg_desc(s, len, re) rb_reg_desc(s, len, re)
char *s; const char *s;
int len; int len;
VALUE re; VALUE re;
{ {
@ -282,9 +282,9 @@ rb_reg_inspect(re)
static void static void
rb_reg_raise(s, len, err, re) rb_reg_raise(s, len, err, re)
char *s; const char *s;
int len; int len;
char *err; const char *err;
VALUE re; VALUE re;
{ {
VALUE desc = rb_reg_desc(s, len, re); VALUE desc = rb_reg_desc(s, len, re);
@ -329,7 +329,7 @@ rb_reg_kcode_method(re)
static Regexp* static Regexp*
make_regexp(s, len, flag) make_regexp(s, len, flag)
char *s; const char *s;
int len, flag; int len, flag;
{ {
Regexp *rp; Regexp *rp;
@ -392,6 +392,59 @@ match_clone(orig)
return (VALUE)match; return (VALUE)match;
} }
static VALUE
match_size(match)
VALUE match;
{
return INT2FIX(RMATCH(match)->regs->num_regs);
}
static VALUE
match_offset(match, n)
VALUE match, n;
{
int i = NUM2INT(n);
if (i < 0 || RMATCH(match)->regs->num_regs <= i)
rb_raise(rb_eIndexError, "index %d out of matches", i);
if (RMATCH(match)->regs->beg[i] < 0)
return rb_assoc_new(Qnil, Qnil);
return rb_assoc_new(INT2FIX(RMATCH(match)->regs->beg[i]),
INT2FIX(RMATCH(match)->regs->end[i]));
}
static VALUE
match_begin(match, n)
VALUE match, n;
{
int i = NUM2INT(n);
if (i < 0 || RMATCH(match)->regs->num_regs <= i)
rb_raise(rb_eIndexError, "index %d out of matches", i);
if (RMATCH(match)->regs->beg[i] < 0)
return Qnil;
return INT2FIX(RMATCH(match)->regs->beg[i]);
}
static VALUE
match_end(match, n)
VALUE match, n;
{
int i = NUM2INT(n);
if (i < 0 || RMATCH(match)->regs->num_regs <= i)
rb_raise(rb_eIndexError, "index %d out of matches", i);
if (RMATCH(match)->regs->beg[i] < 0)
return Qnil;
return INT2FIX(RMATCH(match)->regs->end[i]);
}
#define MATCH_BUSY FL_USER2 #define MATCH_BUSY FL_USER2
void void
@ -467,16 +520,12 @@ rb_reg_search(reg, str, start, reverse)
else if (reg_kcode != curr_kcode) else if (reg_kcode != curr_kcode)
kcode_reset_option(); kcode_reset_option();
#ifdef USE_THREAD
if (rb_thread_scope_shared_p()) { if (rb_thread_scope_shared_p()) {
match = Qnil; match = Qnil;
} }
else { else {
match = rb_backref_get(); match = rb_backref_get();
} }
#else
match = rb_backref_get();
#endif
if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) { if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) {
if (matchcache) { if (matchcache) {
match = matchcache; match = matchcache;
@ -569,7 +618,7 @@ rb_reg_match_post(match)
if (NIL_P(match)) return Qnil; if (NIL_P(match)) return Qnil;
if (RMATCH(match)->BEG(0) == -1) return Qnil; if (RMATCH(match)->BEG(0) == -1) return Qnil;
return rb_str_new(RSTRING(RMATCH(match)->str)->ptr+RMATCH(match)->END(0), return rb_str_new(RSTRING(RMATCH(match)->str)->ptr+RMATCH(match)->END(0),
RSTRING(RMATCH(match)->str)->len-RMATCH(match)->END(0)); RSTRING(RMATCH(match)->str)->len-RMATCH(match)->END(0));
} }
VALUE VALUE
@ -648,7 +697,7 @@ match_aref(argc, argv, match)
regs = RMATCH(match)->regs; regs = RMATCH(match)->regs;
i = FIX2INT(idx); i = FIX2INT(idx);
if (i>=regs->num_regs) return Qnil; if (i >= regs->num_regs) return Qnil;
ptr = RSTRING(RMATCH(match)->str)->ptr; ptr = RSTRING(RMATCH(match)->str)->ptr;
return rb_str_new(ptr+regs->beg[i], regs->end[i]-regs->beg[i]); return rb_str_new(ptr+regs->beg[i], regs->end[i]-regs->beg[i]);
@ -664,12 +713,19 @@ match_to_s(match)
return str; return str;
} }
static VALUE
match_string(match)
VALUE match;
{
return rb_str_dup(RMATCH(match)->str);
}
VALUE rb_cRegexp; VALUE rb_cRegexp;
static VALUE static VALUE
rb_reg_new_1(klass, s, len, options) rb_reg_new_1(klass, s, len, options)
VALUE klass; VALUE klass;
char *s; const char *s;
int len; int len;
int options; /* CASEFOLD = 1 */ int options; /* CASEFOLD = 1 */
/* EXTENDED = 2 */ /* EXTENDED = 2 */
@ -727,7 +783,7 @@ rb_reg_new_1(klass, s, len, options)
VALUE VALUE
rb_reg_new(s, len, options) rb_reg_new(s, len, options)
char *s; const char *s;
int len; int len;
int options; int options;
{ {
@ -815,6 +871,16 @@ rb_reg_match2(re)
return INT2FIX(start); return INT2FIX(start);
} }
static VALUE
rb_reg_match_method(re, str)
VALUE re, str;
{
VALUE result = rb_reg_match(re, str);
if (NIL_P(result)) return Qnil;
return rb_backref_get();
}
static VALUE static VALUE
rb_reg_s_new(argc, argv, self) rb_reg_s_new(argc, argv, self)
int argc; int argc;
@ -827,8 +893,9 @@ rb_reg_s_new(argc, argv, self)
if (argc == 0 || argc > 3) { if (argc == 0 || argc > 3) {
rb_raise(rb_eArgError, "wrong # of argument"); rb_raise(rb_eArgError, "wrong # of argument");
} }
if (argc >= 2 && RTEST(argv[1])) { if (argc >= 2) {
flag = RE_OPTION_IGNORECASE; if (FIXNUM_P(argv[1])) flag = FIX2INT(argv[1]);
else if (RTEST(argv[1])) flag = RE_OPTION_IGNORECASE;
} }
if (argc == 3) { if (argc == 3) {
char *kcode = STR2CSTR(argv[2]); char *kcode = STR2CSTR(argv[2]);
@ -865,40 +932,50 @@ rb_reg_s_new(argc, argv, self)
} }
static VALUE static VALUE
rb_reg_s_quote(re, str) rb_reg_s_quote(argc, argv)
VALUE re, str; int argc;
VALUE *argv;
{ {
char *s, *send, *t; VALUE str, kcode;
char *tmp; int kcode_saved = reg_kcode;
int len; char *s, *send, *t;
char *tmp;
int len;
s = str2cstr(str, &len); rb_scan_args(argc, argv, "11", &str, &kcode);
send = s + len; if (!NIL_P(kcode)) {
tmp = ALLOCA_N(char, len*2); rb_set_kcode(STR2CSTR(kcode));
t = tmp; curr_kcode = reg_kcode;
reg_kcode = kcode_saved;
for (; s != send; s++) {
if (ismbchar(*s)) {
size_t n = mbclen(*s);
while (n--)
*t++ = *s++;
s--;
continue;
}
if (*s == '[' || *s == ']'
|| *s == '{' || *s == '}'
|| *s == '(' || *s == ')'
|| *s == '|'
|| *s == '*' || *s == '.' || *s == '\\'
|| *s == '?' || *s == '+'
|| *s == '^' || *s == '$') {
*t++ = '\\';
}
*t++ = *s;
} }
s = str2cstr(str, &len);
send = s + len;
tmp = ALLOCA_N(char, len*2);
t = tmp;
return rb_str_new(tmp, t - tmp); for (; s != send; s++) {
if (ismbchar(*s)) {
size_t n = mbclen(*s);
while (n--)
*t++ = *s++;
s--;
continue;
}
if (*s == '[' || *s == ']'
|| *s == '{' || *s == '}'
|| *s == '(' || *s == ')'
|| *s == '|'
|| *s == '*' || *s == '.' || *s == '\\'
|| *s == '?' || *s == '+'
|| *s == '^' || *s == '$') {
*t++ = '\\';
}
*t++ = *s;
}
kcode_reset_option();
return rb_str_new(tmp, t - tmp);
} }
int int
@ -1039,7 +1116,7 @@ rb_reg_regsub(str, src, regs)
return val; return val;
} }
char* const char*
rb_get_kcode() rb_get_kcode()
{ {
switch (reg_kcode) { switch (reg_kcode) {
@ -1062,7 +1139,7 @@ kcode_getter()
void void
rb_set_kcode(code) rb_set_kcode(code)
char *code; const char *code;
{ {
if (code == 0) goto set_no_conversion; if (code == 0) goto set_no_conversion;
@ -1166,25 +1243,38 @@ Init_Regexp()
rb_cRegexp = rb_define_class("Regexp", rb_cObject); rb_cRegexp = rb_define_class("Regexp", rb_cObject);
rb_define_singleton_method(rb_cRegexp, "new", rb_reg_s_new, -1); rb_define_singleton_method(rb_cRegexp, "new", rb_reg_s_new, -1);
rb_define_singleton_method(rb_cRegexp, "compile", rb_reg_s_new, -1); rb_define_singleton_method(rb_cRegexp, "compile", rb_reg_s_new, -1);
rb_define_singleton_method(rb_cRegexp, "quote", rb_reg_s_quote, 1); rb_define_singleton_method(rb_cRegexp, "quote", rb_reg_s_quote, -1);
rb_define_singleton_method(rb_cRegexp, "escape", rb_reg_s_quote, -1);
rb_define_method(rb_cRegexp, "clone", rb_reg_clone, 0); rb_define_method(rb_cRegexp, "clone", rb_reg_clone, 0);
rb_define_method(rb_cRegexp, "==", rb_reg_equal, 1); rb_define_method(rb_cRegexp, "==", rb_reg_equal, 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_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, "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_method, 0);
rb_define_const(rb_cRegexp, "IGNORECASE", INT2FIX(RE_OPTION_IGNORECASE));
rb_define_const(rb_cRegexp, "EXTENDED", INT2FIX(RE_OPTION_EXTENDED));
rb_global_variable(&reg_cache); rb_global_variable(&reg_cache);
rb_global_variable(&matchcache); rb_global_variable(&matchcache);
rb_cMatch = rb_define_class("MatchingData", rb_cData); rb_cMatch = rb_define_class("MatchingData", rb_cData);
rb_define_method(rb_cMatch, "clone", match_clone, 0); rb_define_method(rb_cMatch, "clone", match_clone, 0);
rb_define_method(rb_cMatch, "size", match_size, 0);
rb_define_method(rb_cMatch, "length", match_size, 0);
rb_define_method(rb_cMatch, "offset", match_offset, 1);
rb_define_method(rb_cMatch, "begin", match_begin, 1);
rb_define_method(rb_cMatch, "end", match_end, 1);
rb_define_method(rb_cMatch, "to_a", match_to_a, 0); rb_define_method(rb_cMatch, "to_a", match_to_a, 0);
rb_define_method(rb_cMatch, "[]", match_aref, -1); rb_define_method(rb_cMatch, "[]", match_aref, -1);
rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0);
rb_define_method(rb_cMatch, "post_match", rb_reg_match_post, 0);
rb_define_method(rb_cMatch, "to_s", match_to_s, 0); rb_define_method(rb_cMatch, "to_s", match_to_s, 0);
rb_define_method(rb_cMatch, "string_s", match_string, 0);
rb_define_method(rb_cMatch, "inspect", rb_any_to_s, 0); rb_define_method(rb_cMatch, "inspect", rb_any_to_s, 0);
} }

4225
regex.c

File diff suppressed because it is too large Load diff

27
regex.h
View file

@ -59,12 +59,17 @@
If not set, then character classes are not supported. */ If not set, then character classes are not supported. */
#define RE_CHAR_CLASSES (1L << 9) #define RE_CHAR_CLASSES (1L << 9)
#define RE_OPTION_EXTENDED (1L<<0) /* match will be done case insensetively */
#define RE_OPTION_IGNORECASE (1L<<1) #define RE_OPTION_IGNORECASE (1L<<1)
#define RE_MAY_IGNORECASE (1L<<2) /* perl-style extended pattern available */
#define RE_OPTIMIZE_ANCHOR (1L<<4) #define RE_OPTION_EXTENDED (RE_OPTION_IGNORECASE<<1)
#define RE_OPTIMIZE_EXACTN (1L<<5) /* newline will be included for . and invert charclass matches */
#define RE_OPTIMIZE_NO_BM (1L<<6) #define RE_OPTION_POSIX (RE_OPTION_EXTENDED<<1)
#define RE_MAY_IGNORECASE (RE_OPTION_POSIX<<1)
#define RE_OPTIMIZE_ANCHOR (RE_MAY_IGNORECASE<<1)
#define RE_OPTIMIZE_EXACTN (RE_OPTIMIZE_ANCHOR<<1)
#define RE_OPTIMIZE_NO_BM (RE_OPTIMIZE_ANCHOR<<1)
/* For multi-byte char support */ /* For multi-byte char support */
#define MBCTYPE_ASCII 0 #define MBCTYPE_ASCII 0
@ -151,22 +156,22 @@ typedef struct
#ifdef __STDC__ #ifdef __STDC__
extern char *re_compile_pattern (char *, int, struct re_pattern_buffer *); extern char *re_compile_pattern (const char *, int, struct re_pattern_buffer *);
void re_free_pattern (struct re_pattern_buffer *); void re_free_pattern (struct re_pattern_buffer *);
/* Is this really advertised? */ /* Is this really advertised? */
extern void re_compile_fastmap (struct re_pattern_buffer *); extern void re_compile_fastmap (struct re_pattern_buffer *);
extern int re_search (struct re_pattern_buffer *, char*, int, int, int, extern int re_search (struct re_pattern_buffer *, const char*, int, int, int,
struct re_registers *); struct re_registers *);
extern int re_match (struct re_pattern_buffer *, char *, int, int, extern int re_match (struct re_pattern_buffer *, const char *, int, int,
struct re_registers *); struct re_registers *);
extern void re_set_casetable (char *table); extern void re_set_casetable (const char *table);
extern void re_copy_registers (struct re_registers*, struct re_registers*); extern void re_copy_registers (struct re_registers*, struct re_registers*);
extern void re_free_registers (struct re_registers*); extern void re_free_registers (struct re_registers*);
#ifndef RUBY #ifndef RUBY
/* 4.2 bsd compatibility. */ /* 4.2 bsd compatibility. */
extern char *re_comp (char *); extern char *re_comp (const char *);
extern int re_exec (char *); extern int re_exec (const char *);
#endif #endif
#else /* !__STDC__ */ #else /* !__STDC__ */

26
ruby.c
View file

@ -34,9 +34,9 @@
#endif #endif
#ifndef HAVE_STRING_H #ifndef HAVE_STRING_H
char *strchr _((char*,char)); char *strchr _((const char*,const char));
char *strrchr _((char*,char)); char *strrchr _((const char*,const char));
char *strstr _((char*,char*)); char *strstr _((const char*,const char*));
#endif #endif
#include "util.h" #include "util.h"
@ -52,14 +52,16 @@ VALUE ruby_verbose = Qfalse;
static int sflag = Qfalse; static int sflag = Qfalse;
char *ruby_inplace_mode = Qfalse; char *ruby_inplace_mode = Qfalse;
# ifndef strdup
char *strdup(); char *strdup();
# endif
extern int yydebug; extern int yydebug;
static int xflag = Qfalse; static int xflag = Qfalse;
static void load_stdin _((void)); static void load_stdin _((void));
static void load_file _((char *, int)); static void load_file _((char *, int));
static void forbid_setid _((char *)); static void forbid_setid _((const char *));
static VALUE do_loop = Qfalse, do_print = Qfalse; static VALUE do_loop = Qfalse, do_print = Qfalse;
static VALUE do_check = Qfalse, do_line = Qfalse; static VALUE do_check = Qfalse, do_line = Qfalse;
@ -72,7 +74,7 @@ static char **origargv;
static void static void
usage(name) usage(name)
char *name; const char *name;
{ {
/* This message really ought to be max 23 lines. /* This message really ought to be max 23 lines.
* Removed -h because the user already knows that opton. Others? */ * Removed -h because the user already knows that opton. Others? */
@ -124,7 +126,7 @@ static char *e_tmpname;
static void static void
addpath(path) addpath(path)
char *path; const char *path;
{ {
const char sep = RUBY_PATH_SEP[0]; const char sep = RUBY_PATH_SEP[0];
@ -137,7 +139,7 @@ addpath(path)
} }
#endif #endif
if (strchr(path, sep)) { if (strchr(path, sep)) {
char *p, *s; const char *p, *s;
VALUE ary = rb_ary_new(); VALUE ary = rb_ary_new();
p = path; p = path;
@ -160,14 +162,14 @@ addpath(path)
} }
struct req_list { struct req_list {
char *name; const char *name;
struct req_list *next; struct req_list *next;
} req_list_head; } req_list_head;
struct req_list *req_list_last = &req_list_head; struct req_list *req_list_last = &req_list_head;
static void static void
add_modules(mod) add_modules(mod)
char *mod; const char *mod;
{ {
struct req_list *list; struct req_list *list;
@ -602,10 +604,10 @@ load_file(fname, script)
if (RSTRING(line)->ptr[RSTRING(line)->len-2] == '\r') if (RSTRING(line)->ptr[RSTRING(line)->len-2] == '\r')
RSTRING(line)->ptr[RSTRING(line)->len-2] = '\0'; RSTRING(line)->ptr[RSTRING(line)->len-2] = '\0';
if (p = strstr(p, " -")) { if (p = strstr(p, " -")) {
int argc; char *argv[2]; char **argvp = argv; int argc; char *argv[3]; char **argvp = argv;
char *s = ++p; char *s = ++p;
argc = 2; argv[0] = 0; argc = 2; argv[0] = argv[2] = 0;
while (*p == '-') { while (*p == '-') {
while (*s && !ISSPACE(*s)) while (*s && !ISSPACE(*s))
s++; s++;
@ -733,7 +735,7 @@ init_ids()
static void static void
forbid_setid(s) forbid_setid(s)
char *s; const char *s;
{ {
if (euid != uid) if (euid != uid)
rb_raise(rb_eSecurityError, "No %s allowed while running setuid", s); rb_raise(rb_eSecurityError, "No %s allowed while running setuid", s);

70
ruby.h
View file

@ -51,19 +51,16 @@ extern "C" {
#ifndef __STDC__ #ifndef __STDC__
# define volatile # define volatile
# ifdef __GNUC__
# define const __const__
# else
# define const
# endif
#endif #endif
#undef _
#ifdef HAVE_PROTOTYPES #ifdef HAVE_PROTOTYPES
# define _(args) args # define _(args) args
#else #else
# define _(args) () # define _(args) ()
#endif #endif
#undef __
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
# define __(args) args # define __(args) args
#else #else
@ -84,9 +81,11 @@ extern "C" {
#if defined(DLLIMPORT) #if defined(DLLIMPORT)
#include "import.h" #include "import.h"
#else #else
#if !defined(__CYGWIN__)
#define environ (*__imp___cygwin_environ) #define environ (*__imp___cygwin_environ)
#endif #endif
#endif #endif
#endif
#ifdef _AIX #ifdef _AIX
#pragma alloca #pragma alloca
@ -371,30 +370,30 @@ void *xrealloc _((void*,size_t));
#define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n)) #define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))
#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n)) #define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))
VALUE rb_define_class _((char*,VALUE)); VALUE rb_define_class _((const char*,VALUE));
VALUE rb_define_module _((char*)); VALUE rb_define_module _((const char*));
VALUE rb_define_class_under _((VALUE, char *, VALUE)); VALUE rb_define_class_under _((VALUE, const char*, VALUE));
VALUE rb_define_module_under _((VALUE, char *)); VALUE rb_define_module_under _((VALUE, const char*));
void rb_include_module _((VALUE,VALUE)); void rb_include_module _((VALUE,VALUE));
void rb_extend_object _((VALUE,VALUE)); void rb_extend_object _((VALUE,VALUE));
void rb_define_variable _((char*,VALUE*)); void rb_define_variable _((const char*,VALUE*));
void rb_define_virtual_variable _((char*,VALUE(*)(),void(*)())); void rb_define_virtual_variable _((const char*,VALUE(*)(),void(*)()));
void rb_define_hooked_variable _((char*,VALUE*,VALUE(*)(),void(*)())); void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(),void(*)()));
void rb_define_readonly_variable _((char*,VALUE*)); void rb_define_readonly_variable _((const char*,VALUE*));
void rb_define_const _((VALUE,char*,VALUE)); void rb_define_const _((VALUE,const char*,VALUE));
void rb_define_global_const _((char*,VALUE)); void rb_define_global_const _((const char*,VALUE));
void rb_define_method _((VALUE,char*,VALUE(*)(),int)); void rb_define_method _((VALUE,const char*,VALUE(*)(),int));
void rb_define_module_function _((VALUE,char*,VALUE(*)(),int)); void rb_define_module_function _((VALUE,const char*,VALUE(*)(),int));
void rb_define_global_function _((char*,VALUE(*)(),int)); void rb_define_global_function _((const char*,VALUE(*)(),int));
void rb_undef_method _((VALUE,char*)); void rb_undef_method _((VALUE,const char*));
void rb_define_alias _((VALUE,char*,char*)); void rb_define_alias _((VALUE,const char*,const char*));
void rb_define_attr _((VALUE,char*,int,int)); void rb_define_attr _((VALUE,const char*,int,int));
ID rb_intern _((char*)); ID rb_intern _((const char*));
char *rb_id2name _((ID)); char *rb_id2name _((ID));
ID rb_to_id _((VALUE)); ID rb_to_id _((VALUE));
@ -402,13 +401,13 @@ char *rb_class2name _((VALUE));
void rb_p _((VALUE)); void rb_p _((VALUE));
VALUE rb_eval_string _((char*)); VALUE rb_eval_string _((const char*));
VALUE rb_eval_string_protect _((char*, int*)); VALUE rb_eval_string_protect _((const char*, int*));
VALUE rb_funcall __((VALUE, ID, int, ...)); VALUE rb_funcall __((VALUE, ID, int, ...));
int rb_scan_args __((int, VALUE*, char*, ...)); int rb_scan_args __((int, VALUE*, const char*, ...));
VALUE rb_iv_get _((VALUE, char *)); VALUE rb_iv_get _((VALUE, const char*));
VALUE rb_iv_set _((VALUE, char *, VALUE)); VALUE rb_iv_set _((VALUE, const char*, VALUE));
VALUE rb_const_get _((VALUE, ID)); VALUE rb_const_get _((VALUE, ID));
VALUE rb_const_get_at _((VALUE, ID)); VALUE rb_const_get_at _((VALUE, ID));
void rb_const_set _((VALUE, ID, VALUE)); void rb_const_set _((VALUE, ID, VALUE));
@ -420,16 +419,16 @@ EXTERN VALUE ruby_verbose, ruby_debug;
int rb_safe_level _((void)); int rb_safe_level _((void));
void rb_set_safe_level _((int)); void rb_set_safe_level _((int));
void rb_raise __((VALUE, char*, ...)) NORETURN; void rb_raise __((VALUE, const char*, ...)) NORETURN;
void rb_fatal __((char*, ...)) NORETURN; void rb_fatal __((const char*, ...)) NORETURN;
void rb_bug __((char*, ...)) NORETURN; void rb_bug __((const char*, ...)) NORETURN;
void rb_sys_fail _((char*)) NORETURN; void rb_sys_fail _((const char*)) NORETURN;
void rb_iter_break _((void)) NORETURN; void rb_iter_break _((void)) NORETURN;
void rb_exit _((int)) NORETURN; void rb_exit _((int)) NORETURN;
void rb_notimplement _((void)) NORETURN; void rb_notimplement _((void)) NORETURN;
void rb_warn __((char*, ...)); void rb_warn __((const char*, ...));
void rb_warning __((char*, ...)); /* reports if `-w' specified */ void rb_warning __((const char*, ...)); /* reports if `-w' specified */
VALUE rb_each _((VALUE)); VALUE rb_each _((VALUE));
VALUE rb_yield _((VALUE)); VALUE rb_yield _((VALUE));
@ -437,8 +436,8 @@ int rb_iterator_p _((void));
VALUE rb_iterate _((VALUE(*)(),VALUE,VALUE(*)(),VALUE)); VALUE rb_iterate _((VALUE(*)(),VALUE,VALUE(*)(),VALUE));
VALUE rb_rescue _((VALUE(*)(),VALUE,VALUE(*)(),VALUE)); VALUE rb_rescue _((VALUE(*)(),VALUE,VALUE(*)(),VALUE));
VALUE rb_ensure _((VALUE(*)(),VALUE,VALUE(*)(),VALUE)); VALUE rb_ensure _((VALUE(*)(),VALUE,VALUE(*)(),VALUE));
VALUE rb_catch _((char*,VALUE(*)(),VALUE)); VALUE rb_catch _((const char*,VALUE(*)(),VALUE));
void rb_throw _((char*,VALUE)) NORETURN; void rb_throw _((const char*,VALUE)) NORETURN;
void ruby_init _((void)); void ruby_init _((void));
void ruby_options _((int, char**)); void ruby_options _((int, char**));
@ -483,6 +482,7 @@ EXTERN VALUE rb_eException;
EXTERN VALUE rb_eStandardError; EXTERN VALUE rb_eStandardError;
EXTERN VALUE rb_eSystemExit; EXTERN VALUE rb_eSystemExit;
EXTERN VALUE rb_eInterrupt; EXTERN VALUE rb_eInterrupt;
EXTERN VALUE rb_eSignal;
EXTERN VALUE rb_eFatal; EXTERN VALUE rb_eFatal;
EXTERN VALUE rb_eArgError; EXTERN VALUE rb_eArgError;
EXTERN VALUE rb_eEOFError; EXTERN VALUE rb_eEOFError;

View file

@ -48,8 +48,8 @@ typedef struct OpenFile {
#define GetReadFile(fptr) ((fptr)->f) #define GetReadFile(fptr) ((fptr)->f)
#define GetWriteFile(fptr) (((fptr)->f2) ? (fptr)->f2 : (fptr)->f) #define GetWriteFile(fptr) (((fptr)->f2) ? (fptr)->f2 : (fptr)->f)
FILE *rb_fopen _((char *, char *)); FILE *rb_fopen _((const char*, const char*));
FILE *rb_fdopen _((int, char *)); FILE *rb_fdopen _((int, const char*));
void rb_io_check_writable _((OpenFile *)); void rb_io_check_writable _((OpenFile *));
void rb_io_check_readable _((OpenFile *)); void rb_io_check_readable _((OpenFile *));
void rb_io_fptr_finalize _((OpenFile *)); void rb_io_fptr_finalize _((OpenFile *));

View file

@ -22,7 +22,6 @@ extern int rb_prohibit_interrupt;
extern int rb_trap_pending; extern int rb_trap_pending;
void rb_trap_restore_mask _((void)); void rb_trap_restore_mask _((void));
#ifdef USE_THREAD
extern int rb_thread_critical; extern int rb_thread_critical;
void rb_thread_schedule _((void)); void rb_thread_schedule _((void));
#if defined(HAVE_SETITIMER) && !defined(__BOW__) #if defined(HAVE_SETITIMER) && !defined(__BOW__)
@ -31,11 +30,11 @@ extern int rb_thread_pending;
if (rb_trap_pending) rb_trap_exec();\ if (rb_trap_pending) rb_trap_exec();\
if (rb_thread_pending && !rb_thread_critical) rb_thread_schedule();\ if (rb_thread_pending && !rb_thread_critical) rb_thread_schedule();\
} }
# else #else
/* pseudo preemptive thread switching */ /* pseudo preemptive thread switching */
extern int rb_thread_tick; extern int rb_thread_tick;
#define THREAD_TICK 500 #define THREAD_TICK 500
# define CHECK_INTS if (!rb_prohibit_interrupt) {\ #define CHECK_INTS if (!rb_prohibit_interrupt) {\
if (rb_trap_pending) rb_trap_exec();\ if (rb_trap_pending) rb_trap_exec();\
if (!rb_thread_critical) {\ if (!rb_thread_critical) {\
if (rb_thread_tick-- <= 0) {\ if (rb_thread_tick-- <= 0) {\
@ -44,11 +43,6 @@ extern int rb_thread_tick;
}\ }\
}\ }\
} }
# endif
#else
# define CHECK_INTS if (!rb_prohibit_interrupt) {\
if (rb_trap_pending) rb_trap_exec();\
}
#endif #endif
#endif #endif

View file

@ -1,7 +1,7 @@
#! /usr/local/bin/ruby #! /usr/local/bin/ruby
# cal.rb (bsd compatible version): Written by Tadayoshi Funaba 1998, 1999 # cal.rb (bsd compatible version): Written by Tadayoshi Funaba 1998, 1999
# $Id: bsdcal.rb,v 1.3 1999/02/06 08:52:21 tadf Exp $ # $Id: bsdcal.rb,v 1.4 1999/03/06 02:05:59 tadf Exp $
require 'date2' require 'date2'
@ -70,10 +70,10 @@ end
while /^-([^-].*)$/no =~ $*[0] while /^-([^-].*)$/no =~ $*[0]
a = $1 a = $1
if /^c(.+)?$/no =~ a then if /^c(.+)?$/no =~ a
if $1 then if $1
$cc = $1.downcase $cc = $1.downcase
elsif $*.length >= 2 then elsif $*.length >= 2
$cc = $*[1].downcase $cc = $*[1].downcase
$*.shift $*.shift
else else
@ -109,7 +109,7 @@ end
usage unless m.nil? or (1..12) === m usage unless m.nil? or (1..12) === m
usage unless y >= -4712 usage unless y >= -4712
$w = if $jd then 3 else 2 end $w = if $jd then 3 else 2 end
unless $yr then unless $yr
print cal(m, y, gs) print cal(m, y, gs)
else else
print y.to_s.center(((($w + 1) * 7) - 1) * print y.to_s.center(((($w + 1) * 7) - 1) *

View file

@ -17,6 +17,8 @@ class String
len += 1 len += 1
me = self[0, len].ljust(len) me = self[0, len].ljust(len)
if me =~ /.$/ and $&.size == 2 if me =~ /.$/ and $&.size == 2
p me[-2..-1]
me[-2..-1] = ' '
me[-2, 2] = ' ' me[-2, 2] = ' '
end end
me.chop! me.chop!

View file

@ -168,6 +168,6 @@ begin
end end
end end
ensure ensure
system("stty -raw echo") system("stty -raw echo")
end end
print "\n" print "\n"

View file

@ -1,17 +1,14 @@
# sieve of Eratosthenes # sieve of Eratosthenes
sieve = []
max = Integer(ARGV.shift || 100) max = Integer(ARGV.shift || 100)
sieve = []
for i in 2 .. max
sieve[i] = i
end
print "1" for i in 2 .. Math.sqrt(max)
for i in 2 .. max next unless sieve[i]
begin (i*i).step(max, i) do |j|
for d in sieve sieve[j] = nil
fail if i % d == 0
end
print ", "
print i
sieve.push(i)
rescue
end end
end end
print "\n" puts sieve.compact.join ", "

118
signal.c
View file

@ -179,6 +179,18 @@ signm2signo(nm)
return 0; return 0;
} }
static char*
signo2signm(no)
int no;
{
struct signals *sigs;
for (sigs = siglist; sigs->signm; sigs++)
if (sigs->signo == no)
return sigs->signm;
return 0;
}
VALUE VALUE
rb_f_kill(argc, argv) rb_f_kill(argc, argv)
int argc; int argc;
@ -284,30 +296,61 @@ posix_signal(signum, handler)
sigact.sa_flags = 0; sigact.sa_flags = 0;
sigaction(signum, &sigact, 0); sigaction(signum, &sigact, 0);
} }
#define ruby_signal(sig,handle) posix_signal((sig),(handle))
#else
#define ruby_signal(sig,handle) signal((sig),(handle))
#endif #endif
#ifdef USE_THREAD static int
# define rb_interrupt rb_thread_interrupt signal_exec(sig)
# define rb_trap_eval rb_thread_trap_eval int sig;
{
if (trap_list[sig] == 0) {
switch (sig) {
case SIGINT:
rb_thread_interrupt();
break;
case SIGHUP:
case SIGTERM:
#ifdef SIGPIPE
case SIGPIPE:
#endif #endif
#ifdef SIGQUIT
case SIGQUIT:
#endif
#ifdef SIGALRM
case SIGALRM:
#endif
#ifdef SIGUSR1
case SIGUSR1:
#endif
#ifdef SIGUSR2
case SIGUSR2:
#endif
rb_thread_signal_raise(signo2signm(sig));
break;
}
}
else {
rb_thread_trap_eval(trap_list[sig], sig);
}
}
static RETSIGTYPE static RETSIGTYPE
sighandle(sig) sighandle(sig)
int sig; int sig;
{ {
if (sig >= NSIG ||(sig != SIGINT && !trap_list[sig])) if (sig >= NSIG) {
rb_bug("trap_handler: Bad signal %d", sig); rb_bug("trap_handler: Bad signal %d", sig);
}
#if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL) #if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL)
signal(sig, sighandle); ruby_signal(sig, sighandle);
#endif #endif
if (rb_trap_immediate) { if (rb_trap_immediate) {
rb_trap_immediate = 0; rb_trap_immediate = 0;
if (sig == SIGINT && !trap_list[SIGINT]) { signal_exec(sig);
rb_interrupt();
}
rb_trap_eval(trap_list[sig], sig);
rb_trap_immediate = 1; rb_trap_immediate = 1;
} }
else { else {
@ -353,11 +396,7 @@ rb_trap_exec()
for (i=0; i<NSIG; i++) { for (i=0; i<NSIG; i++) {
if (trap_pending_list[i]) { if (trap_pending_list[i]) {
trap_pending_list[i] = 0; trap_pending_list[i] = 0;
if (i == SIGINT && trap_list[SIGINT] == 0) { signal_exec(i);
rb_interrupt();
return;
}
rb_trap_eval(trap_list[i], i);
} }
} }
#endif /* MACOS_UNUSE_SIGNAL */ #endif /* MACOS_UNUSE_SIGNAL */
@ -446,7 +485,7 @@ trap(arg)
if (sig < 0 || sig > NSIG) { if (sig < 0 || sig > NSIG) {
rb_raise(rb_eArgError, "invalid signal number (%d)", sig); rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
} }
#if defined(USE_THREAD) && defined(HAVE_SETITIMER) && !defined(__BOW__) #if defined(HAVE_SETITIMER) && !defined(__BOW__)
if (sig == SIGVTALRM) { if (sig == SIGVTALRM) {
rb_raise(rb_eArgError, "SIGVTALRM reserved for Thread; cannot set handler"); rb_raise(rb_eArgError, "SIGVTALRM reserved for Thread; cannot set handler");
} }
@ -454,6 +493,23 @@ trap(arg)
if (func == SIG_DFL) { if (func == SIG_DFL) {
switch (sig) { switch (sig) {
case SIGINT: case SIGINT:
case SIGHUP:
case SIGTERM:
#ifdef SIGQUIT
case SIGQUIT:
#endif
#ifdef SIGALRM
case SIGALRM:
#endif
#ifdef SIGUSR1
case SIGUSR1:
#endif
#ifdef SIGUSR2
case SIGUSR2:
#endif
#ifdef SIGPIPE
case SIGPIPE:
#endif
func = sighandle; func = sighandle;
break; break;
#ifdef SIGBUS #ifdef SIGBUS
@ -468,11 +524,7 @@ trap(arg)
#endif #endif
} }
} }
#ifdef POSIX_SIGNAL ruby_signal(sig, func);
posix_signal(sig, func);
#else
signal(sig, func);
#endif
old = trap_list[sig]; old = trap_list[sig];
if (!old) old = Qnil; if (!old) old = Qnil;
@ -556,16 +608,30 @@ Init_signal()
{ {
#ifndef MACOS_UNUSE_SIGNAL #ifndef MACOS_UNUSE_SIGNAL
rb_define_global_function("trap", rb_f_trap, -1); rb_define_global_function("trap", rb_f_trap, -1);
#ifdef POSIX_SIGNAL ruby_signal(SIGINT, sighandle);
posix_signal(SIGINT, sighandle); ruby_signal(SIGHUP, sighandle);
#else ruby_signal(SIGTERM, sighandle);
signal(SIGINT, sighandle); #ifdef SIGPIPE
ruby_signal(SIGPIPE, sighandle);
#endif #endif
#ifdef SIGQUIT
ruby_signal(SIGQUIT, sighandle);
#endif
#ifdef SIGALRM
ruby_signal(SIGALRM, sighandle);
#endif
#ifdef SIGUSR1
ruby_signal(SIGUSR1, sighandle);
#endif
#ifdef SIGUSR2
ruby_signal(SIGUSR2, sighandle);
#endif
#ifdef SIGBUS #ifdef SIGBUS
signal(SIGBUS, sigbus); ruby_signal(SIGBUS, sigbus);
#endif #endif
#ifdef SIGSEGV #ifdef SIGSEGV
signal(SIGSEGV, sigsegv); ruby_signal(SIGSEGV, sigsegv);
#endif #endif
#endif /* MACOS_UNUSE_SIGNAL */ #endif /* MACOS_UNUSE_SIGNAL */
} }

View file

@ -594,7 +594,7 @@ rb_f_sprintf(argc, argv)
} }
sprint_exit: sprint_exit:
if (RTEST(ruby_verbose) && argc > 1) { if (RTEST(ruby_verbose) && argc > 0) {
rb_raise(rb_eArgError, "too many argument for format string"); rb_raise(rb_eArgError, "too many argument for format string");
} }
result = rb_str_new(buf, blen); result = rb_str_new(buf, blen);

185
string.c
View file

@ -35,7 +35,7 @@ extern VALUE rb_rs;
VALUE VALUE
rb_str_new(ptr, len) rb_str_new(ptr, len)
char *ptr; const char *ptr;
int len; int len;
{ {
NEWOBJ(str, struct RString); NEWOBJ(str, struct RString);
@ -54,14 +54,14 @@ rb_str_new(ptr, len)
VALUE VALUE
rb_str_new2(ptr) rb_str_new2(ptr)
char *ptr; const char *ptr;
{ {
return rb_str_new(ptr, strlen(ptr)); return rb_str_new(ptr, strlen(ptr));
} }
VALUE VALUE
rb_tainted_str_new(ptr, len) rb_tainted_str_new(ptr, len)
char *ptr; const char *ptr;
int len; int len;
{ {
VALUE str = rb_str_new(ptr, len); VALUE str = rb_str_new(ptr, len);
@ -72,7 +72,7 @@ rb_tainted_str_new(ptr, len)
VALUE VALUE
rb_tainted_str_new2(ptr) rb_tainted_str_new2(ptr)
char *ptr; const char *ptr;
{ {
VALUE str = rb_str_new2(ptr); VALUE str = rb_str_new2(ptr);
@ -300,61 +300,32 @@ rb_str_format(str, arg)
} }
VALUE VALUE
rb_str_substr(str, start, len) rb_str_substr(str, beg, len)
VALUE str; VALUE str;
int start, len; int beg, len;
{ {
VALUE str2; VALUE str2;
if (len == 0) return rb_str_new(0,0); if (len < 0) return Qnil;
if (beg > RSTRING(str)->len) return Qnil;
if (beg < 0) {
beg += RSTRING(str)->len;
if (beg < 0) return Qnil;
}
if (beg + len > RSTRING(str)->len) {
len = RSTRING(str)->len - beg;
}
if (len < 0) { if (len < 0) {
rb_raise(rb_eIndexError, "negative length %d", len); len = 0;
}
if (start < 0) {
start = RSTRING(str)->len + start;
}
if (RSTRING(str)->len <= start) {
return rb_str_new(0,0);
}
if (RSTRING(str)->len < start + len) {
len = RSTRING(str)->len - start;
} }
if (len == 0) return rb_str_new(0,0);
str2 = rb_str_new(RSTRING(str)->ptr+start, len); str2 = rb_str_new(RSTRING(str)->ptr+beg, len);
if (OBJ_TAINTED(str)) OBJ_TAINT(str2); if (OBJ_TAINTED(str)) OBJ_TAINT(str2);
return str2; return str2;
} }
static VALUE
rb_str_subseq(str, beg, end)
VALUE str;
int beg, end;
{
int b, e, len;
b = beg; e = end;
if (beg < 0) {
beg = RSTRING(str)->len + beg;
}
if (end < 0) {
end = RSTRING(str)->len + end;
}
if (beg > end) {
if (e != -1) {
rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", b, e);
}
return rb_str_new(0, 0);
}
if (beg >= RSTRING(str)->len) {
len = 0;
}
len = end - beg + 1;
return rb_str_substr(str, beg, len);
}
void void
rb_str_modify(str) rb_str_modify(str)
VALUE str; VALUE str;
@ -424,7 +395,7 @@ rb_str_resize(str, len)
VALUE VALUE
rb_str_cat(str, ptr, len) rb_str_cat(str, ptr, len)
VALUE str; VALUE str;
char *ptr; const char *ptr;
int len; int len;
{ {
if (len > 0) { if (len > 0) {
@ -572,11 +543,16 @@ rb_str_index(str, sub, offset)
char *s, *e, *p; char *s, *e, *p;
int len; int len;
if (offset < 0) {
offset += RSTRING(str)->len;
if (offset < 0) return -1;
}
if (RSTRING(str)->len - offset < RSTRING(sub)->len) return -1; if (RSTRING(str)->len - offset < RSTRING(sub)->len) return -1;
s = RSTRING(str)->ptr+offset; s = RSTRING(str)->ptr+offset;
p = RSTRING(sub)->ptr; p = RSTRING(sub)->ptr;
len = RSTRING(sub)->len; len = RSTRING(sub)->len;
e = s + RSTRING(str)->len - len + 1; if (len == 0) return offset;
e = RSTRING(str)->ptr + RSTRING(str)->len - len + 1;
while (s < e) { while (s < e) {
if (*s == *(RSTRING(sub)->ptr) && memcmp(s, p, len) == 0) { if (*s == *(RSTRING(sub)->ptr) && memcmp(s, p, len) == 0) {
return (s-(RSTRING(str)->ptr)); return (s-(RSTRING(str)->ptr));
@ -761,20 +737,20 @@ rb_str_succ_bang(str)
} }
VALUE VALUE
rb_str_upto(beg, end) rb_str_upto(beg, end, excl)
VALUE beg, end; VALUE beg, end;
int excl;
{ {
VALUE current; VALUE current;
if (TYPE(end) != T_STRING) end = rb_str_to_str(end); if (TYPE(end) != T_STRING) end = rb_str_to_str(end);
if (RTEST(rb_funcall(beg, '>', 1, end)))
return Qnil;
current = beg; current = beg;
for (;;) { for (;;) {
rb_yield(current); rb_yield(current);
if (rb_str_equal(current, end)) break; if (!excl && rb_str_equal(current, end)) break;
current = rb_str_succ(current); current = rb_str_succ(current);
if (excl && rb_str_equal(current, end)) break;
if (RSTRING(current)->len > RSTRING(end)->len) if (RSTRING(current)->len > RSTRING(end)->len)
break; break;
} }
@ -782,6 +758,13 @@ rb_str_upto(beg, end)
return Qnil; return Qnil;
} }
static VALUE
rb_str_upto_method(beg, end)
VALUE beg, end;
{
return rb_str_upto(beg, end, 0);
}
static VALUE static VALUE
rb_str_aref(str, indx) rb_str_aref(str, indx)
VALUE str; VALUE str;
@ -813,9 +796,14 @@ rb_str_aref(str, indx)
default: default:
/* check if indx is Range */ /* check if indx is Range */
{ {
int beg, end; int beg, len;
if (rb_range_beg_end(indx, &beg, &end)) { switch (rb_range_beg_len(indx, &beg, &len, RSTRING(str)->len, 0)) {
return rb_str_subseq(str, beg, end); case Qfalse:
break;
case Qnil:
return Qnil;
default:
return rb_str_substr(str, beg, len);
} }
} }
rb_raise(rb_eIndexError, "invalid index for string"); rb_raise(rb_eIndexError, "invalid index for string");
@ -861,37 +849,6 @@ rb_str_replace(str, beg, len, val)
RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
} }
/* rb_str_replace2() understands negative offset */
static void
rb_str_replace2(str, beg, end, val)
VALUE str, val;
int beg, end;
{
int b, e, len;
b = beg; e = end;
if (beg < 0) {
beg = RSTRING(str)->len + beg;
}
if (end < 0) {
end = RSTRING(str)->len + end;
}
if (beg > end) {
if (e != -1) {
rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", b, e);
}
end = beg - 1;
}
if (beg >= RSTRING(str)->len) {
beg = RSTRING(str)->len;
len = 0;
}
else {
len = end - beg + 1;
}
rb_str_replace(str, beg, len, val);
}
static VALUE rb_str_sub_bang _((int, VALUE*, VALUE)); static VALUE rb_str_sub_bang _((int, VALUE*, VALUE));
static VALUE static VALUE
@ -904,19 +861,23 @@ rb_str_aset(str, indx, val)
switch (TYPE(indx)) { switch (TYPE(indx)) {
case T_FIXNUM: case T_FIXNUM:
idx = NUM2INT(indx); beg = idx = NUM2INT(indx);
if (idx < 0) { if (idx < 0) {
idx = RSTRING(str)->len + idx; idx += RSTRING(str)->len;
} }
if (idx < 0 || RSTRING(str)->len <= idx) { if (idx < 0 || RSTRING(str)->len < idx) {
rb_raise(rb_eIndexError, "index %d out of range [0..%d]", idx, rb_raise(rb_eIndexError, "index %d out of string", NUM2INT(beg));
RSTRING(str)->len - 1);
} }
if (TYPE(val) == T_STRING) { if (FIXNUM_P(val)) {
rb_str_replace(str, idx, 1, val); if (RSTRING(str)->len == idx) {
RSTRING(str)->len += 1;
REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len);
}
RSTRING(str)->ptr[idx] = NUM2INT(val) & 0xff;
} }
else { else {
RSTRING(str)->ptr[idx] = NUM2INT(val) & 0xff; if (TYPE(val) != T_STRING) val = rb_str_to_str(val);
rb_str_replace(str, idx, 1, val);
} }
return val; return val;
@ -932,18 +893,18 @@ rb_str_aset(str, indx, val)
case T_STRING: case T_STRING:
beg = rb_str_index(str, indx, 0); beg = rb_str_index(str, indx, 0);
if (beg != -1) { if (beg != -1) {
end = beg + RSTRING(indx)->len - 1; if (TYPE(val) != T_STRING) val = rb_str_to_str(val);
rb_str_replace2(str, beg, end, val); rb_str_replace(str, beg, RSTRING(indx)->len, val);
} }
return val; return val;
default: default:
/* check if indx is Range */ /* check if indx is Range */
{ {
int beg, end; int beg, len;
if (rb_range_beg_end(indx, &beg, &end)) { if (rb_range_beg_len(indx, &beg, &len, RSTRING(str)->len, 2)) {
if (TYPE(val) != T_STRING) val = rb_str_to_str(val); if (TYPE(val) != T_STRING) val = rb_str_to_str(val);
rb_str_replace2(str, beg, end, val); rb_str_replace(str, beg, len, val);
return val; return val;
} }
} }
@ -962,17 +923,21 @@ rb_str_aset_method(argc, argv, str)
rb_str_modify(str); rb_str_modify(str);
if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) { if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) {
int beg; int beg, len;
int len;
if (TYPE(arg3) != T_STRING) arg3 = rb_str_to_str(arg3); if (TYPE(arg3) != T_STRING) arg3 = rb_str_to_str(arg3);
beg = NUM2INT(arg1); beg = NUM2INT(arg1);
if (beg < 0) {
beg = RSTRING(str)->len + beg;
if (beg < 0) beg = 0;
}
len = NUM2INT(arg2); len = NUM2INT(arg2);
if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len); if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len);
if (beg < 0) {
beg += RSTRING(str)->len;
}
if (beg < 0 || RSTRING(str)->len < beg) {
if (beg < 0) {
beg -= RSTRING(str)->len;
}
rb_raise(rb_eIndexError, "index %d out of string", beg);
}
if (beg + len > RSTRING(str)->len) { if (beg + len > RSTRING(str)->len) {
len = RSTRING(str)->len - beg; len = RSTRING(str)->len - beg;
} }
@ -2069,14 +2034,14 @@ rb_str_split_method(argc, argv, str)
if (BEG(idx) == END(idx)) if (BEG(idx) == END(idx))
tmp = rb_str_new(0, 0); tmp = rb_str_new(0, 0);
else else
tmp = rb_str_subseq(str, BEG(idx), END(idx)-1); tmp = rb_str_substr(str, BEG(idx), END(idx)-BEG(idx));
rb_ary_push(result, tmp); rb_ary_push(result, tmp);
} }
if (!NIL_P(limit) && lim <= ++i) break; if (!NIL_P(limit) && lim <= ++i) break;
} }
} }
if (!NIL_P(limit) || RSTRING(str)->len > beg || lim < 0) { if (!NIL_P(limit) || RSTRING(str)->len > beg || lim < 0) {
rb_ary_push(result, rb_str_subseq(str, beg, -1)); rb_ary_push(result, rb_str_substr(str, beg, RSTRING(str)->len-beg));
} }
if (NIL_P(limit) && lim == 0) { if (NIL_P(limit) && lim == 0) {
while (RARRAY(result)->len > 0 && while (RARRAY(result)->len > 0 &&
@ -2090,7 +2055,7 @@ rb_str_split_method(argc, argv, str)
VALUE VALUE
rb_str_split(str, sep0) rb_str_split(str, sep0)
VALUE str; VALUE str;
char *sep0; const char *sep0;
{ {
VALUE sep; VALUE sep;
@ -2579,7 +2544,7 @@ 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, 1); rb_define_method(rb_cString, "upto", rb_str_upto_method, 1);
rb_define_method(rb_cString, "index", rb_str_index_method, -1); rb_define_method(rb_cString, "index", rb_str_index_method, -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_method, 1);

View file

@ -179,10 +179,10 @@ make_struct(name, member, klass)
VALUE VALUE
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
rb_struct_define(char *name, ...) rb_struct_define(const char *name, ...)
#else #else
rb_struct_define(name, va_alist) rb_struct_define(name, va_alist)
char *name; const char *name;
va_dcl va_dcl
#endif #endif
{ {

129
time.c
View file

@ -48,9 +48,7 @@ static VALUE S_Tms;
struct time_object { struct time_object {
struct timeval tv; struct timeval tv;
struct tm tm; struct tm tm;
#ifndef HAVE_TM_ZONE
int gmt; int gmt;
#endif
int tm_got; int tm_got;
}; };
@ -193,7 +191,7 @@ time_arg(argc, argv, tm)
tm->tm_year = obj2long(v[0]); tm->tm_year = obj2long(v[0]);
if (tm->tm_year < 69) tm->tm_year += 100; if (tm->tm_year < 69) tm->tm_year += 100;
if (tm->tm_year > 1900) tm->tm_year -= 1900; if (tm->tm_year >= 1000) tm->tm_year -= 1900;
if (NIL_P(v[1])) { if (NIL_P(v[1])) {
tm->tm_mon = 0; tm->tm_mon = 0;
} }
@ -239,6 +237,7 @@ time_arg(argc, argv, tm)
static VALUE time_gmtime _((VALUE)); static VALUE time_gmtime _((VALUE));
static VALUE time_localtime _((VALUE)); static VALUE time_localtime _((VALUE));
static VALUE time_get_tm _((VALUE, int));
static time_t static time_t
make_time_t(tptr, fn) make_time_t(tptr, fn)
@ -258,29 +257,30 @@ make_time_t(tptr, fn)
tm = (*fn)(&guess); tm = (*fn)(&guess);
if (!tm) goto error; if (!tm) goto error;
t = tptr->tm_year; t = tptr->tm_year;
if (t < 69) goto out_of_range;
while (diff = t - (tm->tm_year)) { while (diff = t - (tm->tm_year)) {
guess += diff * 364 * 24 * 3600; guess += diff * 364 * 24 * 3600;
if (guess < 0) goto too_future; if (diff > 0 && guess < 0) goto out_of_range;
tm = (*fn)(&guess); tm = (*fn)(&guess);
if (!tm) goto error; if (!tm) goto error;
} }
t = tptr->tm_mon; t = tptr->tm_mon;
while (diff = t - tm->tm_mon) { while (diff = t - tm->tm_mon) {
guess += diff * 27 * 24 * 3600; guess += diff * 27 * 24 * 3600;
if (guess < 0) goto too_future;
tm = (*fn)(&guess); tm = (*fn)(&guess);
if (!tm) goto error; if (!tm) goto error;
if (tptr->tm_year != tm->tm_year) goto out_of_range;
} }
guess += (tptr->tm_mday - tm->tm_mday) * 3600 * 24; guess += (tptr->tm_mday - tm->tm_mday) * 3600 * 24;
guess += (tptr->tm_hour - tm->tm_hour) * 3600; guess += (tptr->tm_hour - tm->tm_hour) * 3600;
guess += (tptr->tm_min - tm->tm_min) * 60; guess += (tptr->tm_min - tm->tm_min) * 60;
guess += tptr->tm_sec - tm->tm_sec; guess += tptr->tm_sec - tm->tm_sec;
if (guess < 0) goto too_future; if (guess < 0) goto out_of_range;
return guess; return guess;
too_future: out_of_range:
rb_raise(rb_eArgError, "too far future"); rb_raise(rb_eArgError, "time out of range");
error: error:
rb_raise(rb_eArgError, "gmtime/localtime error"); rb_raise(rb_eArgError, "gmtime/localtime error");
@ -416,6 +416,17 @@ time_eql(time1, time2)
return Qfalse; return Qfalse;
} }
static VALUE
time_gmt_p(time)
VALUE time;
{
struct time_object *tobj;
GetTimeval(time, tobj);
if (tobj->gmt) return Qtrue;
return Qfalse;
}
static VALUE static VALUE
time_hash(time) time_hash(time)
VALUE time; VALUE time;
@ -428,6 +439,21 @@ time_hash(time)
return INT2FIX(hash); return INT2FIX(hash);
} }
static VALUE
time_clone(time)
VALUE time;
{
VALUE obj;
struct time_object *tobj, *newtobj;
GetTimeval(time, tobj);
obj = Data_Make_Struct(0, struct time_object, 0, free, newtobj);
CLONESETUP(obj, time);
MEMCPY(newtobj, tobj, struct time_object, 1);
return obj;
}
static VALUE static VALUE
time_localtime(time) time_localtime(time)
VALUE time; VALUE time;
@ -439,9 +465,7 @@ time_localtime(time)
tm_tmp = localtime((const time_t*)&tobj->tv.tv_sec); tm_tmp = localtime((const time_t*)&tobj->tv.tv_sec);
tobj->tm = *tm_tmp; tobj->tm = *tm_tmp;
tobj->tm_got = 1; tobj->tm_got = 1;
#ifndef HAVE_TM_ZONE
tobj->gmt = 0; tobj->gmt = 0;
#endif
return time; return time;
} }
@ -456,12 +480,19 @@ time_gmtime(time)
tm_tmp = gmtime((const time_t*)&tobj->tv.tv_sec); tm_tmp = gmtime((const time_t*)&tobj->tv.tv_sec);
tobj->tm = *tm_tmp; tobj->tm = *tm_tmp;
tobj->tm_got = 1; tobj->tm_got = 1;
#ifndef HAVE_TM_ZONE
tobj->gmt = 1; tobj->gmt = 1;
#endif
return time; return time;
} }
static VALUE
time_get_tm(time, gmt)
VALUE time;
int gmt;
{
if (gmt) return time_gmtime(time);
return time_localtime(time);
}
static VALUE static VALUE
time_asctime(time) time_asctime(time)
VALUE time; VALUE time;
@ -471,7 +502,7 @@ time_asctime(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
s = asctime(&(tobj->tm)); s = asctime(&(tobj->tm));
if (s[24] == '\n') s[24] = '\0'; if (s[24] == '\n') s[24] = '\0';
@ -489,7 +520,7 @@ time_to_s(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
#ifndef HAVE_TM_ZONE #ifndef HAVE_TM_ZONE
if (tobj->gmt == 1) { if (tobj->gmt == 1) {
@ -507,58 +538,67 @@ static VALUE
time_plus(time1, time2) time_plus(time1, time2)
VALUE time1, time2; VALUE time1, time2;
{ {
struct time_object *tobj1, *tobj2; struct time_object *tobj;
time_t sec, usec; time_t sec, usec;
double f; double f;
GetTimeval(time1, tobj1); GetTimeval(time1, tobj);
#if 0
if (rb_obj_is_kind_of(time2, rb_cTime)) { if (rb_obj_is_kind_of(time2, rb_cTime)) {
rb_raise(rb_eTypeError, "time + time?"); rb_raise(rb_eTypeError, "time + time?");
} }
#endif
f = NUM2DBL(time2); f = NUM2DBL(time2);
sec = (time_t)f; sec = (time_t)f;
usec = tobj1->tv.tv_usec + (time_t)((f - (double)sec)*1e6); usec = tobj->tv.tv_usec + (time_t)((f - (double)sec)*1e6);
sec = tobj1->tv.tv_sec + sec; sec = tobj->tv.tv_sec + sec;
if (usec >= 1000000) { /* usec overflow */ if (usec >= 1000000) { /* usec overflow */
sec++; sec++;
usec -= 1000000; usec -= 1000000;
} }
return rb_time_new(sec, usec); time2 = rb_time_new(sec, usec);
if (tobj->gmt) {
GetTimeval(time2, tobj);
tobj->gmt = 1;
}
return time2;
} }
static VALUE static VALUE
time_minus(time1, time2) time_minus(time1, time2)
VALUE time1, time2; VALUE time1, time2;
{ {
struct time_object *tobj1, *tobj2; struct time_object *tobj;
time_t sec, usec; time_t sec, usec;
double f; double f;
GetTimeval(time1, tobj1); GetTimeval(time1, tobj);
if (rb_obj_is_instance_of(time2, rb_cTime)) { if (rb_obj_is_instance_of(time2, rb_cTime)) {
struct time_object *tobj2;
GetTimeval(time2, tobj2); GetTimeval(time2, tobj2);
f = tobj1->tv.tv_sec - tobj2->tv.tv_sec; f = tobj->tv.tv_sec - tobj2->tv.tv_sec;
f += (tobj1->tv.tv_usec - tobj2->tv.tv_usec)*1e-6; f += (tobj->tv.tv_usec - tobj2->tv.tv_usec)*1e-6;
return rb_float_new(f); return rb_float_new(f);
} }
else { else {
f = NUM2DBL(time2); f = NUM2DBL(time2);
sec = (time_t)f; sec = (time_t)f;
usec = tobj1->tv.tv_usec - (time_t)((f - (double)sec)*1e6); usec = tobj->tv.tv_usec - (time_t)((f - (double)sec)*1e6);
sec = tobj1->tv.tv_sec - sec; sec = tobj->tv.tv_sec - sec;
} }
if (usec < 0) { /* usec underflow */ if (usec < 0) { /* usec underflow */
sec--; sec--;
usec += 1000000; usec += 1000000;
} }
return rb_time_new(sec, usec); time2 = rb_time_new(sec, usec);
if (tobj->gmt) {
GetTimeval(time2, tobj);
tobj->gmt = 1;
}
return time2;
} }
static VALUE static VALUE
@ -569,7 +609,7 @@ time_sec(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return INT2FIX(tobj->tm.tm_sec); return INT2FIX(tobj->tm.tm_sec);
} }
@ -582,7 +622,7 @@ time_min(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return INT2FIX(tobj->tm.tm_min); return INT2FIX(tobj->tm.tm_min);
} }
@ -595,7 +635,7 @@ time_hour(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return INT2FIX(tobj->tm.tm_hour); return INT2FIX(tobj->tm.tm_hour);
} }
@ -608,7 +648,7 @@ time_mday(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return INT2FIX(tobj->tm.tm_mday); return INT2FIX(tobj->tm.tm_mday);
} }
@ -621,7 +661,7 @@ time_mon(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return INT2FIX(tobj->tm.tm_mon+1); return INT2FIX(tobj->tm.tm_mon+1);
} }
@ -634,7 +674,7 @@ time_year(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return INT2FIX(tobj->tm.tm_year+1900); return INT2FIX(tobj->tm.tm_year+1900);
} }
@ -647,7 +687,7 @@ time_wday(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return INT2FIX(tobj->tm.tm_wday); return INT2FIX(tobj->tm.tm_wday);
} }
@ -660,7 +700,7 @@ time_yday(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return INT2FIX(tobj->tm.tm_yday+1); return INT2FIX(tobj->tm.tm_yday+1);
} }
@ -673,7 +713,7 @@ time_isdst(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return tobj->tm.tm_isdst?Qtrue:Qfalse; return tobj->tm.tm_isdst?Qtrue:Qfalse;
} }
@ -688,7 +728,7 @@ time_zone(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
len = strftime(buf, 64, "%Z", &(tobj->tm)); len = strftime(buf, 64, "%Z", &(tobj->tm));
@ -703,7 +743,7 @@ time_to_a(time)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
return rb_ary_new3(10, return rb_ary_new3(10,
INT2FIX(tobj->tm.tm_sec), INT2FIX(tobj->tm.tm_sec),
@ -765,7 +805,7 @@ time_strftime(time, format)
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got == 0) { if (tobj->tm_got == 0) {
time_localtime(time); time_get_tm(time, tobj->gmt);
} }
fmt = str2cstr(format, &len); fmt = str2cstr(format, &len);
if (len == 0) { if (len == 0) {
@ -842,7 +882,7 @@ time_dump(argc, argv, time)
rb_scan_args(argc, argv, "01", &dummy); rb_scan_args(argc, argv, "01", &dummy);
GetTimeval(time, tobj); GetTimeval(time, tobj);
tm = gmtime(&tobj->tv.tv_sec); tm = gmtime((const time_t*)&tobj->tv.tv_sec);
p = 0x1 << 31 | /* 1 */ p = 0x1 << 31 | /* 1 */
tm->tm_year << 14 | /* 17 */ tm->tm_year << 14 | /* 17 */
@ -892,7 +932,7 @@ time_load(klass, str)
return time_new_internal(klass, sec, usec); return time_new_internal(klass, sec, usec);
} }
p &= ~(1<<31); p &= ~(1<<31);
tm.tm_year = (p >> 14) & 0x3ffff; tm.tm_year = (p >> 14) & 0x1ffff;
tm.tm_mon = (p >> 10) & 0xf; tm.tm_mon = (p >> 10) & 0xf;
tm.tm_mday = (p >> 5) & 0x1f; tm.tm_mday = (p >> 5) & 0x1f;
tm.tm_hour = p & 0x1f; tm.tm_hour = p & 0x1f;
@ -925,6 +965,7 @@ Init_Time()
rb_define_method(rb_cTime, "<=>", time_cmp, 1); rb_define_method(rb_cTime, "<=>", time_cmp, 1);
rb_define_method(rb_cTime, "eql?", time_eql, 1); rb_define_method(rb_cTime, "eql?", time_eql, 1);
rb_define_method(rb_cTime, "hash", time_hash, 0); rb_define_method(rb_cTime, "hash", time_hash, 0);
rb_define_method(rb_cTime, "clone", time_clone, 0);
rb_define_method(rb_cTime, "localtime", time_localtime, 0); rb_define_method(rb_cTime, "localtime", time_localtime, 0);
rb_define_method(rb_cTime, "gmtime", time_gmtime, 0); rb_define_method(rb_cTime, "gmtime", time_gmtime, 0);
@ -950,6 +991,8 @@ Init_Time()
rb_define_method(rb_cTime, "isdst", time_isdst, 0); rb_define_method(rb_cTime, "isdst", time_isdst, 0);
rb_define_method(rb_cTime, "zone", time_zone, 0); rb_define_method(rb_cTime, "zone", time_zone, 0);
rb_define_method(rb_cTime, "gmt?", time_gmt_p, 0);
rb_define_method(rb_cTime, "tv_sec", time_to_i, 0); rb_define_method(rb_cTime, "tv_sec", time_to_i, 0);
rb_define_method(rb_cTime, "tv_usec", time_usec, 0); rb_define_method(rb_cTime, "tv_usec", time_usec, 0);
rb_define_method(rb_cTime, "usec", time_usec, 0); rb_define_method(rb_cTime, "usec", time_usec, 0);

9
util.c
View file

@ -73,11 +73,11 @@ char *strchr _((char*,char));
unsigned long unsigned long
scan_oct(start, len, retlen) scan_oct(start, len, retlen)
char *start; const char *start;
int len; int len;
int *retlen; int *retlen;
{ {
register char *s = start; register const char *s = start;
register unsigned long retval = 0; register unsigned long retval = 0;
while (len-- && *s >= '0' && *s <= '7') { while (len-- && *s >= '0' && *s <= '7') {
@ -90,12 +90,12 @@ int *retlen;
unsigned long unsigned long
scan_hex(start, len, retlen) scan_hex(start, len, retlen)
char *start; const char *start;
int len; int len;
int *retlen; int *retlen;
{ {
static char hexdigit[] = "0123456789abcdef0123456789ABCDEFx"; static char hexdigit[] = "0123456789abcdef0123456789ABCDEFx";
register char *s = start; register const char *s = start;
register unsigned long retval = 0; register unsigned long retval = 0;
char *tmp; char *tmp;
@ -329,7 +329,6 @@ valid_filename(char *s)
#endif #endif
#ifdef DJGPP #ifdef DJGPP
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <libc/stubs.h> #include <libc/stubs.h>
#include <stdio.h> /* For FILENAME_MAX */ #include <stdio.h> /* For FILENAME_MAX */

10
util.h
View file

@ -21,13 +21,13 @@
#endif #endif
#define scan_oct ruby_scan_oct #define scan_oct ruby_scan_oct
unsigned long scan_oct _((char*, int, int*)); unsigned long scan_oct _((const char*, int, int*));
#define scan_hex ruby_scan_hex #define scan_hex ruby_scan_hex
unsigned long scan_hex _((char*, int, int*)); unsigned long scan_hex _((const char*, int, int*));
#if defined(MSDOS) || defined(__CYGWIN32__) || defined(NT) #if defined(MSDOS) || defined(__CYGWIN32__) || defined(NT)
void ruby_add_suffix();
#define add_suffix ruby_add_suffix #define add_suffix ruby_add_suffix
void add_suffix();
#endif #endif
char *ruby_mktemp _((void)); char *ruby_mktemp _((void));
@ -37,5 +37,9 @@ void ruby_qsort _((void*, int, int, int (*)()));
void ruby_setenv _((char*, char*)); void ruby_setenv _((char*, char*));
void ruby_unsetenv _((char*)); void ruby_unsetenv _((char*));
#undef setenv
#undef unsetenv
#define setenv(name,val) ruby_setenv((name),(val))
#define unsetenv(name,val) ruby_unsetenv((name));
#endif /* UTIL_H */ #endif /* UTIL_H */

View file

@ -14,7 +14,7 @@
#include "st.h" #include "st.h"
#ifdef USE_CWGUSI #ifdef USE_CWGUSI
char* strdup(char*); char* strdup(const char*);
#endif #endif
static st_table *rb_global_tbl; static st_table *rb_global_tbl;
@ -176,7 +176,7 @@ rb_class_path(klass)
void void
rb_set_class_path(klass, under, name) rb_set_class_path(klass, under, name)
VALUE klass, under; VALUE klass, under;
char *name; const char *name;
{ {
VALUE str; VALUE str;
@ -193,7 +193,7 @@ rb_set_class_path(klass, under, name)
VALUE VALUE
rb_path2class(path) rb_path2class(path)
char *path; const char *path;
{ {
if (path[0] == '#') { if (path[0] == '#') {
rb_raise(rb_eArgError, "can't retrieve anonymous class %s", path); rb_raise(rb_eArgError, "can't retrieve anonymous class %s", path);
@ -214,7 +214,7 @@ static st_table *autoload_tbl = 0;
static void static void
rb_autoload_id(id, filename) rb_autoload_id(id, filename)
ID id; ID id;
char *filename; const char *filename;
{ {
if (!rb_is_const_id(id)) { if (!rb_is_const_id(id)) {
rb_raise(rb_eNameError, "autoload must be constant name", rb_raise(rb_eNameError, "autoload must be constant name",
@ -229,7 +229,7 @@ rb_autoload_id(id, filename)
void void
rb_autoload(klass, filename) rb_autoload(klass, filename)
char *klass, *filename; const char *klass, *filename;
{ {
rb_autoload_id(rb_intern(klass), filename); rb_autoload_id(rb_intern(klass), filename);
} }
@ -414,7 +414,7 @@ rb_gc_mark_global_tbl()
static ID static ID
global_id(name) global_id(name)
char *name; const char *name;
{ {
ID id; ID id;
@ -430,7 +430,7 @@ global_id(name)
void void
rb_define_hooked_variable(name, var, getter, setter) rb_define_hooked_variable(name, var, getter, setter)
char *name; const char *name;
VALUE *var; VALUE *var;
VALUE (*getter)(); VALUE (*getter)();
void (*setter)(); void (*setter)();
@ -447,7 +447,7 @@ rb_define_hooked_variable(name, var, getter, setter)
void void
rb_define_variable(name, var) rb_define_variable(name, var)
char *name; const char *name;
VALUE *var; VALUE *var;
{ {
rb_define_hooked_variable(name, var, 0, 0); rb_define_hooked_variable(name, var, 0, 0);
@ -455,7 +455,7 @@ rb_define_variable(name, var)
void void
rb_define_readonly_variable(name, var) rb_define_readonly_variable(name, var)
char *name; const char *name;
VALUE *var; VALUE *var;
{ {
rb_define_hooked_variable(name, var, 0, readonly_setter); rb_define_hooked_variable(name, var, 0, readonly_setter);
@ -463,7 +463,7 @@ rb_define_readonly_variable(name, var)
void void
rb_define_virtual_variable(name, getter, setter) rb_define_virtual_variable(name, getter, setter)
char *name; const char *name;
VALUE (*getter)(); VALUE (*getter)();
void (*setter)(); void (*setter)();
{ {
@ -631,7 +631,7 @@ rb_gvar_set(entry, val)
VALUE VALUE
rb_gvar_set2(name, val) rb_gvar_set2(name, val)
char *name; const char *name;
VALUE val; VALUE val;
{ {
struct global_entry *entry; struct global_entry *entry;
@ -1073,7 +1073,7 @@ rb_mod_remove_const(mod, name)
static int static int
autoload_i(key, name, ary) autoload_i(key, name, ary)
ID key; ID key;
char *name; const char *name;
VALUE ary; VALUE ary;
{ {
VALUE kval = rb_str_new2(rb_id2name(key)); VALUE kval = rb_str_new2(rb_id2name(key));
@ -1188,7 +1188,7 @@ rb_const_set(klass, id, val)
void void
rb_define_const(klass, name, val) rb_define_const(klass, name, val)
VALUE klass; VALUE klass;
char *name; const char *name;
VALUE val; VALUE val;
{ {
ID id = rb_intern(name); ID id = rb_intern(name);
@ -1204,7 +1204,7 @@ rb_define_const(klass, name, val)
void void
rb_define_global_const(name, val) rb_define_global_const(name, val)
char *name; const char *name;
VALUE val; VALUE val;
{ {
rb_define_const(rb_cObject, name, val); rb_define_const(rb_cObject, name, val);
@ -1213,7 +1213,7 @@ rb_define_global_const(name, val)
VALUE VALUE
rb_iv_get(obj, name) rb_iv_get(obj, name)
VALUE obj; VALUE obj;
char *name; const char *name;
{ {
ID id = rb_intern(name); ID id = rb_intern(name);
@ -1223,7 +1223,7 @@ rb_iv_get(obj, name)
VALUE VALUE
rb_iv_set(obj, name, val) rb_iv_set(obj, name, val)
VALUE obj; VALUE obj;
char *name; const char *name;
VALUE val; VALUE val;
{ {
ID id = rb_intern(name); ID id = rb_intern(name);

View file

@ -19,13 +19,14 @@ void
Init_version() Init_version()
{ {
rb_define_global_const("VERSION", rb_str_new2(RUBY_VERSION)); rb_define_global_const("VERSION", rb_str_new2(RUBY_VERSION));
rb_define_global_const("RELEASE_DATE", rb_str_new2(RUBY_RELEASE_DATE));
rb_define_global_const("PLATFORM", rb_str_new2(RUBY_PLATFORM)); rb_define_global_const("PLATFORM", rb_str_new2(RUBY_PLATFORM));
} }
void void
ruby_show_version() ruby_show_version()
{ {
fprintf(stderr, "ruby %s(%s) [%s]\n", RUBY_VERSION, VERSION_DATE, RUBY_PLATFORM); fprintf(stderr, "ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM);
} }
void void

View file

@ -1,2 +1,2 @@
#define RUBY_VERSION "1.3.1" #define RUBY_VERSION "1.3.1"
#define VERSION_DATE "99/02/25" #define RUBY_RELEASE_DATE "1999-03-24"

View file

@ -1,4 +1,3 @@
#define USE_THREAD 1
#define SIZEOF_INT 4 #define SIZEOF_INT 4
#define SIZEOF_LONG 4 #define SIZEOF_LONG 4
#define SIZEOF_VOIDP 4 #define SIZEOF_VOIDP 4

View file

@ -32,7 +32,6 @@ EXPORTS
;hash.c: ;hash.c:
rb_cHash rb_cHash
ruby_setenv ruby_setenv
ruby_setenv2
ruby_unsetenv ruby_unsetenv
;io.c: ;io.c:
rb_cIO rb_cIO
@ -319,7 +318,6 @@ EXPORTS
rb_syswait rb_syswait
; range.c ; range.c
rb_range_new rb_range_new
rb_range_beg_end
; re.c ; re.c
rb_str_cicmp rb_str_cicmp
rb_reg_search rb_reg_search