1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

first public release of 1.1d (pre1.2) series

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1dev@354 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1998-12-16 07:30:36 +00:00
parent ce8859c556
commit e299d511db
44 changed files with 907 additions and 466 deletions

View file

@ -1,3 +1,68 @@
Wed Dec 16 16:28:31 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* experimental version 1.1d0 (pre1.2) released.
Wed Dec 16 10:43:34 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* regex.c (re_search): bound check before calling re_match().
Tue Dec 15 13:59:01 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* error.c (exc_to_s): returns class name for unset mesg.
* error.c (exc_initialize): do not initialize @mesg by "".
* parse.y (nextc): __END__ should handle CR+LF newlines.
Wed Dec 9 13:37:12 1998 MAEDA shugo <shugo@aianet.ne.jp>
* pack.c (encodes): use buffering for B-encoding.
* pack.c (pack_pack): Q-encoding by 'M'.
Tue Dec 8 14:10:00 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* variable.c (generic_ivar_get): any object can have instance
variables now. great improvement.
* variable.c (rb_name_class): do not set __classpath__ by default,
use __classid__ instead.
Mon Dec 7 22:08:22 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* ruby.h (struct RFile): IO objects can have instance variables now.
* parse.y (primary): allows `def obj::foo; .. end'.
Mon Dec 7 18:24:50 1998 WATANABE Tetsuya <tetsu@jpn.hp.com>
* ruby.c (set_arg0): $0 supprt for HP-UX.
Mon Dec 7 01:30:28 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
* dln.c (dln_strerror): better error messages on win32.
Sat Dec 5 23:27:23 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (here_document): indentable here-doc delimiter by
`<<-'. Proposed by Clemens <c.hintze@gmx.net>. Thanks.
Thu Dec 3 16:50:17 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* ext/extmk.rb.in (realclean): trouble on install.
Sun Nov 29 22:25:39 1998 Takaaki Tateishi <ttate@jaist.ac.jp>
* process.c (f_exec): check number of argument.
Wed Nov 25 13:07:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (yycompile): reduce known memory leak (hard to remove).
Thu Nov 26 17:27:30 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1c9 released.
Wed Nov 25 03:41:21 1998 Yukihiro Matsumoto <matz@netlab.co.jp> Wed Nov 25 03:41:21 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* st.c (st_init_table_with_size): round size up to prime number. * st.c (st_init_table_with_size): round size up to prime number.
@ -20,6 +85,14 @@ Sat Nov 21 23:27:23 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* string.c (rb_str_dup): do not copy additional data (STR_NO_ORIG). * string.c (rb_str_dup): do not copy additional data (STR_NO_ORIG).
Sat Nov 21 18:44:06 1998 Masaki Fukushima <fukusima@goto.info.waseda.ac.jp>
* time.c (time_s_now): had memory leak.
* ext/md5/md5init.c (md5_new): had memory leak.
* ext/md5/md5init.c (md5_clone): ditto.
Fri Nov 20 23:23:23 1998 Yukihiro Matsumoto <matz@netlab.co.jp> Fri Nov 20 23:23:23 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* lib/delegate.rb: do not propagate hash and eql?. * lib/delegate.rb: do not propagate hash and eql?.
@ -34,15 +107,15 @@ Thu Nov 19 01:40:52 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (rb_eval): actual rest arguments extended arrays too much. * eval.c (rb_eval): actual rest arguments extended arrays too much.
Wed Nov 18 10:48:09 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* io.c (read_all): SEGV on large files.
Wed Nov 18 14:30:24 1998 Yukihiro Matsumoto <matz@netlab.co.jp> Wed Nov 18 14:30:24 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* class.c (rb_define_global_function): global functions now be * class.c (rb_define_global_function): global functions now be
module function of the Kernel. module function of the Kernel.
Wed Nov 18 10:48:09 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* io.c (read_all): SEGV on large files.
Tue Nov 17 18:11:20 1998 Yukihiro Matsumoto <matz@netlab.co.jp> Tue Nov 17 18:11:20 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1c8 released. * version 1.1c8 released.

View file

@ -131,6 +131,11 @@ lib/thwait.rb
lib/timeout.rb lib/timeout.rb
lib/tracer.rb lib/tracer.rb
lib/weakref.rb lib/weakref.rb
misc/README
misc/inf-ruby.el
misc/ruby-mode.el
misc/rubydb2x.el
mics/rubydb3x.el
missing/alloca.c missing/alloca.c
missing/crypt.c missing/crypt.c
missing/dir.h missing/dir.h
@ -174,7 +179,6 @@ sample/from.rb
sample/fullpath.rb sample/fullpath.rb
sample/getopts.test sample/getopts.test
sample/goodfriday.rb sample/goodfriday.rb
sample/inf-ruby.el
sample/less.rb sample/less.rb
sample/list.rb sample/list.rb
sample/list2.rb sample/list2.rb
@ -194,9 +198,6 @@ sample/rcs.awk
sample/rcs.dat sample/rcs.dat
sample/rcs.rb sample/rcs.rb
sample/regx.rb sample/regx.rb
sample/ruby-mode.el
sample/rubydb2x.el
sample/rubydb3x.el
sample/sieve.rb sample/sieve.rb
sample/svr.rb sample/svr.rb
sample/test.rb sample/test.rb

View file

