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

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

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

View file

@ -1,3 +1,68 @@
Wed Dec 16 16:28:31 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* experimental version 1.1d0 (pre1.2) released.
Wed Dec 16 10:43:34 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* regex.c (re_search): bound check before calling re_match().
Tue Dec 15 13:59:01 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* error.c (exc_to_s): returns class name for unset mesg.
* error.c (exc_initialize): do not initialize @mesg by "".
* parse.y (nextc): __END__ should handle CR+LF newlines.
Wed Dec 9 13:37:12 1998 MAEDA shugo <shugo@aianet.ne.jp>
* pack.c (encodes): use buffering for B-encoding.
* pack.c (pack_pack): Q-encoding by 'M'.
Tue Dec 8 14:10:00 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* variable.c (generic_ivar_get): any object can have instance
variables now. great improvement.
* variable.c (rb_name_class): do not set __classpath__ by default,
use __classid__ instead.
Mon Dec 7 22:08:22 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* ruby.h (struct RFile): IO objects can have instance variables now.
* parse.y (primary): allows `def obj::foo; .. end'.
Mon Dec 7 18:24:50 1998 WATANABE Tetsuya <tetsu@jpn.hp.com>
* ruby.c (set_arg0): $0 supprt for HP-UX.
Mon Dec 7 01:30:28 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
* dln.c (dln_strerror): better error messages on win32.
Sat Dec 5 23:27:23 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (here_document): indentable here-doc delimiter by
`<<-'. Proposed by Clemens <c.hintze@gmx.net>. Thanks.
Thu Dec 3 16:50:17 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* ext/extmk.rb.in (realclean): trouble on install.
Sun Nov 29 22:25:39 1998 Takaaki Tateishi <ttate@jaist.ac.jp>
* process.c (f_exec): check number of argument.
Wed Nov 25 13:07:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (yycompile): reduce known memory leak (hard to remove).
Thu Nov 26 17:27:30 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1c9 released.
Wed Nov 25 03:41:21 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* 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.

View file

@ -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

View file

@ -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
4Example - 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:

View file

@ -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 定数定義』で紹介さ
れている関数を使ってください.
3Rubyと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
View file

@ -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
View file

@ -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

View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -97,41 +97,6 @@ rb_clear_cache()
}
}
static int cache_conflict;
static int eval_called;
static int
count_cent()
{
struct cache_entry *ent, *end;
int n = 0, n2 = 0;
int p = 0;
fprintf(stderr, "\n|");
ent = cache; end = ent + CACHE_SIZE;
while (ent < end) {
fprintf(stderr, (ent->klass != 0)?"*":" ");
p++;
if (p % 80 == 0) {
break;
}
ent++;
}
fprintf(stderr, "|\n|");
p = 0; ent = cache;
while (ent < end) {
if (ent->klass != 0) {n++; n2++;}
p++;
if (p % 24 == 0) {
fprintf(stderr, "%c", n2?(n2+'0'):' ');
n2 = 0;
}
ent++;
}
fprintf(stderr, "|\n");
return n;
}
static void
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

View file

@ -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)

View file

@ -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
View file

@ -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
View file

@ -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;

View file

@ -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
View file

@ -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) {

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -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"

View file

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

5
misc/README Normal file
View file

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

View file

@ -1,8 +1,8 @@
(J;;;(B (J-*-Emacs-Lisp-*-(B
;;;
;;; $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
;;;

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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
View file

@ -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
View file

@ -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);
}

View file

@ -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
View file

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

View file

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

22
ruby.c
View file

@ -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
View file

@ -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

View file

@ -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 *));

View file

@ -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
View file

@ -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 */

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

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