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:
parent
ce8859c556
commit
e299d511db
44 changed files with 907 additions and 466 deletions
81
ChangeLog
81
ChangeLog
|
@ -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.
|
||||||
|
|
9
MANIFEST
9
MANIFEST
|
@ -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
|
||||||
|
|
319
README.EXT
319
README.EXT
|
@ -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
|
||||||
|
|
||||||
4.Example - Create dbm module
|
4.Example - 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:
|
||||||
|
|
|
@ -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 定数定義』で紹介さ
|
||||||
れている関数を使ってください.
|
れている関数を使ってください.
|
||||||
|
|
||||||
3.RubyとCとの情報共有
|
3.Rubyと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
39
ToDo
|
@ -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
15
config.guess
vendored
|
@ -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
|
||||||
|
|
40
configure.in
40
configure.in
|
@ -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
17
dln.c
|
@ -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
4
enum.c
|
@ -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
10
error.c
|
@ -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
115
eval.c
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
16
gc.c
|
@ -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
8
hash.c
|
@ -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;
|
||||||
|
|
||||||
|
|
12
intern.h
12
intern.h
|
@ -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
2
io.c
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
10
lib/mkmf.rb
10
lib/mkmf.rb
|
@ -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"
|
||||||
|
|
|
@ -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
5
misc/README
Normal 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
|
|
@ -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
|
||||||
;;;
|
;;;
|
|
@ -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
|
17
missing/nt.c
17
missing/nt.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
22
object.c
22
object.c
|
@ -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
157
pack.c
|
@ -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
48
parse.y
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
44
process.c
44
process.c
|
@ -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
1
re.h
|
@ -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
|
||||||
|
|
||||||
|
|
1
regex.c
1
regex.c
|
@ -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
22
ruby.c
|
@ -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
16
ruby.h
|
@ -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
|
||||||
|
|
||||||
|
|
1
rubyio.h
1
rubyio.h
|
@ -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 *));
|
||||||
|
|
|
@ -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
9
st.c
|
@ -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 */
|
||||||
|
|
6
string.c
6
string.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
2
top.sed
2
top.sed
|
@ -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
|
||||||
|
|
168
variable.c
168
variable.c
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue