summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog81
-rw-r--r--MANIFEST9
-rw-r--r--README.EXT327
-rw-r--r--README.EXT.jp48
-rw-r--r--ToDo39
-rw-r--r--config.guess15
-rw-r--r--configure.in40
-rw-r--r--dln.c17
-rw-r--r--enum.c4
-rw-r--r--error.c10
-rw-r--r--eval.c115
-rw-r--r--ext/extmk.rb.in15
-rw-r--r--ext/gtk/gtk.c10
-rw-r--r--gc.c16
-rw-r--r--hash.c8
-rw-r--r--intern.h12
-rw-r--r--io.c2
-rw-r--r--lib/debug.rb4
-rw-r--r--lib/delegate.rb50
-rw-r--r--lib/mailread.rb2
-rw-r--r--lib/mkmf.rb10
-rw-r--r--lib/pstore.rb1
-rw-r--r--misc/README5
-rw-r--r--misc/inf-ruby.el (renamed from sample/inf-ruby.el)11
-rw-r--r--misc/ruby-mode.el (renamed from sample/ruby-mode.el)8
-rw-r--r--misc/rubydb2x.el (renamed from sample/rubydb2x.el)0
-rw-r--r--misc/rubydb3x.el (renamed from sample/rubydb3x.el)0
-rw-r--r--missing/nt.c17
-rw-r--r--numeric.c2
-rw-r--r--object.c22
-rw-r--r--pack.c157
-rw-r--r--parse.y48
-rw-r--r--process.c44
-rw-r--r--re.h1
-rw-r--r--regex.c1
-rw-r--r--ruby.c22
-rw-r--r--ruby.h16
-rw-r--r--rubyio.h1
-rw-r--r--sample/cal.rb4
-rw-r--r--st.c9
-rw-r--r--string.c6
-rw-r--r--top.sed2
-rw-r--r--variable.c168
-rw-r--r--version.h2
44 files changed, 911 insertions, 470 deletions
diff --git a/ChangeLog b/ChangeLog
index 45aa37915a..b08a28f836 100644
--- a/ChangeLog
+++ b/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.
diff --git a/MANIFEST b/MANIFEST
index 51931493ae..131906d4d7 100644
--- a/MANIFEST
+++ b/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
diff --git a/README.EXT b/README.EXT
index a6d6cdbc33..f169e54995 100644
--- a/README.EXT
+++ b/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です.このデータタイプのオブジェクトはひと
-つずつしか存在しません.
-
-データタイプがT_FIXNUMの時,これは31bitのサイズを持つ整数で
-す.FIXNUMをCの整数に変換するためにはマクロ「FIX2INT()」を使
-います.それから,FIXNUMに限らずRubyのデータを整数に変換する
-「NUM2INT()」というマクロがあります.このマクロはデータタイ
-プのチェック無しで使えます(整数に変換できない場合には例外が
-発生する).
-
-それ以外のデータタイプは対応するCの構造体があります.対応す
-る構造体のあるVALUEはそのままキャスト(型変換)すれば構造体の
-ポインタに変換できます.
-
-構造体は「struct RXxxxx」という名前でruby.hで定義されていま
-す.例えば文字列は「struct RString」です.実際に使う可能性が
-あるのは文字列と配列くらいだと思います.
-
-ruby.hでは構造体へキャストするマクロも「RXXXXX()」(全部大文
-字にしたもの)という名前で提供されています(例: RSTRING()).
-
-例えば,文字列strの長さを得るためには「RSTRING(str)->len」と
-し,文字列strをchar*として得るためには「RSTRING(str)->ptr」
-とします.配列の場合には,それぞれ「RARRAT(str)->len」,
-「RARRAT(str)->ptr」となります.
-
-Rubyの構造体を直接アクセスする時に気をつけなければならないこ
-とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
-ないことです.直接変更した場合,オブジェクトの内容の整合性が
-とれなくなって,思わぬバグの原因になります.
+The data for type T_NIL, T_FALSE, T_TRUE are nil, true, false
+respectively. They are singletons for the data type.
+
+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.
+
+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".
+
+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.
+
+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()は整数がFIXNUMの範囲に収まらない場合,Bignumに変換
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インタプリタに新しい機能
を追加することができます.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の機能を実現している関数を直接呼び出すことが出来
-ます.
-
-# このような関数の一覧表はいまのところありません.ソースを見
-# るしかないですね.
-
-それ以外にもRubyの機能を呼び出す方法はいくつかあります.
+There are several ways to invoke Ruby's features from C code.
-2.2.1 Rubyのプログラムをevalする
+2.2.1 Evaluate Ruby Program in String
-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について説明しておきましょう.
-
-IDとは変数名,メソッド名を表す整数です.Rubyの中では
+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:
- :識別子
+ :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の構造体へのポインタは変数svalに代入されます.
4.Example - Create dbm module
-ここまでの説明でとりあえず拡張モジュールは作れるはずです.
+ここまでの説明でとりあえず拡張ライブラリは作れるはずです.
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
して段階的に説明します.
@@ -485,39 +461,30 @@ Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
% 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_モジュール名」と
--
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のディレクトリでmakeを実行するとMakefileを生成からmake,
してくれます.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のサブクラスとして新しいRubyクラスを定義し,moduleの定
オブジェクトをモジュール(で定義されているメソッド)で拡張する.
-** 大域変数定義
+** 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時に標準エラー出力に警告情報を表示する.引数はprintf()と同じ.
況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外
処理は一切行なわれない.
-** 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:
diff --git a/README.EXT.jp b/README.EXT.jp
index 9dbd845fa7..87175be853 100644
--- a/README.EXT.jp
+++ b/README.EXT.jp
@@ -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では構造体へキャストするマクロも「RXXXXX()」(全部大文
例えば,文字列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には引数としてRubyの配列を与えます.
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の構造体へのポインタは変数svalに代入されます.
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というファイルは,静的リンクのmakeの時にディレクトリ
(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を書き換えるなどしてMakefileの再生成が必要な時はま
動的リンクライブラリはmake installでRubyライブラリのディレク
トリの下にコピーされます.もしモジュールと協調して使うRubyで
記述されたプログラムがあり,Rubyライブラリに置きたい場合には,
-拡張モジュール用のディレクトリの下に lib というディレクトリ
+拡張ライブラリ用のディレクトリの下に lib というディレクトリ
を作り,そこに 拡張子 .rb のファイルを置いておけば同時にイン
ストールされます.
@@ -775,13 +775,13 @@ extconf.rbを書き換えるなどしてMakefileの再生成が必要な時はま
(11) できあがり
後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお
-使いください.Rubyの作者は拡張モジュールに関して一切の権利を
+使いください.Rubyの作者は拡張ライブラリに関して一切の権利を
主張しません.
Appendix A. Rubyのソースコードの分類
Rubyのソースはいくつかに分類することが出来ます.このうちクラ
-スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ
+スライブラリの部分は基本的に拡張ライブラリと同じ作り方になっ
ています.これらのソースは今までの説明でほとんど理解できると
思います.
@@ -962,11 +962,11 @@ onlyであること以外はrb_define_variable()と同じ.
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で指定した例外を発生させる.fmt以下の引数はprintf()と同じ.
** 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はモジュール名を表
す.
diff --git a/ToDo b/ToDo
index edb238997c..87fd542424 100644
--- a/ToDo
+++ b/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
diff --git a/config.guess b/config.guess
index d62857905a..d1eb24fcc1 100644
--- a/config.guess
+++ b/config.guess
@@ -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
diff --git a/configure.in b/configure.in
index 6aa2254633..33b43deed2 100644
--- a/configure.in
+++ b/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
diff --git a/dln.c b/dln.c
index 0c06a03b12..418bb6b76e 100644
--- a/dln.c
+++ b/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;
}
diff --git a/enum.c b/enum.c
index 61d47613f5..7dd1842126 100644
--- a/enum.c
+++ b/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;
}
diff --git a/error.c b/error.c
index bec8febff0..44ca067472 100644
--- a/error.c
+++ b/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
diff --git a/eval.c b/eval.c
index 79ce7abed7..9679eeb102 100644
--- a/eval.c
+++ b/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
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index b60951538d..e1623529b6 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -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)
diff --git a/ext/gtk/gtk.c b/ext/gtk/gtk.c
index fb7c5918a4..1afe083d9e 100644
--- a/ext/gtk/gtk.c
+++ b/ext/gtk/gtk.c
@@ -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);
}
diff --git a/gc.c b/gc.c
index 82b677c93b..dde9826aa5 100644
--- a/gc.c
+++ b/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;
diff --git a/hash.c b/hash.c
index d7d6f4de2c..6ce5313202 100644
--- a/hash.c
+++ b/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;
diff --git a/intern.h b/intern.h
index 86a74b844e..364e97e0d7 100644
--- a/intern.h
+++ b/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));
diff --git a/io.c b/io.c
index 1da75b6411..7144f59fa8 100644
--- a/io.c
+++ b/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) {
diff --git a/lib/debug.rb b/lib/debug.rb
index 497d163024..90270a3fe7 100644
--- a/lib/debug.rb
+++ b/lib/debug.rb
@@ -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
}
diff --git a/lib/delegate.rb b/lib/delegate.rb
index d784586702..594c500cab 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -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
diff --git a/lib/mailread.rb b/lib/mailread.rb
index 8ec951e754..5e46606c09 100644
--- a/lib/mailread.rb
+++ b/lib/mailread.rb
@@ -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
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 0aa9d98b9c..218b3b19f6 100644
--- a/lib/mkmf.rb
+++ b/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"
diff --git a/lib/pstore.rb b/lib/pstore.rb
index f075dbc8bb..2aa9864b58 100644
--- a/lib/pstore.rb
+++ b/lib/pstore.rb
@@ -110,6 +110,7 @@ class PStore
@abort = false
end
ensure
+ @table = nil
@transaction = false
end
value
diff --git a/misc/README b/misc/README
new file mode 100644
index 0000000000..adc119d02e
--- /dev/null
+++ b/misc/README
@@ -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
diff --git a/sample/inf-ruby.el b/misc/inf-ruby.el
index 504aff2db7..8668f1d217 100644
--- a/sample/inf-ruby.el
+++ b/misc/inf-ruby.el
@@ -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
;;;
diff --git a/sample/ruby-mode.el b/misc/ruby-mode.el
index 8bf843c1ea..d202561402 100644
--- a/sample/ruby-mode.el
+++ b/misc/ruby-mode.el
@@ -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
diff --git a/sample/rubydb2x.el b/misc/rubydb2x.el
index a74265fb0e..a74265fb0e 100644
--- a/sample/rubydb2x.el
+++ b/misc/rubydb2x.el
diff --git a/sample/rubydb3x.el b/misc/rubydb3x.el
index 9d4e31f90e..9d4e31f90e 100644
--- a/sample/rubydb3x.el
+++ b/misc/rubydb3x.el
diff --git a/missing/nt.c b/missing/nt.c
index a78d82e1ef..3f25c81cd4 100644
--- a/missing/nt.c
+++ b/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;
}
diff --git a/numeric.c b/numeric.c
index d1921f3898..74350d579f 100644
--- a/numeric.c
+++ b/numeric.c
@@ -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);
diff --git a/object.c b/object.c
index 033539f159..5abf4db5ab 100644
--- a/object.c
+++ b/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);
diff --git a/pack.c b/pack.c
index cfe4b8bad2..6b29857734 100644
--- a/pack.c
+++ b/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;
diff --git a/parse.y b/parse.y
index 9e8cfad2bb..2fc4de40e9 100644
--- a/parse.y
+++ b/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);
}
diff --git a/process.c b/process.c
index e4d0d0ab82..79d30c8139 100644
--- a/process.c
+++ b/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");
@@ -835,6 +819,20 @@ proc_setpgrp(argc, argv)
}
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));
diff --git a/re.h b/re.h
index 8aeb4e3980..3bbbd91f07 100644
--- a/re.h
+++ b/re.h
@@ -3,7 +3,6 @@
re.h -
$Author$
- $Revision$
$Date$
created at: Thu Sep 30 14:18:32 JST 1993
diff --git a/regex.c b/regex.c
index b3cbb77f2c..c5a903e721 100644
--- a/regex.c
+++ b/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
diff --git a/ruby.c b/ruby.c
index 289798ab9c..fb78235d92 100644
--- a/ruby.c
+++ b/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
diff --git a/ruby.h b/ruby.h
index 174cfd68a8..f0978baccd 100644
--- a/ruby.h
+++ b/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
diff --git a/rubyio.h b/rubyio.h
index 9fc4ec8a70..5b8baf0f15 100644
--- a/rubyio.h
+++ b/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 *));
diff --git a/sample/cal.rb b/sample/cal.rb
index b0f5d88335..a5f4b4db18 100644
--- a/sample/cal.rb
+++ b/sample/cal.rb
@@ -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"
diff --git a/st.c b/st.c
index a48d11e9aa..a4bee22c61 100644
--- a/st.c
+++ b/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 */
diff --git a/string.c b/string.c
index 710de1aa48..a97319e5c7 100644
--- a/string.c
+++ b/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;
}
diff --git a/top.sed b/top.sed
index bb9a96c146..a9ec12f7b6 100644
--- a/top.sed
+++ b/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
diff --git a/variable.c b/variable.c
index 85d6eafdaa..a0502315bb 100644
--- a/variable.c
+++ b/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;
diff --git a/version.h b/version.h
index 8f49f67368..18f352c9cf 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
#define RUBY_VERSION "1.1d0"
-#define VERSION_DATE "98/09/08"
+#define VERSION_DATE "98/12/16"