@ -84,37 +84,28 @@ There are faster check-macros for fixnums and nil.
1.3 Convert VALUE into C data 1.3 Convert VALUE into C data
データタイプがT_NIL, T_FALSE, T_TRUEである時データはそれぞ The data for type T_NIL, T_FALSE, T_TRUE are nil, true, false
れnil, false, trueですこのデータタイプのオブジェクトはひと respectively. They are singletons for the data type.
つずつしか存在しません.
データタイプがT_FIXNUMの時これは31bitのサイズを持つ整数で The T_FIXNUM data is the 31bit length fixed integer (63bit length on
FIXNUMをCの整数に変換するためにはマクロ「FIX2INT()」を使 some machines), which can be conver to the C integer by using
いますそれからFIXNUMに限らずRubyのデータを整数に変換する FIX2INT() macro. There also be NUM2INT() which converts any Ruby
「NUM2INT()」というマクロがあります.このマクロはデータタイ numbers into C integer. The NUM2INT() macro includes type check, so
プのチェック無しで使えます(整数に変換できない場合には例外が the exception will be raised if conversion failed.
発生する)
それ以外のデータタイプは対応するCの構造体があります対応す Other data types have corresponding C structures, e.g. struct RArray
る構造体のあるVALUEはそのままキャスト(型変換)すれば構造体の for T_ARRAY etc. VALUE of the type which has corresponding structure
ポインタに変換できます. can be cast to retrieve the pointer to the struct. The casting macro
RXXXX for each data type like RARRAY(obj). see "ruby.h".
構造体は「struct RXxxxx」という名前でruby.hで定義されていま For example, `RSTRING(size)->len' is the way to get the size of the
例えば文字列は「struct RString」です実際に使う可能性が Ruby String object. The allocated region can be accessed by
あるのは文字列と配列くらいだと思います. `RSTRING(str)->ptr'. For arrays, `RARRAY(ary)->len' and
`RARRAY(ary)->ptr' respectively.
ruby.hでは構造体へキャストするマクロも「RXXXXX()」(全部大文 Notice: Do not change the value of the structure directly, unless you
字にしたもの)という名前で提供されています(例: RSTRING()) are responsible about the result. It will be the cause of interesting
bugs.
例えば文字列strの長さを得るためには「RSTRING(str)->len」と
文字列strをchar*として得るためには「RSTRING(str)->ptr」
とします配列の場合にはそれぞれ「RARRAT(str)->len」
「RARRAT(str)->ptr」となります
Rubyの構造体を直接アクセスする時に気をつけなければならないこ
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
ないことです.直接変更した場合,オブジェクトの内容の整合性が
とれなくなって,思わぬバグの原因になります.
1.4 Convert C data into VALUE 1.4 Convert C data into VALUE
@ -150,12 +141,9 @@ INT2NUM()
1.5 Manipulate Ruby data 1.5 Manipulate Ruby data
先程も述べた通りRubyの構造体をアクセスする時に内容の更新を As I already told, it is not recommended to modify object's internal
行うことは勧められませんRubyのデータを操作する時には structure. To manipulate objects, use functions supplied by Ruby
Rubyが用意している関数を用いてください interpreter. Useful functions are listed below (not all):
ここではもっとも使われるであろう文字列と配列の生成/操作を行
い関数をあげます(全部ではないです)
String funtions String funtions
@ -213,160 +201,148 @@ Ruby
を追加することができますRubyでは以下の機能を追加する関数が を追加することができますRubyでは以下の機能を追加する関数が
提供されています. 提供されています.
* クラス,モジュール * Classes, Modules
* メソッド,特異メソッドなど * Methods, Singleton Methods
* 定数 * Constants
では順に紹介します. では順に紹介します.
2.1.1 Class/module definition 2.1.1 Class/module definition
クラスやモジュールを定義するためには,以下の関数を使います. To define class or module, use functions below:
VALUE rb_define_class(char *name, VALUE super) VALUE rb_define_class(char *name, VALUE super)
VALUE rb_define_module(char *name) VALUE rb_define_module(char *name)
これらの関数は新しく定義されたクラスやモジュールを返します. These functions return the newly created class ot module. You may
メソッドや定数の定義にこれらの値が必要なので,ほとんどの場合 want to save this reference into the variable to use later.
は戻り値を変数に格納しておく必要があるでしょう.
2.1.2 Method/singleton method definition 2.1.2 Method/singleton method definition
メソッドや特異メソッドを定義するには以下の関数を使います. To define methods or singleton methods, use functions below:
void rb_define_method(VALUE class, char *name, void rb_define_method(VALUE class, char *name,
VALUE (*func)(), int argc) VALUE (*func)(), int argc)
void rb_define_singleton_method(VALUE object, char *name, void rb_define_singleton_method(VALUE object, char *name,
VALUE (*func)(), int argc) VALUE (*func)(), int argc)
The `argc' represents the number of the arguments to the C function,
which must be less than 17. But I believe you don't need that much. :-)
念のため説明すると「特異メソッド」とは,その特定のオブジェク If `argc' is negative, it specifies calling sequence, not number of
トに対してだけ有効なメソッドですRubyではよくSmalltalkにお the arguments.
けるクラスメソッドとして,クラスに対する特異メソッドが使われ
ます.
これらの関数の argcという引数はCの関数へ渡される引数の数(と If argc is -1, the function will be called like:
形式)を決めますargcが正の時は関数に引き渡す引数の数を意味
します16個以上の引数は使えません(が,要りませんよね,そん
なに)
argcが負の時は引数の数ではなく形式を指定したことになります VALUE func(int argc, VALUE *argv, VALUE obj)
argcが-1の時は引数を配列に入れて渡されますargcが-2の時は引
数はRubyの配列として渡されます
メソッドを定義する関数はもう二つありますひとつはprivateメ where argc is the actual number of arguments, argv is the C array of
ソッドを定義する関数で引数はrb_define_method()と同じです. the arguments, and obj is the receiver.
if argc is -2, the arguments are passed in Ruby array. The function
will be called like:
VALUE func(VALUE obj, VALUE args)
where obj is the receiver, and args is the Ruby array containing
actual arguments.
There're two more functions to define method. One is to define
private method:
void rb_define_private_method(VALUE class, char *name, void rb_define_private_method(VALUE class, char *name,
VALUE (*func)(), int argc) VALUE (*func)(), int argc)
privateメソッドとは関数形式でしか呼び出すことの出来ないメソッ The other is to define module function, which is private AND singleton
ドです. method of the module. For example, sqrt is the module function
defined in Math module. It can be call in the form like:
もうひとつはモジュール関数を定義するものです.モジュール関数
とはモジュールの特異メソッドであり同時にprivateメソッドで
もあるものです例をあげるとMathモジュールのsqrt()などがあげ
られます.このメソッドは
Math.sqrt(4) Math.sqrt(4)
という形式でも or
include Math include Math
sqrt(4) sqrt(4)
という形式でも使えます.モジュール関数を定義する関数は以下の To define module function
通りです.
void rb_define_module_function(VALUE module, char *name, void rb_define_module_function(VALUE module, char *name,
VALUE (*func)(), int argc) VALUE (*func)(), int argc)
関数的メソッド(Kernelモジュールのprivaet method)を定義するた Oh, in addition, function-like method, which is private method defined
めの関数は以下の通りです. in Kernel module, can be defined using:
void rb_define_global_function(char *name, VALUE (*func)(), int argc) void rb_define_global_function(char *name, VALUE (*func)(), int argc)
2.1.3 Constant definition 2.1.3 Constant definition
拡張モジュールが必要な定数はあらかじめ定義しておいた方が良い We have 2 functions to define constants:
でしょう.定数を定義する関数は二つあります.
void rb_define_const(VALUE class, char *name, VALUE val) void rb_define_const(VALUE class, char *name, VALUE val)
void rb_define_global_const(char *name, VALUE val) void rb_define_global_const(char *name, VALUE val)
前者は特定のクラス/モジュールに属する定数を定義するもの,後 The former is to define constant under specified class/module. The
者はグローバルな定数を定義するものです. latter is to define global constant.
2.2 Use Ruby features from C 2.2 Use Ruby features from C
既に『1.5 Rubyのデータを操作する』で一部紹介したような関数を There are several ways to invoke Ruby's features from C code.
使えばRubyの機能を実現している関数を直接呼び出すことが出来
ます.
# このような関数の一覧表はいまのところありません.ソースを見 2.2.1 Evaluate Ruby Program in String
# るしかないですね.
それ以外にもRubyの機能を呼び出す方法はいくつかあります Easiest way to call Ruby's function from C program is to evaluate the
string as Ruby program. This function will do the job.
2.2.1 Rubyのプログラムをevalする
CからRubyの機能を呼び出すもっとも簡単な方法として文字列で
与えられたRubyのプログラムを評価する関数があります
VALUE rb_eval_string(char *str) VALUE rb_eval_string(char *str)
この評価は現在の環境で行われます.つまり,現在のローカル変数 Evaluation is done under current context, thus current local variables
などを受け継ぎます. of the innermost method (which is defined by Ruby) can be accessed.
2.2.2 ID or Symbol 2.2.2 ID or Symbol
Cから文字列を経由せずにRubyのメソッドを呼び出すこともできま You can invoke methods directly, without parsing the string. First I
その前にRubyインタプリタ内でメソッドや変数名を指定する need to explain about symbols (which data type is ID). ID is the
時に使われているIDについて説明しておきましょう integer number to represent Ruby's identifiers such as variable names.
It can be accessed from Ruby in the form like:
IDとは変数名メソッド名を表す整数ですRubyの中では :Identifier
:識別子 You can get the symbol value from string within C code, by using
でアクセスできますCからこの整数を得るためには関数
rb_intern(char *name) rb_intern(char *name)
を使います.また一文字の演算子はその文字コードがそのままシン In addition, the symbols for one character operators (e.g +) is the
ボルになっています. code for that character.
2.2.3 Invoke Ruby method from C 2.2.3 Invoke Ruby method from C
Cから文字列を経由せずにRubyのメソッドを呼び出すためには以下 To invoke methods directly, you can use the function below
の関数を使います.
VALUE rb_funcall(VALUE recv, ID mid, int argc, ...) VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)
この関数はオブジェクトrecvのmidで指定されるメソッドを呼び出 This function invokes the method of the recv, which name is specified
します. by the symbol mid.
2.2.4 変数/定数を参照/更新する 2.2.4 Accessing the variables and constants
Cから関数を使って参照・更新できるのはクラス定数インスタ Cから関数を使って参照・更新できるのはクラス定数インスタ
ンス変数です大域変数は一部のものはCの大域変数としてアクセ ンス変数です大域変数は一部のものはCの大域変数としてアクセ
スできます.ローカル変数を参照する方法は公開していません. スできます.ローカル変数を参照する方法は公開していません.
オブジェクトのインスタンス変数を参照・更新する関数は以下の通 The functions to access/modify instance variables are below:
りです.
VALUE rb_ivar_get(VALUE obj, ID id) VALUE rb_ivar_get(VALUE obj, ID id)
VALUE rb_ivar_set(VALUE obj, ID id, VALUE val) VALUE rb_ivar_set(VALUE obj, ID id, VALUE val)
idはrb_intern()で得られるものを使ってください. id must be the symbol, which can be retrieved by rb_intern().
クラス定数を参照するには以下の関数を使ってください. To access the constants of the class/module:
VALUE rb_const_get(VALUE obj, ID id) VALUE rb_const_get(VALUE obj, ID id)
クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ See 2.1.3 for defining new constant.
れている関数を使ってください.
3. Informatin sharing between Ruby and C 3. Informatin sharing between Ruby and C
@ -477,7 +453,7 @@ C
4Example - Create dbm module 4Example - Create dbm module
ここまでの説明でとりあえず拡張モジュールは作れるはずです. ここまでの説明でとりあえず拡張ライブラリは作れるはずです.
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
して段階的に説明します. して段階的に説明します.
@ -485,39 +461,30 @@ Ruby
% mkdir ext/dbm % mkdir ext/dbm
Rubyを展開したディレクトリの下extディレクトリの中に拡張モ Make a directory for the extension library under ext directory.
ジュール用のディレクトリを作ります.名前は適当に選んで構いま
せん.
(2) create MANIFEST file (2) create MANIFEST file
% cd ext/dbm % cd ext/dbm
% touch MANIFEST % touch MANIFEST
拡張モジュールのディレクトリの下にはMANIFESTというファイルが There should be MANIFEST file in the directory for the extension
必要なので,とりあえず空のファイルを作っておきます.後でこの library. Make empty file now.
ファイルには必要なファイル一覧が入ることになります.
MANIFESTというファイルはmakeの時にディレクトリが拡張モジュー
ルを含んでいるかどうか判定するために使われれています.
(3) design the library (3) design the library
まあ,当然なんですけど,どういう機能を実現するかどうかまず設 You need to design the library features, before making it.
計する必要があります.どんなクラスをつくるか,そのクラスには
どんなメソッドがあるか,クラスが提供する定数などについて設計
しますdbmクラスについてはext/dbm.docを参照してください
(4) write C code. (4) write C code.
拡張モジュール本体となる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から一部引用します
@ -525,22 +492,20 @@ Ruby
-- --
Init_dbm() Init_dbm()
{ {
/* DBMクラスを定義する */ /* define DBM class */
cDBM = rb_define_class("DBM", rb_cObject); cDBM = rb_define_class("DBM", rb_cObject);
/* DBMはEnumerateモジュールをインクルードする */ /* DBM includes Enumerate module */
rb_include_module(cDBM, rb_mEnumerable); rb_include_module(cDBM, rb_mEnumerable);
/* DBMクラスのクラスメソッドopen(): 引数はCの配列で受ける */ /* DBM has class method open(): arguments are received as C array */
rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1); rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
/* DBMクラスのメソッドclose(): 引数はなし */ /* DBM instance method close(): no args */
rb_define_method(cDBM, "close", fdbm_close, 0); rb_define_method(cDBM, "close", fdbm_close, 0);
/* DBMクラスのメソッド[]: 引数は1個 */ /* DBM instance method []: 1 argument */
rb_define_method(cDBM, "[]", fdbm_fetch, 1); rb_define_method(cDBM, "[]", fdbm_fetch, 1);
: :
/* DBMデータを格納するインスタンス変数名のためのID */
id_dbm = rb_intern("dbm");
} }
-- --
@ -646,11 +611,10 @@ fdbm_indexes(obj, args)
らすため struct RArray* で受けていますがVALUEでも同じこと らすため struct RArray* で受けていますがVALUEでも同じこと
です. です.
** 注意事項 ** Notice
Rubyと共有はしないがRubyのオブジェクトを格納する可能性のある GC should know about global variables which refers Ruby's objects, but
Cの大域変数は以下の関数を使ってRubyインタプリタに変数の存在 not exported to the Ruby world. You need to protect them by
を教えてあげてくださいでないとGCでトラブルを起こします
void rb_global_variable(VALUE *var) void rb_global_variable(VALUE *var)
@ -704,22 +668,22 @@ Ruby
してくれますextconf.rbを書き換えるなどしてMakefileの再生成 してくれますextconf.rbを書き換えるなどしてMakefileの再生成
が必要な時はまたRubyディレクトリでmakeしてください が必要な時はまたRubyディレクトリでmakeしてください
(9) rb_debug (9) debug
You may need to rb_debug the module. The modules can be linked You may need to rb_debug the module. The modules 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 can inspect the module by the debugger. so that you can inspect the module by the debugger.
(10) done, now you have the extension module (10) done, now you have the extension library
後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお 後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお
使いくださいRubyの作者は拡張モジュールに関して一切の権利を 使いくださいRubyの作者は拡張ライブラリに関して一切の権利を
主張しません. 主張しません.
Appendix A. Rubyのソースコードの分類 Appendix A. Rubyのソースコードの分類
Rubyのソースはいくつかに分類することが出来ますこのうちクラ Rubyのソースはいくつかに分類することが出来ますこのうちクラ
スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ スライブラリの部分は基本的に拡張ライブラリと同じ作り方になっ
ています.これらのソースは今までの説明でほとんど理解できると ています.これらのソースは今までの説明でほとんど理解できると
思います. 思います.
@ -847,54 +811,63 @@ super
オブジェクトをモジュール(で定義されているメソッド)で拡張する. オブジェクトをモジュール(で定義されているメソッド)で拡張する.
** 大域変数定義 ** Defining Global Variables
void rb_define_variable(char *name, VALUE *var) void rb_define_variable(char *name, VALUE *var)
RubyとCとで共有するグローバル変数を定義する変数名が`$'で始 Defines a global variable which is shared between C and Ruby. If name
まらない時には自動的に追加されるnameとしてRubyの識別子とし contains the character which is not allowed to be part of the symbol,
て許されない文字(例えば` ')を含む場合にはRubyプログラムから it can't be seen from Ruby programs.
は見えなくなる.
void rb_define_readonly_variable(char *name, VALUE *var) void rb_define_readonly_variable(char *name, VALUE *var)
RubyとCとで共有するread onlyのグローバル変数を定義するread Defines a read-only global variable. Works just like
onlyであること以外はrb_define_variable()と同じ. rb_define_variable(), except defined variable is read-only.
void rb_define_virtual_variable(char *name, void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)()) VALUE (*getter)(), VALUE (*setter)())
関数によって実現されるRuby変数を定義する変数が参照された時 Defines a virtual variable, whose behavior is defined by pair of C
にはgetterが変数に値がセットされた時にはsetterが呼ばれる functions. The getter function is called when the variable is
referred. The setter function is called when the value is set to the
variable. The prototype for getter/setter functions are:
VALUE getter(ID id)
void setter(VALUE val, ID id)
The getter function must return the value for the access.
void rb_define_hooked_variable(char *name, VALUE *var, void rb_define_hooked_variable(char *name, VALUE *var,
VALUE (*getter)(), VALUE (*setter)()) VALUE (*getter)(), VALUE (*setter)())
関数によってhookのつけられたグローバル変数を定義する変数が Defines hooked variable. It's virtual variable with C variable. The
参照された時にはgetterが関数に値がセットされた時にはsetter getter is called as
が呼ばれるgetterやsetterに0を指定した時にはhookを指定しな
いのと同じ事になる. VALUE getter(ID id, VALUE *var)
returning new value. The setter is called as
void setter(VALUE val, ID id, VALUE *var)
GC requires to mark the C global variables which hold Ruby values.
void rb_global_variable(VALUE *var) void rb_global_variable(VALUE *var)
GCのためRubyプログラムからはアクセスされないが, Rubyオブジェ Tells GC to protect these variables.
クトを含む大域変数をマークする.
** クラス定数 ** Constant Definition
void rb_define_const(VALUE class, char *name, VALUE val) void rb_define_const(VALUE klass, char *name, VALUE val)
クラス定数を定義する. Defines a new constant under the class/module.
void rb_define_global_const(char *name, VALUE val) void rb_define_global_const(char *name, VALUE val)
大域定数を定義する. Defines global contant. This is just work as
rb_define_const(cKernal, name, val) rb_define_const(cKernal, name, val)
と同じ意味. ** Method Definition
** メソッド定義
rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc) rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
@ -1008,50 +981,46 @@ rb_verbose
況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外 況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外
処理は一切行なわれない. 処理は一切行なわれない.
** Rubyの初期化・実行 ** Initialize and Starts the Interpreter
Rubyをアプリケーションに埋め込む場合には以下のインタフェース The embedding API are below (not needed for extension libraries):
を使う.通常の拡張モジュールには必要ない.
void ruby_init(int argc, char **argv, char **envp) void ruby_init(int argc, char **argv, char **envp)
Rubyインタプリタの初期化を行なう Initializes the interpreter.
void ruby_run() void ruby_run()
Rubyインタプリタを実行する Starts execution of the interpreter.
void ruby_script(char *name) void ruby_script(char *name)
Rubyのスクリプト名($0)を設定する. Specifies the name of the script ($0).
Appendix B. Functions Available in extconf.rb
Appendix B. extconf.rbで使える関数たち
extconf.rbの中では利用可能なコンパイル条件チェックの関数は以 extconf.rbの中では利用可能なコンパイル条件チェックの関数は以
下の通りである. 下の通りである.
have_library(lib, func) have_library(lib, func)
関数funcを定義しているライブラリlibの存在をチェックする Checks whether library which contains specified function exists.
イブラリが存在する時Qtrueを返す Returns true if the library exists.
have_func(func) have_func(func)
関数funcの存在をチェックするfuncが標準ではリンクされないラ Checks whether func exists. Returns true if the function exists. To
イブラリ内のものである時には先にhave_libraryでそのライブラリ check functions in the additional library, you need to check that
をチェックしておく事関数が存在する時TRUEを返す library first using have_library().
have_header(header) have_header(header)
ヘッダファイルの存在をチェックする.ヘッダファイルが存在する Checks for the header files. Returns true if the header file exists.
時TRUEを返す
create_makefile(target) create_makefile(target)
拡張モジュール用のMakefileを生成するこの関数を呼ばなければ Generates the Makefile for the extension library. If you don't invoke
そのモジュールはコンパイルされないtargetはモジュール名を表 this method, the compilation will not be done.
す.
/* /*
* Local variables: * Local variables:

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
Rubyの拡張モジュールの作り方を説明します. Rubyの拡張ライブラリの作り方を説明します.
1基礎知識 1基礎知識
@ -120,8 +120,8 @@ ruby.h
例えば文字列strの長さを得るためには「RSTRING(str)->len」と 例えば文字列strの長さを得るためには「RSTRING(str)->len」と
文字列strをchar*として得るためには「RSTRING(str)->ptr」 文字列strをchar*として得るためには「RSTRING(str)->ptr」
とします配列の場合にはそれぞれ「RARRAY(str)->len」 とします配列の場合にはそれぞれ「RARRAY(ary)->len」
「RARRAY(str)->ptr」となります 「RARRAY(ary)->ptr」となります
Rubyの構造体を直接アクセスする時に気をつけなければならないこ Rubyの構造体を直接アクセスする時に気をつけなければならないこ
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
@ -309,7 +309,7 @@ private
2.1.3 定数定義 2.1.3 定数定義
拡張モジュールが必要な定数はあらかじめ定義しておいた方が良い 拡張ライブラリが必要な定数はあらかじめ定義しておいた方が良い
でしょう.定数を定義する関数は二つあります. でしょう.定数を定義する関数は二つあります.
void rb_define_const(VALUE class, char *name, VALUE val) void rb_define_const(VALUE class, char *name, VALUE val)
@ -376,9 +376,9 @@ apply
2.2.4 変数/定数を参照/更新する 2.2.4 変数/定数を参照/更新する
Cから関数を使って参照・更新できるのはクラス定数,インスタ Cから関数を使って参照・更新できるのは定数インスタンス変
ンス変数です大域変数は一部のものはCの大域変数としてアクセ 数です大域変数は一部のものはCの大域変数としてアクセスでき
スできます.ローカル変数を参照する方法は公開していません. ます.ローカル変数を参照する方法は公開していません.
オブジェクトのインスタンス変数を参照・更新する関数は以下の通 オブジェクトのインスタンス変数を参照・更新する関数は以下の通
りです. りです.
@ -388,11 +388,11 @@ C
idはrb_intern()で得られるものを使ってください. idはrb_intern()で得られるものを使ってください.
クラス定数を参照するには以下の関数を使ってください. 定数を参照するには以下の関数を使ってください.
VALUE rb_const_get(VALUE obj, ID id) VALUE rb_const_get(VALUE obj, ID id)
クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ 定数を新しく定義するためには『2.1.3 定数定義』で紹介さ
れている関数を使ってください. れている関数を使ってください.
3RubyとCとの情報共有 3RubyとCとの情報共有
@ -504,7 +504,7 @@ C
4例題 - dbmパッケージを作る 4例題 - dbmパッケージを作る
ここまでの説明でとりあえず拡張モジュールは作れるはずです. ここまでの説明でとりあえず拡張ライブラリは作れるはずです.
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
して段階的に説明します. して段階的に説明します.
@ -523,12 +523,12 @@ Ruby 1.1
% cd ext/dbm % cd ext/dbm
% touch MANIFEST % touch MANIFEST
拡張モジュールのディレクトリの下にはMANIFESTというファイルが 拡張ライブラリのディレクトリの下にはMANIFESTというファイルが
必要なので,とりあえず空のファイルを作っておきます.後でこの 必要なので,とりあえず空のファイルを作っておきます.後でこの
ファイルには必要なファイル一覧が入ることになります. ファイルには必要なファイル一覧が入ることになります.
MANIFESTというファイルは静的リンクのmakeの時にディレクトリ MANIFESTというファイルは静的リンクのmakeの時にディレクトリ
が拡張モジュールを含んでいるかどうか判定するために使われれて が拡張ライブラリを含んでいるかどうか判定するために使われれて
います.ダイナミックライブラリを作る場合には必ずしも必要では います.ダイナミックライブラリを作る場合には必ずしも必要では
ありません. ありません.
@ -541,14 +541,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から一部引用します
@ -762,7 +762,7 @@ extconf.rb
動的リンクライブラリはmake installでRubyライブラリのディレク 動的リンクライブラリはmake installでRubyライブラリのディレク
トリの下にコピーされますもしモジュールと協調して使うRubyで トリの下にコピーされますもしモジュールと協調して使うRubyで
記述されたプログラムがありRubyライブラリに置きたい場合には 記述されたプログラムがありRubyライブラリに置きたい場合には
拡張モジュール用のディレクトリの下に lib というディレクトリ 拡張ライブラリ用のディレクトリの下に lib というディレクトリ
を作り,そこに 拡張子 .rb のファイルを置いておけば同時にイン を作り,そこに 拡張子 .rb のファイルを置いておけば同時にイン
ストールされます. ストールされます.
@ -775,13 +775,13 @@ extconf.rb
(11) できあがり (11) できあがり
後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお 後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお
使いくださいRubyの作者は拡張モジュールに関して一切の権利を 使いくださいRubyの作者は拡張ライブラリに関して一切の権利を
主張しません. 主張しません.
Appendix A. Rubyのソースコードの分類 Appendix A. Rubyのソースコードの分類
Rubyのソースはいくつかに分類することが出来ますこのうちクラ Rubyのソースはいくつかに分類することが出来ますこのうちクラ
スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ スライブラリの部分は基本的に拡張ライブラリと同じ作り方になっ
ています.これらのソースは今までの説明でほとんど理解できると ています.これらのソースは今までの説明でほとんど理解できると
思います. 思います.
@ -962,11 +962,11 @@ only
GCのためRubyプログラムからはアクセスされないが, Rubyオブジェ GCのためRubyプログラムからはアクセスされないが, Rubyオブジェ
クトを含む大域変数をマークする. クトを含む大域変数をマークする.
** クラス定数 ** 定数
void rb_define_const(VALUE class, char *name, VALUE val) void rb_define_const(VALUE klass, char *name, VALUE val)
クラス定数を定義する. 定数を定義する.
void rb_define_global_const(char *name, VALUE val) void rb_define_global_const(char *name, VALUE val)
@ -1098,7 +1098,7 @@ exception
** Rubyの初期化・実行 ** Rubyの初期化・実行
Rubyをアプリケーションに埋め込む場合には以下のインタフェース Rubyをアプリケーションに埋め込む場合には以下のインタフェース
を使う.通常の拡張モジュールには必要ない. を使う.通常の拡張ライブラリには必要ない.
void ruby_init(int argc, char **argv, char **envp) void ruby_init(int argc, char **argv, char **envp)
@ -1121,7 +1121,7 @@ extconf.rb
have_library(lib, func) have_library(lib, func)
関数funcを定義しているライブラリlibの存在をチェックする 関数funcを定義しているライブラリlibの存在をチェックする
イブラリが存在する時,Qtrueを返す イブラリが存在する時trueを返す
have_func(func) have_func(func)
@ -1132,11 +1132,11 @@ extconf.rb
have_header(header) have_header(header)
ヘッダファイルの存在をチェックする.ヘッダファイルが存在する ヘッダファイルの存在をチェックする.ヘッダファイルが存在する
TRUEを返す. trueを返す.
create_makefile(target) create_makefile(target)
拡張モジュール用のMakefileを生成するこの関数を呼ばなければ 拡張ライブラリ用のMakefileを生成するこの関数を呼ばなければ
そのモジュールはコンパイルされないtargetはモジュール名を表 そのモジュールはコンパイルされないtargetはモジュール名を表
す. す.

39
ToDo
View file

@ -1,5 +1,36 @@
* non-blocking open/write for thread Language Spec.
* avoid blocking with gethostbyname/gethostbyaddr
* package or access control for global variables * package or access control for global variables
* format * named arguments like foo(nation:="german").
* freeze or undump to bundle everything in birary format. * multiple return values, yield values. maybe imcompatible
Hacking Interpreter
* non-blocking open (e.g. named pipe) for thread
* avoid blocking with gethostbyname/gethostbyaddr
* objectify interpreters
* remove rb_eval() recursions
* syntax tree -> bytecode ???
* scrambled script, or script filter
Extension Libraries
* mod_ruby, FastCGI ruby
* InterBase module
* ptk.rb pTk wrapper that is compatible to tk.rb
Ruby Libraries
* CGI.rb
* httplib.rb, urllib.rb, nttplib.rb, etc.
* format like perl's
Tools
* extension library maker like XS or SWIG
* freeze or undump to bundle everything
Misc
* translate README.EXT fully into English
* publish Ruby books

15
config.guess vendored
View file

@ -740,6 +740,21 @@ EOF
BePC:BeOS:*:*) BePC:BeOS:*:*)
echo i586-pc-beos echo i586-pc-beos
exit 0 ;; exit 0 ;;
*:Rhapsody:*:*)
arch=`/usr/bin/arch`
case "$arch" in
ppc)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
;;
i[3456]86)
echo i386-apple-rhapsody${UNAME_RELEASE}
;;
*)
echo $arch-apple-rhapsody${UNAME_RELEASE}
;;
esac
exit 0 ;;
esac esac
#echo '(No uname command or uname output not recognized.)' 1>&2 #echo '(No uname command or uname output not recognized.)' 1>&2

View file

@ -34,25 +34,37 @@ fat_binary=no
AC_ARG_ENABLE( fat-binary, AC_ARG_ENABLE( fat-binary,
[--enable-fat-binary build a NeXT/Apple Multi Architecture Binary. ], [--enable-fat-binary build a NeXT/Apple Multi Architecture Binary. ],
[ fat_binary=$enableval ] ) [ fat_binary=$enableval ] )
if test "$fat_binary" = yes ; then if test "$fat_binary" = yes ; then
AC_MSG_CHECKING( target architecture ) AC_MSG_CHECKING( target architecture )
if test "$host_os" = "rhapsody" ; then case "$host_os" in
echo -n "Rhapsody: " rhapsody*)
if test "$TARGET_ARCHS" = "" ; then echo -n "MacOS X Server: "
TARGET_ARCHS="ppc i486" if test "$TARGET_ARCHS" = "" ; then
TARGET_ARCHS="ppc i386"
fi fi
else ;;
nextstep*|openstep*)
echo -n "NeXTSTEP/OPENSTEP: " echo -n "NeXTSTEP/OPENSTEP: "
if test "$TARGET_ARCHS" = "" ; then
if test `/usr/bin/arch` = "m68k" ; then if test "$host_os" = "rhapsody" ; then
TARGET_ARCHS="m68k i486" echo -n "Rhapsody: "
else if test "$TARGET_ARCHS" = "" ; then
TARGET_ARCHS="m68k `/usr/bin/arch`" TARGET_ARCHS="ppc i486"
fi fi
else
echo -n "NeXTSTEP/OPENSTEP: "
if test "$TARGET_ARCHS" = "" ; then
if test `/usr/bin/arch` = "m68k" ; then
TARGET_ARCHS="m68k i486"
else # Black and Native one
TARGET_ARCHS="m68k `/usr/bin/arch`"
fi
fi
fi fi
fi ;;
esac
# /usr/lib/arch_tool -archify_list $TARGET_ARCHS # /usr/lib/arch_tool -archify_list $TARGET_ARCHS
for archs in $TARGET_ARCHS for archs in $TARGET_ARCHS
do do
@ -163,7 +175,7 @@ AC_REPLACE_FUNCS(dup2 setenv memmove mkdir strcasecmp strerror strftime\
AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd\ AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd\
truncate chsize times utimes fcntl lockf setitimer\ truncate chsize times utimes fcntl lockf setitimer\
setruid seteuid setreuid setrgid setegid setregid\ setruid seteuid setreuid setrgid setegid setregid\
setpgrp2 getpgid getgroups getpriority\ setpgrp2 getpgid setpgid getgroups getpriority\
dlopen sigprocmask sigaction _setjmp setpgrp setsid) dlopen sigprocmask sigaction _setjmp setpgrp setsid)
if test "$ac_cv_func_strftime" = no; then if test "$ac_cv_func_strftime" = no; then
AC_STRUCT_TIMEZONE AC_STRUCT_TIMEZONE

17
dln.c
View file

@ -1129,15 +1129,22 @@ dln_strerror()
#ifdef _WIN32 #ifdef _WIN32
static char message[1024]; static char message[1024];
int error = GetLastError();
char *p = message;
p += sprintf(message, "%d: ", error);
FormatMessage( FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_FROM_SYSTEM,
NULL, NULL,
GetLastError(), error,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
message, p,
sizeof message, sizeof message - strlen(message),
NULL); NULL);
for (p = message; *p; p++) {
if (*p == '\n' || *p == '\r')
*p = ' ';
}
return message; return message;
#endif #endif
} }
@ -1213,7 +1220,7 @@ dln_load(file)
/* Load file */ /* Load file */
if ((handle = if ((handle =
LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) { LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
printf("LoadLibraryExA\n"); printf("LoadLibraryExA: %s\n", winfile);
goto failed; goto failed;
} }

4
enum.c
View file

@ -343,7 +343,11 @@ each_with_index_i(val, indexp)
VALUE val; VALUE val;
int *indexp; int *indexp;
{ {
#if 0
rb_yield(rb_assoc_new(val, INT2FIX(*indexp))); rb_yield(rb_assoc_new(val, INT2FIX(*indexp)));
#else
rb_yield(rb_ary_concat(val, INT2FIX(*indexp)));
#endif
(*indexp)++; (*indexp)++;
return Qnil; return Qnil;
} }

10
error.c
View file

@ -274,10 +274,7 @@ exc_initialize(argc, argv, exc)
{ {
VALUE mesg; VALUE mesg;
if (rb_scan_args(argc, argv, "01", &mesg) == 0) { if (rb_scan_args(argc, argv, "01", &mesg) == 1) {
mesg = rb_str_new(0, 0);
}
else {
STR2CSTR(mesg); /* ensure mesg can be converted to String */ STR2CSTR(mesg); /* ensure mesg can be converted to String */
} }
rb_iv_set(exc, "mesg", mesg); rb_iv_set(exc, "mesg", mesg);
@ -308,7 +305,10 @@ static VALUE
exc_to_s(exc) exc_to_s(exc)
VALUE exc; VALUE exc;
{ {
return rb_iv_get(exc, "mesg"); VALUE mesg = rb_iv_get(exc, "mesg");
if (NIL_P(mesg)) return rb_class_path(CLASS_OF(exc));
return mesg;
} }
static VALUE static VALUE

115
eval.c
View file

@ -97,41 +97,6 @@ rb_clear_cache()
} }
} }
static int cache_conflict;
static int eval_called;
static int
count_cent()
{
struct cache_entry *ent, *end;
int n = 0, n2 = 0;
int p = 0;
fprintf(stderr, "\n|");
ent = cache; end = ent + CACHE_SIZE;
while (ent < end) {
fprintf(stderr, (ent->klass != 0)?"*":" ");
p++;
if (p % 80 == 0) {
break;
}
ent++;
}
fprintf(stderr, "|\n|");
p = 0; ent = cache;
while (ent < end) {
if (ent->klass != 0) {n++; n2++;}
p++;
if (p % 24 == 0) {
fprintf(stderr, "%c", n2?(n2+'0'):' ');
n2 = 0;
}
ent++;
}
fprintf(stderr, "|\n");
return n;
}
static void static void
rb_clear_cache_by_id(id) rb_clear_cache_by_id(id)
ID id; ID id;
@ -433,7 +398,10 @@ static struct SCOPE *top_scope;
_frame.argc = 0; \ _frame.argc = 0; \
ruby_frame = &_frame; \ ruby_frame = &_frame; \
#define POP_FRAME() ruby_frame = _frame.prev; } #define POP_FRAME() \
ruby_sourcefile = _frame.file; \
ruby_sourceline = _frame.line; \
ruby_frame = _frame.prev; }
struct BLOCK { struct BLOCK {
NODE *var; NODE *var;
@ -873,7 +841,9 @@ error_print()
ep = RARRAY(errat); ep = RARRAY(errat);
for (i=1; i<ep->len; i++) { for (i=1; i<ep->len; i++) {
fprintf(stderr, "\tfrom %s\n", RSTRING(ep->ptr[i])->ptr); if (TYPE(ep->ptr[i]) == T_STRING) {
fprintf(stderr, "\tfrom %s\n", RSTRING(ep->ptr[i])->ptr);
}
if (i == TRACE_HEAD && ep->len > TRACE_MAX) { if (i == TRACE_HEAD && ep->len > TRACE_MAX) {
fprintf(stderr, "\t ... %d levels...\n", fprintf(stderr, "\t ... %d levels...\n",
ep->len - TRACE_HEAD - TRACE_TAIL); ep->len - TRACE_HEAD - TRACE_TAIL);
@ -1016,11 +986,6 @@ ruby_run()
#endif #endif
exec_end_proc(); exec_end_proc();
rb_gc_call_finalizer_at_exit(); rb_gc_call_finalizer_at_exit();
#if 1
fprintf(stderr, "%d/%d(%d)\n", count_cent(), CACHE_SIZE, cache_conflict);
#else
fprintf(stderr, "rb_eval() called %d times\n", eval_called);
#endif
} }
else { else {
ex = state; ex = state;
@ -1666,8 +1631,6 @@ rb_eval(self, node)
#define RETURN(v) { result = (v); goto finish; } #define RETURN(v) { result = (v); goto finish; }
eval_called++;
again: again:
if (!node) RETURN(Qnil); if (!node) RETURN(Qnil);
@ -3030,12 +2993,12 @@ rb_f_raise(argc, argv)
} }
if (!NIL_P(mesg)) { if (!NIL_P(mesg)) {
if (n >= 2) { if (n == 1 && TYPE(mesg) == T_STRING) {
mesg = rb_funcall(etype, rb_intern("new"), 1, mesg);
}
else if (TYPE(mesg) == T_STRING) {
mesg = rb_exc_new3(rb_eRuntimeError, mesg); mesg = rb_exc_new3(rb_eRuntimeError, mesg);
} }
else if (n == 1 || n == 2) {
mesg = rb_funcall(etype, rb_intern("new"), n-1, mesg);
}
if (!rb_obj_is_kind_of(mesg, rb_eException)) { if (!rb_obj_is_kind_of(mesg, rb_eException)) {
rb_raise(rb_eTypeError, "exception object expected"); rb_raise(rb_eTypeError, "exception object expected");
} }
@ -3835,22 +3798,13 @@ rb_call(klass, recv, mid, argc, argv, scope)
noex = ent->noex; noex = ent->noex;
body = ent->method; body = ent->method;
} }
else { else if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) {
if (ent->mid) {
fprintf(stderr, "%s#%s -> %s#%s (%d)\n", rb_class2name(ent->klass),
rb_id2name(ent->mid),
rb_class2name(klass),
rb_id2name(id), ent-cache);
cache_conflict++;
}
if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) {
if (scope == 3) { if (scope == 3) {
rb_raise(rb_eNameError, "super: no superclass method `%s'", rb_raise(rb_eNameError, "super: no superclass method `%s'",
rb_id2name(mid)); rb_id2name(mid));
} }
return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0); return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0);
} }
}
/* receiver specified form for private method */ /* receiver specified form for private method */
if ((noex & NOEX_PRIVATE) && scope == 0) if ((noex & NOEX_PRIVATE) && scope == 0)
@ -4537,7 +4491,7 @@ rb_f_require(obj, fname)
VALUE obj, fname; VALUE obj, fname;
{ {
char *ext, *file, *feature, *buf; /* OK */ char *ext, *file, *feature, *buf; /* OK */
VALUE load; volatile VALUE load;
rb_secure(4); rb_secure(4);
Check_SafeStr(fname); Check_SafeStr(fname);
@ -5510,7 +5464,7 @@ method_call(argc, argv, method)
Data_Get_Struct(method, struct METHOD, data); Data_Get_Struct(method, struct METHOD, data);
PUSH_ITER(rb_iterator_p()?ITER_PRE:ITER_NOT); PUSH_ITER(rb_iterator_p()?ITER_PRE:ITER_NOT);
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
if (FL_TEST(data->recv, FL_TAINT)) { if (FL_TEST(data->recv, FL_TAINT) || FL_TEST(method, FL_TAINT)) {
FL_SET(method, FL_TAINT); FL_SET(method, FL_TAINT);
if (safe_level < 4) safe_level = 4; if (safe_level < 4) safe_level = 4;
} }
@ -6543,6 +6497,34 @@ static VALUE rb_thread_raise _((int, VALUE*, VALUE));
#define SCOPE_SHARED FL_USER1 #define SCOPE_SHARED FL_USER1
#if defined(HAVE_SETITIMER) && !defined(__BOW__)
static int thread_init = 0;
void
thread_start_timer()
{
struct itimerval tval;
if (!thread_init) return;
tval.it_interval.tv_sec = 0;
tval.it_interval.tv_usec = 100000;
tval.it_value = tval.it_interval;
setitimer(ITIMER_VIRTUAL, &tval, NULL);
}
void
thread_stop_timer()
{
struct itimerval tval;
if (!thread_init) return;
tval.it_interval.tv_sec = 0;
tval.it_interval.tv_usec = 0;
tval.it_value = tval.it_interval;
setitimer(ITIMER_VIRTUAL, &tval, NULL);
}
#endif
static VALUE static VALUE
rb_thread_create_0(fn, arg, klass) rb_thread_create_0(fn, arg, klass)
VALUE (*fn)(); VALUE (*fn)();
@ -6554,11 +6536,7 @@ rb_thread_create_0(fn, arg, klass)
int state; int state;
#if defined(HAVE_SETITIMER) && !defined(__BOW__) #if defined(HAVE_SETITIMER) && !defined(__BOW__)
static init = 0; if (!thread_init) {
if (!init) {
struct itimerval tval;
#ifdef POSIX_SIGNAL #ifdef POSIX_SIGNAL
posix_signal(SIGVTALRM, catch_timer); posix_signal(SIGVTALRM, catch_timer);
posix_signal(SIGALRM, catch_timer); posix_signal(SIGALRM, catch_timer);
@ -6567,11 +6545,8 @@ rb_thread_create_0(fn, arg, klass)
signal(SIGALRM, catch_timer); signal(SIGALRM, catch_timer);
#endif #endif
tval.it_interval.tv_sec = 0; thread_init = 1;
tval.it_interval.tv_usec = 100000; thread_start_timer();
tval.it_value = tval.it_interval;
setitimer(ITIMER_VIRTUAL, &tval, NULL);
init = 1;
} }
#endif #endif

View file

@ -313,11 +313,11 @@ archdir = $(pkglibdir)/@arch@
mfile.printf $objs.join(" ") mfile.printf $objs.join(" ")
mfile.printf "\n" mfile.printf "\n"
mfile.printf "\ mfile.printf << EOS
TARGET = %s.%s TARGET = #{target}.#{$static ? "a" : "@DLEXT@"}
INSTALL = %s@INSTALL@ INSTALL = #{$dots}@INSTALL@
INSTALL_DATA = %s@INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
binsuffix = @binsuffix@ binsuffix = @binsuffix@
@ -328,16 +328,15 @@ clean:; @rm -f *.o *.a *.so *.sl
@rm -f core ruby$(binsuffix) *~ @rm -f core ruby$(binsuffix) *~
realclean: clean realclean: clean
", target, EOS
if $static then "a" else "@DLEXT@" end, $dots, $dots
mfile.printf "\ mfile.printf <<EOS
install: install:
@test -d $(DESTDIR)$(libdir) || mkdir $(DESTDIR)$(libdir) @test -d $(DESTDIR)$(libdir) || mkdir $(DESTDIR)$(libdir)
@test -d $(DESTDIR)$(pkglibdir) || mkdir $(DESTDIR)$(pkglibdir) @test -d $(DESTDIR)$(pkglibdir) || mkdir $(DESTDIR)$(pkglibdir)
@test -d $(DESTDIR)$(archdir) || mkdir $(DESTDIR)$(archdir) @test -d $(DESTDIR)$(archdir) || mkdir $(DESTDIR)$(archdir)
" EOS
if !$static if !$static
mfile.printf "\ mfile.printf "\
$(INSTALL) $(TARGET) $(DESTDIR)$(archdir)/$(TARGET) $(INSTALL) $(TARGET) $(DESTDIR)$(archdir)/$(TARGET)

View file

@ -6647,11 +6647,11 @@ idle()
return Qtrue; return Qtrue;
} }
static void static VALUE
exec_interval(proc) exec_interval(proc)
VALUE proc; VALUE proc;
{ {
rb_funcall(proc, id_call, 0); return rb_funcall(proc, id_call, 0);
} }
static VALUE static VALUE
@ -6660,8 +6660,8 @@ timeout_add(self, interval)
{ {
int id; int id;
id = gtk_timeout_add_interp(NUM2INT(interval), exec_interval, id = gtk_timeout_add(NUM2INT(interval), (GtkFunction)exec_interval,
(gpointer)rb_f_lambda(), 0); (gpointer)rb_f_lambda());
return INT2FIX(id); return INT2FIX(id);
} }
@ -6679,7 +6679,7 @@ idle_add(self)
{ {
int id; int id;
id = gtk_idle_add_interp(exec_interval, (gpointer)rb_f_lambda(), 0); id = gtk_idle_add((GtkFunction)exec_interval, (gpointer)rb_f_lambda());
return INT2FIX(id); return INT2FIX(id);
} }

