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>
|
||||
|
||||
* 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).
|
||||
|
||||
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>
|
||||
|
||||
* 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.
|
||||
|
||||
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>
|
||||
|
||||
* class.c (rb_define_global_function): global functions now be
|
||||
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>
|
||||
|
||||
* version 1.1c8 released.
|
||||
|
|
9
MANIFEST
9
MANIFEST
|
@ -131,6 +131,11 @@ lib/thwait.rb
|
|||
lib/timeout.rb
|
||||
lib/tracer.rb
|
||||
lib/weakref.rb
|
||||
misc/README
|
||||
misc/inf-ruby.el
|
||||
misc/ruby-mode.el
|
||||
misc/rubydb2x.el
|
||||
mics/rubydb3x.el
|
||||
missing/alloca.c
|
||||
missing/crypt.c
|
||||
missing/dir.h
|
||||
|
@ -174,7 +179,6 @@ sample/from.rb
|
|||
sample/fullpath.rb
|
||||
sample/getopts.test
|
||||
sample/goodfriday.rb
|
||||
sample/inf-ruby.el
|
||||
sample/less.rb
|
||||
sample/list.rb
|
||||
sample/list2.rb
|
||||
|
@ -194,9 +198,6 @@ sample/rcs.awk
|
|||
sample/rcs.dat
|
||||
sample/rcs.rb
|
||||
sample/regx.rb
|
||||
sample/ruby-mode.el
|
||||
sample/rubydb2x.el
|
||||
sample/rubydb3x.el
|
||||
sample/sieve.rb
|
||||
sample/svr.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
|
||||
|
||||
データタイプがT_NIL, T_FALSE, T_TRUEである時,データはそれぞ
|
||||
れnil, false, trueです.このデータタイプのオブジェクトはひと
|
||||
つずつしか存在しません.
|
||||
The data for type T_NIL, T_FALSE, T_TRUE are nil, true, false
|
||||
respectively. They are singletons for the data type.
|
||||
|
||||
データタイプがT_FIXNUMの時,これは31bitのサイズを持つ整数で
|
||||
す.FIXNUMをCの整数に変換するためにはマクロ「FIX2INT()」を使
|
||||
います.それから,FIXNUMに限らずRubyのデータを整数に変換する
|
||||
「NUM2INT()」というマクロがあります.このマクロはデータタイ
|
||||
プのチェック無しで使えます(整数に変換できない場合には例外が
|
||||
発生する).
|
||||
The T_FIXNUM data is the 31bit length fixed integer (63bit length on
|
||||
some machines), which can be conver to the C integer by using
|
||||
FIX2INT() macro. There also be NUM2INT() which converts any Ruby
|
||||
numbers into C integer. The NUM2INT() macro includes type check, so
|
||||
the exception will be raised if conversion failed.
|
||||
|
||||
それ以外のデータタイプは対応するCの構造体があります.対応す
|
||||
る構造体のあるVALUEはそのままキャスト(型変換)すれば構造体の
|
||||
ポインタに変換できます.
|
||||
Other data types have corresponding C structures, e.g. struct RArray
|
||||
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で定義されていま
|
||||
す.例えば文字列は「struct RString」です.実際に使う可能性が
|
||||
あるのは文字列と配列くらいだと思います.
|
||||
For example, `RSTRING(size)->len' is the way to get the size of the
|
||||
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()」(全部大文
|
||||
字にしたもの)という名前で提供されています(例: RSTRING()).
|
||||
|
||||
例えば,文字列strの長さを得るためには「RSTRING(str)->len」と
|
||||
し,文字列strをchar*として得るためには「RSTRING(str)->ptr」
|
||||
とします.配列の場合には,それぞれ「RARRAT(str)->len」,
|
||||
「RARRAT(str)->ptr」となります.
|
||||
|
||||
Rubyの構造体を直接アクセスする時に気をつけなければならないこ
|
||||
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
|
||||
ないことです.直接変更した場合,オブジェクトの内容の整合性が
|
||||
とれなくなって,思わぬバグの原因になります.
|
||||
Notice: Do not change the value of the structure directly, unless you
|
||||
are responsible about the result. It will be the cause of interesting
|
||||
bugs.
|
||||
|
||||
1.4 Convert C data into VALUE
|
||||
|
||||
|
@ -150,12 +141,9 @@ INT2NUM()
|
|||
|
||||
1.5 Manipulate Ruby data
|
||||
|
||||
先程も述べた通り,Rubyの構造体をアクセスする時に内容の更新を
|
||||
行うことは勧められません.で,Rubyのデータを操作する時には
|
||||
Rubyが用意している関数を用いてください.
|
||||
|
||||
ここではもっとも使われるであろう文字列と配列の生成/操作を行
|
||||
い関数をあげます(全部ではないです).
|
||||
As I already told, it is not recommended to modify object's internal
|
||||
structure. To manipulate objects, use functions supplied by Ruby
|
||||
interpreter. Useful functions are listed below (not all):
|
||||
|
||||
String funtions
|
||||
|
||||
|
@ -213,160 +201,148 @@ Ruby
|
|||
を追加することができます.Rubyでは以下の機能を追加する関数が
|
||||
提供されています.
|
||||
|
||||
* クラス,モジュール
|
||||
* メソッド,特異メソッドなど
|
||||
* 定数
|
||||
* Classes, Modules
|
||||
* Methods, Singleton Methods
|
||||
* Constants
|
||||
|
||||
では順に紹介します.
|
||||
|
||||
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_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
|
||||
|
||||
メソッドや特異メソッドを定義するには以下の関数を使います.
|
||||
To define methods or singleton methods, use functions below:
|
||||
|
||||
void rb_define_method(VALUE class, char *name,
|
||||
VALUE (*func)(), int argc)
|
||||
|
||||
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. :-)
|
||||
|
||||
念のため説明すると「特異メソッド」とは,その特定のオブジェク
|
||||
トに対してだけ有効なメソッドです.RubyではよくSmalltalkにお
|
||||
けるクラスメソッドとして,クラスに対する特異メソッドが使われ
|
||||
ます.
|
||||
If `argc' is negative, it specifies calling sequence, not number of
|
||||
the arguments.
|
||||
|
||||
これらの関数の argcという引数はCの関数へ渡される引数の数(と
|
||||
形式)を決めます.argcが正の時は関数に引き渡す引数の数を意味
|
||||
します.16個以上の引数は使えません(が,要りませんよね,そん
|
||||
なに).
|
||||
If argc is -1, the function will be called like:
|
||||
|
||||
argcが負の時は引数の数ではなく,形式を指定したことになります.
|
||||
argcが-1の時は引数を配列に入れて渡されます.argcが-2の時は引
|
||||
数はRubyの配列として渡されます.
|
||||
VALUE func(int argc, VALUE *argv, VALUE obj)
|
||||
|
||||
メソッドを定義する関数はもう二つあります.ひとつはprivateメ
|
||||
ソッドを定義する関数で,引数はrb_define_method()と同じです.
|
||||
where argc is the actual number of arguments, argv is the C array of
|
||||
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,
|
||||
VALUE (*func)(), int argc)
|
||||
|
||||
privateメソッドとは関数形式でしか呼び出すことの出来ないメソッ
|
||||
ドです.
|
||||
|
||||
もうひとつはモジュール関数を定義するものです.モジュール関数
|
||||
とはモジュールの特異メソッドであり,同時にprivateメソッドで
|
||||
もあるものです.例をあげるとMathモジュールのsqrt()などがあげ
|
||||
られます.このメソッドは
|
||||
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:
|
||||
|
||||
Math.sqrt(4)
|
||||
|
||||
という形式でも
|
||||
or
|
||||
|
||||
include Math
|
||||
sqrt(4)
|
||||
|
||||
という形式でも使えます.モジュール関数を定義する関数は以下の
|
||||
通りです.
|
||||
To define module function
|
||||
|
||||
void rb_define_module_function(VALUE module, char *name,
|
||||
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)
|
||||
|
||||
|
||||
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_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
|
||||
|
||||
既に『1.5 Rubyのデータを操作する』で一部紹介したような関数を
|
||||
使えば,Rubyの機能を実現している関数を直接呼び出すことが出来
|
||||
ます.
|
||||
There are several ways to invoke Ruby's features from C code.
|
||||
|
||||
# このような関数の一覧表はいまのところありません.ソースを見
|
||||
# るしかないですね.
|
||||
2.2.1 Evaluate Ruby Program in String
|
||||
|
||||
それ以外にもRubyの機能を呼び出す方法はいくつかあります.
|
||||
|
||||
2.2.1 Rubyのプログラムをevalする
|
||||
|
||||
CからRubyの機能を呼び出すもっとも簡単な方法として,文字列で
|
||||
与えられた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.
|
||||
|
||||
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
|
||||
|
||||
Cから文字列を経由せずにRubyのメソッドを呼び出すこともできま
|
||||
す.その前に,Rubyインタプリタ内でメソッドや変数名を指定する
|
||||
時に使われているIDについて説明しておきましょう.
|
||||
You can invoke methods directly, without parsing the string. First I
|
||||
need to explain about symbols (which data type is ID). ID is the
|
||||
integer number to represent Ruby's identifiers such as variable names.
|
||||
It can be accessed from Ruby in the form like:
|
||||
|
||||
IDとは変数名,メソッド名を表す整数です.Rubyの中では
|
||||
:Identifier
|
||||
|
||||
:識別子
|
||||
|
||||
でアクセスできます.Cからこの整数を得るためには関数
|
||||
You can get the symbol value from string within C code, by using
|
||||
|
||||
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
|
||||
|
||||
Cから文字列を経由せずにRubyのメソッドを呼び出すためには以下
|
||||
の関数を使います.
|
||||
To invoke methods directly, you can use the function below
|
||||
|
||||
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の大域変数としてアクセ
|
||||
スできます.ローカル変数を参照する方法は公開していません.
|
||||
|
||||
オブジェクトのインスタンス変数を参照・更新する関数は以下の通
|
||||
りです.
|
||||
The functions to access/modify instance variables are below:
|
||||
|
||||
VALUE rb_ivar_get(VALUE obj, ID id)
|
||||
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)
|
||||
|
||||
クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ
|
||||
れている関数を使ってください.
|
||||
See 2.1.3 for defining new constant.
|
||||
|
||||
3. Informatin sharing between Ruby and C
|
||||
|
||||
|
@ -477,7 +453,7 @@ C
|
|||
|
||||
4.Example - Create dbm module
|
||||
|
||||
ここまでの説明でとりあえず拡張モジュールは作れるはずです.
|
||||
ここまでの説明でとりあえず拡張ライブラリは作れるはずです.
|
||||
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
|
||||
して段階的に説明します.
|
||||
|
||||
|
@ -485,39 +461,30 @@ Ruby
|
|||
|
||||
% mkdir ext/dbm
|
||||
|
||||
Rubyを展開したディレクトリの下,extディレクトリの中に拡張モ
|
||||
ジュール用のディレクトリを作ります.名前は適当に選んで構いま
|
||||
せん.
|
||||
Make a directory for the extension library under ext directory.
|
||||
|
||||
(2) create MANIFEST file
|
||||
|
||||
% cd ext/dbm
|
||||
% touch MANIFEST
|
||||
|
||||
拡張モジュールのディレクトリの下にはMANIFESTというファイルが
|
||||
必要なので,とりあえず空のファイルを作っておきます.後でこの
|
||||
ファイルには必要なファイル一覧が入ることになります.
|
||||
|
||||
MANIFESTというファイルは,makeの時にディレクトリが拡張モジュー
|
||||
ルを含んでいるかどうか判定するために使われれています.
|
||||
There should be MANIFEST file in the directory for the extension
|
||||
library. Make empty file now.
|
||||
|
||||
(3) design the library
|
||||
|
||||
まあ,当然なんですけど,どういう機能を実現するかどうかまず設
|
||||
計する必要があります.どんなクラスをつくるか,そのクラスには
|
||||
どんなメソッドがあるか,クラスが提供する定数などについて設計
|
||||
します.dbmクラスについてはext/dbm.docを参照してください.
|
||||
You need to design the library features, before making it.
|
||||
|
||||
(4) write C code.
|
||||
|
||||
拡張モジュール本体となるC言語のソースを書きます.C言語のソー
|
||||
拡張ライブラリ本体となるC言語のソースを書きます.C言語のソー
|
||||
スがひとつの時には「モジュール名.c」を選ぶと良いでしょう.C
|
||||
言語のソースが複数の場合には逆に「モジュール名.c」というファ
|
||||
イル名は避ける必要があります.オブジェクトファイルとモジュー
|
||||
ル生成時に中間的に生成される「モジュール名.o」というファイル
|
||||
とが衝突するからです.
|
||||
|
||||
Rubyは拡張モジュールをロードする時に「Init_モジュール名」と
|
||||
Rubyは拡張ライブラリをロードする時に「Init_モジュール名」と
|
||||
いう関数を自動的に実行します.dbmモジュールの場合「Init_dbm」
|
||||
です.この関数の中でクラス,モジュール,メソッド,定数などの
|
||||
定義を行います.dbm.cから一部引用します.
|
||||
|
@ -525,22 +492,20 @@ Ruby
|
|||
--
|
||||
Init_dbm()
|
||||
{
|
||||
/* DBMクラスを定義する */
|
||||
/* define DBM class */
|
||||
cDBM = rb_define_class("DBM", rb_cObject);
|
||||
/* DBMはEnumerateモジュールをインクルードする */
|
||||
/* DBM includes Enumerate module */
|
||||
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);
|
||||
|
||||
/* DBMクラスのメソッドclose(): 引数はなし */
|
||||
/* DBM instance method close(): no args */
|
||||
rb_define_method(cDBM, "close", fdbm_close, 0);
|
||||
/* DBMクラスのメソッド[]: 引数は1個 */
|
||||
/* DBM instance method []: 1 argument */
|
||||
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でも同じこと
|
||||
です.
|
||||
|
||||
** 注意事項
|
||||
** Notice
|
||||
|
||||
Rubyと共有はしないがRubyのオブジェクトを格納する可能性のある
|
||||
Cの大域変数は以下の関数を使ってRubyインタプリタに変数の存在
|
||||
を教えてあげてください.でないとGCでトラブルを起こします.
|
||||
GC should know about global variables which refers Ruby's objects, but
|
||||
not exported to the Ruby world. You need to protect them by
|
||||
|
||||
void rb_global_variable(VALUE *var)
|
||||
|
||||
|
@ -704,22 +668,22 @@ Ruby
|
|||
してくれます.extconf.rbを書き換えるなどしてMakefileの再生成
|
||||
が必要な時はまたRubyディレクトリでmakeしてください.
|
||||
|
||||
(9) rb_debug
|
||||
(9) debug
|
||||
|
||||
You may need to rb_debug the module. The modules can be linked
|
||||
statically by adding directory name in the ext/Setup file,
|
||||
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のソースコードの分類
|
||||
|
||||
Rubyのソースはいくつかに分類することが出来ます.このうちクラ
|
||||
スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ
|
||||
スライブラリの部分は基本的に拡張ライブラリと同じ作り方になっ
|
||||
ています.これらのソースは今までの説明でほとんど理解できると
|
||||
思います.
|
||||
|
||||
|
@ -847,54 +811,63 @@ super
|
|||
|
||||
オブジェクトをモジュール(で定義されているメソッド)で拡張する.
|
||||
|
||||
** 大域変数定義
|
||||
** Defining Global Variables
|
||||
|
||||
void rb_define_variable(char *name, VALUE *var)
|
||||
|
||||
RubyとCとで共有するグローバル変数を定義する.変数名が`$'で始
|
||||
まらない時には自動的に追加される.nameとしてRubyの識別子とし
|
||||
て許されない文字(例えば` ')を含む場合にはRubyプログラムから
|
||||
は見えなくなる.
|
||||
Defines a global variable which is shared between C and Ruby. If name
|
||||
contains the character which is not allowed to be part of the symbol,
|
||||
it can't be seen from Ruby programs.
|
||||
|
||||
void rb_define_readonly_variable(char *name, VALUE *var)
|
||||
|
||||
RubyとCとで共有するread onlyのグローバル変数を定義する.read
|
||||
onlyであること以外はrb_define_variable()と同じ.
|
||||
Defines a read-only global variable. Works just like
|
||||
rb_define_variable(), except defined variable is read-only.
|
||||
|
||||
void rb_define_virtual_variable(char *name,
|
||||
VALUE (*getter)(), VALUE (*setter)())
|
||||
|
||||
関数によって実現されるRuby変数を定義する.変数が参照された時
|
||||
にはgetterが,変数に値がセットされた時にはsetterが呼ばれる.
|
||||
Defines a virtual variable, whose behavior is defined by pair of C
|
||||
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,
|
||||
VALUE (*getter)(), VALUE (*setter)())
|
||||
|
||||
関数によってhookのつけられたグローバル変数を定義する.変数が
|
||||
参照された時にはgetterが,関数に値がセットされた時にはsetter
|
||||
が呼ばれる.getterやsetterに0を指定した時にはhookを指定しな
|
||||
いのと同じ事になる.
|
||||
Defines hooked variable. It's virtual variable with C variable. The
|
||||
getter is called as
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
大域定数を定義する.
|
||||
Defines global contant. This is just work as
|
||||
|
||||
rb_define_const(cKernal, name, val)
|
||||
|
||||
と同じ意味.
|
||||
|
||||
** メソッド定義
|
||||
** Method Definition
|
||||
|
||||
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)
|
||||
|
||||
Rubyインタプリタの初期化を行なう.
|
||||
Initializes the interpreter.
|
||||
|
||||
void ruby_run()
|
||||
|
||||
Rubyインタプリタを実行する.
|
||||
Starts execution of the interpreter.
|
||||
|
||||
void ruby_script(char *name)
|
||||
|
||||
Rubyのスクリプト名($0)を設定する.
|
||||
Specifies the name of the script ($0).
|
||||
|
||||
|
||||
Appendix B. extconf.rbで使える関数たち
|
||||
Appendix B. Functions Available in extconf.rb
|
||||
|
||||
extconf.rbの中では利用可能なコンパイル条件チェックの関数は以
|
||||
下の通りである.
|
||||
|
||||
have_library(lib, func)
|
||||
|
||||
関数funcを定義しているライブラリlibの存在をチェックする.ラ
|
||||
イブラリが存在する時,Qtrueを返す.
|
||||
Checks whether library which contains specified function exists.
|
||||
Returns true if the library exists.
|
||||
|
||||
have_func(func)
|
||||
|
||||
関数funcの存在をチェックする.funcが標準ではリンクされないラ
|
||||
イブラリ内のものである時には先にhave_libraryでそのライブラリ
|
||||
をチェックしておく事.関数が存在する時TRUEを返す.
|
||||
Checks whether func exists. Returns true if the function exists. To
|
||||
check functions in the additional library, you need to check that
|
||||
library first using have_library().
|
||||
|
||||
have_header(header)
|
||||
|
||||
ヘッダファイルの存在をチェックする.ヘッダファイルが存在する
|
||||
時TRUEを返す.
|
||||
Checks for the header files. Returns true if the header file exists.
|
||||
|
||||
create_makefile(target)
|
||||
|
||||
拡張モジュール用のMakefileを生成する.この関数を呼ばなければ
|
||||
そのモジュールはコンパイルされない.targetはモジュール名を表
|
||||
す.
|
||||
Generates the Makefile for the extension library. If you don't invoke
|
||||
this method, the compilation will not be done.
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
|
||||
|
||||
Rubyの拡張モジュールの作り方を説明します.
|
||||
Rubyの拡張ライブラリの作り方を説明します.
|
||||
|
||||
1.基礎知識
|
||||
|
||||
|
@ -120,8 +120,8 @@ ruby.h
|
|||
|
||||
例えば,文字列strの長さを得るためには「RSTRING(str)->len」と
|
||||
し,文字列strをchar*として得るためには「RSTRING(str)->ptr」
|
||||
とします.配列の場合には,それぞれ「RARRAY(str)->len」,
|
||||
「RARRAY(str)->ptr」となります.
|
||||
とします.配列の場合には,それぞれ「RARRAY(ary)->len」,
|
||||
「RARRAY(ary)->ptr」となります.
|
||||
|
||||
Rubyの構造体を直接アクセスする時に気をつけなければならないこ
|
||||
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
|
||||
|
@ -309,7 +309,7 @@ private
|
|||
|
||||
2.1.3 定数定義
|
||||
|
||||
拡張モジュールが必要な定数はあらかじめ定義しておいた方が良い
|
||||
拡張ライブラリが必要な定数はあらかじめ定義しておいた方が良い
|
||||
でしょう.定数を定義する関数は二つあります.
|
||||
|
||||
void rb_define_const(VALUE class, char *name, VALUE val)
|
||||
|
@ -376,9 +376,9 @@ apply
|
|||
|
||||
2.2.4 変数/定数を参照/更新する
|
||||
|
||||
Cから関数を使って参照・更新できるのは,クラス定数,インスタ
|
||||
ンス変数です.大域変数は一部のものはCの大域変数としてアクセ
|
||||
スできます.ローカル変数を参照する方法は公開していません.
|
||||
Cから関数を使って参照・更新できるのは,定数,インスタンス変
|
||||
数です.大域変数は一部のものはCの大域変数としてアクセスでき
|
||||
ます.ローカル変数を参照する方法は公開していません.
|
||||
|
||||
オブジェクトのインスタンス変数を参照・更新する関数は以下の通
|
||||
りです.
|
||||
|
@ -388,11 +388,11 @@ C
|
|||
|
||||
idはrb_intern()で得られるものを使ってください.
|
||||
|
||||
クラス定数を参照するには以下の関数を使ってください.
|
||||
定数を参照するには以下の関数を使ってください.
|
||||
|
||||
VALUE rb_const_get(VALUE obj, ID id)
|
||||
|
||||
クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ
|
||||
定数を新しく定義するためには『2.1.3 定数定義』で紹介さ
|
||||
れている関数を使ってください.
|
||||
|
||||
3.RubyとCとの情報共有
|
||||
|
@ -504,7 +504,7 @@ C
|
|||
|
||||
4.例題 - dbmパッケージを作る
|
||||
|
||||
ここまでの説明でとりあえず拡張モジュールは作れるはずです.
|
||||
ここまでの説明でとりあえず拡張ライブラリは作れるはずです.
|
||||
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
|
||||
して段階的に説明します.
|
||||
|
||||
|
@ -523,12 +523,12 @@ Ruby 1.1
|
|||
% cd ext/dbm
|
||||
% touch MANIFEST
|
||||
|
||||
拡張モジュールのディレクトリの下にはMANIFESTというファイルが
|
||||
拡張ライブラリのディレクトリの下にはMANIFESTというファイルが
|
||||
必要なので,とりあえず空のファイルを作っておきます.後でこの
|
||||
ファイルには必要なファイル一覧が入ることになります.
|
||||
|
||||
MANIFESTというファイルは,静的リンクのmakeの時にディレクトリ
|
||||
が拡張モジュールを含んでいるかどうか判定するために使われれて
|
||||
が拡張ライブラリを含んでいるかどうか判定するために使われれて
|
||||
います.ダイナミックライブラリを作る場合には必ずしも必要では
|
||||
ありません.
|
||||
|
||||
|
@ -541,14 +541,14 @@ MANIFEST
|
|||
|
||||
(4) Cコードを書く
|
||||
|
||||
拡張モジュール本体となるC言語のソースを書きます.C言語のソー
|
||||
拡張ライブラリ本体となるC言語のソースを書きます.C言語のソー
|
||||
スがひとつの時には「モジュール名.c」を選ぶと良いでしょう.C
|
||||
言語のソースが複数の場合には逆に「モジュール名.c」というファ
|
||||
イル名は避ける必要があります.オブジェクトファイルとモジュー
|
||||
ル生成時に中間的に生成される「モジュール名.o」というファイル
|
||||
とが衝突するからです.
|
||||
|
||||
Rubyは拡張モジュールをロードする時に「Init_モジュール名」と
|
||||
Rubyは拡張ライブラリをロードする時に「Init_モジュール名」と
|
||||
いう関数を自動的に実行します.dbmモジュールの場合「Init_dbm」
|
||||
です.この関数の中でクラス,モジュール,メソッド,定数などの
|
||||
定義を行います.dbm.cから一部引用します.
|
||||
|
@ -762,7 +762,7 @@ extconf.rb
|
|||
動的リンクライブラリはmake installでRubyライブラリのディレク
|
||||
トリの下にコピーされます.もしモジュールと協調して使うRubyで
|
||||
記述されたプログラムがあり,Rubyライブラリに置きたい場合には,
|
||||
拡張モジュール用のディレクトリの下に lib というディレクトリ
|
||||
拡張ライブラリ用のディレクトリの下に lib というディレクトリ
|
||||
を作り,そこに 拡張子 .rb のファイルを置いておけば同時にイン
|
||||
ストールされます.
|
||||
|
||||
|
@ -775,13 +775,13 @@ extconf.rb
|
|||
(11) できあがり
|
||||
|
||||
後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお
|
||||
使いください.Rubyの作者は拡張モジュールに関して一切の権利を
|
||||
使いください.Rubyの作者は拡張ライブラリに関して一切の権利を
|
||||
主張しません.
|
||||
|
||||
Appendix A. Rubyのソースコードの分類
|
||||
|
||||
Rubyのソースはいくつかに分類することが出来ます.このうちクラ
|
||||
スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ
|
||||
スライブラリの部分は基本的に拡張ライブラリと同じ作り方になっ
|
||||
ています.これらのソースは今までの説明でほとんど理解できると
|
||||
思います.
|
||||
|
||||
|
@ -962,11 +962,11 @@ only
|
|||
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)
|
||||
|
||||
|
@ -1098,7 +1098,7 @@ exception
|
|||
** Rubyの初期化・実行
|
||||
|
||||
Rubyをアプリケーションに埋め込む場合には以下のインタフェース
|
||||
を使う.通常の拡張モジュールには必要ない.
|
||||
を使う.通常の拡張ライブラリには必要ない.
|
||||
|
||||
void ruby_init(int argc, char **argv, char **envp)
|
||||
|
||||
|
@ -1121,7 +1121,7 @@ extconf.rb
|
|||
have_library(lib, func)
|
||||
|
||||
関数funcを定義しているライブラリlibの存在をチェックする.ラ
|
||||
イブラリが存在する時,Qtrueを返す.
|
||||
イブラリが存在する時,trueを返す.
|
||||
|
||||
have_func(func)
|
||||
|
||||
|
@ -1132,11 +1132,11 @@ extconf.rb
|
|||
have_header(header)
|
||||
|
||||
ヘッダファイルの存在をチェックする.ヘッダファイルが存在する
|
||||
時TRUEを返す.
|
||||
時trueを返す.
|
||||
|
||||
create_makefile(target)
|
||||
|
||||
拡張モジュール用のMakefileを生成する.この関数を呼ばなければ
|
||||
拡張ライブラリ用のMakefileを生成する.この関数を呼ばなければ
|
||||
そのモジュールはコンパイルされない.targetはモジュール名を表
|
||||
す.
|
||||
|
||||
|
|
39
ToDo
39
ToDo
|
@ -1,5 +1,36 @@
|
|||
* non-blocking open/write for thread
|
||||
* avoid blocking with gethostbyname/gethostbyaddr
|
||||
Language Spec.
|
||||
|
||||
* package or access control for global variables
|
||||
* format
|
||||
* freeze or undump to bundle everything in birary format.
|
||||
* named arguments like foo(nation:="german").
|
||||
* 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:*:*)
|
||||
echo i586-pc-beos
|
||||
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
|
||||
|
||||
#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,
|
||||
[--enable-fat-binary build a NeXT/Apple Multi Architecture Binary. ],
|
||||
[ fat_binary=$enableval ] )
|
||||
if test "$fat_binary" = yes ; then
|
||||
if test "$fat_binary" = yes ; then
|
||||
|
||||
AC_MSG_CHECKING( target architecture )
|
||||
|
||||
if test "$host_os" = "rhapsody" ; then
|
||||
echo -n "Rhapsody: "
|
||||
if test "$TARGET_ARCHS" = "" ; then
|
||||
TARGET_ARCHS="ppc i486"
|
||||
case "$host_os" in
|
||||
rhapsody*)
|
||||
echo -n "MacOS X Server: "
|
||||
if test "$TARGET_ARCHS" = "" ; then
|
||||
TARGET_ARCHS="ppc i386"
|
||||
fi
|
||||
else
|
||||
;;
|
||||
nextstep*|openstep*)
|
||||
echo -n "NeXTSTEP/OPENSTEP: "
|
||||
if test "$TARGET_ARCHS" = "" ; then
|
||||
if test `/usr/bin/arch` = "m68k" ; then
|
||||
TARGET_ARCHS="m68k i486"
|
||||
else
|
||||
TARGET_ARCHS="m68k `/usr/bin/arch`"
|
||||
fi
|
||||
|
||||
if test "$host_os" = "rhapsody" ; then
|
||||
echo -n "Rhapsody: "
|
||||
if test "$TARGET_ARCHS" = "" ; then
|
||||
TARGET_ARCHS="ppc i486"
|
||||
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
|
||||
;;
|
||||
esac
|
||||
# /usr/lib/arch_tool -archify_list $TARGET_ARCHS
|
||||
for archs in $TARGET_ARCHS
|
||||
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\
|
||||
truncate chsize times utimes fcntl lockf setitimer\
|
||||
setruid seteuid setreuid setrgid setegid setregid\
|
||||
setpgrp2 getpgid getgroups getpriority\
|
||||
setpgrp2 getpgid setpgid getgroups getpriority\
|
||||
dlopen sigprocmask sigaction _setjmp setpgrp setsid)
|
||||
if test "$ac_cv_func_strftime" = no; then
|
||||
AC_STRUCT_TIMEZONE
|
||||
|
|
17
dln.c
17
dln.c
|
@ -1129,15 +1129,22 @@ dln_strerror()
|
|||
|
||||
#ifdef _WIN32
|
||||
static char message[1024];
|
||||
int error = GetLastError();
|
||||
char *p = message;
|
||||
p += sprintf(message, "%d: ", error);
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
||||
message,
|
||||
sizeof message,
|
||||
error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
p,
|
||||
sizeof message - strlen(message),
|
||||
NULL);
|
||||
|
||||
for (p = message; *p; p++) {
|
||||
if (*p == '\n' || *p == '\r')
|
||||
*p = ' ';
|
||||
}
|
||||
return message;
|
||||
#endif
|
||||
}
|
||||
|
@ -1213,7 +1220,7 @@ dln_load(file)
|
|||
/* Load file */
|
||||
if ((handle =
|
||||
LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
|
||||
printf("LoadLibraryExA\n");
|
||||
printf("LoadLibraryExA: %s\n", winfile);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
|
4
enum.c
4
enum.c
|
@ -343,7 +343,11 @@ each_with_index_i(val, indexp)
|
|||
VALUE val;
|
||||
int *indexp;
|
||||
{
|
||||
#if 0
|
||||
rb_yield(rb_assoc_new(val, INT2FIX(*indexp)));
|
||||
#else
|
||||
rb_yield(rb_ary_concat(val, INT2FIX(*indexp)));
|
||||
#endif
|
||||
(*indexp)++;
|
||||
return Qnil;
|
||||
}
|
||||
|
|
10
error.c
10
error.c
|
@ -274,10 +274,7 @@ exc_initialize(argc, argv, exc)
|
|||
{
|
||||
VALUE mesg;
|
||||
|
||||
if (rb_scan_args(argc, argv, "01", &mesg) == 0) {
|
||||
mesg = rb_str_new(0, 0);
|
||||
}
|
||||
else {
|
||||
if (rb_scan_args(argc, argv, "01", &mesg) == 1) {
|
||||
STR2CSTR(mesg); /* ensure mesg can be converted to String */
|
||||
}
|
||||
rb_iv_set(exc, "mesg", mesg);
|
||||
|
@ -308,7 +305,10 @@ static VALUE
|
|||
exc_to_s(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
|
||||
|
|
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
|
||||
rb_clear_cache_by_id(id)
|
||||
ID id;
|
||||
|
@ -433,7 +398,10 @@ static struct SCOPE *top_scope;
|
|||
_frame.argc = 0; \
|
||||
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 {
|
||||
NODE *var;
|
||||
|
@ -873,7 +841,9 @@ error_print()
|
|||
|
||||
ep = RARRAY(errat);
|
||||
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) {
|
||||
fprintf(stderr, "\t ... %d levels...\n",
|
||||
ep->len - TRACE_HEAD - TRACE_TAIL);
|
||||
|
@ -1016,11 +986,6 @@ ruby_run()
|
|||
#endif
|
||||
exec_end_proc();
|
||||
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 {
|
||||
ex = state;
|
||||
|
@ -1666,8 +1631,6 @@ rb_eval(self, node)
|
|||
|
||||
#define RETURN(v) { result = (v); goto finish; }
|
||||
|
||||
eval_called++;
|
||||
|
||||
again:
|
||||
if (!node) RETURN(Qnil);
|
||||
|
||||
|
@ -3030,12 +2993,12 @@ rb_f_raise(argc, argv)
|
|||
}
|
||||
|
||||
if (!NIL_P(mesg)) {
|
||||
if (n >= 2) {
|
||||
mesg = rb_funcall(etype, rb_intern("new"), 1, mesg);
|
||||
}
|
||||
else if (TYPE(mesg) == T_STRING) {
|
||||
if (n == 1 && TYPE(mesg) == T_STRING) {
|
||||
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)) {
|
||||
rb_raise(rb_eTypeError, "exception object expected");
|
||||
}
|
||||
|
@ -3835,22 +3798,13 @@ rb_call(klass, recv, mid, argc, argv, scope)
|
|||
noex = ent->noex;
|
||||
body = ent->method;
|
||||
}
|
||||
else {
|
||||
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) {
|
||||
else if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) {
|
||||
if (scope == 3) {
|
||||
rb_raise(rb_eNameError, "super: no superclass method `%s'",
|
||||
rb_id2name(mid));
|
||||
}
|
||||
return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0);
|
||||
}
|
||||
}
|
||||
|
||||
/* receiver specified form for private method */
|
||||
if ((noex & NOEX_PRIVATE) && scope == 0)
|
||||
|
@ -4537,7 +4491,7 @@ rb_f_require(obj, fname)
|
|||
VALUE obj, fname;
|
||||
{
|
||||
char *ext, *file, *feature, *buf; /* OK */
|
||||
VALUE load;
|
||||
volatile VALUE load;
|
||||
|
||||
rb_secure(4);
|
||||
Check_SafeStr(fname);
|
||||
|
@ -5510,7 +5464,7 @@ method_call(argc, argv, method)
|
|||
Data_Get_Struct(method, struct METHOD, data);
|
||||
PUSH_ITER(rb_iterator_p()?ITER_PRE:ITER_NOT);
|
||||
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);
|
||||
if (safe_level < 4) safe_level = 4;
|
||||
}
|
||||
|
@ -6543,6 +6497,34 @@ static VALUE rb_thread_raise _((int, VALUE*, VALUE));
|
|||
|
||||
#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
|
||||
rb_thread_create_0(fn, arg, klass)
|
||||
VALUE (*fn)();
|
||||
|
@ -6554,11 +6536,7 @@ rb_thread_create_0(fn, arg, klass)
|
|||
int state;
|
||||
|
||||
#if defined(HAVE_SETITIMER) && !defined(__BOW__)
|
||||
static init = 0;
|
||||
|
||||
if (!init) {
|
||||
struct itimerval tval;
|
||||
|
||||
if (!thread_init) {
|
||||
#ifdef POSIX_SIGNAL
|
||||
posix_signal(SIGVTALRM, catch_timer);
|
||||
posix_signal(SIGALRM, catch_timer);
|
||||
|
@ -6567,11 +6545,8 @@ rb_thread_create_0(fn, arg, klass)
|
|||
signal(SIGALRM, catch_timer);
|
||||
#endif
|
||||
|
||||
tval.it_interval.tv_sec = 0;
|
||||
tval.it_interval.tv_usec = 100000;
|
||||
tval.it_value = tval.it_interval;
|
||||
setitimer(ITIMER_VIRTUAL, &tval, NULL);
|
||||
init = 1;
|
||||
thread_init = 1;
|
||||
thread_start_timer();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -313,11 +313,11 @@ archdir = $(pkglibdir)/@arch@
|
|||
mfile.printf $objs.join(" ")
|
||||
mfile.printf "\n"
|
||||
|
||||
mfile.printf "\
|
||||
TARGET = %s.%s
|
||||
mfile.printf << EOS
|
||||
TARGET = #{target}.#{$static ? "a" : "@DLEXT@"}
|
||||
|
||||
INSTALL = %s@INSTALL@
|
||||
INSTALL_DATA = %s@INSTALL_DATA@
|
||||
INSTALL = #{$dots}@INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
binsuffix = @binsuffix@
|
||||
|
||||
|
@ -328,16 +328,15 @@ clean:; @rm -f *.o *.a *.so *.sl
|
|||
@rm -f core ruby$(binsuffix) *~
|
||||
|
||||
realclean: clean
|
||||
", target,
|
||||
if $static then "a" else "@DLEXT@" end, $dots, $dots
|
||||
EOS
|
||||
|
||||
mfile.printf "\
|
||||
mfile.printf <<EOS
|
||||
|
||||
install:
|
||||
@test -d $(DESTDIR)$(libdir) || mkdir $(DESTDIR)$(libdir)
|
||||
@test -d $(DESTDIR)$(pkglibdir) || mkdir $(DESTDIR)$(pkglibdir)
|
||||
@test -d $(DESTDIR)$(archdir) || mkdir $(DESTDIR)$(archdir)
|
||||
"
|
||||
EOS
|
||||
if !$static
|
||||
mfile.printf "\
|
||||
$(INSTALL) $(TARGET) $(DESTDIR)$(archdir)/$(TARGET)
|
||||
|
|
|
@ -6647,11 +6647,11 @@ idle()
|
|||
return Qtrue;
|
||||
}
|
||||
|
||||
static void
|
||||
static VALUE
|
||||
exec_interval(proc)
|
||||
VALUE proc;
|
||||
{
|
||||
rb_funcall(proc, id_call, 0);
|
||||
return rb_funcall(proc, id_call, 0);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -6660,8 +6660,8 @@ timeout_add(self, interval)
|
|||
{
|
||||
int id;
|
||||
|
||||
id = gtk_timeout_add_interp(NUM2INT(interval), exec_interval,
|
||||
(gpointer)rb_f_lambda(), 0);
|
||||
id = gtk_timeout_add(NUM2INT(interval), (GtkFunction)exec_interval,
|
||||
(gpointer)rb_f_lambda());
|
||||
return INT2FIX(id);
|
||||
}
|
||||
|
||||
|
@ -6679,7 +6679,7 @@ idle_add(self)
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
16
gc.c
16
gc.c
|
@ -392,6 +392,10 @@ rb_gc_mark(ptr)
|
|||
|
||||
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) {
|
||||
case T_NIL:
|
||||
case T_FIXNUM:
|
||||
|
@ -616,7 +620,7 @@ rb_gc_mark(ptr)
|
|||
|
||||
#define MIN_FREE_OBJ 512
|
||||
|
||||
static void obj_free();
|
||||
static void obj_free _((VALUE));
|
||||
|
||||
static void
|
||||
gc_sweep()
|
||||
|
@ -693,6 +697,10 @@ obj_free(obj)
|
|||
if (need_call_final && FL_TEST(obj, FL_FINALIZE)) {
|
||||
run_final(obj);
|
||||
}
|
||||
if (FL_TEST(obj, FL_EXIVAR)) {
|
||||
rb_free_generic_ivar((VALUE)obj);
|
||||
}
|
||||
|
||||
switch (RANY(obj)->as.basic.flags & T_MASK) {
|
||||
case T_OBJECT:
|
||||
if (RANY(obj)->as.object.iv_tbl) {
|
||||
|
@ -871,11 +879,14 @@ rb_gc()
|
|||
for (list = Global_List; list; list = list->next) {
|
||||
rb_gc_mark(*list->varptr);
|
||||
}
|
||||
|
||||
rb_gc_mark_global_tbl();
|
||||
|
||||
mark_tbl(rb_class_tbl);
|
||||
rb_gc_mark_trap_list();
|
||||
|
||||
/* mark generic instance variables for special constants */
|
||||
rb_mark_generic_ivar_tbl();
|
||||
|
||||
gc_sweep();
|
||||
dont_gc--;
|
||||
}
|
||||
|
@ -1070,6 +1081,7 @@ id2ref(obj, id)
|
|||
{
|
||||
unsigned long ptr = NUM2UINT(id);
|
||||
|
||||
rb_secure(4);
|
||||
if (FIXNUM_P(ptr)) return (VALUE)ptr;
|
||||
if (ptr == Qtrue) return Qtrue;
|
||||
if (ptr == Qfalse) return Qfalse;
|
||||
|
|
8
hash.c
8
hash.c
|
@ -1027,7 +1027,7 @@ static VALUE
|
|||
env_each(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
VALUE ary = env_keys();
|
||||
volatile VALUE ary = env_keys();
|
||||
VALUE *ptr = RARRAY(ary)->ptr;
|
||||
int len = RARRAY(ary)->len;
|
||||
|
||||
|
@ -1044,7 +1044,7 @@ env_each(hash)
|
|||
static VALUE
|
||||
env_delete_if()
|
||||
{
|
||||
VALUE ary;
|
||||
volatile VALUE ary;
|
||||
VALUE *ptr;
|
||||
int len;
|
||||
|
||||
|
@ -1124,7 +1124,7 @@ env_has_value(dmy, value)
|
|||
VALUE dmy, value;
|
||||
{
|
||||
char **env;
|
||||
VALUE ary;
|
||||
volatile VALUE ary;
|
||||
|
||||
if (TYPE(value) != T_STRING) return Qfalse;
|
||||
ary = rb_ary_new();
|
||||
|
@ -1168,7 +1168,7 @@ env_to_hash(obj)
|
|||
VALUE obj;
|
||||
{
|
||||
VALUE hash = rb_hash_new();
|
||||
VALUE ary = env_keys();
|
||||
volatile VALUE ary = env_keys();
|
||||
VALUE *ptr = RARRAY(ary)->ptr;
|
||||
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_ancestors _((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_obj_singleton_methods _((VALUE));
|
||||
void rb_define_method_id _((VALUE, ID, VALUE (*)(), int));
|
||||
|
@ -100,9 +101,6 @@ VALUE rb_dvar_defined _((ID));
|
|||
VALUE rb_dvar_ref _((ID));
|
||||
void rb_dvar_asgn _((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_trap_eval _((VALUE, int));
|
||||
int rb_respond_to _((VALUE, ID));
|
||||
|
@ -119,6 +117,8 @@ VALUE rb_class_new_instance _((int, VALUE*, VALUE));
|
|||
VALUE rb_f_lambda _((void));
|
||||
void rb_set_end_proc _((void (*)(),VALUE));
|
||||
void rb_gc_mark_threads _((void));
|
||||
void thread_start_timer _((void));
|
||||
void thread_stop_timer _((void));
|
||||
void rb_thread_schedule _((void));
|
||||
void rb_thread_wait_fd _((int));
|
||||
void rb_thread_fd_writable _((int));
|
||||
|
@ -175,9 +175,7 @@ VALUE rb_num2fix _((VALUE));
|
|||
VALUE rb_fix2str _((VALUE, int));
|
||||
VALUE rb_fix_upto _((VALUE, VALUE));
|
||||
/* object.c */
|
||||
VALUE rb_equal _((VALUE, VALUE));
|
||||
int rb_eql _((VALUE, VALUE));
|
||||
VALUE rb_obj_equal _((VALUE, VALUE));
|
||||
VALUE rb_any_to_s _((VALUE));
|
||||
VALUE rb_inspect _((VALUE));
|
||||
VALUE rb_obj_is_instance_of _((VALUE, VALUE));
|
||||
|
@ -191,7 +189,6 @@ VALUE rb_Integer _((VALUE));
|
|||
VALUE rb_Float _((VALUE));
|
||||
VALUE rb_String _((VALUE));
|
||||
VALUE rb_Array _((VALUE));
|
||||
double rb_num2dbl _((VALUE));
|
||||
/* parse.y */
|
||||
extern int ruby_sourceline;
|
||||
extern char *ruby_sourcefile;
|
||||
|
@ -291,6 +288,9 @@ VALUE rb_f_untrace_var _((int, VALUE*));
|
|||
VALUE rb_gvar_set2 _((char*, VALUE));
|
||||
VALUE rb_f_global_variables _((void));
|
||||
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_set _((VALUE, ID, VALUE));
|
||||
VALUE rb_ivar_defined _((VALUE, ID));
|
||||
|
|
2
io.c
2
io.c
|
@ -2544,7 +2544,7 @@ arg_read(argc, argv)
|
|||
next_p = 1;
|
||||
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 rb_str_cat(str, RSTRING(tmp)->ptr, RSTRING(tmp)->len);
|
||||
if (argc == 0) {
|
||||
|
|
|
@ -267,6 +267,6 @@ class DEBUGGER__
|
|||
CONTEXT = new
|
||||
end
|
||||
|
||||
set_trace_func proc{|event, file, line, id, binding, klass|
|
||||
DEBUGGER__::CONTEXT.trace_func event, file, line, id, binding, klass
|
||||
set_trace_func proc{|event, file, line, id, binding|
|
||||
DEBUGGER__::CONTEXT.trace_func event, file, line, id, binding
|
||||
}
|
||||
|
|
|
@ -20,24 +20,32 @@ class Delegator
|
|||
|
||||
def initialize(obj)
|
||||
preserved = ::Kernel.instance_methods
|
||||
preserved -= ["to_s","to_a","inspect","==","=~","==="]
|
||||
for t in self.type.ancestors
|
||||
preserved |= t.instance_methods
|
||||
preserved |= t.private_instance_methods
|
||||
preserved |= t.protected_instance_methods
|
||||
break if t == Delegator
|
||||
end
|
||||
preserved -= ["to_s","to_a","inspect","==","=~","==="]
|
||||
for method in obj.methods
|
||||
next if preserved.include? method
|
||||
eval <<EOS
|
||||
def self.#{method}(*args, &block)
|
||||
begin
|
||||
__getobj__.__send__(:#{method}, *args, &block)
|
||||
rescue Exception
|
||||
n = if /:in `__getobj__'$/ =~ $@[0] then 1 else 2 end #`
|
||||
$@[1,n] = nil
|
||||
raise
|
||||
end
|
||||
end
|
||||
EOS
|
||||
eval <<-EOS
|
||||
def self.#{method}(*args, &block)
|
||||
begin
|
||||
__getobj__.__send__(:#{method}, *args, &block)
|
||||
rescue Exception
|
||||
c = -caller(0).size
|
||||
if /:in `__getobj__'$/ =~ $@[c-1] #`
|
||||
n = 1
|
||||
else
|
||||
c -= 1
|
||||
n = 2
|
||||
end
|
||||
$@[c,n] = nil
|
||||
raise
|
||||
end
|
||||
end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -72,14 +80,14 @@ def DelegateClass(superclass)
|
|||
klass = Class.new
|
||||
methods = superclass.instance_methods
|
||||
methods -= ::Kernel.instance_methods
|
||||
methods |= ["to_s","to_a","inspect","hash","eql?","==","=~","==="]
|
||||
klass.module_eval <<EOS
|
||||
methods |= ["to_s","to_a","inspect","==","=~","==="]
|
||||
klass.module_eval <<-EOS
|
||||
def initialize(obj)
|
||||
@obj = obj
|
||||
end
|
||||
EOS
|
||||
EOS
|
||||
for method in methods
|
||||
klass.module_eval <<EOS
|
||||
klass.module_eval <<-EOS
|
||||
def #{method}(*args, &block)
|
||||
begin
|
||||
@obj.__send__(:#{method}, *args, &block)
|
||||
|
@ -88,7 +96,7 @@ EOS
|
|||
raise
|
||||
end
|
||||
end
|
||||
EOS
|
||||
EOS
|
||||
end
|
||||
return klass;
|
||||
end
|
||||
|
@ -107,10 +115,12 @@ if __FILE__ == $0
|
|||
|
||||
foo = Object.new
|
||||
def foo.test
|
||||
25
|
||||
end
|
||||
def foo.error
|
||||
raise 'this is OK'
|
||||
end
|
||||
foo2 = SimpleDelegator.new(foo)
|
||||
p foo.hash == foo2.hash # => true
|
||||
foo.test # raise error!
|
||||
|
||||
p foo.test == foo2.test # => true
|
||||
foo2.error # raise error!
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Mail
|
||||
|
||||
def initialize(f)
|
||||
unless f.kind_of?(IO)
|
||||
unless defined? f.gets
|
||||
f = open(f, "r")
|
||||
opened = true
|
||||
end
|
||||
|
|
10
lib/mkmf.rb
10
lib/mkmf.rb
|
@ -289,7 +289,8 @@ LDSHARED = #{CONFIG["LDSHARED"]}
|
|||
|
||||
prefix = #{CONFIG["prefix"]}
|
||||
exec_prefix = #{CONFIG["exec_prefix"]}
|
||||
libdir = #{$archdir}
|
||||
libdir = #{$libdir}
|
||||
archdir = #{$archdir}
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
|
@ -312,11 +313,12 @@ clean:; @rm -f *.o *.so *.sl
|
|||
|
||||
realclean: clean
|
||||
|
||||
install: $(libdir)/$(TARGET)
|
||||
install: $(archdir)/$(TARGET)
|
||||
|
||||
$(libdir)/$(TARGET): $(TARGET)
|
||||
$(archdir)/$(TARGET): $(TARGET)
|
||||
@test -d $(libdir) || mkdir $(libdir)
|
||||
$(INSTALL) $(TARGET) $(libdir)/$(TARGET)
|
||||
@test -d $(archdir) || mkdir $(archdir)
|
||||
$(INSTALL) $(TARGET) $(archdir)/$(TARGET)
|
||||
EOMF
|
||||
install_rb(mfile)
|
||||
mfile.printf "\n"
|
||||
|
|
|
@ -110,6 +110,7 @@ class PStore
|
|||
@abort = false
|
||||
end
|
||||
ensure
|
||||
@table = nil
|
||||
@transaction = false
|
||||
end
|
||||
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
|
||||
;;;
|
||||
;;; $Id: inf-ruby.el,v 1.4 1998/05/20 02:45:58 senda Exp $
|
||||
;;; $Author: senda $
|
||||
;;; $Date: 1998/05/20 02:45:58 $
|
||||
;;; $Id$
|
||||
;;; $Author$
|
||||
;;; $Date$
|
||||
;;;
|
||||
;;; Inferior Ruby Mode - ruby process in a buffer.
|
||||
;;; adapted from cmuscheme.el
|
||||
|
@ -34,7 +34,10 @@
|
|||
;;;
|
||||
;;; HISTORY
|
||||
;;; 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
|
||||
;;; default program to irb
|
||||
;;;
|
|
@ -2,11 +2,19 @@
|
|||
;;; ruby-mode.el -
|
||||
;;;
|
||||
;;; $Author$
|
||||
<<<<<<< ruby-mode.el
|
||||
;;; $Date$
|
||||
=======
|
||||
;;; $Date$
|
||||
>>>>>>> 1.1.1.2.2.23
|
||||
;;; created at: Fri Feb 4 14:49:13 JST 1994
|
||||
;;;
|
||||
|
||||
<<<<<<< ruby-mode.el
|
||||
(defconst ruby-mode-revision "$Revision$")
|
||||
=======
|
||||
(defconst ruby-mode-revision "$Revision$")
|
||||
>>>>>>> 1.1.1.2.2.23
|
||||
|
||||
(defconst ruby-mode-version
|
||||
(progn
|
17
missing/nt.c
17
missing/nt.c
|
@ -251,6 +251,9 @@ int SafeFree(char **vec, int vecc)
|
|||
|
||||
|
||||
static char *szInternalCmds[] = {
|
||||
"append",
|
||||
"break",
|
||||
"call",
|
||||
"cd",
|
||||
"chdir",
|
||||
"cls",
|
||||
|
@ -264,6 +267,7 @@ static char *szInternalCmds[] = {
|
|||
"md",
|
||||
"mkdir",
|
||||
"path",
|
||||
"pause",
|
||||
"rd",
|
||||
"rem",
|
||||
"ren",
|
||||
|
@ -280,13 +284,18 @@ static char *szInternalCmds[] = {
|
|||
int
|
||||
isInternalCmd(char *cmd)
|
||||
{
|
||||
int fRet;
|
||||
int i, fRet;
|
||||
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);
|
||||
|
||||
return 0;
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1044,7 +1044,7 @@ static VALUE
|
|||
fix_rev(num)
|
||||
VALUE num;
|
||||
{
|
||||
unsigned long val = FIX2UINT(num);
|
||||
unsigned long val = FIX2ULONG(num);
|
||||
|
||||
val = ~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);
|
||||
}
|
||||
|
||||
VALUE
|
||||
static VALUE
|
||||
rb_obj_equal(obj1, obj2)
|
||||
VALUE obj1, obj2;
|
||||
{
|
||||
|
@ -598,13 +598,6 @@ rb_class_s_inherited()
|
|||
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
|
||||
rb_class_superclass(klass)
|
||||
VALUE klass;
|
||||
|
@ -624,11 +617,16 @@ ID
|
|||
rb_to_id(name)
|
||||
VALUE name;
|
||||
{
|
||||
ID id;
|
||||
|
||||
if (TYPE(name) == T_STRING) {
|
||||
return rb_intern(RSTRING(name)->ptr);
|
||||
}
|
||||
Check_Type(name, T_FIXNUM);
|
||||
return FIX2UINT(name);
|
||||
id = NUM2UINT(name);
|
||||
if (!rb_id2name(id)) {
|
||||
rb_raise(rb_eArgError, "%d is not a symbol", id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -686,8 +684,6 @@ rb_mod_attr_accessor(argc, argv, klass)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE rb_mod_constants();
|
||||
|
||||
static VALUE
|
||||
rb_mod_const_get(mod, name)
|
||||
VALUE mod, name;
|
||||
|
@ -935,6 +931,7 @@ Init_Object()
|
|||
|
||||
rb_mKernel = rb_define_module("Kernel");
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -1022,7 +1019,6 @@ Init_Object()
|
|||
rb_define_method(rb_cNilClass, "+", nil_plus, 1);
|
||||
#endif
|
||||
|
||||
rb_define_global_function("initialize", rb_obj_dummy, -1);
|
||||
rb_define_global_function("singleton_method_added", rb_obj_dummy, 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 void encodes _((VALUE,char*,int,int));
|
||||
static void qpencode _((VALUE,VALUE,int));
|
||||
|
||||
static void
|
||||
pack_add_ptr(str, add)
|
||||
|
@ -104,7 +105,7 @@ pack_pack(ary, fmt)
|
|||
int plen;
|
||||
|
||||
|
||||
p = str2cstr(fmt, &plen);
|
||||
p = rb_str2cstr(fmt, &plen);
|
||||
pend = p + plen;
|
||||
res = rb_str_new(0, 0);
|
||||
|
||||
|
@ -469,6 +470,13 @@ pack_pack(ary, fmt)
|
|||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
from = rb_obj_as_string(NEXTFROM);
|
||||
if (len <= 1)
|
||||
len = 72;
|
||||
qpencode(res, from, len);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
len = 1;
|
||||
/* FALL THROUGH */
|
||||
|
@ -505,38 +513,121 @@ encodes(str, s, len, type)
|
|||
int len;
|
||||
int type;
|
||||
{
|
||||
char hunk[4];
|
||||
char *buff = ALLOCA_N(char, len * 4 / 3 + 6);
|
||||
int i = 0;
|
||||
char *p, *pend;
|
||||
char *trans = type == 'u' ? uu_table : b64_table;
|
||||
int padding;
|
||||
|
||||
if (type == 'u') {
|
||||
*hunk = len + ' ';
|
||||
rb_str_cat(str, hunk, 1);
|
||||
buff[i++] = len + ' ';
|
||||
padding = '`';
|
||||
}
|
||||
else {
|
||||
padding = '=';
|
||||
}
|
||||
while (len > 0) {
|
||||
hunk[0] = trans[077 & (*s >> 2)];
|
||||
hunk[1] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
|
||||
hunk[2] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
|
||||
hunk[3] = trans[077 & s[2]];
|
||||
rb_str_cat(str, hunk, 4);
|
||||
while (len >= 3) {
|
||||
buff[i++] = trans[077 & (*s >> 2)];
|
||||
buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
|
||||
buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
|
||||
buff[i++] = trans[077 & s[2]];
|
||||
s += 3;
|
||||
len -= 3;
|
||||
}
|
||||
p = RSTRING(str)->ptr;
|
||||
pend = RSTRING(str)->ptr + RSTRING(str)->len;
|
||||
if (len == -1) {
|
||||
pend[-1] = padding;
|
||||
if (len == 2) {
|
||||
buff[i++] = trans[077 & (*s >> 2)];
|
||||
buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
|
||||
buff[i++] = trans[077 & (((s[1] << 2) & 074) | (('\0' >> 6) & 03))];
|
||||
buff[i++] = padding;
|
||||
}
|
||||
else if (len == -2) {
|
||||
pend[-2] = padding;
|
||||
pend[-1] = padding;
|
||||
else if (len == 1) {
|
||||
buff[i++] = trans[077 & (*s >> 2)];
|
||||
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
|
||||
|
@ -550,9 +641,9 @@ pack_unpack(str, fmt)
|
|||
char type;
|
||||
int len;
|
||||
|
||||
s = str2cstr(str, &len);
|
||||
s = rb_str2cstr(str, &len);
|
||||
send = s + len;
|
||||
p = str2cstr(fmt, &len);
|
||||
p = rb_str2cstr(fmt, &len);
|
||||
pend = p + len;
|
||||
|
||||
ary = rb_ary_new();
|
||||
|
@ -929,6 +1020,32 @@ pack_unpack(str, fmt)
|
|||
}
|
||||
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 '@':
|
||||
s = RSTRING(str)->ptr + len;
|
||||
break;
|
||||
|
|
48
parse.y
48
parse.y
|
@ -1150,7 +1150,7 @@ primary : literal
|
|||
local_pop();
|
||||
cur_mid = 0;
|
||||
}
|
||||
| kDEF singleton '.' {lex_state = EXPR_FNAME;} fname
|
||||
| kDEF singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
|
||||
{
|
||||
value_expr($2);
|
||||
in_single++;
|
||||
|
@ -1284,6 +1284,7 @@ method_call : operation '(' opt_call_args ')'
|
|||
{
|
||||
value_expr($1);
|
||||
$$ = new_call($1, $3, 0);
|
||||
fixpos($$, $1);
|
||||
}
|
||||
| primary tCOLON2 operation '(' opt_call_args ')'
|
||||
{
|
||||
|
@ -1557,6 +1558,9 @@ operation : tIDENTIFIER
|
|||
| tCONSTANT
|
||||
| tFID
|
||||
|
||||
dot_or_colon : '.'
|
||||
| tCOLON2
|
||||
|
||||
opt_terms : /* none */
|
||||
| terms
|
||||
|
||||
|
@ -1723,6 +1727,20 @@ rb_compile_file(f, file, start)
|
|||
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
|
||||
nextc()
|
||||
{
|
||||
|
@ -1737,19 +1755,20 @@ nextc()
|
|||
ruby_sourceline = heredoc_end+1;
|
||||
heredoc_end = 0;
|
||||
}
|
||||
normalize_newline(v);
|
||||
while (RSTRING(v)->len >= 2 &&
|
||||
RSTRING(v)->ptr[RSTRING(v)->len-1] == '\n' &&
|
||||
RSTRING(v)->ptr[RSTRING(v)->len-2] == '\\') {
|
||||
VALUE v2 = (*lex_gets)(lex_input);
|
||||
|
||||
if (!NIL_P(v2)) {
|
||||
normalize_newline(v2);
|
||||
rb_str_cat(v, RSTRING(v2)->ptr, RSTRING(v2)->len);
|
||||
}
|
||||
}
|
||||
lex_pbeg = lex_p = RSTRING(v)->ptr;
|
||||
lex_pend = lex_p + RSTRING(v)->len;
|
||||
if (RSTRING(v)->len == 8 &&
|
||||
strncmp(lex_pbeg, "__END__", 7) == 0) {
|
||||
if (strncmp(lex_pbeg, "__END__", 7) == 0 && lex_pbeg[7] == '\n') {
|
||||
lex_lastline = 0;
|
||||
return -1;
|
||||
}
|
||||
|
@ -2220,11 +2239,12 @@ parse_quotedword(term, paren)
|
|||
char *strdup();
|
||||
|
||||
static int
|
||||
here_document(term)
|
||||
here_document(term, indent)
|
||||
char term;
|
||||
int indent;
|
||||
{
|
||||
int c;
|
||||
char *eos;
|
||||
char *eos, *p;
|
||||
int len;
|
||||
VALUE str, line;
|
||||
char *save_beg, *save_end, *save_lexp;
|
||||
|
@ -2273,10 +2293,15 @@ here_document(term)
|
|||
free(eos);
|
||||
return 0;
|
||||
}
|
||||
normalize_newline(line);
|
||||
ruby_sourceline++;
|
||||
if (strncmp(eos, RSTRING(line)->ptr, len) == 0 &&
|
||||
(RSTRING(line)->ptr[len] == '\n' ||
|
||||
RSTRING(line)->ptr[len] == '\r')) {
|
||||
p = RSTRING(line)->ptr;
|
||||
if (indent) {
|
||||
while (*p && (*p == ' ' || *p == '\t')) {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
if (strncmp(eos, p, len) == 0 && p[len] == '\n') {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2486,8 +2511,13 @@ retry:
|
|||
lex_state != EXPR_END && lex_state != EXPR_CLASS &&
|
||||
(lex_state != EXPR_ARG || space_seen)) {
|
||||
int c2 = nextc();
|
||||
int indent = 0;
|
||||
if (c2 == '-') {
|
||||
indent = 1;
|
||||
c2 = nextc();
|
||||
}
|
||||
if (!ISSPACE(c2) && (strchr("\"'`", c2) || is_identchar(c2))) {
|
||||
return here_document(c2);
|
||||
return here_document(c2, indent);
|
||||
}
|
||||
pushback(c2);
|
||||
}
|
||||
|
|
44
process.c
44
process.c
|
@ -212,28 +212,9 @@ rb_f_waitpid(obj, vpid, vflags)
|
|||
|
||||
char *strtok();
|
||||
|
||||
#if defined(USE_THREAD) && defined(HAVE_SETITIMER)
|
||||
static void
|
||||
before_exec()
|
||||
{
|
||||
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);
|
||||
}
|
||||
#if defined(THREAD) && defined(HAVE_SETITIMER)
|
||||
#define before_exec() thread_stop_timer()
|
||||
#define after_exec() thread_start_timer()
|
||||
#else
|
||||
#define before_exec()
|
||||
#define after_exec()
|
||||
|
@ -503,6 +484,9 @@ rb_f_exec(argc, argv)
|
|||
VALUE prog = 0;
|
||||
int i;
|
||||
|
||||
if (argc == 0) {
|
||||
rb_raise(rb_eArgError, "wrong # of arguments");
|
||||
}
|
||||
if (TYPE(argv[0]) == T_ARRAY) {
|
||||
if (RARRAY(argv[0])->len != 2) {
|
||||
rb_raise(rb_eArgError, "wrong first argument");
|
||||
|
@ -834,6 +818,20 @@ proc_setpgrp(argc, argv)
|
|||
#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
|
||||
proc_setpgid(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, "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_PGRP", INT2FIX(PRIO_PGRP));
|
||||
rb_define_const(rb_mProcess, "PRIO_USER", INT2FIX(PRIO_USER));
|
||||
|
|
1
re.h
1
re.h
|
@ -3,7 +3,6 @@
|
|||
re.h -
|
||||
|
||||
$Author$
|
||||
$Revision$
|
||||
$Date$
|
||||
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
|
||||
&& (bufp->can_be_null == 0 ||
|
||||
(bufp->can_be_null && size > 0
|
||||
|
|
22
ruby.c
22
ruby.c
|
@ -20,6 +20,10 @@
|
|||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef __hpux
|
||||
#include <sys/pstat.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
@ -607,6 +611,7 @@ set_arg0(val, id)
|
|||
static int len;
|
||||
|
||||
if (origargv == 0) rb_raise(rb_eRuntimeError, "$0 not initialized");
|
||||
#ifndef __hpux
|
||||
if (len == 0) {
|
||||
s = origargv[0];
|
||||
s += strlen(s);
|
||||
|
@ -617,7 +622,9 @@ set_arg0(val, id)
|
|||
}
|
||||
len = s - origargv[0];
|
||||
}
|
||||
#endif
|
||||
s = str2cstr(val, &i);
|
||||
#ifndef __hpux
|
||||
if (i > len) {
|
||||
memcpy(origargv[0], s, len);
|
||||
origargv[0][len] = '\0';
|
||||
|
@ -630,6 +637,21 @@ set_arg0(val, id)
|
|||
*s++ = ' ';
|
||||
}
|
||||
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
|
||||
|
|
16
ruby.h
16
ruby.h
|
@ -163,11 +163,11 @@ VALUE rb_int2inum _((long));
|
|||
#define T_DATA 0x22
|
||||
#define T_MATCH 0x23
|
||||
|
||||
#define T_VARMAP 0xfd
|
||||
#define T_SCOPE 0xfe
|
||||
#define T_NODE 0xff
|
||||
#define T_VARMAP 0x7d
|
||||
#define T_SCOPE 0x7e
|
||||
#define T_NODE 0x7f
|
||||
|
||||
#define T_MASK 0xff
|
||||
#define T_MASK 0x7f
|
||||
|
||||
#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
|
||||
|
||||
|
@ -271,6 +271,7 @@ struct RHash {
|
|||
|
||||
struct RFile {
|
||||
struct RBasic basic;
|
||||
struct st_table *iv_tbl;
|
||||
struct OpenFile *fptr;
|
||||
};
|
||||
|
||||
|
@ -329,9 +330,10 @@ struct RBignum {
|
|||
#define RFILE(obj) (R_CAST(RFile)(obj))
|
||||
|
||||
#define FL_SINGLETON FL_USER0
|
||||
#define FL_MARK (1<<8)
|
||||
#define FL_FINALIZE (1<<9)
|
||||
#define FL_TAINT (1<<10)
|
||||
#define FL_MARK (1<<7)
|
||||
#define FL_FINALIZE (1<<8)
|
||||
#define FL_TAINT (1<<9)
|
||||
#define FL_EXIVAR (1<<10)
|
||||
|
||||
#define FL_USHIFT 11
|
||||
|
||||
|
|
1
rubyio.h
1
rubyio.h
|
@ -45,6 +45,7 @@ typedef struct OpenFile {
|
|||
fp->finalize = 0;\
|
||||
} while (0)
|
||||
|
||||
#define GetReadFile(fptr) ((fptr)->f)
|
||||
#define GetWriteFile(fptr) (((fptr)->f2) ? (fptr)->f2 : (fptr)->f)
|
||||
|
||||
FILE *rb_fopen _((char *, char *));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#! /usr/local/bin/ruby
|
||||
|
||||
# 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'
|
||||
|
||||
|
@ -59,7 +59,7 @@ def zip(xs)
|
|||
until xs.empty?
|
||||
ln = (if $jd then l, r, *xs = xs; [l, r]
|
||||
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
|
||||
yr << ln.collect{|x|
|
||||
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
|
||||
|
||||
/*
|
||||
Table of irreducible polynomials to efficiently cycle through
|
||||
GF(2^n)-{0}, 2<=n<=30.
|
||||
Table of prime numbers 2^n+a, 2<=n<=30.
|
||||
*/
|
||||
static long polys[] = {
|
||||
static long primes[] = {
|
||||
8 + 3,
|
||||
16 + 3,
|
||||
32 + 5,
|
||||
|
@ -108,10 +107,10 @@ new_size(size)
|
|||
int i, newsize;
|
||||
|
||||
for (i = 0, newsize = MINSIZE;
|
||||
i < sizeof(polys)/sizeof(polys[0]);
|
||||
i < sizeof(primes)/sizeof(primes[0]);
|
||||
i++, newsize <<= 1)
|
||||
{
|
||||
if (newsize > size) return polys[i];
|
||||
if (newsize > size) return primes[i];
|
||||
}
|
||||
/* Ran out of polynomials */
|
||||
return -1; /* should raise exception */
|
||||
|
|
6
string.c
6
string.c
|
@ -1345,7 +1345,7 @@ rb_str_inspect(str)
|
|||
CHECK(1);
|
||||
*b++ = c;
|
||||
}
|
||||
else if (c == '"' || c == '\''|| c == '\\') {
|
||||
else if (c == '"'|| c == '\\') {
|
||||
CHECK(2);
|
||||
*b++ = '\\';
|
||||
*b++ = c;
|
||||
|
@ -1414,7 +1414,7 @@ rb_str_dump(str)
|
|||
while (p < pend) {
|
||||
char c = *p++;
|
||||
switch (c) {
|
||||
case '"': case '\'': case '\\':
|
||||
case '"': case '\\':
|
||||
case '\n': case '\r':
|
||||
case '\t': case '\f':
|
||||
case '\013': case '\007': case '\033':
|
||||
|
@ -1440,7 +1440,7 @@ rb_str_dump(str)
|
|||
while (p < pend) {
|
||||
char c = *p++;
|
||||
|
||||
if (c == '"' || c == '\'' || c == '\\') {
|
||||
if (c == '"' || c == '\\') {
|
||||
*q++ = '\\';
|
||||
*q++ = c;
|
||||
}
|
||||
|
|
2
top.sed
2
top.sed
|
@ -33,7 +33,7 @@ s%@AR@%ar%g
|
|||
s%@INSTALL_PROGRAM@%${INSTALL}%g
|
||||
s%@INSTALL_DATA@%${INSTALL} -m 644%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%@DLDFLAGS@%%g
|
||||
s%@STATIC@%%g
|
||||
|
|
168
variable.c
168
variable.c
|
@ -129,7 +129,7 @@ classname(klass)
|
|||
path = rb_ivar_get(klass, classid);
|
||||
if (!NIL_P(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);
|
||||
}
|
||||
}
|
||||
|
@ -205,12 +205,7 @@ rb_name_class(klass, id)
|
|||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
if (rb_cString) {
|
||||
rb_iv_set(klass, "__classpath__", rb_str_new2(rb_id2name(id)));
|
||||
}
|
||||
else {
|
||||
rb_iv_set(klass, "__classid__", INT2FIX(id));
|
||||
}
|
||||
rb_iv_set(klass, "__classid__", INT2FIX(id));
|
||||
}
|
||||
|
||||
static st_table *autoload_tbl = 0;
|
||||
|
@ -690,6 +685,133 @@ rb_alias_variable(name1, name2)
|
|||
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
|
||||
rb_ivar_get(obj, id)
|
||||
VALUE obj;
|
||||
|
@ -701,12 +823,13 @@ rb_ivar_get(obj, id)
|
|||
case T_OBJECT:
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
case T_FILE:
|
||||
if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, &val))
|
||||
return val;
|
||||
return Qnil;
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "class %s can not have instance variables",
|
||||
rb_class2name(CLASS_OF(obj)));
|
||||
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
|
||||
return generic_ivar_get(obj, id);
|
||||
break;
|
||||
}
|
||||
if (rb_verbose) {
|
||||
|
@ -725,14 +848,14 @@ rb_ivar_set(obj, id, val)
|
|||
case T_OBJECT:
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
case T_FILE:
|
||||
if (rb_safe_level() >= 4 && !FL_TEST(obj, FL_TAINT))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
|
||||
if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable();
|
||||
st_insert(ROBJECT(obj)->iv_tbl, id, val);
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "class %s can not have instance variables",
|
||||
rb_class2name(CLASS_OF(obj)));
|
||||
generic_ivar_set(obj, id, val);
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
|
@ -749,9 +872,14 @@ rb_ivar_defined(obj, id)
|
|||
case T_OBJECT:
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
case T_FILE:
|
||||
if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, 0))
|
||||
return Qtrue;
|
||||
break;
|
||||
default:
|
||||
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
|
||||
return generic_ivar_defined(obj, id);
|
||||
break;
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
|
@ -778,11 +906,22 @@ rb_obj_instance_variables(obj)
|
|||
case T_OBJECT:
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
case T_FILE:
|
||||
ary = rb_ary_new();
|
||||
if (ROBJECT(obj)->iv_tbl) {
|
||||
st_foreach(ROBJECT(obj)->iv_tbl, ivar_i, 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;
|
||||
}
|
||||
|
@ -803,13 +942,14 @@ rb_obj_remove_instance_variable(obj, name)
|
|||
case T_OBJECT:
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
case T_FILE:
|
||||
if (ROBJECT(obj)->iv_tbl) {
|
||||
st_delete(ROBJECT(obj)->iv_tbl, &id, &val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "object %s can not have instance variables",
|
||||
rb_class2name(CLASS_OF(obj)));
|
||||
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
|
||||
return generic_ivar_remove(obj, id);
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#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