16
gc.c
View file

@ -392,6 +392,10 @@ rb_gc_mark(ptr)
obj->as.basic.flags |= FL_MARK; obj->as.basic.flags |= FL_MARK;
if (FL_TEST(obj, FL_EXIVAR)) {
return rb_mark_generic_ivar((VALUE)obj);
}
switch (obj->as.basic.flags & T_MASK) { switch (obj->as.basic.flags & T_MASK) {
case T_NIL: case T_NIL:
case T_FIXNUM: case T_FIXNUM:
@ -616,7 +620,7 @@ rb_gc_mark(ptr)
#define MIN_FREE_OBJ 512 #define MIN_FREE_OBJ 512
static void obj_free(); static void obj_free _((VALUE));
static void static void
gc_sweep() gc_sweep()
@ -693,6 +697,10 @@ obj_free(obj)
if (need_call_final && FL_TEST(obj, FL_FINALIZE)) { if (need_call_final && FL_TEST(obj, FL_FINALIZE)) {
run_final(obj); run_final(obj);
} }
if (FL_TEST(obj, FL_EXIVAR)) {
rb_free_generic_ivar((VALUE)obj);
}
switch (RANY(obj)->as.basic.flags & T_MASK) { switch (RANY(obj)->as.basic.flags & T_MASK) {
case T_OBJECT: case T_OBJECT:
if (RANY(obj)->as.object.iv_tbl) { if (RANY(obj)->as.object.iv_tbl) {
@ -871,11 +879,14 @@ rb_gc()
for (list = Global_List; list; list = list->next) { for (list = Global_List; list; list = list->next) {
rb_gc_mark(*list->varptr); rb_gc_mark(*list->varptr);
} }
rb_gc_mark_global_tbl(); rb_gc_mark_global_tbl();
mark_tbl(rb_class_tbl); mark_tbl(rb_class_tbl);
rb_gc_mark_trap_list(); rb_gc_mark_trap_list();
/* mark generic instance variables for special constants */
rb_mark_generic_ivar_tbl();
gc_sweep(); gc_sweep();
dont_gc--; dont_gc--;
} }
@ -1070,6 +1081,7 @@ id2ref(obj, id)
{ {
unsigned long ptr = NUM2UINT(id); unsigned long ptr = NUM2UINT(id);
rb_secure(4);
if (FIXNUM_P(ptr)) return (VALUE)ptr; if (FIXNUM_P(ptr)) return (VALUE)ptr;
if (ptr == Qtrue) return Qtrue; if (ptr == Qtrue) return Qtrue;
if (ptr == Qfalse) return Qfalse; if (ptr == Qfalse) return Qfalse;

8
hash.c
View file

@ -1027,7 +1027,7 @@ static VALUE
env_each(hash) env_each(hash)
VALUE hash; VALUE hash;
{ {
VALUE ary = env_keys(); volatile VALUE ary = env_keys();
VALUE *ptr = RARRAY(ary)->ptr; VALUE *ptr = RARRAY(ary)->ptr;
int len = RARRAY(ary)->len; int len = RARRAY(ary)->len;
@ -1044,7 +1044,7 @@ env_each(hash)
static VALUE static VALUE
env_delete_if() env_delete_if()
{ {
VALUE ary; volatile VALUE ary;
VALUE *ptr; VALUE *ptr;
int len; int len;
@ -1124,7 +1124,7 @@ env_has_value(dmy, value)
VALUE dmy, value; VALUE dmy, value;
{ {
char **env; char **env;
VALUE ary; volatile VALUE ary;
if (TYPE(value) != T_STRING) return Qfalse; if (TYPE(value) != T_STRING) return Qfalse;
ary = rb_ary_new(); ary = rb_ary_new();
@ -1168,7 +1168,7 @@ env_to_hash(obj)
VALUE obj; VALUE obj;
{ {
VALUE hash = rb_hash_new(); VALUE hash = rb_hash_new();
VALUE ary = env_keys(); volatile VALUE ary = env_keys();
VALUE *ptr = RARRAY(ary)->ptr; VALUE *ptr = RARRAY(ary)->ptr;
int len = RARRAY(ary)->len; int len = RARRAY(ary)->len;

View file

@ -67,6 +67,7 @@ VALUE rb_define_module_id _((ID));
VALUE rb_mod_included_modules _((VALUE)); VALUE rb_mod_included_modules _((VALUE));
VALUE rb_mod_ancestors _((VALUE)); VALUE rb_mod_ancestors _((VALUE));
VALUE rb_class_instance_methods _((int, VALUE*, VALUE)); VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE)); VALUE rb_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));
@ -100,9 +101,6 @@ VALUE rb_dvar_defined _((ID));
VALUE rb_dvar_ref _((ID)); 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));
void ruby_init _((void));
void ruby_options _((int, char**));
void ruby_run _((void));
VALUE rb_eval_cmd _((VALUE, VALUE)); VALUE rb_eval_cmd _((VALUE, VALUE));
VALUE rb_trap_eval _((VALUE, int)); VALUE rb_trap_eval _((VALUE, int));
int rb_respond_to _((VALUE, ID)); int rb_respond_to _((VALUE, ID));
@ -119,6 +117,8 @@ VALUE rb_class_new_instance _((int, VALUE*, VALUE));
VALUE rb_f_lambda _((void)); VALUE rb_f_lambda _((void));
void rb_set_end_proc _((void (*)(),VALUE)); void rb_set_end_proc _((void (*)(),VALUE));
void rb_gc_mark_threads _((void)); void rb_gc_mark_threads _((void));
void thread_start_timer _((void));
void thread_stop_timer _((void));
void rb_thread_schedule _((void)); void rb_thread_schedule _((void));
void rb_thread_wait_fd _((int)); void rb_thread_wait_fd _((int));
void rb_thread_fd_writable _((int)); void rb_thread_fd_writable _((int));
@ -175,9 +175,7 @@ VALUE rb_num2fix _((VALUE));
VALUE rb_fix2str _((VALUE, int)); VALUE rb_fix2str _((VALUE, int));
VALUE rb_fix_upto _((VALUE, VALUE)); VALUE rb_fix_upto _((VALUE, VALUE));
/* object.c */ /* object.c */
VALUE rb_equal _((VALUE, VALUE));
int rb_eql _((VALUE, VALUE)); int rb_eql _((VALUE, VALUE));
VALUE rb_obj_equal _((VALUE, VALUE));
VALUE rb_any_to_s _((VALUE)); VALUE rb_any_to_s _((VALUE));
VALUE rb_inspect _((VALUE)); VALUE rb_inspect _((VALUE));
VALUE rb_obj_is_instance_of _((VALUE, VALUE)); VALUE rb_obj_is_instance_of _((VALUE, VALUE));
@ -191,7 +189,6 @@ VALUE rb_Integer _((VALUE));
VALUE rb_Float _((VALUE)); VALUE rb_Float _((VALUE));
VALUE rb_String _((VALUE)); VALUE rb_String _((VALUE));
VALUE rb_Array _((VALUE)); VALUE rb_Array _((VALUE));
double rb_num2dbl _((VALUE));
/* parse.y */ /* parse.y */
extern int ruby_sourceline; extern int ruby_sourceline;
extern char *ruby_sourcefile; extern char *ruby_sourcefile;
@ -291,6 +288,9 @@ VALUE rb_f_untrace_var _((int, VALUE*));
VALUE rb_gvar_set2 _((char*, VALUE)); VALUE rb_gvar_set2 _((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_tbl _((void));
void rb_free_generic_ivar _((VALUE));
VALUE rb_ivar_get _((VALUE, ID)); VALUE rb_ivar_get _((VALUE, ID));
VALUE rb_ivar_set _((VALUE, ID, VALUE)); VALUE rb_ivar_set _((VALUE, ID, VALUE));
VALUE rb_ivar_defined _((VALUE, ID)); VALUE rb_ivar_defined _((VALUE, ID));

2
io.c
View file

@ -2544,7 +2544,7 @@ arg_read(argc, argv)
next_p = 1; next_p = 1;
goto retry; goto retry;
} }
if (NIL_P(tmp)) return str; if (NIL_P(tmp) || RSTRING(tmp)->len == 0) return str;
else if (NIL_P(str)) str = tmp; else if (NIL_P(str)) str = tmp;
else rb_str_cat(str, RSTRING(tmp)->ptr, RSTRING(tmp)->len); else rb_str_cat(str, RSTRING(tmp)->ptr, RSTRING(tmp)->len);
if (argc == 0) { if (argc == 0) {

View file

@ -267,6 +267,6 @@ class DEBUGGER__
CONTEXT = new CONTEXT = new
end end
set_trace_func proc{|event, file, line, id, binding, klass| set_trace_func proc{|event, file, line, id, binding|
DEBUGGER__::CONTEXT.trace_func event, file, line, id, binding, klass DEBUGGER__::CONTEXT.trace_func event, file, line, id, binding
} }

View file

@ -20,24 +20,32 @@ class Delegator
def initialize(obj) def initialize(obj)
preserved = ::Kernel.instance_methods preserved = ::Kernel.instance_methods
preserved -= ["to_s","to_a","inspect","==","=~","==="]
for t in self.type.ancestors for t in self.type.ancestors
preserved |= t.instance_methods preserved |= t.instance_methods
preserved |= t.private_instance_methods
preserved |= t.protected_instance_methods
break if t == Delegator break if t == Delegator
end end
preserved -= ["to_s","to_a","inspect","==","=~","==="]
for method in obj.methods for method in obj.methods
next if preserved.include? method next if preserved.include? method
eval <<EOS eval <<-EOS
def self.#{method}(*args, &block) def self.#{method}(*args, &block)
begin begin
__getobj__.__send__(:#{method}, *args, &block) __getobj__.__send__(:#{method}, *args, &block)
rescue Exception rescue Exception
n = if /:in `__getobj__'$/ =~ $@[0] then 1 else 2 end #` c = -caller(0).size
$@[1,n] = nil if /:in `__getobj__'$/ =~ $@[c-1] #`
raise n = 1
end else
end c -= 1
EOS n = 2
end
$@[c,n] = nil
raise
end
end
EOS
end end
end end
@ -72,14 +80,14 @@ def DelegateClass(superclass)
klass = Class.new klass = Class.new
methods = superclass.instance_methods methods = superclass.instance_methods
methods -= ::Kernel.instance_methods methods -= ::Kernel.instance_methods
methods |= ["to_s","to_a","inspect","hash","eql?","==","=~","==="] methods |= ["to_s","to_a","inspect","==","=~","==="]
klass.module_eval <<EOS klass.module_eval <<-EOS
def initialize(obj) def initialize(obj)
@obj = obj @obj = obj
end end
EOS EOS
for method in methods for method in methods
klass.module_eval <<EOS klass.module_eval <<-EOS
def #{method}(*args, &block) def #{method}(*args, &block)
begin begin
@obj.__send__(:#{method}, *args, &block) @obj.__send__(:#{method}, *args, &block)
@ -88,7 +96,7 @@ EOS
raise raise
end end
end end
EOS EOS
end end
return klass; return klass;
end end
@ -107,10 +115,12 @@ if __FILE__ == $0
foo = Object.new foo = Object.new
def foo.test def foo.test
25
end
def foo.error
raise 'this is OK' raise 'this is OK'
end end
foo2 = SimpleDelegator.new(foo) foo2 = SimpleDelegator.new(foo)
p foo.hash == foo2.hash # => true p foo.test == foo2.test # => true
foo.test # raise error! foo2.error # raise error!
end end

View file

@ -1,7 +1,7 @@
class Mail class Mail
def initialize(f) def initialize(f)
unless f.kind_of?(IO) unless defined? f.gets
f = open(f, "r") f = open(f, "r")
opened = true opened = true
end end

View file

@ -289,7 +289,8 @@ LDSHARED = #{CONFIG["LDSHARED"]}
prefix = #{CONFIG["prefix"]} prefix = #{CONFIG["prefix"]}
exec_prefix = #{CONFIG["exec_prefix"]} exec_prefix = #{CONFIG["exec_prefix"]}
libdir = #{$archdir} libdir = #{$libdir}
archdir = #{$archdir}
#### End of system configuration section. #### #### End of system configuration section. ####
@ -312,11 +313,12 @@ clean:; @rm -f *.o *.so *.sl
realclean: clean realclean: clean
install: $(libdir)/$(TARGET) install: $(archdir)/$(TARGET)
$(libdir)/$(TARGET): $(TARGET) $(archdir)/$(TARGET): $(TARGET)
@test -d $(libdir) || mkdir $(libdir) @test -d $(libdir) || mkdir $(libdir)
$(INSTALL) $(TARGET) $(libdir)/$(TARGET) @test -d $(archdir) || mkdir $(archdir)
$(INSTALL) $(TARGET) $(archdir)/$(TARGET)
EOMF EOMF
install_rb(mfile) install_rb(mfile)
mfile.printf "\n" mfile.printf "\n"

View file

@ -110,6 +110,7 @@ class PStore
@abort = false @abort = false
end end
ensure ensure
@table = nil
@transaction = false @transaction = false
end end
value value

5
misc/README Normal file
View file

@ -0,0 +1,5 @@
README this file
inf-ruby.el program to run ruby under emacs
ruby-mode.el ruby mode for emacs
rubydb2x.el ruby debugger support for emacs 19.2x or before
rubydb3x.el ruby debugger support for emacs 19.3x or later

View file

@ -1,8 +1,8 @@
(J;;;(B (J-*-Emacs-Lisp-*-(B (J;;;(B (J-*-Emacs-Lisp-*-(B
;;; ;;;
;;; $Id: inf-ruby.el,v 1.4 1998/05/20 02:45:58 senda Exp $ ;;; $Id$
;;; $Author: senda $ ;;; $Author$
;;; $Date: 1998/05/20 02:45:58 $ ;;; $Date$
;;; ;;;
;;; Inferior Ruby Mode - ruby process in a buffer. ;;; Inferior Ruby Mode - ruby process in a buffer.
;;; adapted from cmuscheme.el ;;; adapted from cmuscheme.el
@ -34,7 +34,10 @@
;;; ;;;
;;; HISTORY ;;; HISTORY
;;; senda - 8 Apr 1998: Created. ;;; senda - 8 Apr 1998: Created.
;;; $Log: inf-ruby.el,v $ ;;; $Log$
;;; Revision 1.1.2.1 1998/12/16 07:30:36 matz
;;; first public release of 1.1d (pre1.2) series
;;;
;;; Revision 1.4 1998/05/20 02:45:58 senda ;;; Revision 1.4 1998/05/20 02:45:58 senda
;;; default program to irb ;;; default program to irb
;;; ;;;

View file

@ -2,11 +2,19 @@
;;; ruby-mode.el - ;;; ruby-mode.el -
;;; ;;;
;;; $Author$ ;;; $Author$
<<<<<<< ruby-mode.el
;;; $Date$ ;;; $Date$
=======
;;; $Date$
>>>>>>> 1.1.1.2.2.23
;;; created at: Fri Feb 4 14:49:13 JST 1994 ;;; created at: Fri Feb 4 14:49:13 JST 1994
;;; ;;;
<<<<<<< ruby-mode.el
(defconst ruby-mode-revision "$Revision$") (defconst ruby-mode-revision "$Revision$")
=======
(defconst ruby-mode-revision "$Revision$")
>>>>>>> 1.1.1.2.2.23
(defconst ruby-mode-version (defconst ruby-mode-version
(progn (progn

View file

@ -251,6 +251,9 @@ int SafeFree(char **vec, int vecc)
static char *szInternalCmds[] = { static char *szInternalCmds[] = {
"append",
"break",
"call",
"cd", "cd",
"chdir", "chdir",
"cls", "cls",
@ -264,6 +267,7 @@ static char *szInternalCmds[] = {
"md", "md",
"mkdir", "mkdir",
"path", "path",
"pause",
"rd", "rd",
"rem", "rem",
"ren", "ren",
@ -280,13 +284,18 @@ static char *szInternalCmds[] = {
int int
isInternalCmd(char *cmd) isInternalCmd(char *cmd)
{ {
int fRet; int i, fRet;
char **vec; char **vec;
int vecc = NtMakeCmdVector(cmd, &vec, FALSE); for( i = 0; szInternalCmds[i] ; i++){
if(!strcmp(szInternalCmds[i], vec[0])){
fRet = 1;
break;
}
}
SafeFree (vec, vecc); SafeFree (vec, vecc);
return 0; return fRet;
} }

View file

@ -1044,7 +1044,7 @@ static VALUE
fix_rev(num) fix_rev(num)
VALUE num; VALUE num;
{ {
unsigned long val = FIX2UINT(num); unsigned long val = FIX2ULONG(num);
val = ~val; val = ~val;
return rb_int2inum(val); return rb_int2inum(val);

View file

@ -49,7 +49,7 @@ rb_eql(obj1, obj2)
return rb_funcall(obj1, eql, 1, obj2); return rb_funcall(obj1, eql, 1, obj2);
} }
VALUE static VALUE
rb_obj_equal(obj1, obj2) rb_obj_equal(obj1, obj2)
VALUE obj1, obj2; VALUE obj1, obj2;
{ {
@ -598,13 +598,6 @@ rb_class_s_inherited()
rb_raise(rb_eTypeError, "can't make subclass of Class"); rb_raise(rb_eTypeError, "can't make subclass of Class");
} }
VALUE rb_mod_name();
VALUE rb_mod_included_modules();
VALUE rb_mod_ancestors();
VALUE rb_class_instance_methods();
VALUE rb_class_protected_instance_methods();
VALUE rb_class_private_instance_methods();
static VALUE static VALUE
rb_class_superclass(klass) rb_class_superclass(klass)
VALUE klass; VALUE klass;
@ -624,11 +617,16 @@ ID
rb_to_id(name) rb_to_id(name)
VALUE name; VALUE name;
{ {
ID id;
if (TYPE(name) == T_STRING) { if (TYPE(name) == T_STRING) {
return rb_intern(RSTRING(name)->ptr); return rb_intern(RSTRING(name)->ptr);
} }
Check_Type(name, T_FIXNUM); id = NUM2UINT(name);
return FIX2UINT(name); if (!rb_id2name(id)) {
rb_raise(rb_eArgError, "%d is not a symbol", id);
}
return id;
} }
static VALUE static VALUE
@ -686,8 +684,6 @@ rb_mod_attr_accessor(argc, argv, klass)
return Qnil; return Qnil;
} }
VALUE rb_mod_constants();
static VALUE static VALUE
rb_mod_const_get(mod, name) rb_mod_const_get(mod, name)
VALUE mod, name; VALUE mod, name;
@ -935,6 +931,7 @@ Init_Object()
rb_mKernel = rb_define_module("Kernel"); rb_mKernel = rb_define_module("Kernel");
rb_include_module(rb_cObject, rb_mKernel); rb_include_module(rb_cObject, rb_mKernel);
rb_define_private_method(rb_cObject, "initialize", rb_obj_dummy, -1);
rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1); rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1);
/* /*
@ -1022,7 +1019,6 @@ Init_Object()
rb_define_method(rb_cNilClass, "+", nil_plus, 1); rb_define_method(rb_cNilClass, "+", nil_plus, 1);
#endif #endif
rb_define_global_function("initialize", rb_obj_dummy, -1);
rb_define_global_function("singleton_method_added", rb_obj_dummy, 1); rb_define_global_function("singleton_method_added", rb_obj_dummy, 1);
rb_define_method(rb_cModule, "===", rb_mod_eqq, 1); rb_define_method(rb_cModule, "===", rb_mod_eqq, 1);

157
pack.c
View file

@ -77,6 +77,7 @@ endian()
static char *toofew = "too few arguments"; static char *toofew = "too few arguments";
static void encodes _((VALUE,char*,int,int)); static void encodes _((VALUE,char*,int,int));
static void qpencode _((VALUE,VALUE,int));
static void static void
pack_add_ptr(str, add) pack_add_ptr(str, add)
@ -104,7 +105,7 @@ pack_pack(ary, fmt)
int plen; int plen;
p = str2cstr(fmt, &plen); p = rb_str2cstr(fmt, &plen);
pend = p + plen; pend = p + plen;
res = rb_str_new(0, 0); res = rb_str_new(0, 0);
@ -469,6 +470,13 @@ pack_pack(ary, fmt)
} }
break; break;
case 'M':
from = rb_obj_as_string(NEXTFROM);
if (len <= 1)
len = 72;
qpencode(res, from, len);
break;
case 'P': case 'P':
len = 1; len = 1;
/* FALL THROUGH */ /* FALL THROUGH */
@ -505,38 +513,121 @@ encodes(str, s, len, type)
int len; int len;
int type; int type;
{ {
char hunk[4]; char *buff = ALLOCA_N(char, len * 4 / 3 + 6);
int i = 0;
char *p, *pend; char *p, *pend;
char *trans = type == 'u' ? uu_table : b64_table; char *trans = type == 'u' ? uu_table : b64_table;
int padding; int padding;
if (type == 'u') { if (type == 'u') {
*hunk = len + ' '; buff[i++] = len + ' ';
rb_str_cat(str, hunk, 1);
padding = '`'; padding = '`';
} }
else { else {
padding = '='; padding = '=';
} }
while (len > 0) { while (len >= 3) {
hunk[0] = trans[077 & (*s >> 2)]; buff[i++] = trans[077 & (*s >> 2)];
hunk[1] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
hunk[2] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))]; buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
hunk[3] = trans[077 & s[2]]; buff[i++] = trans[077 & s[2]];
rb_str_cat(str, hunk, 4);
s += 3; s += 3;
len -= 3; len -= 3;
} }
p = RSTRING(str)->ptr; if (len == 2) {
pend = RSTRING(str)->ptr + RSTRING(str)->len; buff[i++] = trans[077 & (*s >> 2)];
if (len == -1) { buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
pend[-1] = padding; buff[i++] = trans[077 & (((s[1] << 2) & 074) | (('\0' >> 6) & 03))];
buff[i++] = padding;
} }
else if (len == -2) { else if (len == 1) {
pend[-2] = padding; buff[i++] = trans[077 & (*s >> 2)];
pend[-1] = padding; buff[i++] = trans[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))];
buff[i++] = padding;
buff[i++] = padding;
}
buff[i++] = '\n';
rb_str_cat(str, buff, i);
}
static char hex_table[] = "0123456789ABCDEF";
static void
qpencode(str, from, len)
VALUE str, from;
int len;
{
char buff[1024];
int i = 0, n = 0, prev = EOF;
unsigned char *s = RSTRING(from)->ptr;
unsigned char *send = s + RSTRING(from)->len;
while (s < send) {
if ((*s > 126) ||
(*s < 32 && *s != '\n' && *s != '\t') ||
(*s == '=')) {
buff[i++] = '=';
buff[i++] = hex_table[*s >> 4];
buff[i++] = hex_table[*s & 0x0f];
n += 3;
prev = EOF;
}
else if (*s == '\n') {
if (prev == ' ' || prev == '\t') {
buff[i++] = '=';
buff[i++] = *s;
}
buff[i++] = *s;
n = 0;
prev = *s;
}
else {
buff[i++] = *s;
n++;
prev = *s;
}
if (n > len) {
buff[i++] = '=';
buff[i++] = '\n';
n = 0;
prev = '\n';
}
if (i > 1024 - 5) {
rb_str_cat(str, buff, i);
i = 0;
}
s++;
}
if (n > 0) {
buff[i++] = '=';
buff[i++] = '\n';
}
if (i > 0) {
rb_str_cat(str, buff, i);
}
}
#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(RUBY_NO_INLINE)
static __inline__ int
#else
static int
#endif
hex2num(c)
char c;
{
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return c - '0';
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f':
return c - 'a' + 10;
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F':
return c - 'A' + 10;
default:
return -1;
} }
rb_str_cat(str, "\n", 1);
} }
static VALUE static VALUE
@ -550,9 +641,9 @@ pack_unpack(str, fmt)
char type; char type;
int len; int len;
s = str2cstr(str, &len); s = rb_str2cstr(str, &len);
send = s + len; send = s + len;
p = str2cstr(fmt, &len); p = rb_str2cstr(fmt, &len);
pend = p + len; pend = p + len;
ary = rb_ary_new(); ary = rb_ary_new();
@ -929,6 +1020,32 @@ pack_unpack(str, fmt)
} }
break; break;
case 'M':
{
VALUE str = rb_str_new(0, send - s);
char *ptr = RSTRING(str)->ptr;
int c1, c2;
while (s < send) {
if (*s == '=') {
if (++s == send) break;
if (*s != '\n' && s < send - 1) {
if ((c1 = hex2num(*s)) == -1) break;
if (++s == send) break;
if ((c2 = hex2num(*s)) == -1) break;
*ptr++ = c1 << 4 | c2;
}
}
else {
*ptr++ = *s;
}
s++;
}
RSTRING(str)->len = ptr - RSTRING(str)->ptr;
rb_ary_push(ary, str);
}
break;
case '@': case '@':
s = RSTRING(str)->ptr + len; s = RSTRING(str)->ptr + len;
break; break;

48
parse.y
View file

@ -1150,7 +1150,7 @@ primary : literal
local_pop(); local_pop();
cur_mid = 0; cur_mid = 0;
} }
| kDEF singleton '.' {lex_state = EXPR_FNAME;} fname | kDEF singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
{ {
value_expr($2); value_expr($2);
in_single++; in_single++;
@ -1284,6 +1284,7 @@ method_call : operation '(' opt_call_args ')'
{ {
value_expr($1); value_expr($1);
$$ = new_call($1, $3, 0); $$ = new_call($1, $3, 0);
fixpos($$, $1);
} }
| primary tCOLON2 operation '(' opt_call_args ')' | primary tCOLON2 operation '(' opt_call_args ')'
{ {
@ -1557,6 +1558,9 @@ operation : tIDENTIFIER
| tCONSTANT | tCONSTANT
| tFID | tFID
dot_or_colon : '.'
| tCOLON2
opt_terms : /* none */ opt_terms : /* none */
| terms | terms
@ -1723,6 +1727,20 @@ rb_compile_file(f, file, start)
return yycompile(strdup(f)); return yycompile(strdup(f));
} }
static void
normalize_newline(line)
VALUE line;
{
if (RSTRING(line)->len >= 2 &&
RSTRING(line)->ptr[RSTRING(line)->len-1] == '\n' &&
RSTRING(line)->ptr[RSTRING(line)->len-2] == '\r')
{
RSTRING(line)->ptr[RSTRING(line)->len-2] = '\n';
RSTRING(line)->len--;
}
}
static int static int
nextc() nextc()
{ {
@ -1737,19 +1755,20 @@ nextc()
ruby_sourceline = heredoc_end+1; ruby_sourceline = heredoc_end+1;
heredoc_end = 0; heredoc_end = 0;
} }
normalize_newline(v);
while (RSTRING(v)->len >= 2 && while (RSTRING(v)->len >= 2 &&
RSTRING(v)->ptr[RSTRING(v)->len-1] == '\n' && RSTRING(v)->ptr[RSTRING(v)->len-1] == '\n' &&
RSTRING(v)->ptr[RSTRING(v)->len-2] == '\\') { RSTRING(v)->ptr[RSTRING(v)->len-2] == '\\') {
VALUE v2 = (*lex_gets)(lex_input); VALUE v2 = (*lex_gets)(lex_input);
if (!NIL_P(v2)) { if (!NIL_P(v2)) {
normalize_newline(v2);
rb_str_cat(v, RSTRING(v2)->ptr, RSTRING(v2)->len); 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 (RSTRING(v)->len == 8 && if (strncmp(lex_pbeg, "__END__", 7) == 0 && lex_pbeg[7] == '\n') {
strncmp(lex_pbeg, "__END__", 7) == 0) {
lex_lastline = 0; lex_lastline = 0;
return -1; return -1;
} }
@ -2220,11 +2239,12 @@ parse_quotedword(term, paren)
char *strdup(); char *strdup();
static int static int
here_document(term) here_document(term, indent)
char term; char term;
int indent;
{ {
int c; int c;
char *eos; char *eos, *p;
int len; int len;
VALUE str, line; VALUE str, line;
char *save_beg, *save_end, *save_lexp; char *save_beg, *save_end, *save_lexp;
@ -2273,10 +2293,15 @@ here_document(term)
free(eos); free(eos);
return 0; return 0;
} }
normalize_newline(line);
ruby_sourceline++; ruby_sourceline++;
if (strncmp(eos, RSTRING(line)->ptr, len) == 0 && p = RSTRING(line)->ptr;
(RSTRING(line)->ptr[len] == '\n' || if (indent) {
RSTRING(line)->ptr[len] == '\r')) { while (*p && (*p == ' ' || *p == '\t')) {
p++;
}
}
if (strncmp(eos, p, len) == 0 && p[len] == '\n') {
break; break;
} }
@ -2486,8 +2511,13 @@ retry:
lex_state != EXPR_END && lex_state != EXPR_CLASS && lex_state != EXPR_END && lex_state != EXPR_CLASS &&
(lex_state != EXPR_ARG || space_seen)) { (lex_state != EXPR_ARG || space_seen)) {
int c2 = nextc(); int c2 = nextc();
int indent = 0;
if (c2 == '-') {
indent = 1;
c2 = nextc();
}
if (!ISSPACE(c2) && (strchr("\"'`", c2) || is_identchar(c2))) { if (!ISSPACE(c2) && (strchr("\"'`", c2) || is_identchar(c2))) {
return here_document(c2); return here_document(c2, indent);
} }
pushback(c2); pushback(c2);
} }

View file

@ -212,28 +212,9 @@ rb_f_waitpid(obj, vpid, vflags)
char *strtok(); char *strtok();
#if defined(USE_THREAD) && defined(HAVE_SETITIMER) #if defined(THREAD) && defined(HAVE_SETITIMER)
static void #define before_exec() thread_stop_timer()
before_exec() #define after_exec() thread_start_timer()
{
struct itimerval tval;
tval.it_interval.tv_sec = 0;
tval.it_interval.tv_usec = 0;
tval.it_value = tval.it_interval;
setitimer(ITIMER_VIRTUAL, &tval, NULL);
}
static void
after_exec()
{
struct itimerval tval;
tval.it_interval.tv_sec = 0;
tval.it_interval.tv_usec = 100000;
tval.it_value = tval.it_interval;
setitimer(ITIMER_VIRTUAL, &tval, NULL);
}
#else #else
#define before_exec() #define before_exec()
#define after_exec() #define after_exec()
@ -503,6 +484,9 @@ rb_f_exec(argc, argv)
VALUE prog = 0; VALUE prog = 0;
int i; int i;
if (argc == 0) {
rb_raise(rb_eArgError, "wrong # of arguments");
}
if (TYPE(argv[0]) == T_ARRAY) { if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) { if (RARRAY(argv[0])->len != 2) {
rb_raise(rb_eArgError, "wrong first argument"); rb_raise(rb_eArgError, "wrong first argument");
@ -834,6 +818,20 @@ proc_setpgrp(argc, argv)
#endif #endif
} }
static VALUE
proc_getpgid(obj, pid)
VALUE obj, pid;
{
#ifdef HAVE_GETPGID
int i;
i = getpgid(NUM2INT(pid));
return INT2NUM(i);
#else
rb_notimplement();
#endif
}
static VALUE static VALUE
proc_setpgid(obj, pid, pgrp) proc_setpgid(obj, pid, pgrp)
VALUE obj, pid, pgrp; VALUE obj, pid, pgrp;
@ -1085,7 +1083,7 @@ Init_process()
rb_define_module_function(rb_mProcess, "getpriority", proc_getpriority, 2); rb_define_module_function(rb_mProcess, "getpriority", proc_getpriority, 2);
rb_define_module_function(rb_mProcess, "setpriority", proc_setpriority, 3); rb_define_module_function(rb_mProcess, "setpriority", proc_setpriority, 3);
#ifdef PRIO_PROCESS #ifdef HAVE_GETPRIORITY
rb_define_const(rb_mProcess, "PRIO_PROCESS", INT2FIX(PRIO_PROCESS)); rb_define_const(rb_mProcess, "PRIO_PROCESS", INT2FIX(PRIO_PROCESS));
rb_define_const(rb_mProcess, "PRIO_PGRP", INT2FIX(PRIO_PGRP)); rb_define_const(rb_mProcess, "PRIO_PGRP", INT2FIX(PRIO_PGRP));
rb_define_const(rb_mProcess, "PRIO_USER", INT2FIX(PRIO_USER)); rb_define_const(rb_mProcess, "PRIO_USER", INT2FIX(PRIO_USER));

1
re.h
View file

@ -3,7 +3,6 @@
re.h - re.h -
$Author$ $Author$
$Revision$
$Date$ $Date$
created at: Thu Sep 30 14:18:32 JST 1993 created at: Thu Sep 30 14:18:32 JST 1993

View file

@ -2812,6 +2812,7 @@ re_search(bufp, string, size, startpos, range, regs)
} }
} }
if (startpos > size) return -1;
if (fastmap && startpos == size && range >= 0 if (fastmap && startpos == size && range >= 0
&& (bufp->can_be_null == 0 || && (bufp->can_be_null == 0 ||
(bufp->can_be_null && size > 0 (bufp->can_be_null && size > 0

22
ruby.c
View file

@ -20,6 +20,10 @@
#include <fcntl.h> #include <fcntl.h>
#include <ctype.h> #include <ctype.h>
#ifdef __hpux
#include <sys/pstat.h>
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -607,6 +611,7 @@ set_arg0(val, id)
static int len; static int len;
if (origargv == 0) rb_raise(rb_eRuntimeError, "$0 not initialized"); if (origargv == 0) rb_raise(rb_eRuntimeError, "$0 not initialized");
#ifndef __hpux
if (len == 0) { if (len == 0) {
s = origargv[0]; s = origargv[0];
s += strlen(s); s += strlen(s);
@ -617,7 +622,9 @@ set_arg0(val, id)
} }
len = s - origargv[0]; len = s - origargv[0];
} }
#endif
s = str2cstr(val, &i); s = str2cstr(val, &i);
#ifndef __hpux
if (i > len) { if (i > len) {
memcpy(origargv[0], s, len); memcpy(origargv[0], s, len);
origargv[0][len] = '\0'; origargv[0][len] = '\0';
@ -630,6 +637,21 @@ set_arg0(val, id)
*s++ = ' '; *s++ = ' ';
} }
rb_progname = rb_tainted_str_new2(origargv[0]); rb_progname = rb_tainted_str_new2(origargv[0]);
#else
if (i >= PST_CLEN) {
union pstun j;
j.pst_command = s;
i = PST_CLEN;
RSTRING(val)->len = i;
*(s + i) = '\0';
pstat(PSTAT_SETCMD, j, PST_CLEN, 0, 0);
} else {
union pstun j;
j.pst_command = s;
pstat(PSTAT_SETCMD, j, i, 0, 0);
}
rb_progname = str_taint(str_new(s, i));
#endif
} }
void void

16
ruby.h
View file

@ -163,11 +163,11 @@ VALUE rb_int2inum _((long));
#define T_DATA 0x22 #define T_DATA 0x22
#define T_MATCH 0x23 #define T_MATCH 0x23
#define T_VARMAP 0xfd #define T_VARMAP 0x7d
#define T_SCOPE 0xfe #define T_SCOPE 0x7e
#define T_NODE 0xff #define T_NODE 0x7f
#define T_MASK 0xff #define T_MASK 0x7f
#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK) #define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
@ -271,6 +271,7 @@ struct RHash {
struct RFile { struct RFile {
struct RBasic basic; struct RBasic basic;
struct st_table *iv_tbl;
struct OpenFile *fptr; struct OpenFile *fptr;
}; };
@ -329,9 +330,10 @@ struct RBignum {
#define RFILE(obj) (R_CAST(RFile)(obj)) #define RFILE(obj) (R_CAST(RFile)(obj))
#define FL_SINGLETON FL_USER0 #define FL_SINGLETON FL_USER0
#define FL_MARK (1<<8) #define FL_MARK (1<<7)
#define FL_FINALIZE (1<<9) #define FL_FINALIZE (1<<8)
#define FL_TAINT (1<<10) #define FL_TAINT (1<<9)
#define FL_EXIVAR (1<<10)
#define FL_USHIFT 11 #define FL_USHIFT 11

View file

@ -45,6 +45,7 @@ typedef struct OpenFile {
fp->finalize = 0;\ fp->finalize = 0;\
} while (0) } while (0)
#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 _((char *, char *));

View file

@ -1,7 +1,7 @@
#! /usr/local/bin/ruby #! /usr/local/bin/ruby
# cal.rb (bsd compatible version): Written by Tadayoshi Funaba 1998 # cal.rb (bsd compatible version): Written by Tadayoshi Funaba 1998
# $Id: bsdcal.rb,v 1.1 1998/06/01 12:53:01 tadf Exp $ # $Id: bsdcal.rb,v 1.2 1998/12/01 13:47:40 tadf Exp $
require 'date2' require 'date2'
@ -59,7 +59,7 @@ def zip(xs)
until xs.empty? until xs.empty?
ln = (if $jd then l, r, *xs = xs; [l, r] ln = (if $jd then l, r, *xs = xs; [l, r]
else l, c, r, *xs = xs; [l, c, r] end). else l, c, r, *xs = xs; [l, c, r] end).
collect{|x| x.split(/\n/no)} collect{|x| x.split(/\n/no, -1)}
8.times do 8.times do
yr << ln.collect{|x| yr << ln.collect{|x|
x.shift.ljust((($w + 1) * 7) - 1)}.join(' ') << "\n" x.shift.ljust((($w + 1) * 7) - 1)}.join(' ') << "\n"

9
st.c
View file

@ -66,10 +66,9 @@ static void rehash();
#define MINSIZE 8 #define MINSIZE 8
/* /*
Table of irreducible polynomials to efficiently cycle through Table of prime numbers 2^n+a, 2<=n<=30.
GF(2^n)-{0}, 2<=n<=30.
*/ */
static long polys[] = { static long primes[] = {
8 + 3, 8 + 3,
16 + 3, 16 + 3,
32 + 5, 32 + 5,
@ -108,10 +107,10 @@ new_size(size)
int i, newsize; int i, newsize;
for (i = 0, newsize = MINSIZE; for (i = 0, newsize = MINSIZE;
i < sizeof(polys)/sizeof(polys[0]); i < sizeof(primes)/sizeof(primes[0]);
i++, newsize <<= 1) i++, newsize <<= 1)
{ {
if (newsize > size) return polys[i]; if (newsize > size) return primes[i];
} }
/* Ran out of polynomials */ /* Ran out of polynomials */
return -1; /* should raise exception */ return -1; /* should raise exception */

View file

@ -1345,7 +1345,7 @@ rb_str_inspect(str)
CHECK(1); CHECK(1);
*b++ = c; *b++ = c;
} }
else if (c == '"' || c == '\''|| c == '\\') { else if (c == '"'|| c == '\\') {
CHECK(2); CHECK(2);
*b++ = '\\'; *b++ = '\\';
*b++ = c; *b++ = c;
@ -1414,7 +1414,7 @@ rb_str_dump(str)
while (p < pend) { while (p < pend) {
char c = *p++; char c = *p++;
switch (c) { switch (c) {
case '"': case '\'': case '\\': case '"': case '\\':
case '\n': case '\r': case '\n': case '\r':
case '\t': case '\f': case '\t': case '\f':
case '\013': case '\007': case '\033': case '\013': case '\007': case '\033':
@ -1440,7 +1440,7 @@ rb_str_dump(str)
while (p < pend) { while (p < pend) {
char c = *p++; char c = *p++;
if (c == '"' || c == '\'' || c == '\\') { if (c == '"' || c == '\\') {
*q++ = '\\'; *q++ = '\\';
*q++ = c; *q++ = c;
} }

View file

@ -33,7 +33,7 @@ s%@AR@%ar%g
s%@INSTALL_PROGRAM@%${INSTALL}%g s%@INSTALL_PROGRAM@%${INSTALL}%g
s%@INSTALL_DATA@%${INSTALL} -m 644%g s%@INSTALL_DATA@%${INSTALL} -m 644%g
s%@SET_MAKE@%%g s%@SET_MAKE@%%g
s%@LIBOBJS@% crypt.o flock.o snprintf.o%g s%@LIBOBJS@% crypt.o flock.o vsnprintf.o%g
s%@ALLOCA@%%g s%@ALLOCA@%%g
s%@DLDFLAGS@%%g s%@DLDFLAGS@%%g
s%@STATIC@%%g s%@STATIC@%%g

View file

@ -129,7 +129,7 @@ classname(klass)
path = rb_ivar_get(klass, classid); path = rb_ivar_get(klass, classid);
if (!NIL_P(path)) { if (!NIL_P(path)) {
path = rb_str_new2(rb_id2name(FIX2INT(path))); path = rb_str_new2(rb_id2name(FIX2INT(path)));
rb_ivar_set(klass, classid, path); rb_ivar_set(klass, rb_intern("__classpath__"), path);
st_delete(RCLASS(klass)->iv_tbl, &classid, 0); st_delete(RCLASS(klass)->iv_tbl, &classid, 0);
} }
} }
@ -205,12 +205,7 @@ rb_name_class(klass, id)
VALUE klass; VALUE klass;
ID id; ID id;
{ {
if (rb_cString) { rb_iv_set(klass, "__classid__", INT2FIX(id));
rb_iv_set(klass, "__classpath__", rb_str_new2(rb_id2name(id)));
}
else {
rb_iv_set(klass, "__classid__", INT2FIX(id));
}
} }
static st_table *autoload_tbl = 0; static st_table *autoload_tbl = 0;
@ -690,6 +685,133 @@ rb_alias_variable(name1, name2)
entry1->marker = entry2->marker; entry1->marker = entry2->marker;
} }
static int special_generic_ivar = 0;
static st_table *generic_iv_tbl;
static VALUE
generic_ivar_get(obj, id)
VALUE obj;
ID id;
{
st_table *tbl;
VALUE val;
if (!generic_iv_tbl) return Qnil;
if (!st_lookup(generic_iv_tbl, obj, &tbl)) return Qnil;
if (st_lookup(tbl, id, &val)) {
return val;
}
return Qnil;
}
static void
generic_ivar_set(obj, id, val)
VALUE obj;
ID id;
VALUE val;
{
st_table *tbl;
if (rb_special_const_p(obj)) {
special_generic_ivar = 1;
}
if (!generic_iv_tbl) {
generic_iv_tbl = st_init_numtable();
}
if (!st_lookup(generic_iv_tbl, obj, &tbl)) {
FL_SET(obj, FL_EXIVAR);
tbl = st_init_numtable();
st_add_direct(generic_iv_tbl, obj, tbl);
st_add_direct(tbl, id, val);
return;
}
st_insert(tbl, id, val);
}
static VALUE
generic_ivar_defined(obj, id)
VALUE obj;
ID id;
{
st_table *tbl;
VALUE val;
if (!generic_iv_tbl) return Qfalse;
if (!st_lookup(generic_iv_tbl, obj, &tbl)) return Qfalse;
if (st_lookup(tbl, id, &val)) {
return Qtrue;
}
return Qfalse;
}
static VALUE
generic_ivar_remove(obj, id)
VALUE obj;
ID id;
{
st_table *tbl;
VALUE val;
if (!generic_iv_tbl) return Qnil;
if (!st_lookup(generic_iv_tbl, obj, &tbl)) return Qnil;
st_delete(tbl, &id, &val);
if (tbl->num_entries == 0) {
st_delete(generic_iv_tbl, &obj, &tbl);
st_free_table(tbl);
}
return val;
}
static int
givar_mark_i(key, value)
ID key;
VALUE value;
{
rb_gc_mark(value);
return ST_CONTINUE;
}
void
rb_mark_generic_ivar(obj)
VALUE obj;
{
st_table *tbl;
if (st_lookup(generic_iv_tbl, obj, &tbl)) {
st_foreach(tbl, givar_mark_i, 0);
}
}
static int
givar_i(obj, tbl)
VALUE obj;
st_table *tbl;
{
if (rb_special_const_p(obj)) {
st_foreach(tbl, givar_mark_i, 0);
}
return ST_CONTINUE;
}
void
rb_mark_generic_ivar_tbl()
{
if (special_generic_ivar == 0) return;
if (!generic_iv_tbl) return;
st_foreach(generic_iv_tbl, givar_i, 0);
}
void
rb_free_generic_ivar(obj)
VALUE obj;
{
st_table *tbl;
if (st_delete(generic_iv_tbl, &obj, &tbl))
st_free_table(tbl);
}
VALUE VALUE
rb_ivar_get(obj, id) rb_ivar_get(obj, id)
VALUE obj; VALUE obj;
@ -701,12 +823,13 @@ rb_ivar_get(obj, id)
case T_OBJECT: case T_OBJECT:
case T_CLASS: case T_CLASS:
case T_MODULE: case T_MODULE:
case T_FILE:
if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, &val)) if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, &val))
return val; return val;
return Qnil; break;
default: default:
rb_raise(rb_eTypeError, "class %s can not have instance variables", if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
rb_class2name(CLASS_OF(obj))); return generic_ivar_get(obj, id);
break; break;
} }
if (rb_verbose) { if (rb_verbose) {
@ -725,14 +848,14 @@ rb_ivar_set(obj, id, val)
case T_OBJECT: case T_OBJECT:
case T_CLASS: case T_CLASS:
case T_MODULE: case T_MODULE:
case T_FILE:
if (rb_safe_level() >= 4 && !FL_TEST(obj, FL_TAINT)) if (rb_safe_level() >= 4 && !FL_TEST(obj, FL_TAINT))
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable"); rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable(); if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable();
st_insert(ROBJECT(obj)->iv_tbl, id, val); st_insert(ROBJECT(obj)->iv_tbl, id, val);
break; break;
default: default:
rb_raise(rb_eTypeError, "class %s can not have instance variables", generic_ivar_set(obj, id, val);
rb_class2name(CLASS_OF(obj)));
break; break;
} }
return val; return val;
@ -749,9 +872,14 @@ rb_ivar_defined(obj, id)
case T_OBJECT: case T_OBJECT:
case T_CLASS: case T_CLASS:
case T_MODULE: case T_MODULE:
case T_FILE:
if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, 0)) if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, 0))
return Qtrue; return Qtrue;
break; break;
default:
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
return generic_ivar_defined(obj, id);
break;
} }
return Qfalse; return Qfalse;
} }
@ -778,11 +906,22 @@ rb_obj_instance_variables(obj)
case T_OBJECT: case T_OBJECT:
case T_CLASS: case T_CLASS:
case T_MODULE: case T_MODULE:
case T_FILE:
ary = rb_ary_new(); ary = rb_ary_new();
if (ROBJECT(obj)->iv_tbl) { if (ROBJECT(obj)->iv_tbl) {
st_foreach(ROBJECT(obj)->iv_tbl, ivar_i, ary); st_foreach(ROBJECT(obj)->iv_tbl, ivar_i, ary);
} }
return ary; return ary;
default:
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
st_table *tbl;
if (st_lookup(generic_iv_tbl, obj, &tbl)) {
ary = rb_ary_new();
st_foreach(tbl, ivar_i, ary);
return ary;
}
}
} }
return Qnil; return Qnil;
} }
@ -803,13 +942,14 @@ rb_obj_remove_instance_variable(obj, name)
case T_OBJECT: case T_OBJECT:
case T_CLASS: case T_CLASS:
case T_MODULE: case T_MODULE:
case T_FILE:
if (ROBJECT(obj)->iv_tbl) { if (ROBJECT(obj)->iv_tbl) {
st_delete(ROBJECT(obj)->iv_tbl, &id, &val); st_delete(ROBJECT(obj)->iv_tbl, &id, &val);
} }
break; break;
default: default:
rb_raise(rb_eTypeError, "object %s can not have instance variables", if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
rb_class2name(CLASS_OF(obj))); return generic_ivar_remove(obj, id);
break; break;
} }
return val; return val;

View file

@ -1,2 +1,2 @@
#define RUBY_VERSION "1.1d0" #define RUBY_VERSION "1.1d0"
#define VERSION_DATE "98/09/08" #define VERSION_DATE "98/12/16"