From 1f8e38befa8e9aef05e4aaa14f464c1754f40cd7 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Fri, 23 Jan 1998 10:40:43 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'v1_1b6'. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_1b6@52 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 59 + MANIFEST | 4 + README.EXT.jp | 1072 +++++++++ array.c | 2 +- class.c | 18 +- compar.c | 2 +- dir.c | 2 +- dln.c | 10 +- enum.c | 2 +- error.c | 4 +- eval.c | 164 +- ext/Setup | 1 + ext/extmk.rb.in | 2 +- ext/gtk/MANIFEST | 18 - ext/gtk/extconf.rb | 6 - ext/gtk/gtk.c | 5904 ----------------------------------------------- ext/gtk/test.rb | 96 - ext/gtk/test.xpm | 92 - ext/gtk/test0.rb | 13 - ext/gtk/test1.rb | 41 - ext/gtk/test2.rb | 89 - ext/gtk/test3.rb | 16 - ext/gtk/test4.rb | 77 - ext/gtk/test5.rb | 63 - ext/gtk/test6.rb | 49 - ext/gtk/test7.rb | 49 - ext/gtk/test8.rb | 49 - ext/gtk/test9.rb | 98 - ext/gtk/testa.rb | 78 - ext/gtk/testb.rb | 78 - ext/gtk/testc.rb | 64 - ext/marshal/MANIFEST | 5 - ext/marshal/depend | 2 - ext/marshal/extconf.rb | 1 - ext/marshal/marshal.c | 850 ------- ext/marshal/marshal.doc | 48 - ext/tcltklib/extconf.rb | 105 +- file.c | 98 +- gc.c | 10 +- hash.c | 2 +- inits.c | 2 +- instruby.rb | 1 + io.c | 5 +- io.h | 2 +- lib/Env.rb | 28 + lib/complex.rb | 4 +- lib/date.rb | 4 +- lib/delegate.rb | 3 + lib/e2mmap.rb | 6 +- lib/e2mmap1_0.rb | 71 - lib/final.rb | 41 + lib/finalize.rb | 156 +- lib/ftplib.rb | 6 +- lib/mathn.rb | 4 +- lib/matrix.rb | 6 +- lib/mutex_m.rb | 4 +- lib/rational.rb | 4 +- lib/sync.rb | 8 +- lib/tempfile.rb | 72 + lib/thwait.rb | 6 +- lib/tk.rb | 22 +- lib/tkcore.rb | 528 ----- lib/tkmenubar.rb | 137 ++ lib/tkthcore.rb | 550 ----- math.c | 2 +- missing/dir.h | 21 +- node.h | 5 +- numeric.c | 2 +- object.c | 13 +- pack.c | 2 +- parse.y | 31 +- process.c | 7 +- random.c | 2 +- range.c | 2 +- re.c | 6 +- re.h | 2 +- regex.c | 3389 +++++++++++++++++++++++++++ ruby.c | 4 +- ruby.h | 5 +- sample/io.rb | 44 - sample/rbc.rb | 6 +- sample/ruby-mode.el | 4 +- sprintf.c | 2 +- st.c | 435 ++++ st.h | 52 + string.c | 2 +- time.c | 2 +- util.c | 2 +- util.h | 2 +- variable.c | 137 +- version.c | 4 +- version.h | 4 +- win32/sdbm.c | 4 +- 93 files changed, 5801 insertions(+), 9405 deletions(-) create mode 100644 README.EXT.jp delete mode 100644 ext/gtk/MANIFEST delete mode 100644 ext/gtk/extconf.rb delete mode 100644 ext/gtk/gtk.c delete mode 100644 ext/gtk/test.rb delete mode 100644 ext/gtk/test.xpm delete mode 100644 ext/gtk/test0.rb delete mode 100644 ext/gtk/test1.rb delete mode 100644 ext/gtk/test2.rb delete mode 100644 ext/gtk/test3.rb delete mode 100644 ext/gtk/test4.rb delete mode 100644 ext/gtk/test5.rb delete mode 100644 ext/gtk/test6.rb delete mode 100644 ext/gtk/test7.rb delete mode 100644 ext/gtk/test8.rb delete mode 100644 ext/gtk/test9.rb delete mode 100644 ext/gtk/testa.rb delete mode 100644 ext/gtk/testb.rb delete mode 100644 ext/gtk/testc.rb delete mode 100644 ext/marshal/MANIFEST delete mode 100644 ext/marshal/depend delete mode 100644 ext/marshal/extconf.rb delete mode 100644 ext/marshal/marshal.c delete mode 100644 ext/marshal/marshal.doc create mode 100644 lib/Env.rb delete mode 100644 lib/e2mmap1_0.rb create mode 100644 lib/final.rb create mode 100644 lib/tempfile.rb delete mode 100644 lib/tkcore.rb create mode 100644 lib/tkmenubar.rb delete mode 100644 lib/tkthcore.rb create mode 100644 regex.c delete mode 100644 sample/io.rb create mode 100644 st.c create mode 100644 st.h diff --git a/ChangeLog b/ChangeLog index 029e20077c..436061191b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,60 @@ +Fri Jan 23 14:19:28 1998 Yukihiro Matsumoto + + * version 1.1b6 released. + + * object.c (mod_to_s): need to duplicate classpath. + + * error.c (exc_inspect): need to duplicate classpath. + +Thu Jan 22 00:37:47 1998 Yukihiro Matsumoto + + * ruby.h (STR2CSTR): new macro to retrieve char*. + + * class.c (rb_define_method): `initialize' should always be + private, even if it defined by C extensions. + + * eval.c (rb_eval): `initialize' should always be private. + +Thu Jan 22 16:21:08 1998 Yukihiro Matsumoto + + * eval.c (rb_eval): some singleton class def cause SEGV. + + * eval.c (ALLOCTMP): replace ALLOCA_N, where thread context switch + may happen. + +Wed Jan 21 01:43:42 1998 Yukihiro Matsumoto + + * eval.c (PUSH_FRAME): do not use ALLOCA_N(). crash on some + platforms that use missing/alloca.c. + + * regex.c (re_compile_pattern): too many pops for non register + subexpr. + + * parse.y (yylex): open parentheses after identifiers are argument + list, even if whitespaces have seen. + +Tue Jan 20 15:19:59 1998 Yukihiro Matsumoto + + * parse.y (terms): quoted word list by %w(a b c). + + * ext/tcltklib/extconf.rb: more accurate check for tcl/tk libs. + + * file.c (rb_stat): most of the FileTest methods (and function + `test') accept File objects as the argument. + +Tue Jan 19 18:19:24 1998 WATANABE Hirofumi + + * ext/extmk.rb.in (install): there should be no newline after install: + + * re.c (MIN): renamed from min(). there's a local variable named + min in the file, so that some cpp will raise an error. + +Mon Jan 19 16:30:05 1998 Yukihiro Matsumoto + + * version 1.1b5 released. + + * process.c (rb_syswait): no exception raised. + Fri Jan 16 00:43:43 1998 Yukihiro Matsumoto * ruby.h (CLONESETUP): copies its singleton classes too. @@ -27,6 +84,8 @@ Tue Jan 13 10:00:18 1998 Yukihiro Matsumoto Fri Jan 9 13:19:55 1998 Yukihiro Matsumoto + * version 1.1b4 released. + * eval.c (f_missing): class name omitted from the error message. * error.c (exc_inspect): description changed. diff --git a/MANIFEST b/MANIFEST index 2bdaf290b3..27bb946f50 100644 --- a/MANIFEST +++ b/MANIFEST @@ -5,6 +5,7 @@ Makefile.in README README.jp README.EXT +README.EXT.jp ToDo array.c bignum.c @@ -81,6 +82,7 @@ ext/extmk.rb.in ext/extmk.rb.nt ext/aix_ld.rb lib/English.rb +lib/Env.rb lib/base64.rb lib/cgi-lib.rb lib/complex.rb @@ -110,6 +112,7 @@ lib/pstore.rb lib/rational.rb lib/shellwords.rb lib/sync.rb +lib/tempfile.rb lib/thread.rb lib/thwait.rb lib/tk.rb @@ -117,6 +120,7 @@ lib/tkcanvas.rb lib/tkclass.rb lib/tkdialog.rb lib/tkentry.rb +lib/tkmenubar.rb lib/tkscrollbox.rb lib/tktext.rb lib/tracer.rb diff --git a/README.EXT.jp b/README.EXT.jp new file mode 100644 index 0000000000..3b430de65a --- /dev/null +++ b/README.EXT.jp @@ -0,0 +1,1072 @@ +.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995 + +rubyの拡張モジュールの作り方を説明します. + +1.基礎知識 + +Cの変数には型があり,データには型がありません.ですから,た +とえばポインタをintの変数に代入すると,その値は整数として取 +り扱われます.逆にrubyの変数には型がなく,データに型がありま +す.この違いのため,Cとrubyは相互に変換しなければ,お互いの +データをアクセスできません. + +rubyのデータはVALUEというCの型で表現されます.VALUE型のデー +タはそのデータタイプを自分で知っています.このデータタイプと +いうのはデータ(オブジェクト)の実際の構造を意味していて,ruby +のクラスとはまた違ったものです. + +VALUEからCにとって意味のあるデータを取り出すためには + + (1) VALUEのデータタイプを知る + (2) VALUEをCのデータに変換する + +の両方が必要です.(1)を忘れると間違ったデータの変換が行われ +て,最悪プログラムがcore dumpします. + +1.1 データタイプ + +rubyにはユーザが使う可能性のある以下のタイプがあります. + + T_NIL nil + T_OBJECT 通常のオブジェクト + T_CLASS クラス + T_MODULE モジュール + T_FLOAT 浮動小数点数 + T_STRING 文字列 + T_REGEXP 正規表現 + T_ARRAY 配列 + T_FIXNUM Fixnum(31bit長整数) + T_HASH 連想配列 + T_STRUCT (rubyの)構造体 + T_BIGNUM 多倍長整数 + T_TRUE 真 + T_FALSE 偽 + T_DATA データ + +その他に内部で利用されている以下のタイプがあります. + + T_ICLASS + T_MATCH + T_VARMAP + T_SCOPE + T_NODE + +いくつかのタイプはCの構造体で実装されています. + +1.2 VALUEのデータタイプをチェックする + +ruby.hではTYPE()というマクロが定義されていて,VALUEのデータ +タイプを知ることが出来ます.TYPE()マクロは上で紹介したT_XXXX +の形式の定数を返します.VALUEのデータタイプに応じて処理する +場合には,TYPE()の値で分岐することになります. + + switch (TYPE(obj)) { + case T_FIXNUM: + /* FIXNUMの処理 */ + break; + case T_STRING: + /* 文字列の処理 */ + break; + case T_ARRAY: + /* 配列の処理 */ + break; + default: + /* 例外を発生させる */ + Fail("not valid value"); + break; + } + +それとデータタイプをチェックして,正しくなければ例外を発生す +る関数が用意されています. + + void Check_Type(VALUE value, int type) + +この関数はvalueがtypeで無ければ,例外を発生させます.引数と +して与えられたVALUEのデータタイプが正しいかどうかチェックす +るためには,この関数を使います. + +FIXNUMとNILに関してはより高速な判別マクロが用意されています. + + FIXNUM_P(obj) + NIL_P(obj) + +1.3 VALUEをCのデータに変換する + +データタイプが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の構造体を直接アクセスする時に気をつけなければならないこ +とは,配列や文字列の構造体の中身は参照するだけで,直接変更し +ないことです.直接変更した場合,オブジェクトの内容の整合性が +とれなくなって,思わぬバグの原因になります. + +1.4 CのデータをVALUEに変換する + +VALUEの実際の構造は + + * FIXNUMの場合 + + 1bit右シフトして,LSBを立てる. + + * その他のポインタの場合 + + そのままVALUEにキャストする. + +となっています.よって,LSBをチェックすればVALUEがFIXNUMかど +うかわかるわけです(ポインタのLSBが立っていないことを仮定して +いる). + +ですから,FIXNUM以外のrubyのオブジェクトの構造体は単にVALUE +にキャストするだけでVALUEに変換出来ます.ただし,任意の構造 +体がVALUEにキャスト出来るわけではありません.キャストするの +はrubyの知っている構造体(ruby.hで定義されているstruct RXxxx +のもの)だけにしておいてください. + +FIXNUMに関しては変換マクロを経由する必要があります.Cの整数 +からVALUEに変換するマクロは以下のものがあります.必要に応じ +て使い分けてください. + + INT2FIX() もとの整数が31bit以内に収まる時 + INT2NUM() 任意の整数からVALUEへ + +INT2NUM()は整数がFIXNUMの範囲に収まらない場合,Bignumに変換 +してくれます(が,少し遅い). + +1.5 rubyのデータを操作する + +先程も述べた通り,rubyの構造体をアクセスする時に内容の更新を +行うことは勧められません.で,rubyのデータを操作する時には +rubyが用意している関数を用いてください. + +ここではもっとも使われるであろう文字列と配列の生成/操作を行 +い関数をあげます(全部ではないです). + + 文字列に対する関数 + + str_new(char *ptr, int len) + + 新しいrubyの文字列を生成する. + + str_new2(char *ptr) + + Cの文字列からrubyの文字列を生成する.この関数の機能は + str_new(ptr, strlen(ptr))と同等である. + + str_cat(VALUE str, char *ptr, int len) + + rubyの文字列strにlenバイトの文字列ptrを追加する. + + 配列に対する関数 + + ary_new() + + 要素が0の配列を生成する. + + ary_new2(int len) + + 要素が0の配列を生成する.len要素分の領域をあらかじめ割り + 当てておく. + + ary_new3(int n, ...) + + 引数で指定したn要素を含む配列を生成する. + + ary_new4(int n, VALUE *elts) + + 配列で与えたn要素の配列を生成する. + + ary_push(VALUE ary) + ary_pop(VALUE ary, VALUE val) + ary_shift(VALUE ary) + ary_unshift(VALUE ary, VALUE val) + ary_entry(VALUE ary, int idx) + + Arrayの同名のメソッドと同じ働きをする関数.第1引数は必ず + 配列でなければならない. + +2.rubyの機能を使う + +原理的にrubyで書けることはCでも書けます.rubyそのものがCで記 +述されているんですから,当然といえば当然なんですけど.ここで +はrubyの拡張に使うことが多いだろうと予測される機能を中心に紹 +介します. + +2.1 rubyに機能を追加する + +rubyで提供されている関数を使えばrubyインタプリタに新しい機能 +を追加することができます.rubyでは以下の機能を追加する関数が +提供されています. + + * クラス,モジュール + * メソッド,特異メソッドなど + * 定数 + +では順に紹介します. + +2.1.1 クラス/モジュール定義 + +クラスやモジュールを定義するためには,以下の関数を使います. + + VALUE rb_define_class(char *name, VALUE super) + VALUE rb_define_module(char *name) + +これらの関数は新しく定義されたクラスやモジュールを返します. +メソッドや定数の定義にこれらの値が必要なので,ほとんどの場合 +は戻り値を変数に格納しておく必要があるでしょう. + +2.1.2 メソッド/特異メソッド定義 + +メソッドや特異メソッドを定義するには以下の関数を使います. + + 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) + + +念のため説明すると「特異メソッド」とは,その特定のオブジェク +トに対してだけ有効なメソッドです.rubyではよくSmalltalkにお +けるクラスメソッドとして,クラスに対する特異メソッドが使われ +ます. + +これらの関数の argcという引数はCの関数へ渡される引数の数(と +形式)を決めます.argcが正の時は関数に引き渡す引数の数を意味 +します.16個以上の引数は使えません(が,要りませんよね,そん +なに). + +argcが負の時は引数の数ではなく,形式を指定したことになります. +argcが-1の時は引数を配列に入れて渡されます.argcが-2の時は引 +数はrubyの配列として渡されます. + +メソッドを定義する関数はもう二つあります.ひとつはprivateメ +ソッドを定義する関数で,引数はrb_define_method()と同じです. + + void rb_define_private_method(VALUE class, char *name, + VALUE (*func)(), int argc) + +privateメソッドとは関数形式でしか呼び出すことの出来ないメソッ +ドです. + +もうひとつはモジュール関数を定義するものです.モジュール関数 +とはモジュールの特異メソッドであり,同時にprivateメソッドで +もあるものです.例をあげるとMathモジュールのsqrt()などがあげ +られます.このメソッドは + + Math.sqrt(4) + +という形式でも + + include Math + sqrt(4) + +という形式でも使えます.モジュール関数を定義する関数は以下の +通りです. + + void rb_define_module_function(VALUE module, char *name, + VALUE (*func)(), int argc) + +関数的メソッド(Kernelモジュールのprivaet method)を定義するた +めの関数は以下の通りです. + + void rb_define_global_function(char *name, VALUE (*func)(), int argc) + + +2.1.3 定数定義 + +拡張モジュールが必要な定数はあらかじめ定義しておいた方が良い +でしょう.定数を定義する関数は二つあります. + + void rb_define_const(VALUE class, char *name, VALUE val) + void rb_define_global_const(char *name, VALUE val) + +前者は特定のクラス/モジュールに属する定数を定義するもの,後 +者はグローバルな定数を定義するものです. + +2.2 rubyの機能をCから呼び出す + +既に『1.5 rubyのデータを操作する』で一部紹介したような関数を +使えば,rubyの機能を実現している関数を直接呼び出すことが出来 +ます. + +# このような関数の一覧表はいまのところありません.ソースを見 +# るしかないですね. + +それ以外にもrubyの機能を呼び出す方法はいくつかあります. + +2.2.1 rubyのプログラムをevalする + +Cからrubyの機能を呼び出すもっとも簡単な方法として,文字列で +与えられたrubyのプログラムを評価する関数があります. + + VALUE rb_eval_string(char *str) + +この評価は現在の環境で行われます.つまり,現在のローカル変数 +などを受け継ぎます. + +2.2.2 IDまたはシンボル + +Cから文字列を経由せずにrubyのメソッドを呼び出すこともできま +す.その前に,rubyインタプリタ内でメソッドや変数名を指定する +時に使われているIDについて説明しておきましょう. + +IDとは変数名,メソッド名を表す整数です.rubyの中では + + :識別子 + +でアクセスできます.Cからこの整数を得るためには関数 + + rb_intern(char *name) + +を使います.また一文字の演算子はその文字コードがそのままシン +ボルになっています. + +2.2.3 Cからrubyのメソッドを呼び出す + +Cから文字列を経由せずにrubyのメソッドを呼び出すためには以下 +の関数を使います. + + VALUE rb_funcall(VALUE recv, ID mid, int argc, ...) + +この関数はオブジェクトrecvのmidで指定されるメソッドを呼び出 +します. + +2.2.4 変数/定数を参照/更新する + +Cから関数を使って参照・更新できるのは,クラス定数,インスタ +ンス変数です.大域変数は一部のものはCの大域変数としてアクセ +スできます.ローカル変数を参照する方法は公開していません. + +オブジェクトのインスタンス変数を参照・更新する関数は以下の通 +りです. + + VALUE rb_ivar_get(VALUE obj, ID id) + VALUE rb_ivar_set(VALUE obj, ID id, VALUE val) + +idはrb_intern()で得られるものを使ってください. + +クラス定数を参照するには以下の関数を使ってください. + + VALUE rb_const_get(VALUE obj, ID id) + +クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ +れている関数を使ってください. + +3.rubyとCとの情報共有 + +C言語とrubyの間で情報を共有する方法について解説します. + +3.1 Cから参照できるrubyの定数 + +以下のrubyの定数はCのレベルから参照できる. + + TRUE + FALSE + +真偽値.FALSEはC言語でも偽とみなされる(つまり0). + + Qnil + +C言語から見た「nil」. + +3.2 Cとrubyで共有される大域変数 + +Cとrubyで大域変数を使って情報を共有できます.共有できる大域 +変数にはいくつかの種類があります.そのなかでもっとも良く使わ +れると思われるのはrb_define_variable()です. + + void rb_define_variable(char *name, VALUE *var) + +この関数はrubyとCとで共有する大域変数を定義します.変数名が +`$'で始まらない時には自動的に追加されます.この変数の値を変 +更すると自動的にrubyの対応する変数の値も変わります. + +またruby側からは更新できない変数もあります.このread onlyの +変数は以下の関数で定義します. + + void rb_define_readonly_variable(char *name, VALUE *var) + +これら変数の他にhookをつけた大域変数を定義できます.hook付き +の大域変数は以下の関数を用いて定義します.hook付き大域変数の +値の参照や設定はhookで行う必要があります. + + void rb_define_hooked_variable(char *name, VALUE *var, + VALUE (*getter)(), VALUE (*setter)()) + +この関数はCの関数によってhookのつけられた大域変数を定義しま +す.変数が参照された時には関数getterが,変数に値がセットされ +た時には関数setterが呼ばれる.hookを指定しない場合はgetterや +setterに0を指定します. + +# getterもsetterも0ならばrb_define_variable()と同じになる. + +それから,Cの関数によって実現されるrubyの大域変数を定義する +関数があります. + + void rb_define_virtual_variable(char *name, + VALUE (*getter)(), VALUE (*setter)()) + +この関数によって定義されたrubyの大域変数が参照された時には +getterが,変数に値がセットされた時にはsetterが呼ばれます. + +getterとsetterの仕様は以下の通りです. + + (*getter)(ID id, void *data, struct global_entry* entry); + (*setter)(VALUE val, ID id, void *data, struct global_entry* entry); + +3.3 Cのデータをrubyオブジェクトにする + +Cの世界で定義されたデータ(構造体)をrubyのオブジェクトとして +取り扱いたい場合がありえます.このような場合には,Dataという +rubyオブジェクトにCの構造体(へのポインタ)をくるむことでruby +オブジェクトとして取り扱えるようになります. + +Dataオブジェクトを生成して構造体をrubyオブジェクトにカプセル +化するためには,以下のマクロを使います. + + Data_Wrap_Struct(class,mark,free,ptr) + +このマクロの戻り値は生成されたDataオブジェクトです. + +classはこのDataオブジェクトのクラスです.ptrはカプセル化する +Cの構造体へのポインタです.markはこの構造体がrubyのオブジェ +クトへの参照がある時に使う関数です.そのような参照を含まない +時には0を指定します. + +# そのような参照は勧められません. + +freeはこの構造体がもう不要になった時に呼ばれる関数です.この +関数がガーベージコレクタから呼ばれます. + +Cの構造体の割当とDataオブジェクトの生成を同時に行うマクロと +して以下のものが提供されています. + + Data_Make_Struct(class, type, mark, free, sval) + +このマクロの戻り値は生成されたDataオブジェクトです. + +class, mark, freeはData_Wrap_Structと同じ働きをします.type +は割り当てるC構造体の型です.割り当てられた構造体は変数sval +に代入されます.この変数の型は (type*) である必要があります. + +Dataオブジェクトからポインタを取り出すのは以下のマクロを用い +ます. + + Data_Get_Struct(obj, type, sval) + +Cの構造体へのポインタは変数svalに代入されます. + +これらのDataの使い方はちょっと分かりにくいので,後で説明する +例題を参照してください. + +4.例題 - dbmパッケージを作る + +ここまでの説明でとりあえず拡張モジュールは作れるはずです. +rubyのextディレクトリにすでに含まれているdbmモジュールを例に +して段階的に説明します. + +(1) ディレクトリを作る + + % mkdir ext/dbm + +rubyを展開したディレクトリの下,extディレクトリの中に拡張モ +ジュール用のディレクトリを作ります.名前は適当に選んで構いま +せん. + +(2) MANIFESTファイルを作る + + % cd ext/dbm + % touch MANIFEST + +拡張モジュールのディレクトリの下にはMANIFESTというファイルが +必要なので,とりあえず空のファイルを作っておきます.後でこの +ファイルには必要なファイル一覧が入ることになります. + +MANIFESTというファイルは,makeの時にディレクトリが拡張モジュー +ルを含んでいるかどうか判定するために使われれています. + +(3) 設計する + +まあ,当然なんですけど,どういう機能を実現するかどうかまず設 +計する必要があります.どんなクラスをつくるか,そのクラスには +どんなメソッドがあるか,クラスが提供する定数などについて設計 +します.dbmクラスについてはext/dbm.docを参照してください. + +(4) Cコードを書く + +拡張モジュール本体となるC言語のソースを書きます.C言語のソー +スがひとつの時には「モジュール名.c」を選ぶと良いでしょう.C +言語のソースが複数の場合には逆に「モジュール名.c」というファ +イル名は避ける必要があります.オブジェクトファイルとモジュー +ル生成時に中間的に生成される「モジュール名.o」というファイル +とが衝突するからです. + +rubyは拡張モジュールをロードする時に「Init_モジュール名」と +いう関数を自動的に実行します.dbmモジュールの場合「Init_dbm」 +です.この関数の中でクラス,モジュール,メソッド,定数などの +定義を行います.dbm.cから一部引用します. + +-- +Init_dbm() +{ + /* DBMクラスを定義する */ + cDBM = rb_define_class("DBM", cObject); + /* DBMはEnumerateモジュールをインクルードする */ + rb_include_module(cDBM, mEnumerable); + + /* DBMクラスのクラスメソッドopen(): 引数はCの配列で受ける */ + rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1); + + /* DBMクラスのメソッドclose(): 引数はなし */ + rb_define_method(cDBM, "close", fdbm_close, 0); + /* DBMクラスのメソッド[]: 引数は1個 */ + rb_define_method(cDBM, "[]", fdbm_fetch, 1); + : + + /* DBMデータを格納するインスタンス変数名のためのID */ + id_dbm = rb_intern("dbm"); +} +-- + +DBMモジュールはdbmのデータと対応するオブジェクトになるはずで +すから,Cの世界のdbmをrubyの世界に取り込む必要があります. + + +dbm.cではData_Make_Structを以下のように使っています. + +-- +struct dbmdata { + int di_size; + DBM *di_dbm; +}; + + +obj = Data_Make_Struct(class,struct dbmdata,0,free_dbm,dbmp); +-- + +ここではdbmstruct構造体へのポインタをDataにカプセル化してい +ます.DBM*を直接カプセル化しないのはclose()した時の処理を考 +えてのことです. + +Dataオブジェクトからdbmstruct構造体のポインタを取り出すため +に以下のマクロを使っています. + +-- +#define GetDBM(obj, dbmp) {\ + Data_Get_Struct(obj, struct dbmdata, dbmp);\ + if (dbmp->di_dbm == 0) closed_dbm();\ +} +-- + +ちょっと複雑なマクロですが,要するにdbmdata構造体のポインタ +の取り出しと,closeされているかどうかのチェックをまとめてい +るだけです. + +DBMクラスにはたくさんメソッドがありますが,分類すると3種類の +引数の受け方があります.ひとつは引数の数が固定のもので,例と +してはdeleteメソッドがあります.deleteメソッドを実装している +fdbm_delete()はこのようになっています. + +-- +static VALUE +fdbm_delete(obj, keystr) + VALUE obj, keystr; +{ + : +} +-- + +引数の数が固定のタイプは第1引数がself,第2引数以降がメソッド +の引数となります. + +引数の数が不定のものはCの配列で受けるものとrubyの配列で受け +るものとがあります.dbmモジュールの中で,Cの配列で受けるもの +はDBMのクラスメソッドであるopen()です.これを実装している関 +数fdbm_s_open()はこうなっています. + +-- +static VALUE +fdbm_s_open(argc, argv, class) + int argc; + VALUE *argv; + VALUE class; +{ + : + if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) { + mode = 0666; /* default value */ + } + : +} +-- + +このタイプの関数は第1引数が与えられた引数の数,第2引数が与え +られた引数の入っている配列になります.selfは第3引数として与 +えられます. + +この配列で与えられた引数を解析するための関数がopen()でも使わ +れているrb_scan_args()です.第3引数に指定したフォーマットに +従い,第4変数以降に指定した変数に値を代入してくれます.この +フォーマットは,第1文字目が省略できない引数の数,第2文字目が +省略できる引数の数,第3文字目が対応する相手が無いあまりの引 +数があるかどうかを示す"*"です.2文字目と3文字目は省略できま +す.dbm.cの例では,フォーマットは"11"ですから,引数は最低1つ +で,2つまで許されるという意味になります.省略されている時の +変数の値はnil(C言語のレベルではQnil)になります. + +rubyの配列で引数を受け取るものはindexesがあります.実装はこ +うです. + +-- +static VALUE +fdbm_indexes(obj, args) + VALUE obj; + struct RArray *args; +{ + : +} +-- + +第1引数はself,第2引数はrubyの配列です.ここではキャストを減 +らすため struct RArray* で受けていますが,VALUEでも同じこと +です. + +** 注意事項 + +rubyと共有はしないがrubyのオブジェクトを格納する可能性のある +Cの大域変数は以下の関数を使ってrubyインタプリタに変数の存在 +を教えてあげてください.でないとGCでトラブルを起こします. + + void rb_global_variable(VALUE *var) + +(5) extconf.rbを用意する + +もしディレクトリに「extconf.rb」というファイルが存在すれば, +make時に実行されます.なければ適当にMakefileが生成されます. + +extconf.rbはモジュールのコンパイルに必要な条件のチェックなど +を行うことが目的です.extconf.rbの中では以下のruby関数を使う +ことが出来ます. + + have_library(lib, func): ライブラリの存在チェック + have_func(func): 関数の存在チェック + have_header(header): ヘッダファイルの存在チェック + create_makefile(target): Makefileの生成 + +以下の変数を使うことができます. + + $CFLAGS: コンパイル時に追加的に指定するフラグ(-Iなど) + $LDFLAGS: リンク時に追加的に指定するフラグ(-Lなど) + +モジュールをコンパイルする条件が揃わなず,そのモジュールはコ +ンパイルしない時にはcreate_makefileを呼ばなければMakefileは +生成されず,コンパイルも行われません. + +(6) dependを用意する + +もし,ディレクトリにdependというファイルが存在すれば, +Makefileが依存関係をチェックしてくれます. + + % gcc -MM *.c > depend + +などで作ることが出来ます.あって損は無いでしょう. + +(7) MANIFESTファイルにファイル名を入れる + + % ls > MANIFEST + % vi MANIFEST + +*.o, *~など不必要なファイル以外はMANIFESTに追加しておきます. +make時にはMANIFESTの内容は参照しませんので,空のままでも問題 +は起きませんが,パッケージングの時に参照することがあるのと, +必要なファイルを区別できるので,用意しておいた方が良いでしょ +う. + +(8) makeする + +rubyのディレクトリでmakeを実行するとMakefileを生成からmake, +必要によってはそのモジュールのrubyへのリンクまで自動的に実行 +してくれます.extconf.rbを書き換えるなどしてMakefileの再生成 +が必要な時はまたrubyディレクトリでmakeしてください. + +(9) デバッグ + +まあ,デバッグしないと動かないでしょうね.ext/Setupにディレ +クトリ名を書くと静的にリンクするのでデバッガが使えるようにな +ります.その分コンパイルが遅くなりますけど. + +(10) できあがり + +後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお +使いください.rubyの作者は拡張モジュールに関して一切の権利を +主張しません. + +Appendix A. rubyのソースコードの分類 + +rubyのソースはいくつかに分類することが出来ます.このうちクラ +スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ +ています.これらのソースは今までの説明でほとんど理解できると +思います. + +ruby言語のコア + + class.c + error.c + eval.c + gc.c + object.c + parse.y + variable.c + +ユーティリティ関数 + + dln.c + fnmatch.c + glob.c + regex.c + st.c + util.c + +rubyコマンドの実装 + + dmyext.c + inits.c + main.c + ruby.c + version.c + +クラスライブラリ + + array.c + bignum.c + compar.c + dir.c + enum.c + file.c + hash.c + io.c + math.c + numeric.c + pack.c + process.c + random.c + range.c + re.c + signal.c + sprintf.c + string.c + struct.c + time.c + +Appendix B. 拡張用関数リファレンス + +C言語からrubyの機能を利用するAPIは以下の通りである. + +** 型 + + VALUE + +rubyオブジェクトを表現する型.必要に応じてキャストして用いる. +組み込み型を表現するCの型はruby.hに記述してあるRで始まる構造 +体である.VALUE型をこれらにキャストするためにRで始まる構造体 +名を全て大文字にした名前のマクロが用意されている. + +** 変数・定数 + + Qnil + +定数: nilオブジェクト + + TRUE + +定数: TRUEオブジェクト(真のデフォルト値) + + FALSE + +定数: FALSEオブジェクト + +** Cデータのカプセル化 + + Wrap_Data_Ptr(VALUE class, void (*mark)(), void (*free)(), void *sval) + +Cの任意のポインタをカプセル化したrubyオブジェクトを返す.こ +のポインタがrubyからアクセスされなくなった時,freeで指定した +関数が呼ばれる.また,このポインタの指すデータが他のrubyオブ +ジェクトを指している場合,markに指定する関数でマークする必要 +がある. + + Make_Data_Struct(class, type, mark, free, sval) + +type型のメモリをmallocし,変数svalに代入した後,それをカプセ +ル化したデータを返すマクロ. + + Data_Get_Struct(data, type, sval) + +dataからtype型のポインタを取り出し変数svalに代入するマクロ. + +** クラス/モジュール定義 + + VALUE rb_define_class(char *name, VALUE super) + +superのサブクラスとして新しいrubyクラスを定義する. + + VALUE rb_define_class_under(VALUE module, char *name, VALUE super) + +superのサブクラスとして新しいrubyクラスを定義し,moduleの定 +数として定義する. + + VALUE rb_define_module(char *name) + +新しいrubyモジュールを定義する. + + VALUE rb_define_module_under(VALUE module, char *name, VALUE super) + +新しいrubyモジュールを定義し,moduleの定数として定義する. + + void rb_include_module(VALUE class, VALUE module) + +モジュールをインクルードする.classがすでにmoduleをインクルー +ドしている時には何もしない(多重インクルードの禁止). + + void rb_extend_object(VALUE object, VALUE module) + +オブジェクトをモジュール(で定義されているメソッド)で拡張する. + +** 大域変数定義 + + void rb_define_variable(char *name, VALUE *var) + +rubyとCとで共有するグローバル変数を定義する.変数名が`$'で始 +まらない時には自動的に追加される.nameとしてrubyの識別子とし +て許されない文字(例えば` ')を含む場合にはrubyプログラムから +は見えなくなる. + + void rb_define_readonly_variable(char *name, VALUE *var) + +rubyとCとで共有するread onlyのグローバル変数を定義する.read +onlyであること以外はrb_define_variable()と同じ. + + void rb_define_virtual_variable(char *name, + VALUE (*getter)(), VALUE (*setter)()) + +関数によって実現されるruby変数を定義する.変数が参照された時 +にはgetterが,変数に値がセットされた時にはsetterが呼ばれる. + + void rb_define_hooked_variable(char *name, VALUE *var, + VALUE (*getter)(), VALUE (*setter)()) + +関数によってhookのつけられたグローバル変数を定義する.変数が +参照された時にはgetterが,関数に値がセットされた時にはsetter +が呼ばれる.getterやsetterに0を指定した時にはhookを指定しな +いのと同じ事になる. + + void rb_global_variable(VALUE *var) + +GCのため,rubyプログラムからはアクセスされないが, rubyオブジェ +クトを含む大域変数をマークする. + +** クラス定数 + + void rb_define_const(VALUE class, char *name, VALUE val) + +クラス定数を定義する. + + void rb_define_global_const(char *name, VALUE val) + +大域定数を定義する. + + rb_define_const(cKernal, name, val) + +と同じ意味. + +** メソッド定義 + + rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc) + +メソッドを定義する.argcはselfを除く引数の数.argcが-1の時, +関数には引数の数(selfを含まない)を第1引数, 引数の配列を第2引 +数とする形式で与えられる(第3引数はself).argcが-2の時, 第1引 +数がself, 第2引数がargs(argsは引数を含むrubyの配列)という形 +式で与えられる. + + rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc) + +privateメソッドを定義する.引数はrb_define_method()と同じ. + + rb_define_singleton_method(VALUE class, char *name, VALUE (*func)(), int argc) + +特異メソッドを定義する.引数はrb_define_method()と同じ. + + rb_scan_args(int atgc, VALUE *argv, char *fmt, ...) + +argc,argv形式で与えられた引数を分解する.fmtは必須引数の数, +付加引数の数, 残りの引数があるかを指定する文字列で, "数字数 +字*"という形式である. 2 番目の数字と"*"はそれぞれ省略可能で +ある.必須引数が一つもない場合は0を指定する.第3引数以降は変 +数へのポインタで, 該当する要素がその変数に格納される.付加引 +数に対応する引数が与えられていない場合は変数にQnilが代入され +る. + +** rubyメソッド呼び出し + + VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) + +メソッド呼び出し.文字列からmidを得るためにはrb_intern()を使う. + + VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv) + +メソッド呼び出し.引数をargc,argv形式で渡す. + + VALUE rb_eval_string(char *str) + +文字列をrubyとスクリプトしてコンパイル・実行する. + + ID rb_intern(char *name) + +文字列に対応するIDを返す. + + char *rb_id2name(ID id) + +IDに対応する文字列を返す(デバッグ用). + + char *rb_class2name(VALUE class) + +classの名前を返す(デバッグ用).classが名前を持たない時には, +祖先を遡って名前を持つクラスの名前を返す. + +** インスタンス変数 + + VALUE rb_iv_get(VALUE obj, char *name) + +objのインスタンス変数の値を得る.`@'で始まらないインスタンス +変数は rubyプログラムからアクセスできない「隠れた」インスタ +ンス変数になる. + + VALUE rb_iv_set(VALUE obj, char *name, VALUE val) + +objのインスタンス変数をvalにセットする. + +** 制御構造 + + VALUE rb_iterate(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2) + +func2をブロックとして設定し, func1をイテレータとして呼ぶ. +func1には arg1が引数として渡され, func2には第1引数にイテレー +タから与えられた値, 第2引数にarg2が渡される. + + VALUE rb_yield(VALUE val) + +valを値としてイテレータブロックを呼び出す. + + VALUE rb_rescue(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2) + +関数func1をarg1を引数に呼び出す.func1の実行中に例外が発生し +た時には func2をarg2を引数として呼ぶ.戻り値は例外が発生しな +かった時はfunc1の戻り値, 例外が発生した時にはfunc2の戻り値で +ある. + + VALUE rb_ensure(VALUE (*func1)(), void *arg1, void (*func2)(), void *arg2) + +関数func1をarg1を引数として実行し, 実行終了後(たとえ例外が発 +生しても) func2をarg2を引数として実行する.戻り値はfunc1の戻 +り値である(例外が発生した時は戻らない). + +** 例外・エラー + + void Warning(char *fmt, ...) + +verbose時に標準エラー出力に警告情報を表示する.引数はprintf()と同じ. + + void Fail(char *fmt, ...) + +RuntimeError例外を発生させる.引数はprintf()と同じ. + + void Raise(VALUE exception, char *fmt, ...) + +exceptionで指定した例外を発生させる.引数はprintf()と同じ. + + void Fatal(char *fmt, ...) + +致命的例外を発生させる.通常の例外処理は行なわれず, インター +プリタが終了する(ただしensureで指定されたコードは終了前に実 +行される). + + void Bug(char *fmt, ...) + +インタープリタなどプログラムのバグでしか発生するはずのない状 +況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外 +処理は一切行なわれない. + +** rubyの初期化・実行 + +rubyをアプリケーションに埋め込む場合には以下のインタフェース +を使う.通常の拡張モジュールには必要ない. + + void ruby_init(int argc, char **argv, char **envp) + +rubyインタプリタの初期化を行なう. + + void ruby_run() + +rubyインタプリタを実行する. + + void ruby_script(char *name) + +rubyのスクリプト名($0)を設定する. + + +Appendix B. extconf.rbで使える関数たち + +extconf.rbの中では利用可能なコンパイル条件チェックの関数は以 +下の通りである. + + have_library(lib, func) + +関数funcを定義しているライブラリlibの存在をチェックする.ラ +イブラリが存在する時,TRUEを返す. + + have_func(func) + +関数funcの存在をチェックする.funcが標準ではリンクされないラ +イブラリ内のものである時には先にhave_libraryでそのライブラリ +をチェックしておく事.関数が存在する時TRUEを返す. + + have_header(header) + +ヘッダファイルの存在をチェックする.ヘッダファイルが存在する +時TRUEを返す. + + create_makefile(target) + +拡張モジュール用のMakefileを生成する.この関数を呼ばなければ +そのモジュールはコンパイルされない.targetはモジュール名を表 +す. + +/* + * Local variables: + * fill-column: 60 + * end: + */ diff --git a/array.c b/array.c index 388fb05bd7..a0e1e000d1 100644 --- a/array.c +++ b/array.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 6 09:46:12 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/class.c b/class.c index 13c9298c1c..6f6a9bc5b8 100644 --- a/class.c +++ b/class.c @@ -419,25 +419,29 @@ rb_define_method(klass, name, func, argc) VALUE (*func)(); int argc; { - rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC); + ID id = rb_intern(name); + + rb_add_method(klass, id, NEW_CFUNC(func, argc), + (name[0] == 'i' && id == rb_intern("initialize"))? + NOEX_PRIVATE:NOEX_PUBLIC); } void -rb_undef_method(klass, name) +rb_define_private_method(klass, name, func, argc) VALUE klass; char *name; + VALUE (*func)(); + int argc; { - rb_add_method(klass, rb_intern(name), 0, NOEX_PUBLIC); + rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE); } void -rb_define_private_method(klass, name, func, argc) +rb_undef_method(klass, name) VALUE klass; char *name; - VALUE (*func)(); - int argc; { - rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE); + rb_add_method(klass, rb_intern(name), 0, NOEX_PUBLIC); } VALUE diff --git a/compar.c b/compar.c index e852fb1e49..ce85198873 100644 --- a/compar.c +++ b/compar.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Aug 26 14:39:48 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/dir.c b/dir.c index 29ce261272..e89f247a02 100644 --- a/dir.c +++ b/dir.c @@ -6,7 +6,7 @@ $Date$ created at: Wed Jan 5 09:51:01 JST 1994 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/dln.c b/dln.c index f4ab012021..4a8dcdc8ec 100644 --- a/dln.c +++ b/dln.c @@ -6,20 +6,20 @@ $Date$ created at: Tue Jan 18 17:05:06 JST 1994 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ -#ifdef _AIX -#pragma alloca -#endif - #include "config.h" #include "defines.h" #include "dln.h" char *dln_argv0; +#ifdef _AIX +#pragma alloca +#endif + #if defined(HAVE_ALLOCA_H) && !defined(__GNUC__) #include #endif diff --git a/enum.c b/enum.c index d8e2fcdc8b..e37fee7f03 100644 --- a/enum.c +++ b/enum.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 1 15:15:19 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/error.c b/error.c index 7163f62609..4c8aea5964 100644 --- a/error.c +++ b/error.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 16:11:34 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -254,7 +254,7 @@ exc_inspect(exc) klass = CLASS_OF(exc); if (RSTRING(exc)->len == 0) { - return rb_class_path(klass); + return str_dup(rb_class_path(klass)); } str = str_new2("#<"); diff --git a/eval.c b/eval.c index 42617c2b27..2452c68e79 100644 --- a/eval.c +++ b/eval.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Jun 10 14:22:17 JST 1993 - Copyright (C) 1993-1997 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -43,6 +43,7 @@ static VALUE f_binding _((VALUE)); static void f_END _((void)); #define SCOPE_PRIVATE FL_USER4 +#define SCOPE_MODFUNC FL_USER5 #define CACHE_SIZE 0x200 #define CACHE_MASK 0x1ff @@ -282,15 +283,15 @@ static struct FRAME *top_frame; static struct SCOPE *top_scope; #define PUSH_FRAME() { \ - struct FRAME *_frame = ALLOCA_N(struct FRAME,1);\ - _frame->prev = the_frame; \ - _frame->file = sourcefile; \ - _frame->line = sourceline; \ - _frame->iter = the_iter->iter; \ - _frame->cbase = the_frame->cbase; \ - the_frame = _frame; \ + struct FRAME _frame; \ + _frame.prev = the_frame; \ + _frame.file = sourcefile; \ + _frame.line = sourceline; \ + _frame.iter = the_iter->iter; \ + _frame.cbase = the_frame->cbase; \ + the_frame = &_frame; \ -#define POP_FRAME() the_frame = _frame->prev; } +#define POP_FRAME() the_frame = _frame.prev; } struct BLOCK { NODE *var; @@ -309,29 +310,29 @@ struct BLOCK { } *the_block; #define PUSH_BLOCK(v,b) { \ - struct BLOCK *_block = ALLOCA_N(struct BLOCK,1);\ - _block->tag = prot_tag; \ - _block->var = v; \ - _block->body = b; \ - _block->self = self; \ - _block->frame = *the_frame; \ - _block->class = the_class; \ - _block->frame.file = sourcefile; \ - _block->frame.line = sourceline; \ - _block->scope = the_scope; \ - _block->d_vars = the_dyna_vars; \ - _block->prev = the_block; \ - _block->iter = the_iter->iter; \ - the_block = _block; + struct BLOCK _block; \ + _block.tag = prot_tag; \ + _block.var = v; \ + _block.body = b; \ + _block.self = self; \ + _block.frame = *the_frame; \ + _block.class = the_class; \ + _block.frame.file = sourcefile; \ + _block.frame.line = sourceline; \ + _block.scope = the_scope; \ + _block.d_vars = the_dyna_vars; \ + _block.prev = the_block; \ + _block.iter = the_iter->iter; \ + the_block = &_block; #define PUSH_BLOCK2(b) { \ - struct BLOCK *_block = ALLOCA_N(struct BLOCK,1);\ - *_block = *b; \ - _block->prev = the_block; \ - the_block = _block; + struct BLOCK _block; \ + _block = *b; \ + _block.prev = the_block; \ + the_block = &_block; #define POP_BLOCK() \ - the_block = the_block->prev; \ + the_block = _block.prev; \ } struct RVarmap *the_dyna_vars; @@ -416,38 +417,26 @@ static struct iter { the_iter = _iter.prev; \ } -#ifdef C_ALLOCA -/* need to protect retval in struct tag from GC. */ -#define tag_retval_dcl VALUE *dd_retval -#define tag_retval_init VALUE _tag_retval = Qnil;\ - _tag->dd_retval = &_tag_retval; -#define tag_retval dd_retval[0] -#else -#define tag_retval_dcl VALUE retval -#define tag_retval_init _tag->retval = Qnil -#define tag_retval retval -#endif - static struct tag { jmp_buf buf; struct FRAME *frame; struct iter *iter; ID tag; - tag_retval_dcl; + VALUE retval; ID dst; struct tag *prev; } *prot_tag; #define PUSH_TAG(ptag) { \ - struct tag *_tag = ALLOCA_N(struct tag,1);\ - tag_retval_init; \ - _tag->frame = the_frame; \ - _tag->iter = the_iter; \ - _tag->prev = prot_tag; \ - _tag->tag_retval = Qnil; \ - _tag->tag = ptag; \ - _tag->dst = 0; \ - prot_tag = _tag; + struct tag _tag; \ + _tag.retval = Qnil; \ + _tag.frame = the_frame; \ + _tag.iter = the_iter; \ + _tag.prev = prot_tag; \ + _tag.retval = Qnil; \ + _tag.tag = ptag; \ + _tag.dst = 0; \ + prot_tag = &_tag; #define PROT_NONE 0 #define PROT_FUNC -1 @@ -462,7 +451,7 @@ static struct tag { } #define POP_TAG() \ - prot_tag = _tag->prev; \ + prot_tag = _tag.prev; \ } #define TAG_RETURN 0x1 @@ -717,6 +706,7 @@ ruby_init() top_scope = the_scope; /* default visibility is private at toplevel */ FL_SET(top_scope, SCOPE_PRIVATE); + FL_UNSET(top_scope, SCOPE_MODFUNC); PUSH_TAG(PROT_NONE) if ((state = EXEC_TAG()) == 0) { @@ -1113,6 +1103,17 @@ mod_alias_method(mod, new, old) return mod; } +#if defined(C_ALLOCA) && defined(THREAD) +# define TMP_PROTECT NODE *__protect_tmp=0 +# define ALLOCTMP(type,n) \ + (__protect_tmp = node_newnode(NODE_ALLOCA, \ + str_new(0,sizeof(type)*(n)),0,__protect_tmp), \ + (void*)RSTRING(__protect_tmp->nd_head)->ptr) +#else +# define TMP_PROTECT typedef int foobazzz +# define ALLOCTMP(type,n) ALLOCA_N(type,n) +#endif + #define SETUP_ARGS(anode) {\ NODE *n = anode;\ if (!n) {\ @@ -1126,7 +1127,7 @@ mod_alias_method(mod, new, old) int line = sourceline;\ int i;\ n = anode;\ - argv = ALLOCA_N(VALUE,argc);\ + argv = ALLOCTMP(VALUE,argc);\ for (i=0;ind_head);\ n=n->nd_next;\ @@ -1371,7 +1372,7 @@ call_trace_func(event, file, line, self, id) prev = the_frame; PUSH_FRAME(); - *the_frame = *_frame->prev; + *the_frame = *_frame.prev; the_frame->prev = prev; the_frame->line = sourceline = line; @@ -1606,7 +1607,7 @@ rb_eval(self, node) else if (the_block->tag->dst == state) { state &= TAG_MASK; if (state == TAG_RETURN) { - result = prot_tag->tag_retval; + result = prot_tag->retval; } } POP_TAG(); @@ -1767,6 +1768,7 @@ rb_eval(self, node) { VALUE recv; int argc; VALUE *argv; /* used in SETUP_ARGS */ + TMP_PROTECT; PUSH_ITER(ITER_NOT); recv = rb_eval(self, node->nd_recv); @@ -1779,6 +1781,7 @@ rb_eval(self, node) case NODE_FCALL: { int argc; VALUE *argv; /* used in SETUP_ARGS */ + TMP_PROTECT; PUSH_ITER(ITER_NOT); SETUP_ARGS(node->nd_args); @@ -1795,6 +1798,7 @@ rb_eval(self, node) case NODE_ZSUPER: { int argc; VALUE *argv; /* used in SETUP_ARGS */ + TMP_PROTECT; if (nd_type(node) == NODE_ZSUPER) { argc = the_frame->argc; @@ -1846,6 +1850,7 @@ rb_eval(self, node) int argc; VALUE *argv; /* used in SETUP_ARGS */ VALUE recv, val; NODE *rval; + TMP_PROTECT; recv = rb_eval(self, node->nd_recv); rval = node->nd_args->nd_head; @@ -2112,13 +2117,19 @@ rb_eval(self, node) rb_clear_cache_by_id(node->nd_mid); } - if (FL_TEST(the_scope,SCOPE_PRIVATE)) { + if (FL_TEST(the_scope,SCOPE_PRIVATE) || node->nd_mid == init) { noex = NOEX_PRIVATE; } else { noex = NOEX_PUBLIC; } rb_add_method(the_class, node->nd_mid, node->nd_defn, noex); + if (FL_TEST(the_scope,SCOPE_MODFUNC)) { + rb_add_method(rb_singleton_class(the_class), + node->nd_mid, node->nd_defn, NOEX_PUBLIC); + rb_funcall(the_class, rb_intern("singleton_method_added"), + 1, INT2FIX(node->nd_mid)); + } if (FL_TEST(the_class, FL_SINGLETON)) { VALUE recv = rb_iv_get(the_class, "__attached__"); rb_funcall(recv, rb_intern("singleton_method_added"), @@ -2281,9 +2292,9 @@ rb_eval(self, node) } if (FL_TEST(CLASS_OF(class), FL_SINGLETON)) { rb_clear_cache(); - class = rb_singleton_class(class); } - + class = rb_singleton_class(class); + result = module_setup(class, node->nd_body); } break; @@ -2326,6 +2337,7 @@ module_setup(module, node) VALUE result; /* OK */ char *file = sourcefile; int line = sourceline; + TMP_PROTECT; /* fill c-ref */ node->nd_clss = module; @@ -2337,7 +2349,7 @@ module_setup(module, node) if (node->nd_rval) the_frame->cbase = node->nd_rval; if (node->nd_tbl) { - VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1); + VALUE *vars = ALLOCTMP(VALUE, node->nd_tbl[0]+1); *vars++ = (VALUE)node; the_scope->local_vars = vars; memclear(the_scope->local_vars, node->nd_tbl[0]); @@ -2568,7 +2580,7 @@ f_raise(argc, argv) } PUSH_FRAME(); /* fake frame */ - *the_frame = *_frame->prev->prev; + *the_frame = *_frame.prev->prev; rb_longjmp(TAG_RAISE, mesg, arg3); POP_FRAME(); } @@ -2795,7 +2807,7 @@ rb_iterate(it_proc, data1, bl_proc, data2) if (the_block->tag->dst == state) { state &= TAG_MASK; if (state == TAG_RETURN) { - retval = prot_tag->tag_retval; + retval = prot_tag->retval; } } POP_TAG(); @@ -2828,6 +2840,7 @@ handle_rescue(self, node) NODE *node; { int argc; VALUE *argv; /* used in SETUP_ARGS */ + TMP_PROTECT; if (!node->nd_args) { return obj_is_kind_of(errinfo, eException); @@ -2968,7 +2981,7 @@ f_missing(argc, argv, obj) sourcefile = file; sourceline = line; PUSH_FRAME(); /* fake frame */ - *the_frame = *_frame->prev->prev; + *the_frame = *_frame.prev->prev; NameError(format, rb_id2name(id), @@ -3037,6 +3050,7 @@ rb_call(class, recv, mid, argc, argv, scope) int itr; enum node_type type; static int tick; + TMP_PROTECT; again: /* is it in the method cache? */ @@ -3225,7 +3239,7 @@ rb_call(class, recv, mid, argc, argv, scope) if (body->nd_rval) the_frame->cbase = body->nd_rval; if (body->nd_tbl) { - local_vars = ALLOCA_N(VALUE, body->nd_tbl[0]+1); + local_vars = ALLOCTMP(VALUE, body->nd_tbl[0]+1); *local_vars++ = (VALUE)body; memclear(local_vars, body->nd_tbl[0]); the_scope->local_tbl = body->nd_tbl; @@ -3301,7 +3315,7 @@ rb_call(class, recv, mid, argc, argv, scope) result = rb_eval(recv, body); } else if (state == TAG_RETURN) { - result = prot_tag->tag_retval; + result = prot_tag->retval; state = 0; } POP_VARS(); @@ -3644,8 +3658,8 @@ eval_under(under, self, src) PUSH_CLASS(); the_class = under; PUSH_FRAME(); - the_frame->last_func = _frame->last_func; - the_frame->last_class = _frame->last_class; + the_frame->last_func = _frame.last_func; + the_frame->last_class = _frame.last_class; the_frame->argc = 1; the_frame->argv = &src; the_frame->cbase = (VALUE)node_newnode(NODE_CREF,under,0,cbase); @@ -3722,6 +3736,7 @@ f_load(obj, fname) int state; char *file; volatile ID last_func; + TMP_PROTECT; Check_SafeStr(fname); if (RSTRING(fname)->ptr[0] == '~') { @@ -3737,7 +3752,7 @@ f_load(obj, fname) if (top_scope->local_tbl) { int len = top_scope->local_tbl[0]+1; ID *tbl = ALLOC_N(ID, len); - VALUE *vars = ALLOCA_N(VALUE, len); + VALUE *vars = ALLOCTMP(VALUE, len); *vars++ = 0; MEMCPY(tbl, top_scope->local_tbl, ID, len); MEMCPY(vars, top_scope->local_vars, ID, len-1); @@ -3746,6 +3761,7 @@ f_load(obj, fname) } /* default visibility is private at loading toplevel */ FL_SET(the_scope, SCOPE_PRIVATE); + FL_UNSET(top_scope, SCOPE_MODFUNC); state = EXEC_TAG(); last_func = the_frame->last_func; @@ -3938,6 +3954,7 @@ mod_public(argc, argv, module) { if (argc == 0) { FL_UNSET(the_scope, SCOPE_PRIVATE); + FL_UNSET(top_scope, SCOPE_MODFUNC); } else { set_method_visibility(module, argc, argv, NOEX_PUBLIC); @@ -3953,6 +3970,7 @@ mod_private(argc, argv, module) { if (argc == 0) { FL_SET(the_scope, SCOPE_PRIVATE); + FL_UNSET(top_scope, SCOPE_MODFUNC); } else { set_method_visibility(module, argc, argv, NOEX_PRIVATE); @@ -4006,7 +4024,12 @@ mod_modfunc(argc, argv, module) ID id; NODE *body; - rb_clear_cache(); + if (argc == 0) { + FL_SET(the_scope, SCOPE_PRIVATE); + FL_SET(the_scope, SCOPE_MODFUNC); + return module; + } + set_method_visibility(module, argc, argv, NOEX_PRIVATE); for (i=0; ind_body, NOEX_PUBLIC); } return module; @@ -5721,7 +5745,7 @@ f_catch(dmy, tag) val = rb_yield(tag); } else if (state == TAG_THROW && prot_tag->tag == prot_tag->dst) { - val = prot_tag->tag_retval; + val = prot_tag->retval; state = 0; } POP_TAG(); @@ -5745,7 +5769,7 @@ f_throw(argc, argv) while (tt) { if (tt->tag == t) { tt->dst = t; - tt->tag_retval = value; + tt->retval = value; break; } #ifdef THREAD @@ -5773,7 +5797,7 @@ return_value(val) while (tt) { if (tt->tag == PROT_FUNC) { - tt->tag_retval = val; + tt->retval = val; break; } #ifdef THREAD diff --git a/ext/Setup b/ext/Setup index c92ac53e00..9e3a2474c3 100644 --- a/ext/Setup +++ b/ext/Setup @@ -10,3 +10,4 @@ #socket #tkutil #tcltklib +#gtk diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in index e1d318d19c..066e744944 100644 --- a/ext/extmk.rb.in +++ b/ext/extmk.rb.in @@ -276,7 +276,7 @@ realclean: clean install: " if !$static - mfile.printf " + mfile.printf "\ @test -d $(libdir) || mkdir $(libdir) $(INSTALL) $(TARGET) $(libdir)/$(TARGET) " diff --git a/ext/gtk/MANIFEST b/ext/gtk/MANIFEST deleted file mode 100644 index 3e1962e1f3..0000000000 --- a/ext/gtk/MANIFEST +++ /dev/null @@ -1,18 +0,0 @@ -MANIFEST -extconf.rb -gtk.c -test.rb -test.xpm -test0.rb -test1.rb -test2.rb -test3.rb -test4.rb -test5.rb -test6.rb -test7.rb -test8.rb -test9.rb -testa.rb -testb.rb -testc.rb diff --git a/ext/gtk/extconf.rb b/ext/gtk/extconf.rb deleted file mode 100644 index 621e0739a5..0000000000 --- a/ext/gtk/extconf.rb +++ /dev/null @@ -1,6 +0,0 @@ -require "mkmf" -if have_library("glib", "g_print") and - have_library("gdk", "gdk_init") and - have_library("gtk", "gtk_init") - create_makefile("gtk") -end diff --git a/ext/gtk/gtk.c b/ext/gtk/gtk.c deleted file mode 100644 index 9114312195..0000000000 --- a/ext/gtk/gtk.c +++ /dev/null @@ -1,5904 +0,0 @@ -/************************************************ - - gtk.c - - - $Author$ - $Date$ - created at: Wed Jan 7 23:55:11 JST 1998 - -************************************************/ - -#include "ruby.h" -#include "sig.h" -#include -#include - -extern VALUE rb_argv, rb_argv0; -extern VALUE cData; - -static VALUE mGtk; - -static VALUE gObject; -static VALUE gWidget; -static VALUE gContainer; -static VALUE gBin; -static VALUE gAlignment; -static VALUE gMisc; -static VALUE gArrow; -static VALUE gFrame; -static VALUE gAspectFrame; -static VALUE gData; -static VALUE gAdjustment; -static VALUE gBox; -static VALUE gButton; -static VALUE gTButton; -static VALUE gCButton; -static VALUE gRButton; -static VALUE gBBox; -static VALUE gCList; -static VALUE gWindow; -static VALUE gDialog; -static VALUE gFileSel; -static VALUE gVBox; -static VALUE gColorSel; -static VALUE gColorSelDialog; -static VALUE gImage; -static VALUE gDrawArea; -static VALUE gEntry; -static VALUE gEventBox; -static VALUE gFixed; -static VALUE gGamma; -static VALUE gHBBox; -static VALUE gVBBox; -static VALUE gHBox; -static VALUE gPaned; -static VALUE gHPaned; -static VALUE gVPaned; -static VALUE gRuler; -static VALUE gHRuler; -static VALUE gVRuler; -static VALUE gRange; -static VALUE gScale; -static VALUE gHScale; -static VALUE gVScale; -static VALUE gScrollbar; -static VALUE gHScrollbar; -static VALUE gVScrollbar; -static VALUE gSeparator; -static VALUE gHSeparator; -static VALUE gVSeparator; -static VALUE gInputDialog; -static VALUE gLabel; -static VALUE gList; -static VALUE gItem; -static VALUE gListItem; -static VALUE gMenuShell; -static VALUE gMenu; -static VALUE gMenuBar; -static VALUE gMenuItem; -static VALUE gCMenuItem; -static VALUE gRMenuItem; -static VALUE gNotebook; -static VALUE gOptionMenu; -static VALUE gPixmap; -static VALUE gPreview; -static VALUE gProgressBar; -static VALUE gScrolledWin; -static VALUE gTable; -static VALUE gText; -static VALUE gToolbar; -static VALUE gTooltips; -static VALUE gTree; -static VALUE gTreeItem; -static VALUE gViewPort; - -static VALUE gAcceleratorTable; -static VALUE gStyle; -static VALUE gPreviewInfo; -static VALUE gAllocation; -static VALUE gRequisiton; - -static VALUE mGdk; - -static VALUE gdkFont; -static VALUE gdkColor; -static VALUE gdkColormap; -static VALUE gdkPixmap; -static VALUE gdkBitmap; -static VALUE gdkWindow; -static VALUE gdkImage; -static VALUE gdkVisual; -static VALUE gdkGC; -static VALUE gdkRectangle; -static VALUE gdkGCValues; -static VALUE gdkRectangle; -static VALUE gdkSegment; -static VALUE gdkWindowAttr; -static VALUE gdkCursor; -static VALUE gdkAtom; -static VALUE gdkColorContext; -static VALUE gdkEvent; - -ID id_gtkdata, id_relatives, id_call; - -static void gobj_free(); - -static char* -get_cstring(str) - VALUE str; -{ - if (NIL_P(str)) return NULL; - Check_Type(str, T_STRING); - return RSTRING(str)->ptr; -} - -static GtkObject* -get_gobject(obj) - VALUE obj; -{ - struct RData *data; - GtkObject *gtkp; - - if (NIL_P(obj)) return NULL; - - Check_Type(obj, T_OBJECT); - data = RDATA(rb_ivar_get(obj, id_gtkdata)); - if (NIL_P(data) || data->dfree != gobj_free) { - TypeError("not a Gtk object"); - } - Data_Get_Struct(data, GtkObject, gtkp); - if (!GTK_IS_OBJECT(gtkp)) { - TypeError("not a GtkObject"); - } - - return gtkp; -} - -static GtkWidget* -get_widget(obj) - VALUE obj; -{ - GtkObject *data = get_gobject(obj); - - return GTK_WIDGET(data); -} - -static VALUE -get_value_from_gobject(obj) - GtkObject *obj; -{ - return (VALUE)gtk_object_get_user_data(obj); -} - -static void -clear_gobject(obj) - VALUE obj; -{ - rb_ivar_set(obj, id_relatives, Qnil); -} - -static void -add_relative(obj, relative) - VALUE obj, relative; -{ - VALUE ary = rb_ivar_get(obj, id_relatives); - - if (TYPE(ary) != T_ARRAY) { - ary = ary_new(); - rb_ivar_set(obj, id_relatives, ary); - } - ary_push(ary, relative); -} - -static VALUE gtk_object_list; - -static void -gobj_free(obj) - GtkObject *obj; -{ - VALUE self = get_value_from_gobject(obj); - - if (GTK_OBJECT_NEED_DESTROY(obj)) { - gtk_object_destroy(obj); - } - rb_ivar_set(self, id_relatives, Qnil); -} - -static void -delete_gobject(obj) - GtkObject *obj; -{ - ary_delete(gtk_object_list, get_value_from_gobject(obj)); -} - -static VALUE -make_gobject(klass, gtkobj) - VALUE klass; - GtkObject *gtkobj; -{ - VALUE obj = obj_alloc(klass); - VALUE data; - - data = Data_Wrap_Struct(cData, 0, gobj_free, gtkobj); - gtk_object_set_user_data(gtkobj, (gpointer)obj); - - rb_ivar_set(obj, id_gtkdata, data); - gtk_signal_connect(gtkobj, "destroy", (GtkSignalFunc)delete_gobject, 0); - ary_push(gtk_object_list, obj); - return obj; -} - -static VALUE -make_widget(klass, widget) - VALUE klass; - GtkWidget *widget; -{ - return make_gobject(klass, GTK_OBJECT(widget)); -} - -static void -free_gstyle(style) - GtkStyle *style; -{ - gtk_style_unref(style); -} - -static VALUE -make_gstyle(style) - GtkStyle *style; -{ - gtk_style_ref(style); - return Data_Wrap_Struct(gStyle, 0, free_gstyle, style); -} - -static GtkStyle* -get_gstyle(style) - VALUE style; -{ - GtkStyle *gstyle; - - if (NIL_P(style)) return NULL; - if (!obj_is_instance_of(style, gStyle)) { - TypeError("not a GtkStyle"); - } - Data_Get_Struct(style, GtkStyle, gstyle); - - return gstyle; -} - -static void -free_gaccel(tbl) - GtkAcceleratorTable *tbl; -{ - gtk_accelerator_table_unref(tbl); -} - -static VALUE -make_gtkacceltbl(tbl) - GtkAcceleratorTable *tbl; -{ - gtk_accelerator_table_ref(tbl); - return Data_Wrap_Struct(gAcceleratorTable, 0, free_gaccel, tbl); -} - -static GtkAcceleratorTable* -get_gtkacceltbl(value) - VALUE value; -{ - GtkAcceleratorTable *tbl; - - if (NIL_P(value)) return NULL; - - if (!obj_is_instance_of(value, gAcceleratorTable)) { - TypeError("not an AcceleratorTable"); - } - Data_Get_Struct(value, GtkAcceleratorTable, tbl); - - return tbl; -} - -static VALUE -make_gtkprevinfo(info) - GtkPreviewInfo *info; -{ - return Data_Wrap_Struct(gAcceleratorTable, 0, 0, info); -} - -static GtkPreviewInfo* -get_gtkprevinfo(value) - VALUE value; -{ - GtkPreviewInfo *info; - - if (NIL_P(value)) return NULL; - - if (!obj_is_instance_of(value, gPreviewInfo)) { - TypeError("not a PreviewInfo"); - } - Data_Get_Struct(value, GtkPreviewInfo, info); - - return info; -} - -static void -exec_callback(widget, data, nparams, params) - GtkWidget *widget; - VALUE data; - int nparams; - GtkType *params; -{ - VALUE self = get_value_from_gobject(GTK_OBJECT(widget)); - VALUE proc = RARRAY(data)->ptr[0]; - VALUE event = RARRAY(data)->ptr[1]; - ID id = NUM2INT(event); - - if (NIL_P(proc) && rb_respond_to(self, id)) { - rb_funcall(self, id, 3, self, - INT2FIX(nparams), INT2NUM((INT)params)); - } - else { - rb_funcall(proc, id_call, 1, self); - } -} - -static void -free_ttips(tips) - GtkTooltips *tips; -{ - gtk_tooltips_unref(tips); -} - -static VALUE -make_ttips(klass, tips) - VALUE klass; - GtkTooltips *tips; -{ - gtk_tooltips_ref(tips); - return Data_Wrap_Struct(klass, 0, free_ttips, tips); -} - -static GtkTooltips* -get_ttips(tips) - VALUE tips; -{ - GtkTooltips *gtips; - - if (NIL_P(tips)) return NULL; - - if (!obj_is_instance_of(tips, gTooltips)) { - TypeError("not a GtkTooltips"); - } - Data_Get_Struct(tips, GtkTooltips, gtips); - - return gtips; -} - -static void -free_gdkfont(font) - GdkFont *font; -{ - gdk_font_unref(font); -} - -static VALUE -make_gdkfont(font) - GdkFont *font; -{ - gdk_font_ref(font); - return Data_Wrap_Struct(gdkFont, 0, free_gdkfont, font); -} - -static GdkFont* -get_gdkfont(font) - VALUE font; -{ - GdkFont *gfont; - - if (NIL_P(font)) return NULL; - - if (!obj_is_instance_of(font, gdkFont)) { - TypeError("not a GdkFont"); - } - Data_Get_Struct(font, GdkFont, gfont); - - return gfont; -} - -static VALUE -gdkfnt_equal(fn1, fn2) - VALUE fn1, fn2; -{ - if (gdk_font_equal(get_gdkfont(fn1), get_gdkfont(fn2))) - return TRUE; - return FALSE; -} - -static void -free_tobj(obj) - gpointer obj; -{ - free(obj); -} - -static VALUE -make_tobj(obj, klass, size) - gpointer obj; - VALUE klass; - int size; -{ - gpointer copy; - VALUE data; - - copy = xmalloc(size); - memcpy(copy, obj, size); - data = Data_Wrap_Struct(klass, 0, free_tobj, copy); - - return data; -} - -static gpointer -get_tobj(obj, klass) - VALUE obj, klass; -{ - void *ptr; - - if (NIL_P(obj)) return NULL; - - if (!obj_is_instance_of(obj, klass)) { - TypeError("not a %s", rb_class2name(klass)); - } - Data_Get_Struct(obj, void, ptr); - - return ptr; -} - -#define make_gdkcolor(c) make_tobj(c, gdkColor, sizeof(GdkColor)) -#define get_gdkcolor(c) ((GdkColor*)get_tobj(c, gdkColor)) - -#define make_gdkrect(c) make_tobj(c, gdkRectangle, sizeof(GdkRectangle)) -#define get_gdkrect(c) ((GdkRectangle*)get_tobj(c, gdkRectangle)) - -#define make_gdksegment(c) make_tobj(c, gdkSegment, sizeof(GdkSegment)) -#define get_gdksegment(c) ((GdkSegment*)get_tobj(c, gdkSegment)) - -#define make_gdkwinattr(c) make_tobj(c, gdkWindowAttr, sizeof(GdkWindowAttr)) -#define get_gdkwinattr(c) ((GdkWindowAttr*)get_tobj(c, gdkWindowAttr)) - -#define make_gdkwinattr(c) make_tobj(c, gdkWindowAttr, sizeof(GdkWindowAttr)) -#define get_gdkwinattr(c) ((GdkWindowAttr*)get_tobj(c, gdkWindowAttr)) - -#define make_gallocation(c) make_tobj(c, gAllocation, sizeof(GtkAllocation)) -#define get_gallocation(c) ((GtkAllocation*)get_tobj(c, gAllocation)) - -#define make_grequisiton(c) make_tobj(c, gRequisiton, sizeof(GtkRequisition)) -#define get_grequisiton(c) ((GtkRequisition*)get_tobj(c, gRequisiton)) - -#define make_gdkrectangle(r) make_tobj(r, gdkRectangle, sizeof(GdkRectangle)) -#define get_gdkrectangle(r) ((GdkRectangle*)get_tobj(r, gdkRectangle)) - -static void -free_gdkcmap(cmap) - GdkColormap *cmap; -{ - gdk_colormap_unref(cmap); -} - -static VALUE -make_gdkcmap(cmap) - GdkColormap *cmap; -{ - gdk_colormap_ref(cmap); - return Data_Wrap_Struct(gdkColormap, 0, free_gdkcmap, cmap); -} - -static GdkColormap* -get_gdkcmap(cmap) - VALUE cmap; -{ - GdkColormap *gcmap; - - if (NIL_P(cmap)) return NULL; - - if (!obj_is_kind_of(cmap, gdkColormap)) { - TypeError("not a GdkColormap"); - } - Data_Get_Struct(cmap, GdkColormap, gcmap); - - return gcmap; -} - -static VALUE -make_gdkvisual(visual) - GdkVisual *visual; -{ - return Data_Wrap_Struct(gdkVisual, 0, 0, visual); -} - -static GdkVisual* -get_gdkvisual(visual) - VALUE visual; -{ - GdkVisual *gvisual; - - if (NIL_P(visual)) return NULL; - - if (!obj_is_kind_of(visual, gdkVisual)) { - TypeError("not a GdkVisual"); - } - Data_Get_Struct(visual, GdkVisual, gvisual); - - return gvisual; -} - -static void -free_gdkwindow(window) - GdkWindow *window; -{ - gdk_window_unref(window); -} - -static VALUE -make_gdkwindow(window) - GdkWindow *window; -{ - gdk_window_ref(window); - return Data_Wrap_Struct(gdkWindow, 0, free_gdkwindow, window); -} - -static GdkWindow* -get_gdkwindow(window) - VALUE window; -{ - GdkWindow *gwindow; - - if (NIL_P(window)) return NULL; - - if (!obj_is_kind_of(window, gdkWindow)) { - TypeError("not a GdkWindow"); - } - Data_Get_Struct(window, GdkWindow, gwindow); - - return gwindow; -} - -static void -free_gdkpixmap(pixmap) - GdkPixmap *pixmap; -{ - gdk_pixmap_unref(pixmap); -} - -static VALUE -make_gdkpixmap(klass, pixmap) - VALUE klass; - GdkPixmap *pixmap; -{ - gdk_pixmap_ref(pixmap); - return Data_Wrap_Struct(klass, 0, free_gdkpixmap, pixmap); -} - -static GdkPixmap* -get_gdkpixmap(pixmap) - VALUE pixmap; -{ - GdkPixmap *gpixmap; - - if (NIL_P(pixmap)) return NULL; - - if (!obj_is_kind_of(pixmap, gdkPixmap)) { - TypeError("not a GdkPixmap"); - } - Data_Get_Struct(pixmap, GdkPixmap, gpixmap); - - return gpixmap; -} - -static VALUE -gdkpmap_s_new(self, win, w, h, depth) - VALUE self, win, w, h, depth; -{ - GdkPixmap *new; - GdkWindow *window = get_gdkwindow(win); - - new = gdk_pixmap_new(window, NUM2INT(w), NUM2INT(h), NUM2INT(depth)); - return make_gdkpixmap(self, new); -} - -static VALUE -gdkpmap_create_from_data(self, win, data, w, h, depth, fg, bg) - VALUE self, win, data, w, h, depth, fg, bg; -{ - GdkPixmap *new; - GdkWindow *window = get_gdkwindow(win); - - Check_Type(data, T_STRING); - new = gdk_pixmap_create_from_data(window, - RSTRING(data)->ptr, - NUM2INT(w), NUM2INT(h), - NUM2INT(depth), - get_gdkcolor(fg), - get_gdkcolor(bg)); - return make_gdkpixmap(self, new); -} - -static VALUE -gdkpmap_create_from_xpm(self, win, tcolor, fname) - VALUE self, win, tcolor, fname; -{ - GdkPixmap *new; - GdkBitmap *mask; - GdkWindow *window = get_gdkwindow(win); - - Check_Type(fname, T_STRING); - new = gdk_pixmap_create_from_xpm(window, &mask, - get_gdkcolor(tcolor), - RSTRING(fname)->ptr); - if (!new) { - ArgError("Pixmap not created from %s", RSTRING(fname)->ptr); - } - return assoc_new(make_gdkpixmap(self, new), - make_gdkpixmap(gdkBitmap, mask)); -} - -static VALUE -gdkpmap_create_from_xpm_d(self, win, tcolor, data) - VALUE self, win, tcolor, data; -{ - GdkPixmap *new; - GdkBitmap *mask; - GdkWindow *window = get_gdkwindow(win); - int i; - gchar **buf; - - Check_Type(data, T_ARRAY); - buf = ALLOCA_N(char*, RARRAY(data)->len); - for (i=0; ilen; i++) { - Check_Type(RARRAY(data)->ptr[i], T_STRING); - buf[i] = RSTRING(RARRAY(data)->ptr[i])->ptr; - } - - new = gdk_pixmap_create_from_xpm_d(window, &mask, - get_gdkcolor(tcolor), - buf); - - return assoc_new(make_gdkpixmap(self, new), - make_gdkpixmap(gdkBitmap, mask)); -} - -static VALUE -gdkbmap_s_new(self, win, w, h) - VALUE self, win, w, h; -{ - GdkPixmap *new; - GdkWindow *window = get_gdkwindow(win); - - new = gdk_pixmap_new(window, NUM2INT(w), NUM2INT(h), 1); - return make_gdkpixmap(self, new); -} - -static VALUE -gdkbmap_create_from_data(self, win, data, w, h) - VALUE self, win, data, w, h; -{ - GdkBitmap *new; - GdkWindow *window = get_gdkwindow(win); - - Check_Type(data, T_STRING); - new = gdk_bitmap_create_from_data(window, - RSTRING(data)->ptr, - NUM2INT(w), NUM2INT(h)); - return make_gdkpixmap(self, (GdkPixmap*)new); -} - -static void -free_gdkimage(image) - GdkImage *image; -{ - gdk_image_destroy(image); -} - -static VALUE -make_gdkimage(image) - GdkImage *image; -{ - return Data_Wrap_Struct(gdkImage, 0, free_gdkimage, image); -} - -static GdkImage* -get_gdkimage(image) - VALUE image; -{ - GdkImage *gimage; - - if (NIL_P(image)) return NULL; - - if (!obj_is_instance_of(image, gdkImage)) { - TypeError("not a GdkImage"); - } - Data_Get_Struct(image, GdkImage, gimage); - - return gimage; -} - -static void -free_gdkevent(event) - GdkEvent *event; -{ - gdk_event_free(event); -} - -static VALUE -make_gdkevent(event) - GdkEvent *event; -{ - event = gdk_event_copy(event); - return Data_Wrap_Struct(gdkEvent, 0, free_gdkevent, event); -} - -static GdkEvent* -get_gdkevent(event) - VALUE event; -{ - GdkEvent *gevent; - - if (NIL_P(event)) return NULL; - - if (!obj_is_instance_of(event, gdkEvent)) { - TypeError("not a GdkEvent"); - } - Data_Get_Struct(event, GdkEvent, gevent); - - return gevent; -} - -static VALUE -glist2ary(list) - GList *list; -{ - VALUE ary = ary_new(); - - while (list) { - ary_push(ary, get_value_from_gobject(GTK_OBJECT(list->data))); - list = list->next; - } - - return ary; -} - -static GList* -ary2glist(ary) - VALUE ary; -{ - int i; - GList *glist = NULL; - - Check_Type(ary, T_ARRAY); - for (i=0; ilen; i++) { - glist = g_list_prepend(glist,get_widget(RARRAY(ary)->ptr[i])); - } - - return g_list_reverse(glist); -} - -static GSList* -ary2gslist(ary) - VALUE ary; -{ - int i; - GSList *glist = NULL; - - if (NIL_P(ary)) return NULL; - Check_Type(ary, T_ARRAY); - for (i=0; ilen; i++) { - glist = g_slist_append(glist,get_widget(RARRAY(ary)->ptr[i])); - } - - return glist; -} - -static VALUE -gslist2ary(list) - GSList *list; -{ - VALUE ary = ary_new(); - - while (list) { - ary_push(ary, get_value_from_gobject(GTK_OBJECT(list->data))); - list = list->next; - } - - return ary; -} - -static VALUE -gobj_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - Fail("can't instantiate class %s", rb_class2name(self)); -} - -static VALUE -gobj_smethod_added(self, id) - VALUE self, id; -{ - GtkObject *obj = get_gobject(self); - char *name = rb_id2name(NUM2INT(id)); - - - if (gtk_signal_lookup(name, GTK_OBJECT_TYPE(obj))) { - VALUE handler = assoc_new(Qnil, id); - - add_relative(self, handler); - gtk_signal_connect_interp(obj, name, - exec_callback, (gpointer)handler, - NULL, 0); - } - return Qnil; -} - -static VALUE -gobj_destroy(self) - VALUE self; -{ - printf("a\n"); - gtk_object_destroy(get_gobject(self)); - printf("b\n"); - clear_gobject(self); - return Qnil; -} - -static VALUE -gobj_set_flags(self, flags) - VALUE self, flags; -{ - GtkObject *object = get_gobject(self); - GTK_OBJECT_SET_FLAGS(object, NUM2INT(flags)); - return self; -} - -static VALUE -gobj_unset_flags(self, flags) - VALUE self, flags; -{ - GtkObject *object = get_gobject(self); - GTK_OBJECT_UNSET_FLAGS(object, NUM2INT(flags)); - return self; -} - -static VALUE -gobj_sig_connect(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE sig, handler; - GtkWidget *widget = get_widget(self); - ID id = 0; - int n; - - rb_scan_args(argc, argv, "11", &sig, &handler); - Check_Type(sig, T_STRING); - if (NIL_P(handler) && iterator_p()) { - handler = f_lambda(); - id = rb_intern(RSTRING(sig)->ptr); - } - handler = assoc_new(handler, INT2NUM(id)); - add_relative(self, handler); - n = gtk_signal_connect_interp(GTK_OBJECT(widget), RSTRING(sig)->ptr, - exec_callback, (gpointer)handler, - NULL, 0); - - return INT2FIX(n); -} - -static VALUE -gobj_sig_connect_after(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE sig, handler; - GtkWidget *widget = get_widget(self); - ID id = 0; - int n; - - rb_scan_args(argc, argv, "11", &sig, &handler); - Check_Type(sig, T_STRING); - if (NIL_P(handler) && iterator_p()) { - handler = f_lambda(); - id = rb_intern(RSTRING(sig)->ptr); - } - add_relative(self, handler); - n = gtk_signal_connect_interp(GTK_OBJECT(widget), RSTRING(sig)->ptr, - exec_callback, (gpointer)handler, - NULL, 1); - - return INT2FIX(n); -} - -static VALUE -cont_bwidth(self, width) - VALUE self, width; -{ - GtkWidget *widget = get_widget(self); - gtk_container_border_width(GTK_CONTAINER(widget), NUM2INT(width)); - return self; -} - -static VALUE -cont_add(self, other) - VALUE self, other; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_add(GTK_CONTAINER(widget), get_widget(other)); - return self; -} - -static VALUE -cont_disable_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_disable_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_enable_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_enable_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_block_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_block_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_unblock_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_unblock_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_need_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_need_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_foreach(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE callback; - GtkWidget *widget = get_widget(self); - - rb_scan_args(argc, argv, "01", &callback); - if (NIL_P(callback)) { - callback = f_lambda(); - } - gtk_container_foreach(GTK_CONTAINER(widget), - exec_callback, (gpointer)callback); - return self; -} - -static void -yield_callback(widget) - GtkWidget *widget; -{ - rb_yield(get_value_from_gobject(GTK_OBJECT(widget))); -} - -static VALUE -cont_each(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_foreach(GTK_CONTAINER(widget), - yield_callback, 0); - return self; -} - -static VALUE -cont_focus(self, direction) - VALUE self, direction; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_focus(GTK_CONTAINER(widget), - (GtkDirectionType)NUM2INT(direction)); - return self; -} - -static void -cont_children_callback(widget, data) - GtkWidget *widget; - gpointer data; -{ - VALUE ary = (VALUE)data; - - ary_push(ary, get_value_from_gobject(GTK_OBJECT(widget))); -} - -static VALUE -cont_children(self, direction) - VALUE self, direction; -{ - GtkWidget *widget = get_widget(self); - VALUE ary = ary_new(); - - gtk_container_foreach(GTK_CONTAINER(widget), - cont_children_callback, - (gpointer)ary); - return ary; -} - -static VALUE -align_s_new(self, xalign, yalign, xscale, yscale) - VALUE self, xalign, yalign, xscale, yscale; -{ - return make_widget(self, gtk_alignment_new(NUM2DBL(xalign), - NUM2DBL(yalign), - NUM2DBL(xscale), - NUM2DBL(yscale))); -} - -static VALUE -align_set(self, xalign, yalign, xscale, yscale) - VALUE self, xalign, yalign, xscale, yscale; -{ - GtkWidget *widget = get_widget(self); - - gtk_alignment_set(GTK_ALIGNMENT(widget), - NUM2DBL(xalign), NUM2DBL(yalign), - NUM2DBL(xscale), NUM2DBL(yscale)); - return self; -} - -static VALUE -misc_set_align(self, xalign, yalign) - VALUE self, xalign, yalign; -{ - GtkWidget *widget = get_widget(self); - - gtk_misc_set_alignment(GTK_MISC(widget), - NUM2DBL(xalign), NUM2DBL(yalign)); - return self; -} - -static VALUE -misc_set_padding(self, xpad, ypad) - VALUE self, xpad, ypad; -{ - GtkWidget *widget = get_widget(self); - - gtk_misc_set_padding(GTK_MISC(widget), - NUM2DBL(xpad), NUM2DBL(ypad)); - return self; -} - -static VALUE -arrow_s_new(self, arrow_t, shadow_t) - VALUE self, arrow_t, shadow_t; -{ - return make_widget(self, gtk_arrow_new((GtkArrowType)NUM2INT(arrow_t), - (GtkShadowType)NUM2INT(shadow_t))); -} - -static VALUE -arrow_set(self, arrow_t, shadow_t) - VALUE self, arrow_t, shadow_t; -{ - GtkWidget *widget = get_widget(self); - - gtk_arrow_set(GTK_ARROW(widget), - (GtkArrowType)NUM2INT(arrow_t), - (GtkShadowType)NUM2INT(shadow_t)); - return self; -} - -static VALUE -frame_s_new(self, label) - VALUE self, label; -{ - return make_widget(self, gtk_frame_new(get_cstring(label))); -} - -static VALUE -frame_set_label(self, label) - VALUE self, label; -{ - GtkWidget *widget = get_widget(self); - - gtk_frame_set_label(GTK_FRAME(widget), get_cstring(label)); - return self; -} - -static VALUE -frame_set_label_align(self, xalign, yalign) - VALUE self, xalign, yalign; -{ - GtkWidget *widget = get_widget(self); - - gtk_frame_set_label_align(GTK_FRAME(widget), - NUM2DBL(xalign), - NUM2DBL(yalign)); - - return self; -} - -static VALUE -frame_set_shadow_type(self, type) - VALUE self, type; -{ - GtkWidget *widget = get_widget(self); - - gtk_frame_set_shadow_type(GTK_FRAME(widget), - (GtkShadowType)NUM2INT(type)); - return self; -} - -static VALUE -aframe_s_new(self, label, xalign, yalign, ratio, obey_child) - VALUE self, label, xalign, yalign, ratio, obey_child; -{ - return make_widget(self, gtk_aspect_frame_new(get_cstring(label), - NUM2DBL(xalign), - NUM2DBL(yalign), - NUM2DBL(ratio), - RTEST(obey_child))); -} - -static VALUE -aframe_set(self, xalign, yalign, ratio, obey_child) - VALUE self, xalign, yalign, ratio, obey_child; -{ - GtkWidget *widget = get_widget(self); - - gtk_aspect_frame_set(GTK_ASPECT_FRAME(widget), - NUM2DBL(xalign), NUM2DBL(yalign), - NUM2DBL(ratio), RTEST(obey_child)); - return self; -} - -static VALUE -adj_s_new(self, value, lower, upper, step_inc, page_inc, page_size) - VALUE self, value, lower, upper, step_inc, page_inc, page_size; -{ - return make_widget(self, gtk_adjustment_new(NUM2DBL(value), - NUM2DBL(lower), - NUM2DBL(upper), - NUM2DBL(step_inc), - NUM2DBL(page_inc), - NUM2DBL(page_size))); -} - -static VALUE -widget_destroy(self) - VALUE self; -{ - gtk_widget_destroy(get_widget(self)); - clear_gobject(self); - - return Qnil; -} - -static VALUE -widget_show(self) - VALUE self; -{ - gtk_widget_show(get_widget(self)); - return self; -} - -static VALUE -widget_show_all(self) - VALUE self; -{ - gtk_widget_show_all(get_widget(self)); - return self; -} - -static VALUE -widget_hide(self) - VALUE self; -{ - gtk_widget_hide(get_widget(self)); - return self; -} - -static VALUE -widget_hide_all(self) - VALUE self; -{ - gtk_widget_hide_all(get_widget(self)); - return self; -} - -static VALUE -widget_map(self) - VALUE self; -{ - gtk_widget_map(get_widget(self)); - return self; -} - -static VALUE -widget_unmap(self) - VALUE self; -{ - gtk_widget_unmap(get_widget(self)); - return self; -} - -static VALUE -widget_realize(self) - VALUE self; -{ - gtk_widget_realize(get_widget(self)); - return self; -} - -static VALUE -widget_unrealize(self) - VALUE self; -{ - gtk_widget_unrealize(get_widget(self)); - return self; -} - -static VALUE -widget_queue_draw(self) - VALUE self; -{ - gtk_widget_queue_draw(get_widget(self)); - return self; -} - -static VALUE -widget_queue_resize(self) - VALUE self; -{ - gtk_widget_queue_resize(get_widget(self)); - return self; -} - -static VALUE -widget_draw(self, rect) - VALUE self, rect; -{ - gtk_widget_draw(get_widget(self), get_gdkrectangle(rect)); - return self; -} - -static VALUE -widget_draw_focus(self) - VALUE self; -{ - gtk_widget_draw_focus(get_widget(self)); - return self; -} - -static VALUE -widget_draw_default(self) - VALUE self; -{ - gtk_widget_draw_default(get_widget(self)); - return self; -} - -static VALUE -widget_draw_children(self) - VALUE self; -{ - gtk_widget_draw_children(get_widget(self)); - return self; -} - -static VALUE -widget_size_request(self, req) - VALUE self, req; -{ - gtk_widget_size_request(get_widget(self), get_grequisiton(req)); - return self; -} - -static VALUE -widget_size_allocate(self, alloc) - VALUE self, alloc; -{ - gtk_widget_size_allocate(get_widget(self), get_gallocation(alloc)); - return self; -} - -static VALUE -widget_inst_accel(self, accel, sig, key, mod) - VALUE self, accel, sig, key, mod; -{ - gtk_widget_install_accelerator(get_widget(self), - get_gtkacceltbl(accel), - get_cstring(sig), - NUM2INT(key), - (guint8)NUM2INT(mod)); - return self; -} - -static VALUE -widget_rm_accel(self, accel, sig) - VALUE self, accel, sig; -{ - gtk_widget_remove_accelerator(get_widget(self), - get_gtkacceltbl(accel), - get_cstring(sig)); - return self; -} - -static VALUE -widget_event(self, event) - VALUE self, event; -{ - int n = gtk_widget_event(get_widget(self), get_gdkevent(event)); - return NUM2INT(n); -} - -static VALUE -widget_activate(self) - VALUE self; -{ - gtk_widget_activate(get_widget(self)); - return self; -} - -static VALUE -widget_grab_focus(self) - VALUE self; -{ - gtk_widget_grab_focus(get_widget(self)); - return self; -} - -static VALUE -widget_grab_default(self) - VALUE self; -{ - gtk_widget_grab_default(get_widget(self)); - return self; -} - -static VALUE -widget_restore_state(self) - VALUE self; -{ - gtk_widget_restore_state(get_widget(self)); - return self; -} - -static VALUE -widget_visible(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - if (GTK_WIDGET_VISIBLE(widget)) - return TRUE; - return FALSE; -} - -static VALUE -widget_reparent(self, parent) - VALUE self, parent; -{ - gtk_widget_reparent(get_widget(self), get_widget(parent)); - return self; -} - -static VALUE -widget_popup(self, x, y) - VALUE self, x, y; -{ - gtk_widget_popup(get_widget(self), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -widget_intersect(self, area, intersect) - VALUE self, area, intersect; -{ - int n = gtk_widget_intersect(get_widget(self), - get_gdkrectangle(area), - get_gdkrectangle(intersect)); - return NUM2INT(n); -} - -static VALUE -widget_basic(self) - VALUE self; -{ - int n = gtk_widget_basic(get_widget(self)); - return NUM2INT(n); -} - -static VALUE -widget_set_state(self, state) - VALUE self, state; -{ - gtk_widget_set_state(get_widget(self), (GtkStateType)NUM2INT(state)); - return self; -} - -static VALUE -widget_set_style(self, style) - VALUE self, style; -{ - gtk_widget_set_style(get_widget(self), - get_gstyle(style)); - return self; -} - -static VALUE -widget_set_parent(self, parent) - VALUE self, parent; -{ - gtk_widget_set_parent(get_widget(self), get_widget(parent)); - return self; -} - -static VALUE -widget_set_name(self, name) - VALUE self, name; -{ - gtk_widget_set_name(get_widget(self), get_cstring(name)); - return self; -} - -static VALUE -widget_get_name(self) - VALUE self; -{ - char *name = gtk_widget_get_name(get_widget(self)); - - return str_new2(name); -} - -static VALUE -widget_set_sensitive(self, sensitive) - VALUE self, sensitive; -{ - gtk_widget_set_sensitive(get_widget(self), RTEST(sensitive)); - return self; -} - -static VALUE -widget_set_uposition(self, x, y) - VALUE self, x, y; -{ - gtk_widget_set_uposition(get_widget(self), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -widget_set_usize(self, w, h) - VALUE self, w, h; -{ - gtk_widget_set_usize(get_widget(self), NUM2INT(w), NUM2INT(h)); - return self; -} - -static VALUE -widget_set_events(self, events) - VALUE self, events; -{ - gtk_widget_set_events(get_widget(self), NUM2INT(events)); - return self; -} - -static VALUE -widget_set_eevents(self, mode) - VALUE self, mode; -{ - gtk_widget_set_extension_events(get_widget(self), - (GdkExtensionMode)NUM2INT(mode)); - return self; -} - -static VALUE -widget_unparent(self) - VALUE self; -{ - gtk_widget_unparent(get_widget(self)); - return self; -} - -static VALUE -widget_window(self) - VALUE self; -{ - return make_gdkwindow(get_widget(self)->window); -} - -static VALUE -widget_get_toplevel(self) - VALUE self; -{ - return get_value_from_gobject(gtk_widget_get_toplevel(get_widget(self))); -} - -static VALUE -widget_get_ancestor(self, type) - VALUE self, type; -{ - GtkWidget *widget = get_widget(self); -#if 0 - if (obj_is_kind_of(type, cClass)) { - } -#endif - widget = gtk_widget_get_ancestor(widget, NUM2INT(type)); - - return get_value_from_gobject(widget); -} - -static VALUE -widget_get_colormap(self) - VALUE self; -{ - GdkColormap *cmap = gtk_widget_get_colormap(get_widget(self)); - - return make_gdkcmap(cmap); -} - -static VALUE -widget_get_visual(self) - VALUE self; -{ - GdkVisual *v = gtk_widget_get_visual(get_widget(self)); - - return make_gdkvisual(v); -} - -static VALUE -widget_get_style(self) - VALUE self; -{ - GtkStyle *s = gtk_widget_get_style(get_widget(self)); - - return make_gstyle(s); -} - -static VALUE -widget_get_pointer(self) - VALUE self; -{ - int x, y; - - gtk_widget_get_pointer(get_widget(self), &x, &y); - return assoc_new(INT2FIX(x), INT2FIX(y)); -} - -static VALUE -widget_is_ancestor(self, ancestor) - VALUE self, ancestor; -{ - if (gtk_widget_is_ancestor(get_widget(self), get_widget(ancestor))) { - return TRUE; - } - return FALSE; -} - -static VALUE -widget_is_child(self, child) - VALUE self, child; -{ - if (gtk_widget_is_child(get_widget(self), get_widget(child))) { - return TRUE; - } - return FALSE; -} - -static VALUE -widget_get_events(self) - VALUE self; -{ - int n = gtk_widget_get_events(get_widget(self)); - return NUM2INT(n); -} - -static VALUE -widget_get_eevents(self) - VALUE self; -{ - GdkExtensionMode m; - m = gtk_widget_get_extension_events(get_widget(self)); - return NUM2INT((int)m); -} - -static VALUE -widget_push_cmap(self, cmap) - VALUE self, cmap; -{ - gtk_widget_push_colormap(get_gdkcmap(cmap)); - return Qnil; -} - -static VALUE -widget_push_visual(self, visual) - VALUE self, visual; -{ - gtk_widget_push_visual(get_gdkvisual(visual)); - return make_gdkcmap(visual); -} - -static VALUE -widget_push_style(self, style) - VALUE self, style; -{ - gtk_widget_push_style(get_gstyle(style)); - return Qnil; -} - -static VALUE -widget_pop_cmap(self, cmap) - VALUE self, cmap; -{ - gtk_widget_pop_colormap(); - return Qnil; -} - -static VALUE -widget_pop_visual(self, visual) - VALUE self, visual; -{ - gtk_widget_pop_visual(); - return Qnil; -} - -static VALUE -widget_pop_style(self, style) - VALUE self, style; -{ - gtk_widget_pop_style(); - return Qnil; -} - -static VALUE -widget_set_default_cmap(self, cmap) - VALUE self, cmap; -{ - gtk_widget_set_default_colormap(get_gdkcmap(cmap)); - return Qnil; -} - -static VALUE -widget_set_default_visual(self, visual) - VALUE self, visual; -{ - gtk_widget_set_default_visual(get_gdkvisual(visual)); - return make_gdkcmap(visual); -} - -static VALUE -widget_set_default_style(self, style) - VALUE self, style; -{ - gtk_widget_set_default_style(get_gstyle(style)); - return Qnil; -} - -static VALUE -widget_get_default_cmap(self) - VALUE self; -{ - GdkColormap *cmap = gtk_widget_get_default_colormap(); - - return make_gdkcmap(cmap); -} - -static VALUE -widget_get_default_visual(self) - VALUE self; -{ - GdkVisual *v = gtk_widget_get_default_visual(); - - return make_gdkvisual(v); -} - -static VALUE -widget_get_default_style(self) - VALUE self; -{ - GtkStyle *s = gtk_widget_get_default_style(); - - return make_gstyle(s); -} - -static VALUE -widget_propagate_default_style(self) - VALUE self; -{ - gtk_widget_propagate_default_style(); - return Qnil; -} - -static VALUE -bbox_get_child_size_default(self) - VALUE self; -{ - int min_width, max_width; - - gtk_button_box_get_child_size_default(&min_width, &max_width); - - return assoc_new(INT2FIX(min_width), INT2FIX(max_width)); -} - -static VALUE -bbox_get_child_ipadding_default(self) - VALUE self; -{ - int ipad_x, ipad_y; - - gtk_button_box_get_child_ipadding_default(&ipad_x, &ipad_y); - return assoc_new(INT2FIX(ipad_x), INT2FIX(ipad_y)); -} - -static VALUE -bbox_set_child_size_default(self, min_width, max_width) - VALUE self, min_width, max_width; -{ - gtk_button_box_set_child_size_default(NUM2INT(min_width), - NUM2INT(max_width)); - return Qnil; -} - -static VALUE -bbox_set_child_ipadding_default(self, ipad_x, ipad_y) - VALUE self, ipad_x, ipad_y; -{ - gtk_button_box_set_child_ipadding_default(NUM2INT(ipad_x), - NUM2INT(ipad_y)); - return Qnil; -} - -static VALUE -bbox_get_spacing(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int n = gtk_button_box_get_spacing(GTK_BUTTON_BOX(widget)); - - return INT2FIX(n); -} - -static VALUE -bbox_get_layout(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int n = gtk_button_box_get_layout(GTK_BUTTON_BOX(widget)); - - return INT2FIX(n); -} - -static VALUE -bbox_get_child_size(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int min_width, max_width; - - gtk_button_box_get_child_size(GTK_BUTTON_BOX(widget), - &min_width, &max_width); - return assoc_new(INT2FIX(min_width), INT2FIX(max_width)); -} - -static VALUE -bbox_get_child_ipadding(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int ipad_x, ipad_y; - - gtk_button_box_get_child_ipadding(GTK_BUTTON_BOX(widget), - &ipad_x, &ipad_y); - return assoc_new(INT2FIX(ipad_x), INT2FIX(ipad_y)); -} - -static VALUE -bbox_set_spacing(self, spacing) - VALUE self, spacing; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_box_set_spacing(GTK_BUTTON_BOX(widget), - NUM2INT(spacing)); - return self; -} - -static VALUE -bbox_set_layout(self, layout) - VALUE self, layout; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_box_set_layout(GTK_BUTTON_BOX(widget), - NUM2INT(layout)); - return self; -} - -static VALUE -bbox_set_child_size(self, min_width, max_width) - VALUE self, min_width, max_width; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_box_set_child_size(GTK_BUTTON_BOX(widget), - NUM2INT(min_width), - NUM2INT(max_width)); - return self; -} - -static VALUE -bbox_set_child_ipadding(self, ipad_x, ipad_y) - VALUE self, ipad_x, ipad_y; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_box_set_child_ipadding(GTK_BUTTON_BOX(widget), - NUM2INT(ipad_x), - NUM2INT(ipad_y)); - return self; -} - -static VALUE -clist_s_new(self, titles) - VALUE self, titles; -{ - char **buf; - int i, len; - - Check_Type(titles, T_ARRAY); - len = RARRAY(titles)->len; - buf = ALLOCA_N(char*, len); - for (i=0; iptr[i], T_STRING); - buf[i] = RSTRING(RARRAY(titles)->ptr[i])->ptr; - } - return make_widget(self, gtk_clist_new(len, buf)); -} - -static VALUE -clist_set_border(self, border) - VALUE self, border; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_border(GTK_CLIST(widget), (GtkShadowType)NUM2INT(border)); - return self; -} - -static VALUE -clist_set_sel_mode(self, mode) - VALUE self, mode; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_selection_mode(GTK_CLIST(widget), - (GtkSelectionMode)NUM2INT(mode)); - return self; -} - -static VALUE -clist_set_policy(self, vpolicy, hpolicy) - VALUE self, vpolicy, hpolicy; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_policy(GTK_CLIST(widget), - (GtkPolicyType)NUM2INT(vpolicy), - (GtkPolicyType)NUM2INT(hpolicy)); - return self; -} - -static VALUE -clist_freeze(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_freeze(GTK_CLIST(widget)); - return self; -} - -static VALUE -clist_thaw(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_thaw(GTK_CLIST(widget)); - return self; -} - -static VALUE -clist_set_col_title(self, col, title) - VALUE self, col, title; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_column_title(GTK_CLIST(widget), - NUM2INT(col), - get_cstring(title)); - return self; -} - -static VALUE -clist_set_col_wigdet(self, col, win) - VALUE self, col, win; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_column_widget(GTK_CLIST(widget), - NUM2INT(col), - get_widget(win)); - return self; -} - -static VALUE -clist_set_col_just(self, col, just) - VALUE self, col, just; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_column_justification(GTK_CLIST(widget), - NUM2INT(col), - (GtkJustification)NUM2INT(just)); - return self; -} - -static VALUE -clist_set_col_width(self, col, width) - VALUE self, col, width; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_column_width(GTK_CLIST(widget), - NUM2INT(col), NUM2INT(width)); - return self; -} - -static VALUE -clist_set_row_height(self, height) - VALUE self, height; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_row_height(GTK_CLIST(widget), NUM2INT(height)); - return self; -} - -static VALUE -clist_moveto(self, row, col, row_align, col_align) - VALUE self, row, col, row_align, col_align; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_moveto(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - NUM2INT(row_align), NUM2INT(col_align)); - return self; -} - -static VALUE -clist_set_text(self, row, col, text) - VALUE self, row, col, text; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_text(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - get_cstring(text)); - return self; -} - -static VALUE -clist_set_pixmap(self, row, col, pixmap, mask) - VALUE self, row, col, pixmap, mask; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_pixmap(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - get_gdkpixmap(pixmap), - (GdkBitmap*)get_gdkpixmap(mask)); - return self; -} - -static VALUE -clist_set_pixtext(self, row, col, text, spacing, pixmap, mask) - VALUE self, row, col, text, spacing, pixmap, mask; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_pixtext(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - get_cstring(text), - NUM2INT(spacing), - get_gdkpixmap(pixmap), - (GdkBitmap*)get_gdkpixmap(mask)); - return self; -} - -static VALUE -clist_set_foreground(self, row, color) - VALUE self, row, color; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_foreground(GTK_CLIST(widget), - NUM2INT(row), get_gdkcolor(color)); - return self; -} - -static VALUE -clist_set_background(self, row, color) - VALUE self, row, color; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_background(GTK_CLIST(widget), - NUM2INT(row), get_gdkcolor(color)); - return self; -} - -static VALUE -clist_set_shift(self, row, col, verticle, horizontal) - VALUE self, row, col, verticle, horizontal; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_shift(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - NUM2INT(verticle), NUM2INT(horizontal)); - return self; -} - -static VALUE -clist_append(self, text) - VALUE self, text; -{ - GtkWidget *widget = get_widget(self); - char **buf; - int i, len; - - Check_Type(text, T_ARRAY); - len = GTK_CLIST(widget)->columns; - if (len > RARRAY(text)->len) { - ArgError("text too short"); - } - buf = ALLOCA_N(char*, len); - for (i=0; iptr[i], T_STRING); - buf[i] = RSTRING(RARRAY(text)->ptr[i])->ptr; - } - i = gtk_clist_append(GTK_CLIST(widget), buf); - return INT2FIX(i); -} - -static VALUE -clist_insert(self, row, text) - VALUE self, row, text; -{ - GtkWidget *widget = get_widget(self); - char **buf; - int i, len; - - Check_Type(text, T_ARRAY); - len = GTK_CLIST(widget)->columns; - if (len > RARRAY(text)->len) { - ArgError("text too short"); - } - buf = ALLOCA_N(char*, len); - for (i=0; iptr[i], T_STRING); - buf[i] = RSTRING(RARRAY(text)->ptr[i])->ptr; - } - gtk_clist_insert(GTK_CLIST(widget), NUM2INT(row), buf); - return self; -} - -static VALUE -clist_remove(self, row) - VALUE self, row; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_remove(GTK_CLIST(widget), NUM2INT(row)); - return self; -} - -static VALUE -clist_set_row_data(self, row, data) - VALUE self, row, data; -{ - GtkWidget *widget = get_widget(self); - - add_relative(self, data); - gtk_clist_set_row_data(GTK_CLIST(widget), NUM2INT(row), (gpointer)data); - return self; -} - -static VALUE -clist_get_row_data(self, row) - VALUE self, row; -{ - GtkWidget *widget = get_widget(self); - - return (VALUE)gtk_clist_get_row_data(GTK_CLIST(widget), NUM2INT(row)); -} - -static VALUE -clist_select_row(self, row, col) - VALUE self, row, col; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_select_row(GTK_CLIST(widget), NUM2INT(row), NUM2INT(col)); - return self; -} - -static VALUE -clist_unselect_row(self, row, col) - VALUE self, row, col; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_unselect_row(GTK_CLIST(widget), NUM2INT(row), NUM2INT(col)); - return self; -} - -static VALUE -clist_clear(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_clear(GTK_CLIST(widget)); - return self; -} - -static VALUE -gwin_s_new(self, type) - VALUE self, type; -{ - return make_widget(self, gtk_window_new(NUM2INT(type))); -} - -static VALUE -gwin_set_policy(self, shrink, grow, auto_shrink) - VALUE self, shrink, grow, auto_shrink; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_policy(GTK_WINDOW(widget), - RTEST(shrink), RTEST(grow), RTEST(auto_shrink)); - return self; -} - -static VALUE -gwin_set_title(self, title) - VALUE self, title; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_title(GTK_WINDOW(widget), get_cstring(title)); - return self; -} - -static VALUE -gwin_position(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_position(GTK_WINDOW(widget), - (GtkWindowPosition)NUM2INT(pos)); - - return self; -} - -static VALUE -gwin_set_wmclass(self, wmclass1, wmclass2) - VALUE self, wmclass1, wmclass2; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_wmclass(GTK_WINDOW(widget), - get_cstring(wmclass1), - get_cstring(wmclass2)); - return self; -} - -static VALUE -gwin_set_focus(self, win) - VALUE self, win; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_focus(GTK_WINDOW(widget), get_widget(win)); - return self; -} - -static VALUE -gwin_set_default(self, win) - VALUE self, win; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_default(GTK_WINDOW(widget), get_widget(win)); - return self; -} - -static VALUE -gwin_add_accel(self, accel) - VALUE self, accel; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_add_accelerator_table(GTK_WINDOW(widget), - get_gtkacceltbl(accel)); - return self; -} - -static VALUE -gwin_rm_accel(self, accel) - VALUE self, accel; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_remove_accelerator_table(GTK_WINDOW(widget), - get_gtkacceltbl(accel)); - return self; -} - -static VALUE -dialog_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_dialog_new()); -} - -static VALUE -fsel_s_new(self, title) - VALUE self, title; -{ - return make_widget(self, gtk_file_selection_new(get_cstring(title))); -} - -static VALUE -fsel_set_fname(self, fname) - VALUE self, fname; -{ - GtkWidget *widget = get_widget(self); - - Check_Type(fname, T_STRING); - gtk_file_selection_set_filename(GTK_FILE_SELECTION(widget), - RSTRING(fname)->ptr); - - return self; -} - -static VALUE -fsel_get_fname(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - gchar *fname; - - fname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(widget)); - - return str_new2(fname); -} - -static VALUE -fsel_ok_button(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - VALUE b = rb_iv_get(self, "ok_button"); - - if (NIL_P(b)) { - GtkWidget *w = GTK_FILE_SELECTION(widget)->ok_button; - b = make_widget(gButton, w); - rb_iv_set(self, "ok_button", b); - } - - return b; -} - -static VALUE -fsel_cancel_button(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - VALUE b = rb_iv_get(self, "cancel_button"); - - if (NIL_P(b)) { - GtkWidget *w = GTK_FILE_SELECTION(widget)->cancel_button; - b = make_widget(gButton, w); - rb_iv_set(self, "cancel_button", b); - } - - return b; -} - -static VALUE -fsel_help_button(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - VALUE b = rb_iv_get(self, "help_button"); - - if (NIL_P(b)) { - GtkWidget *w = GTK_FILE_SELECTION(widget)->help_button; - b = make_widget(gButton, w); - rb_iv_set(self, "help_button", b); - } - - return b; -} - -static VALUE -label_s_new(self, label) - VALUE self, label; -{ - return make_widget(self, gtk_label_new(get_cstring(label))); -} - -static VALUE -list_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_list_new()); -} - -static VALUE -list_set_sel_mode(self, mode) - VALUE self, mode; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_set_selection_mode(GTK_LIST(widget), - (GtkSelectionMode)NUM2INT(mode)); - return self; -} - -static VALUE -list_sel_mode(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return INT2FIX(GTK_LIST(widget)->selection_mode); -} - -static VALUE -list_selection(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - return glist2ary(GTK_LIST(widget)->selection); -} - -static VALUE -list_insert_items(self, items, pos) - VALUE self, items, pos; -{ - GtkWidget *widget = get_widget(self); - GList *glist; - - glist = ary2glist(items); - - gtk_list_insert_items(GTK_LIST(widget), glist, NUM2INT(pos)); - g_list_free(glist); - - return self; -} - -static VALUE -list_append_items(self, items) - VALUE self, items; -{ - GtkWidget *widget = get_widget(self); - GList *glist; - - glist = ary2glist(items); - - gtk_list_append_items(GTK_LIST(widget), glist); - g_list_free(glist); - - return self; -} - -static VALUE -list_prepend_items(self, items) - VALUE self, items; -{ - GtkWidget *widget = get_widget(self); - GList *glist; - - glist = ary2glist(items); - gtk_list_prepend_items(GTK_LIST(widget), glist); - g_list_free(glist); - - return self; -} - -static VALUE -list_remove_items(self, items) - VALUE self, items; -{ - GtkWidget *widget = get_widget(self); - GList *glist; - - glist = ary2glist(items); - gtk_list_remove_items(GTK_LIST(widget), glist); - g_list_free(glist); - - return self; -} - -static VALUE -list_clear_items(self, start, end) - VALUE self, start, end; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_clear_items(GTK_LIST(widget), NUM2INT(start), NUM2INT(end)); - return self; -} - -static VALUE -list_select_item(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_select_item(GTK_LIST(widget), NUM2INT(pos)); - return self; -} - -static VALUE -list_unselect_item(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_unselect_item(GTK_LIST(widget), NUM2INT(pos)); - return self; -} - -static VALUE -list_select_child(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_select_child(GTK_LIST(widget), get_widget(child)); - return self; -} - -static VALUE -list_unselect_child(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_unselect_child(GTK_LIST(widget), get_widget(child)); - return self; -} - -static VALUE -list_child_position(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - gint pos; - - pos = gtk_list_child_position(GTK_LIST(widget), get_widget(child)); - return INT2FIX(pos); -} - -static VALUE -item_select(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_item_select(GTK_ITEM(widget)); - return self; -} - -static VALUE -item_deselect(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_item_deselect(GTK_ITEM(widget)); - return self; -} - -static VALUE -item_toggle(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_item_toggle(GTK_ITEM(widget)); - return self; -} - -static VALUE -litem_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - widget = gtk_list_item_new_with_label(get_cstring(label)); - } - else { - widget = gtk_list_item_new(); - } - - return make_widget(self, widget); -} - -static VALUE -mshell_append(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_shell_append(GTK_MENU_SHELL(widget), get_widget(child)); - return self; -} - -static VALUE -mshell_prepend(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_shell_prepend(GTK_MENU_SHELL(widget), get_widget(child)); - return self; -} - -static VALUE -mshell_insert(self, child, pos) - VALUE self, child, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_shell_insert(GTK_MENU_SHELL(widget), get_widget(child), - NUM2INT(pos)); - return self; -} - -static VALUE -mshell_deactivate(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_shell_deactivate(GTK_MENU_SHELL(widget)); - return self; -} - -static VALUE -menu_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_menu_new()); -} - -static VALUE -menu_append(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_append(GTK_MENU(widget), get_widget(child)); - return self; -} - -static VALUE -menu_prepend(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_prepend(GTK_MENU(widget), get_widget(child)); - return self; -} - -static VALUE -menu_insert(self, child, pos) - VALUE self, child, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_insert(GTK_MENU(widget), get_widget(child), NUM2INT(pos)); - return self; -} - -static void -menu_pos_func(menu, x, y, data) - GtkMenu *menu; - gint x, y; - gpointer data; -{ - VALUE m = get_value_from_gobject(GTK_OBJECT(menu)); - - rb_funcall((VALUE)data, 3, m, INT2FIX(x), INT2FIX(y)); -} - -static VALUE -menu_popup(self, pshell, pitem, func, button, activate_time) - VALUE self, pshell, pitem, func, button, activate_time; -{ - GtkWidget *widget = get_widget(self); - GtkMenuPositionFunc pfunc = NULL; - gpointer data = NULL; - - if (!NIL_P(func)) { - pfunc = menu_pos_func; - data = (gpointer)func; - add_relative(self, func); - } - gtk_menu_popup(GTK_MENU(widget), - get_widget(pshell), get_widget(pitem), - pfunc, - data, - NUM2INT(button), - NUM2INT(activate_time)); - return self; -} - -static VALUE -menu_popdown(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_popdown(GTK_MENU(widget)); - return self; -} - -static VALUE -menu_get_active(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GtkWidget *mitem = gtk_menu_get_active(GTK_MENU(widget)); - - return make_widget(gMenuItem, mitem); -} - -static VALUE -menu_set_active(self, active) - VALUE self, active; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_set_active(GTK_MENU(widget), NUM2INT(active)); - return self; -} - -static VALUE -menu_set_acceltbl(self, table) - VALUE self, table; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_set_accelerator_table(GTK_MENU(widget), - get_gtkacceltbl(table)); - return self; -} - -static VALUE -mbar_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_menu_bar_new()); -} - -static VALUE -mbar_append(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_bar_append(GTK_MENU_BAR(widget), get_widget(child)); - return self; -} - -static VALUE -mbar_prepend(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_bar_prepend(GTK_MENU_BAR(widget), get_widget(child)); - return self; -} -static VALUE -mbar_insert(self, child, pos) - VALUE self, child, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_bar_insert(GTK_MENU_BAR(widget), - get_widget(child), NUM2INT(pos)); - return self; -} - -static VALUE -mitem_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - widget = gtk_menu_item_new_with_label(get_cstring(label)); - } - else { - widget = gtk_menu_item_new(); - } - - return make_widget(self, widget); -} - -static VALUE -mitem_set_submenu(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget), get_widget(child)); - return self; -} - -static VALUE -mitem_set_placement(self, place) - VALUE self, place; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_set_placement(GTK_MENU_ITEM(widget), - (GtkSubmenuPlacement)NUM2INT(place)); - return self; -} - -static VALUE -mitem_accelerator_size(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_accelerator_size(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -mitem_accelerator_text(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - char buf[1024]; /* enough? */ - - gtk_menu_item_accelerator_text(GTK_MENU_ITEM(widget), buf); - return str_new2(buf); -} - -static VALUE -mitem_configure(self, show_toggle, show_submenu) - VALUE self, show_toggle, show_submenu; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_configure(GTK_MENU_ITEM(widget), - NUM2INT(show_toggle), - NUM2INT(show_submenu)); - return self; -} - -static VALUE -mitem_select(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_select(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -mitem_deselect(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_deselect(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -mitem_activate(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_activate(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -mitem_right_justify(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_right_justify(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -cmitem_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - widget = gtk_check_menu_item_new_with_label(get_cstring(label)); - } - else { - widget = gtk_check_menu_item_new(); - } - - return make_widget(self, widget); -} - -static VALUE -cmitem_set_state(self, state) - VALUE self, state; -{ - GtkWidget *widget = get_widget(self); - - gtk_check_menu_item_set_state(GTK_CHECK_MENU_ITEM(widget), - NUM2INT(state)); - return self; -} - -static VALUE -cmitem_set_show_toggle(self, always) - VALUE self, always; -{ - GtkWidget *widget = get_widget(self); - - gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(widget), - (gboolean)RTEST(always)); - return self; -} - -static VALUE -cmitem_toggled(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_check_menu_item_toggled(GTK_CHECK_MENU_ITEM(widget)); - return self; -} - -static VALUE -rmitem_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE arg1, arg2; - GtkWidget *widget; - GSList *list = NULL; - char *label = NULL; - - if (rb_scan_args(argc, argv, "02", &arg1, &arg2) == 1 && - TYPE(arg1) == T_STRING) { - label = RSTRING(arg1)->ptr; - } - else { - if (!NIL_P(arg2)) { - Check_Type(arg2, T_STRING); - label = RSTRING(arg2)->ptr; - } - if (obj_is_kind_of(arg1, gRMenuItem)) { - GtkWidget *b = get_widget(arg1); - list = GTK_RADIO_MENU_ITEM(b)->group; - } - else { - list = ary2gslist(arg1); - } - } - if (label) { - widget = gtk_radio_menu_item_new_with_label(list, label); - } - else { - widget = gtk_radio_menu_item_new(list); - } - return make_widget(self, widget); -} - -static VALUE -rmitem_group(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return gslist2ary(gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(widget))); -} - -static VALUE -note_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_notebook_new()); -} - -static VALUE -note_append_page(self, child, label) - VALUE self, child, label; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_append_page(GTK_NOTEBOOK(widget), - get_widget(child), - get_widget(label)); - return self; -} - -static VALUE -note_prepend_page(self, child, label) - VALUE self, child, label; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_prepend_page(GTK_NOTEBOOK(widget), - get_widget(child), - get_widget(label)); - return self; -} - -static VALUE -note_insert_page(self, child, label, pos) - VALUE self, child, label, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_insert_page(GTK_NOTEBOOK(widget), - get_widget(child), - get_widget(label), - NUM2INT(pos)); - return self; -} - -static VALUE -note_remove_page(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_remove_page(GTK_NOTEBOOK(widget), NUM2INT(pos)); - return self; -} - -static VALUE -note_set_page(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_set_page(GTK_NOTEBOOK(widget), NUM2INT(pos)); - return self; -} - -static VALUE -note_cur_page(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return INT2FIX(GTK_NOTEBOOK(widget)->cur_page); -} - -static VALUE -note_next_page(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_next_page(GTK_NOTEBOOK(widget)); - return self; -} - -static VALUE -note_prev_page(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_prev_page(GTK_NOTEBOOK(widget)); - return self; -} - -static VALUE -note_set_tab_pos(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widget), NUM2INT(pos)); - return self; -} - -static VALUE -note_tab_pos(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - return INT2FIX(GTK_NOTEBOOK(widget)->tab_pos); -} - -static VALUE -note_set_show_tabs(self, show_tabs) - VALUE self, show_tabs; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widget), RTEST(show_tabs)); - return self; -} - -static VALUE -note_show_tabs(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return GTK_NOTEBOOK(widget)->show_tabs?TRUE:FALSE; -} - -static VALUE -note_set_show_border(self, show_border) - VALUE self, show_border; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widget), RTEST(show_border)); - return self; -} - -static VALUE -note_show_border(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return GTK_NOTEBOOK(widget)->show_border?TRUE:FALSE; -} - -static VALUE -omenu_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_option_menu_new()); -} - -static VALUE -omenu_set_menu(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - rb_iv_set(self, "option_menu", child); - gtk_option_menu_set_menu(GTK_OPTION_MENU(widget), get_widget(child)); - return self; -} - -static VALUE -omenu_get_menu(self) - VALUE self; -{ - return rb_iv_get(self, "option_menu"); -} - -static VALUE -omenu_remove_menu(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_option_menu_remove_menu(GTK_OPTION_MENU(widget)); - return self; -} - -static VALUE -omenu_set_history(self, index) - VALUE self, index; -{ - GtkWidget *widget = get_widget(self); - - gtk_option_menu_set_history(GTK_OPTION_MENU(widget), NUM2INT(index)); - return self; -} - -static VALUE -image_s_new(self, val, mask) - VALUE self, val, mask; -{ - return make_widget(self, gtk_image_new(get_gdkimage(val), - (GdkBitmap*)get_gdkpixmap(mask))); -} - -static VALUE -image_set(self, val, mask) - VALUE self, val, mask; -{ - GtkWidget *widget = get_widget(self); - - gtk_image_set(GTK_IMAGE(widget), get_gdkimage(val), get_gdkpixmap(mask)); - return self; -} - -static VALUE -image_get(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GdkImage *val; - GdkBitmap *mask; - - gtk_image_get(GTK_IMAGE(widget), &val, &mask); - - return assoc_new(make_gdkimage(self, val), - make_gdkpixmap(self, mask)); -} - -static VALUE -preview_s_new(self, type) - VALUE self, type; -{ - return make_widget(self, gtk_preview_new((GtkPreviewType)NUM2INT(type))); -} - - -static VALUE -preview_size(self, w, h) - VALUE self, w, h; -{ - GtkWidget *widget = get_widget(self); - - gtk_preview_size(GTK_PREVIEW(widget), NUM2INT(w), NUM2INT(h)); - return self; -} - -#if 0 - rb_define_method(gPixmap, "put", preview_size, 8); - rb_define_method(gPixmap, "put_row", preview_size, 5); - rb_define_method(gPixmap, "draw_row", preview_size, 4); -#endif - -static VALUE -preview_set_expand(self, expand) - VALUE self, expand; -{ - GtkWidget *widget = get_widget(self); - - gtk_preview_set_expand(GTK_PREVIEW(widget), NUM2INT(expand)); - return self; -} - -static VALUE -preview_set_gamma(self, gamma) - VALUE self, gamma; -{ - gtk_preview_set_gamma(NUM2DBL(gamma)); - return Qnil; -} - -static VALUE -preview_set_color_cube(self, nred, ngreen, nblue, ngray) - VALUE self, nred, ngreen, nblue, ngray; -{ - gtk_preview_set_color_cube(NUM2INT(nred), - NUM2INT(ngreen), - NUM2INT(nblue), - NUM2INT(ngray)); - return Qnil; -} - -static VALUE -preview_set_install_cmap(self, cmap) - VALUE self, cmap; -{ - gtk_preview_set_install_cmap(NUM2INT(cmap)); - return Qnil; -} - -static VALUE -preview_set_reserved(self, nreserved) - VALUE self, nreserved; -{ - gtk_preview_set_reserved(NUM2INT(nreserved)); - return Qnil; -} - -static VALUE -preview_get_visual(self) - VALUE self; -{ - GdkVisual *v = gtk_preview_get_visual(); - return make_gdkvisual(v); -} - -static VALUE -preview_get_cmap(self) - VALUE self; -{ - GdkColormap *c = gtk_preview_get_cmap(); - return make_gdkcmap(c); -} - -static VALUE -preview_get_info(self) - VALUE self; -{ - GtkPreviewInfo *i = gtk_preview_get_info(); - return make_gtkprevinfo(i); -} - -static VALUE -pbar_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_progress_bar_new()); -} - -static VALUE -pbar_update(self, percentage) - VALUE self, percentage; -{ - GtkWidget *widget = get_widget(self); - - gtk_progress_bar_update(GTK_PROGRESS_BAR(widget), - NUM2DBL(percentage)); - return self; -} - -static VALUE -scwin_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1, arg2; - GtkAdjustment *h_adj = NULL; - GtkAdjustment *v_adj = NULL; - - rb_scan_args(argc, argv, "02", &arg1, &arg2); - if (!NIL_P(arg1)) h_adj = (GtkAdjustment*)get_gobject(arg1); - if (!NIL_P(arg2)) v_adj = (GtkAdjustment*)get_gobject(arg2); - - return make_widget(self, gtk_scrolled_window_new(h_adj, v_adj)); -} - -static VALUE -scwin_set_policy(self, hpolicy, vpolicy) - VALUE self, hpolicy, vpolicy; -{ - GtkWidget *widget = get_widget(self); - - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget), - (GtkPolicyType)NUM2INT(hpolicy), - (GtkPolicyType)NUM2INT(vpolicy)); - return self; -} - - -static VALUE -tbl_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE row, col, homogeneous; - - rb_scan_args(argc, argv, "21", &row, &col, &homogeneous); - return make_widget(self, gtk_table_new(NUM2INT(row), - NUM2INT(col), - RTEST(homogeneous))); -} - -static VALUE -tbl_attach(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - GtkWidget *widget = get_widget(self); - VALUE child, left, right, top, bottom; - VALUE arg0, arg1, arg2, arg3; - int xopt, yopt, xspc, yspc; - - xopt = yopt = GTK_EXPAND | GTK_FILL; - xspc = yspc = 0; - rb_scan_args(argc, argv, "54", - &child, &left, &right, &top, &bottom, - &arg0, &arg1, &arg2, &arg3); - if (!NIL_P(arg0)) xopt = NUM2INT(arg0); - if (!NIL_P(arg1)) yopt = NUM2INT(arg1); - if (!NIL_P(arg2)) xspc = NUM2INT(arg2); - if (!NIL_P(arg3)) yspc = NUM2INT(arg3); - - gtk_table_attach(GTK_TABLE(widget), - get_widget(child), - NUM2INT(left),NUM2INT(right), - NUM2INT(top),NUM2INT(bottom), - xopt, yopt, xspc, yspc); - - return self; -} - -static VALUE -tbl_set_row_spacing(self, row, spc) - VALUE self, row, spc; -{ - GtkWidget *widget = get_widget(self); - - gtk_table_set_row_spacing(GTK_TABLE(widget), NUM2INT(row), NUM2INT(spc)); - return self; -} - -static VALUE -tbl_set_col_spacing(self, col, spc) - VALUE self, col, spc; -{ - GtkWidget *widget = get_widget(self); - - gtk_table_set_col_spacing(GTK_TABLE(widget), NUM2INT(col), NUM2INT(spc)); - return self; -} - -static VALUE -tbl_set_row_spacings(self, spc) - VALUE self, spc; -{ - GtkWidget *widget = get_widget(self); - - gtk_table_set_row_spacings(GTK_TABLE(widget), NUM2INT(spc)); - return self; -} - -static VALUE -tbl_set_col_spacings(self, spc) - VALUE self, spc; -{ - GtkWidget *widget = get_widget(self); - - gtk_table_set_col_spacings(GTK_TABLE(widget), NUM2INT(spc)); - return self; -} - -static VALUE -txt_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1, arg2; - GtkAdjustment *h_adj = NULL; - GtkAdjustment *v_adj = NULL; - - rb_scan_args(argc, argv, "02", &arg1, &arg2); - if (!NIL_P(arg1)) h_adj = (GtkAdjustment*)get_gobject(arg1); - if (!NIL_P(arg2)) v_adj = (GtkAdjustment*)get_gobject(arg2); - - return make_widget(self, gtk_text_new(h_adj, v_adj)); -} - -static VALUE -txt_set_editable(self, editable) - VALUE self, editable; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_set_editable(GTK_TEXT(widget), RTEST(editable)); - return self; -} - -static VALUE -txt_set_adjustment(self, h_adj, v_adj) - VALUE self, h_adj, v_adj; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_set_adjustments(GTK_TEXT(widget), - (GtkAdjustment*)get_gobject(h_adj), - (GtkAdjustment*)get_gobject(v_adj)); - - return self; -} - -static VALUE -txt_set_point(self, index) - VALUE self, index; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_set_point(GTK_TEXT(widget), NUM2INT(index)); - return self; -} - -static VALUE -txt_get_point(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int index = gtk_text_get_point(GTK_TEXT(widget)); - - return INT2FIX(index); -} - -static VALUE -txt_get_length(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int len = gtk_text_get_length(GTK_TEXT(widget)); - - return INT2FIX(len); -} - -static VALUE -txt_freeze(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_freeze(GTK_TEXT(widget)); - return self; -} - -static VALUE -txt_thaw(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_thaw(GTK_TEXT(widget)); - return self; -} - -static VALUE -txt_insert(self, font, fore, back, str) - VALUE self, font, fore, back, str; -{ - GtkWidget *widget = get_widget(self); - - Check_Type(str, T_STRING); - gtk_text_insert(GTK_TEXT(widget), - get_gdkfont(font), - get_gdkcolor(fore), - get_gdkcolor(back), - RSTRING(str)->ptr, - RSTRING(str)->len); - - return self; -} - -static VALUE -txt_backward_delete(self, nchars) - VALUE self, nchars; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_backward_delete(GTK_TEXT(widget), NUM2INT(nchars)); - return self; -} - -static VALUE -txt_forward_delete(self, nchars) - VALUE self, nchars; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_forward_delete(GTK_TEXT(widget), NUM2INT(nchars)); - return self; -} - -static VALUE -tbar_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1, arg2; - GtkOrientation orientation = GTK_ORIENTATION_HORIZONTAL; - GtkToolbarStyle style = GTK_TOOLBAR_BOTH; - - rb_scan_args(argc, argv, "02", &arg1, &arg2); - if (!NIL_P(arg1)) orientation = (GtkOrientation)NUM2INT(arg1); - if (!NIL_P(arg2)) style = (GtkToolbarStyle)NUM2INT(arg2); - - return make_widget(self, gtk_toolbar_new(orientation, style)); -} - -static VALUE -tbar_append_item(self, text, ttext, icon, func) - VALUE self, text, ttext, icon, func; -{ - GtkWidget *widget = get_widget(self); - GtkObject *pixmap = get_gobject(icon); - - if (NIL_P(func)) { - func = f_lambda(); - } - gtk_toolbar_append_item(GTK_TOOLBAR(widget), - get_cstring(text), - get_cstring(ttext), - GTK_PIXMAP(pixmap), - exec_callback, - (gpointer)ary_new3(1, func)); - return self; -} - -static VALUE -tbar_prepend_item(self, text, ttext, icon, func) - VALUE self, text, ttext, icon, func; -{ - GtkWidget *widget = get_widget(self); - GtkObject *pixmap = get_gobject(icon); - - if (NIL_P(func)) { - func = f_lambda(); - } - gtk_toolbar_prepend_item(GTK_TOOLBAR(widget), - get_cstring(text), - get_cstring(ttext), - GTK_PIXMAP(pixmap), - exec_callback, - (gpointer)ary_new3(1, func)); - return self; -} - -static VALUE -tbar_insert_item(self, text, ttext, icon, func, pos) - VALUE self, text, ttext, icon, func, pos; -{ - GtkWidget *widget = get_widget(self); - GtkObject *pixmap = get_gobject(icon); - - if (NIL_P(func)) { - func = f_lambda(); - } - gtk_toolbar_insert_item(GTK_TOOLBAR(widget), - get_cstring(text), - get_cstring(ttext), - GTK_PIXMAP(pixmap), - exec_callback, - (gpointer)ary_new3(1, func), - NUM2INT(pos)); - return self; -} - -static VALUE -tbar_append_space(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_append_space(GTK_TOOLBAR(widget)); - return self; -} - -static VALUE -tbar_prepend_space(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_prepend_space(GTK_TOOLBAR(widget)); - return self; -} - -static VALUE -tbar_insert_space(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_insert_space(GTK_TOOLBAR(widget), NUM2INT(pos)); - return self; -} - -static VALUE -tbar_set_orientation(self, orientation) - VALUE self, orientation; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_set_orientation(GTK_TOOLBAR(widget), - (GtkOrientation)NUM2INT(orientation)); - return self; -} - -static VALUE -tbar_set_style(self, style) - VALUE self, style; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_set_style(GTK_TOOLBAR(widget), - (GtkToolbarStyle)NUM2INT(style)); - return self; -} - -static VALUE -tbar_set_space_size(self, size) - VALUE self, size; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_set_space_size(GTK_TOOLBAR(widget), NUM2INT(size)); - return self; -} - -static VALUE -tbar_set_tooltips(self, enable) - VALUE self, enable; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_set_tooltips(GTK_TOOLBAR(widget), RTEST(enable)); - return self; -} - -static VALUE -ttips_s_new(self) - VALUE self; -{ - return make_ttips(self, gtk_tooltips_new()); -} - -static VALUE -ttips_set_tips(self, win, text) - VALUE self, win, text; -{ - Check_Type(text, T_STRING); - gtk_tooltips_set_tips(get_ttips(self), - get_widget(win), - RSTRING(text)->ptr); - - return self; -} - -static VALUE -ttips_set_delay(self, delay) - VALUE self, delay; -{ - gtk_tooltips_set_delay(get_ttips(self), NUM2INT(delay)); - - return self; -} - -static VALUE -ttips_enable(self) - VALUE self; -{ - gtk_tooltips_enable(get_ttips(self)); - return self; -} - -static VALUE -ttips_disable(self) - VALUE self; -{ - gtk_tooltips_enable(get_ttips(self)); - return self; -} - -static VALUE -tree_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_tree_new()); -} - -static VALUE -tree_append(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_append(GTK_TREE(widget), get_widget(child)); - return self; -} - -static VALUE -tree_prepend(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_prepend(GTK_TREE(widget), get_widget(child)); - return self; -} - -static VALUE -tree_insert(self, child, pos) - VALUE self, child, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_insert(GTK_TREE(widget), get_widget(child), NUM2INT(pos)); - return self; -} - -static VALUE -titem_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - Check_Type(label, T_STRING); - widget = gtk_tree_item_new_with_label(RSTRING(label)->ptr); - } - else { - widget = gtk_tree_item_new(); - } - - return make_widget(self, widget); -} - -static VALUE -titem_set_subtree(self, subtree) - VALUE self, subtree; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_set_subtree(GTK_TREE_ITEM(widget), get_widget(subtree)); - return self; -} - -static VALUE -titem_select(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_select(GTK_TREE_ITEM(widget)); - return self; -} - -static VALUE -titem_deselect(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_deselect(GTK_TREE_ITEM(widget)); - return self; -} - -static VALUE -titem_expand(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_expand(GTK_TREE_ITEM(widget)); - return self; -} - -static VALUE -titem_collapse(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_collapse(GTK_TREE_ITEM(widget)); - return self; -} - -static VALUE -vport_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1, arg2; - GtkAdjustment *h_adj = NULL; - GtkAdjustment *v_adj = NULL; - - rb_scan_args(argc, argv, "02", &arg1, &arg2); - if (!NIL_P(arg1)) h_adj = (GtkAdjustment*)get_gobject(arg1); - if (!NIL_P(arg2)) v_adj = (GtkAdjustment*)get_gobject(arg2); - - return make_widget(self, gtk_viewport_new(h_adj, v_adj)); -} - -static VALUE -vport_get_hadj(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GtkAdjustment *adj = gtk_viewport_get_hadjustment(GTK_VIEWPORT(widget)); - - return make_gobject(gAdjustment, GTK_OBJECT(adj)); -} - -static VALUE -vport_get_vadj(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GtkAdjustment *adj = gtk_viewport_get_vadjustment(GTK_VIEWPORT(widget)); - - return make_gobject(gAdjustment, GTK_OBJECT(adj)); -} - -static VALUE -vport_set_vadj(self, adj) - VALUE self, adj; -{ - GtkWidget *widget = get_widget(self); - GtkObject *adjustment = get_gobject(adj); - - gtk_viewport_set_vadjustment(GTK_VIEWPORT(widget), - GTK_ADJUSTMENT(adj)); - - return self; -} - -static VALUE -vport_set_hadj(self, adj) - VALUE self, adj; -{ - GtkWidget *widget = get_widget(self); - GtkObject *adjustment = get_gobject(adj); - - gtk_viewport_set_hadjustment(GTK_VIEWPORT(widget), - GTK_ADJUSTMENT(adj)); - - return self; -} - -static VALUE -vport_set_shadow(self, type) - VALUE self, type; -{ - GtkWidget *widget = get_widget(self); - - gtk_viewport_set_shadow_type(GTK_VIEWPORT(widget), - (GtkShadowType)NUM2INT(type)); - - return self; -} - -static VALUE -button_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - Check_Type(label, T_STRING); - widget = gtk_button_new_with_label(RSTRING(label)->ptr); - } - else { - widget = gtk_button_new(); - } - - return make_widget(self, widget); -} - -static VALUE -button_pressed(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_pressed(GTK_BUTTON(widget)); - return self; -} - -static VALUE -button_released(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_released(GTK_BUTTON(widget)); - return self; -} - -static VALUE -button_clicked(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_clicked(GTK_BUTTON(widget)); - return self; -} - -static VALUE -button_enter(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_enter(GTK_BUTTON(widget)); - return self; -} - -static VALUE -button_leave(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_leave(GTK_BUTTON(widget)); - return self; -} - -static VALUE -tbtn_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - Check_Type(label, T_STRING); - widget = gtk_toggle_button_new_with_label(RSTRING(label)->ptr); - } - else { - widget = gtk_toggle_button_new(); - } - - return make_widget(self, widget); -} - -static VALUE -tbtn_set_mode(self, mode) - VALUE self, mode; -{ - GtkWidget *widget = get_widget(self); - - gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(widget), NUM2INT(mode)); - return self; -} - -static VALUE -tbtn_set_state(self, state) - VALUE self, state; -{ - GtkWidget *widget = get_widget(self); - - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), NUM2INT(state)); - return self; -} - -static VALUE -tbtn_toggled(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(widget)); - return self; -} - -static VALUE -cbtn_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - Check_Type(label, T_STRING); - widget = gtk_check_button_new_with_label(RSTRING(label)->ptr); - } - else { - widget = gtk_check_button_new(); - } - - return make_widget(self, widget); -} - -static VALUE -rbtn_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE arg1, arg2; - GtkWidget *widget; - GSList *list = NULL; - char *label = NULL; - - if (rb_scan_args(argc, argv, "02", &arg1, &arg2) == 1 && - TYPE(arg1) == T_STRING) { - label = RSTRING(arg1)->ptr; - } - else { - if (!NIL_P(arg2)) { - Check_Type(arg2, T_STRING); - label = RSTRING(arg2)->ptr; - } - if (obj_is_kind_of(arg1, gRButton)) { - GtkWidget *b = get_widget(arg1); - list = GTK_RADIO_BUTTON(b)->group; - } - else { - list = ary2gslist(arg1); - } - } - if (label) { - widget = gtk_radio_button_new_with_label(list, label); - } - else { - widget = gtk_radio_button_new(list); - } - return make_widget(self, widget); -} - -static VALUE -rbtn_group(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return gslist2ary(gtk_radio_button_group(GTK_RADIO_BUTTON(widget))); -} - -static void -box_pack_start_or_end(argc, argv, self, start) - int argc; - VALUE *argv; - VALUE self; - int start; -{ - VALUE arg0, arg1, arg2, arg3; - gint expand, fill, padding; - GtkWidget *widget, *child; - - expand = fill = TRUE; padding = 0; - switch (rb_scan_args(argc, argv, "13", &arg0, &arg1, &arg2, &arg3)) { - case 4: - padding = NUM2INT(arg3); - case 3: - fill = RTEST(arg2); - case 2: - expand = RTEST(arg1); - default: - child = get_widget(arg0); - break; - } - widget = get_widget(self); - - if (start) - gtk_box_pack_start(GTK_BOX(widget), child, expand, fill, padding); - else - gtk_box_pack_end(GTK_BOX(widget), child, expand, fill, padding); -} - -static VALUE -box_pack_start(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - box_pack_start_or_end(argc, argv, self, 1); - return self; -} - -static VALUE -box_pack_end(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - box_pack_start_or_end(argc, argv, self, 0); - return self; -} - -static VALUE -vbox_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE homogeneous, spacing; - GtkWidget *widget; - - rb_scan_args(argc, argv, "02", &homogeneous, &spacing); - widget = gtk_vbox_new(RTEST(homogeneous), NUM2INT(spacing)); - - return make_widget(self, widget); -} - -static VALUE -colorsel_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_color_selection_new()); -} - -static VALUE -colorsel_set_update_policy(self, policy) - VALUE self, policy; -{ - GtkWidget *widget = get_widget(self); - - gtk_color_selection_set_update_policy(GTK_COLOR_SELECTION(widget), - (GtkUpdateType)NUM2INT(policy)); - return self; -} - -static VALUE -colorsel_set_opacity(self, opacity) - VALUE self, opacity; -{ - GtkWidget *widget = get_widget(self); - - gtk_color_selection_set_opacity(GTK_COLOR_SELECTION(widget), - RTEST(opacity)); - return self; -} - -static VALUE -colorsel_set_color(self, color) - VALUE self, color; -{ - GtkWidget *widget = get_widget(self); - double buf[3]; - - Check_Type(color, T_ARRAY); - if (RARRAY(color)->len < 3) { - ArgError("color array too small"); - } - buf[0] = NUM2DBL(RARRAY(color)->ptr[0]); - buf[1] = NUM2DBL(RARRAY(color)->ptr[1]); - buf[2] = NUM2DBL(RARRAY(color)->ptr[2]); - - gtk_color_selection_set_color(GTK_COLOR_SELECTION(widget), buf); - return self; -} - -static VALUE -colorsel_get_color(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - double buf[3]; - VALUE ary; - - gtk_color_selection_get_color(GTK_COLOR_SELECTION(widget), buf); - ary = ary_new2(3); - ary_push(ary, NUM2DBL(buf[0])); - ary_push(ary, NUM2DBL(buf[1])); - ary_push(ary, NUM2DBL(buf[2])); - return ary; -} - -static VALUE -cdialog_s_new(self, title) - VALUE self; -{ - char *t; - - Check_Type(title, T_STRING); - t = RSTRING(title)->ptr; - return make_widget(self, gtk_color_selection_dialog_new(t)); -} - -static VALUE -pixmap_s_new(self, val, mask) - VALUE self, val, mask; -{ - return make_widget(self, gtk_pixmap_new(get_gdkpixmap(val), - get_gdkpixmap(mask))); -} - -static VALUE -pixmap_set(self, val, mask) - VALUE self, val, mask; -{ - GtkWidget *widget = get_widget(self); - - gtk_pixmap_set(GTK_PIXMAP(widget), - get_gdkpixmap(val), get_gdkpixmap(mask)); - return self; -} - -static VALUE -pixmap_get(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GdkPixmap *val; - GdkBitmap *mask; - - gtk_pixmap_get(GTK_PIXMAP(widget), &val, &mask); - - return assoc_new(make_gdkpixmap(self, val), - make_gdkpixmap(self, mask)); -} - -static VALUE -darea_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_drawing_area_new()); -} - -static VALUE -darea_size(self, w, h) - VALUE self, w, h; -{ - GtkWidget *widget = get_widget(self); - - gtk_drawing_area_size(GTK_DRAWING_AREA(widget), NUM2INT(w), NUM2INT(h)); - return self; -} - -static VALUE -entry_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_entry_new()); -} - -static VALUE -entry_set_text(self, text) - VALUE self, text; -{ - GtkWidget *widget = get_widget(self); - - Check_Type(text, T_STRING); - gtk_entry_set_text(GTK_ENTRY(widget), RSTRING(text)->ptr); - - return self; -} - -static VALUE -eventbox_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_event_box_new()); -} - -static VALUE -fixed_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_fixed_new()); -} - -static VALUE -fixed_put(self, win, x, y) - VALUE self, win, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_fixed_put(GTK_FIXED(widget), get_widget(win), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -fixed_move(self, win, x, y) - VALUE self, win, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_fixed_move(GTK_FIXED(widget), get_widget(win), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -gamma_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_gamma_curve_new()); -} - -static VALUE -gamma_gamma(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return float_new(GTK_GAMMA_CURVE(widget)->gamma); -} - -static VALUE -hbbox_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_hbutton_box_new()); -} - -static VALUE -hbbox_get_spacing_default(self) - VALUE self; -{ - int n = gtk_hbutton_box_get_spacing_default(); - - return INT2FIX(n); -} - -static VALUE -hbbox_get_layout_default(self) - VALUE self; -{ - int n = gtk_hbutton_box_get_layout_default(); - - return INT2FIX(n); -} - -static VALUE -hbbox_set_spacing_default(self, spacing) - VALUE self, spacing; -{ - gtk_hbutton_box_set_spacing_default(NUM2INT(spacing)); - return Qnil; -} - -static VALUE -hbbox_set_layout_default(self, layout) - VALUE self, layout; -{ - gtk_hbutton_box_set_layout_default(NUM2INT(layout)); - return Qnil; -} - -static VALUE -vbbox_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_vbutton_box_new()); -} - -static VALUE -vbbox_get_spacing_default(self) - VALUE self; -{ - int n = gtk_vbutton_box_get_spacing_default(); - - return INT2FIX(n); -} - -static VALUE -vbbox_get_layout_default(self) - VALUE self; -{ - int n = gtk_vbutton_box_get_layout_default(); - - return INT2FIX(n); -} - -static VALUE -vbbox_set_spacing_default(self, spacing) - VALUE self, spacing; -{ - gtk_vbutton_box_set_spacing_default(NUM2INT(spacing)); - return Qnil; -} - -static VALUE -vbbox_set_layout_default(self, layout) - VALUE self, layout; -{ - gtk_vbutton_box_set_layout_default(NUM2INT(layout)); - return Qnil; -} - -static VALUE -hbox_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE homogeneous, spacing; - GtkWidget *widget; - - rb_scan_args(argc, argv, "02", &homogeneous, &spacing); - widget = gtk_hbox_new(RTEST(homogeneous), NUM2INT(spacing)); - - return make_widget(self, widget); -} - -static VALUE -paned_add1(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_paned_add1(GTK_PANED(widget), get_widget(child)); - return self; -} - -static VALUE -paned_add2(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_paned_add2(GTK_PANED(widget), get_widget(child)); - return self; -} - -static VALUE -paned_handle_size(self, size) - VALUE self, size; -{ - GtkWidget *widget = get_widget(self); - - gtk_paned_handle_size(GTK_PANED(widget), NUM2INT(size)); - return self; -} - -static VALUE -paned_gutter_size(self, size) - VALUE self, size; -{ - GtkWidget *widget = get_widget(self); - - gtk_paned_gutter_size(GTK_PANED(widget), NUM2INT(size)); - return self; -} - -static VALUE -hpaned_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_hpaned_new()); -} - -static VALUE -vpaned_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_vpaned_new()); -} - -static VALUE -ruler_set_metric(self, metric) - VALUE self, metric; -{ - GtkWidget *widget = get_widget(self); - - gtk_ruler_set_metric(GTK_RULER(widget), - (GtkMetricType)NUM2INT(metric)); - - return self; -} - -static VALUE -ruler_set_range(self, lower, upper, position, max_size) - VALUE self, lower, upper, position, max_size; -{ - GtkWidget *widget = get_widget(self); - - gtk_ruler_set_range(GTK_RULER(widget), - NUM2DBL(lower), NUM2DBL(upper), - NUM2DBL(position), NUM2DBL(max_size)); - - return self; -} - -static VALUE -ruler_draw_ticks(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_ruler_draw_ticks(GTK_RULER(widget)); - return self; -} - -static VALUE -ruler_draw_pos(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_ruler_draw_pos(GTK_RULER(widget)); - return self; -} - -static VALUE -hruler_s_new(self) -{ - return make_widget(self, gtk_hruler_new()); -} - -static VALUE -vruler_s_new(self) -{ - return make_widget(self, gtk_vruler_new()); -} - -static VALUE -range_get_adj(self) -{ - GtkWidget *widget = get_widget(self); - GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); - - return make_gobject(gAdjustment, GTK_OBJECT(adj)); -} - -static VALUE -range_set_update_policy(self, policy) - VALUE self, policy; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_set_update_policy(GTK_RANGE(widget), - (GtkUpdateType)NUM2INT(policy)); - return self; -} - -static VALUE -range_set_adj(self, adj) - VALUE self, adj; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_set_adjustment(GTK_RANGE(widget), - (GtkAdjustment*)get_gobject(adj)); - - return self; -} - -static VALUE -range_draw_bg(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_background(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_draw_trough(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_trough(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_draw_slider(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_slider(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_draw_step_forw(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_step_forw(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_draw_step_back(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_step_back(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_slider_update(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_slider_update(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_trough_click(self, x, y) - VALUE self, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_trough_click(GTK_RANGE(widget), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -range_default_hslider_update(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_hslider_update(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_default_vslider_update(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_vslider_update(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_default_htrough_click(self, x, y) - VALUE self, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_htrough_click(GTK_RANGE(widget), - NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -range_default_vtrough_click(self, x, y) - VALUE self, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_vtrough_click(GTK_RANGE(widget), - NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -range_default_hmotion(self, xdelta, ydelta) - VALUE self, xdelta, ydelta; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_hmotion(GTK_RANGE(widget), - NUM2INT(xdelta), NUM2INT(ydelta)); - return self; -} - -static VALUE -range_default_vmotion(self, xdelta, ydelta) - VALUE self, xdelta, ydelta; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_vmotion(GTK_RANGE(widget), - NUM2INT(xdelta), NUM2INT(ydelta)); - return self; -} - -static VALUE -range_calc_value(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_calc_value(GTK_RANGE(widget), NUM2INT(pos)); - return self; -} - -static VALUE -scale_set_digits(self, digits) - VALUE self, digits; -{ - GtkWidget *widget = get_widget(self); - - gtk_scale_set_digits(GTK_SCALE(widget), NUM2INT(digits)); - return self; -} - -static VALUE -scale_set_draw_value(self, draw_value) - VALUE self, draw_value; -{ - GtkWidget *widget = get_widget(self); - - gtk_scale_set_draw_value(GTK_SCALE(widget), NUM2INT(draw_value)); - return self; -} - -static VALUE -scale_set_value_pos(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_scale_set_value_pos(GTK_SCALE(widget), - (GtkPositionType)NUM2INT(pos)); - return self; -} - -static VALUE -scale_value_width(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int i = gtk_scale_value_width(GTK_SCALE(widget)); - - return INT2FIX(i); -} - -static VALUE -scale_draw_value(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_scale_draw_value(GTK_SCALE(widget)); - return self; -} - -static VALUE -hscale_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1; - GtkAdjustment *adj = NULL; - - rb_scan_args(argc, argv, "01", &arg1); - if (!NIL_P(arg1)) adj = (GtkAdjustment*)get_gobject(arg1); - - return make_widget(self, gtk_hscale_new(adj)); -} - -static VALUE -vscale_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1; - GtkAdjustment *adj = NULL; - - rb_scan_args(argc, argv, "01", &arg1); - if (!NIL_P(arg1)) adj = (GtkAdjustment*)get_gobject(arg1); - - return make_widget(self, gtk_vscale_new(adj)); -} - -static VALUE -hscrollbar_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1; - GtkAdjustment *adj = NULL; - - rb_scan_args(argc, argv, "01", &arg1); - if (!NIL_P(arg1)) adj = (GtkAdjustment*)get_gobject(arg1); - - return make_widget(self, gtk_hscrollbar_new(adj)); -} - -static VALUE -vscrollbar_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1; - GtkAdjustment *adj = NULL; - - rb_scan_args(argc, argv, "01", &arg1); - if (!NIL_P(arg1)) adj = (GtkAdjustment*)get_gobject(arg1); - - return make_widget(self, gtk_vscrollbar_new(adj)); -} - -static VALUE -hsep_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_hseparator_new()); -} - -static VALUE -vsep_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_vseparator_new()); -} - -static VALUE -idiag_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_input_dialog_new()); -} - -static VALUE -gtk_m_main(self) - VALUE self; -{ - gtk_main(); - return Qnil; -} - -static gint -idle() -{ - CHECK_INTS; - return TRUE; -} - -static void -exec_interval(proc) - VALUE proc; -{ - rb_funcall(proc, id_call, 0); -} - -static VALUE -timeout_add(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE interval, func; - int id; - - rb_scan_args(argc, argv, "11", &interval, &func); - if (NIL_P(func)) { - func = f_lambda(); - } - id = gtk_timeout_add_interp(NUM2INT(interval), exec_interval, - (gpointer)func, 0); - return INT2FIX(id); -} - -static VALUE -timeout_remove(self, id) - VALUE self, id; -{ - gtk_timeout_remove(NUM2INT(id)); - return Qnil; -} - -static VALUE -idle_add(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE func; - int id; - - rb_scan_args(argc, argv, "01", &func); - if (NIL_P(func)) { - func = f_lambda(); - } - id = gtk_idle_add_interp(exec_interval, (gpointer)func, 0); - return INT2FIX(id); -} - -static VALUE -idle_remove(self, id) - VALUE self, id; -{ - gtk_idle_remove(NUM2INT(id)); - return Qnil; -} - -static VALUE warn_handler; -static VALUE mesg_handler; -static VALUE print_handler; - -static void -gtkwarn(mesg) - char *mesg; -{ - rb_funcall(warn_handler, id_call, 1, str_new2(mesg)); -} - -static void -gtkmesg(mesg) - char *mesg; -{ - rb_funcall(mesg_handler, id_call, 1, str_new2(mesg)); -} - -static void -gtkprint(mesg) - char *mesg; -{ - rb_funcall(print_handler, id_call, 1, str_new2(mesg)); -} - -static VALUE -set_warning_handler(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE handler; - - rb_scan_args(argc, argv, "01", &handler); - if (NIL_P(handler)) { - handler = f_lambda(); - } - g_set_warning_handler(gtkwarn); -} - -static VALUE -set_message_handler(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE handler; - - rb_scan_args(argc, argv, "01", &handler); - if (NIL_P(handler)) { - handler = f_lambda(); - } - g_set_message_handler(gtkmesg); -} - -static VALUE -set_print_handler(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE handler; - - rb_scan_args(argc, argv, "01", &handler); - if (NIL_P(handler)) { - handler = f_lambda(); - } - g_set_print_handler(gtkprint); -} - -static void -gtkerr(mesg) - char *mesg; -{ - Fail("%s", mesg); -} - -void -Init_gtk() -{ - int argc, i; - char **argv; - - gtk_object_list = ary_new(); - rb_global_variable(>k_object_list); - - mGtk = rb_define_module("Gtk"); - - gObject = rb_define_class_under(mGtk, "GtkObject", cObject); - gWidget = rb_define_class_under(mGtk, "Widget", gObject); - gContainer = rb_define_class_under(mGtk, "Container", gWidget); - gBin = rb_define_class_under(mGtk, "Bin", gContainer); - gAlignment = rb_define_class_under(mGtk, "Alignment", gBin); - gMisc = rb_define_class_under(mGtk, "Misc", gWidget); - gArrow = rb_define_class_under(mGtk, "Arrow", gMisc); - gFrame = rb_define_class_under(mGtk, "Frame", gBin); - gAspectFrame = rb_define_class_under(mGtk, "AspectFrame", gFrame); - gData = rb_define_class_under(mGtk, "Data", gObject); - gAdjustment = rb_define_class_under(mGtk, "Adjustment", gData); - gBox = rb_define_class_under(mGtk, "Box", gContainer); - gButton = rb_define_class_under(mGtk, "Button", gContainer); - gTButton = rb_define_class_under(mGtk, "ToggleButton", gButton); - gCButton = rb_define_class_under(mGtk, "CheckButton", gTButton); - gRButton = rb_define_class_under(mGtk, "RadioButton", gCButton); - gBBox = rb_define_class_under(mGtk, "ButtonBox", gBox); - gCList = rb_define_class_under(mGtk, "CList", gContainer); - gWindow = rb_define_class_under(mGtk, "Window", gBin); - gDialog = rb_define_class_under(mGtk, "Dialog", gWindow); - gFileSel = rb_define_class_under(mGtk, "FileSelection", gWindow); - gVBox = rb_define_class_under(mGtk, "VBox", gBox); - gColorSel = rb_define_class_under(mGtk, "ColorSelection", gVBox); - gColorSelDialog = rb_define_class_under(mGtk, "ColorSelectionDialog", gWindow); - gImage = rb_define_class_under(mGtk, "Image", gMisc); - gDrawArea = rb_define_class_under(mGtk, "DrawingArea", gWidget); - gEntry = rb_define_class_under(mGtk, "Entry", gWidget); - gEventBox = rb_define_class_under(mGtk, "EventBox", gBin); - gFixed = rb_define_class_under(mGtk, "Fixed", gContainer); - gGamma = rb_define_class_under(mGtk, "GammaCurve", gVBox); - gHBBox = rb_define_class_under(mGtk, "HButtonBox", gBBox); - gVBBox = rb_define_class_under(mGtk, "VButtonBox", gBBox); - gHBox = rb_define_class_under(mGtk, "HBox", gBox); - gPaned = rb_define_class_under(mGtk, "Paned", gContainer); - gHPaned = rb_define_class_under(mGtk, "HPaned", gPaned); - gVPaned = rb_define_class_under(mGtk, "VPaned", gPaned); - gRuler = rb_define_class_under(mGtk, "Ruler", gWidget); - gHRuler = rb_define_class_under(mGtk, "HRuler", gRuler); - gVRuler = rb_define_class_under(mGtk, "VRuler", gRuler); - gRange = rb_define_class_under(mGtk, "Range", gWidget); - gScale = rb_define_class_under(mGtk, "Scale", gRange); - gHScale = rb_define_class_under(mGtk, "HScale", gScale); - gVScale = rb_define_class_under(mGtk, "VScale", gScale); - gScrollbar = rb_define_class_under(mGtk, "Scrollbar", gRange); - gHScrollbar = rb_define_class_under(mGtk, "HScrollbar", gScrollbar); - gVScrollbar = rb_define_class_under(mGtk, "VScrollbar", gScrollbar); - gSeparator = rb_define_class_under(mGtk, "Separator", gWidget); - gHSeparator = rb_define_class_under(mGtk, "HSeparator", gSeparator); - gVSeparator = rb_define_class_under(mGtk, "VSeparator", gSeparator); - gInputDialog = rb_define_class_under(mGtk, "InputDialog", gDialog); - gLabel = rb_define_class_under(mGtk, "Label", gMisc); - gList = rb_define_class_under(mGtk, "List", gContainer); - gItem = rb_define_class_under(mGtk, "Item", gBin); - gListItem = rb_define_class_under(mGtk, "ListItem", gItem); - gMenuShell = rb_define_class_under(mGtk, "MenuShell", gContainer); - gMenu = rb_define_class_under(mGtk, "Menu", gMenuShell); - gMenuBar = rb_define_class_under(mGtk, "MenuBar", gMenuShell); - gMenuItem = rb_define_class_under(mGtk, "MenuItem", gItem); - gCMenuItem = rb_define_class_under(mGtk, "CheckMenuItem", gMenuItem); - gRMenuItem = rb_define_class_under(mGtk, "RadioMenuItem", gCMenuItem); - gNotebook = rb_define_class_under(mGtk, "Notebook", gContainer); - gOptionMenu = rb_define_class_under(mGtk, "OptionMenu", gButton); - gPixmap = rb_define_class_under(mGtk, "Pixmap", gMisc); - gPreview = rb_define_class_under(mGtk, "Preview", gWidget); - gProgressBar = rb_define_class_under(mGtk, "ProgressBar", gWidget); - gScrolledWin = rb_define_class_under(mGtk, "ScrolledWindow", gContainer); - gTable = rb_define_class_under(mGtk, "Table", gContainer); - gText = rb_define_class_under(mGtk, "Text", gWidget); - gToolbar = rb_define_class_under(mGtk, "Toolbar", gContainer); - gTooltips = rb_define_class_under(mGtk, "Tooltips", cObject); - gTree = rb_define_class_under(mGtk, "Tree", gContainer); - gTreeItem = rb_define_class_under(mGtk, "TreeItem", gItem); - gViewPort = rb_define_class_under(mGtk, "ViewPort", gBin); - - gAcceleratorTable = rb_define_class_under(mGtk, "AcceleratorTable", cObject); - gStyle = rb_define_class_under(mGtk, "Style", cObject); - gPreviewInfo = rb_define_class_under(mGtk, "PreviewInfo", cObject); - gRequisiton = rb_define_class_under(mGtk, "Requisiton", cObject); - gAllocation = rb_define_class_under(mGtk, "Allocation", cObject); - - mGdk = rb_define_module("Gdk"); - - gdkFont = rb_define_class_under(mGdk, "Font", cObject); - gdkColor = rb_define_class_under(mGdk, "Color", cObject); - gdkPixmap = rb_define_class_under(mGdk, "Pixmap", cObject); - gdkBitmap = rb_define_class_under(mGdk, "Bitmap", gdkPixmap); - gdkWindow = rb_define_class_under(mGdk, "Window", cObject); - gdkImage = rb_define_class_under(mGdk, "Image", cObject); - gdkVisual = rb_define_class_under(mGdk, "Visual", cObject); - gdkGC = rb_define_class_under(mGdk, "GC", cObject); - gdkGCValues = rb_define_class_under(mGdk, "GCValues", cObject); - gdkRectangle = rb_define_class_under(mGdk, "Rectangle", cObject); - gdkSegment = rb_define_class_under(mGdk, "Segment", cObject); - gdkWindowAttr = rb_define_class_under(mGdk, "WindowAttr", cObject); - gdkCursor = rb_define_class_under(mGdk, "Cursor", cObject); - gdkAtom = rb_define_class_under(mGdk, "Atom", cObject); - gdkColorContext = rb_define_class_under(mGdk, "ColotContext", cObject); - gdkEvent = rb_define_class_under(mGdk, "gdkEvent", cObject); - - /* GtkObject */ - rb_define_singleton_method(gObject, "new", gobj_s_new, -1); - rb_define_method(gObject, "set_flags", gobj_set_flags, 1); - rb_define_method(gObject, "unset_flags", gobj_unset_flags, 1); - rb_define_method(gObject, "destroy", gobj_destroy, 0); - rb_define_method(gObject, "signal_connect", gobj_sig_connect, -1); - rb_define_method(gObject, "signal_connect_after", gobj_sig_connect_after, -1); - rb_define_method(gObject, "singleton_method_added", gobj_smethod_added, 1); - - /* Widget */ - rb_define_method(gWidget, "destroy", widget_destroy, 0); - rb_define_method(gWidget, "show", widget_show, 0); - rb_define_method(gWidget, "show_all", widget_show_all, 0); - rb_define_method(gWidget, "hide", widget_hide, 0); - rb_define_method(gWidget, "hide_all", widget_hide_all, 0); - rb_define_method(gWidget, "map", widget_map, 0); - rb_define_method(gWidget, "unmap", widget_unmap, 0); - rb_define_method(gWidget, "realize", widget_realize, 0); - rb_define_method(gWidget, "unrealize", widget_unrealize, 0); - rb_define_method(gWidget, "queue_draw", widget_queue_draw, 0); - rb_define_method(gWidget, "queue_resize", widget_queue_resize, 0); - rb_define_method(gWidget, "draw", widget_draw, 1); - rb_define_method(gWidget, "draw_focus", widget_draw_focus, 0); - rb_define_method(gWidget, "draw_default", widget_draw_default, 0); - rb_define_method(gWidget, "draw_children", widget_draw_children, 0); - rb_define_method(gWidget, "size_request", widget_size_request, 1); - rb_define_method(gWidget, "size_alocate", widget_size_allocate, 1); - rb_define_method(gWidget, "install_accelerator", widget_inst_accel, 4); - rb_define_method(gWidget, "remove_accelerator", widget_rm_accel, 4); - rb_define_method(gWidget, "event", widget_event, 1); - rb_define_method(gWidget, "activate", widget_activate, 0); - rb_define_method(gWidget, "grab_focus", widget_grab_focus, 0); - rb_define_method(gWidget, "grab_default", widget_grab_default, 0); - rb_define_method(gWidget, "restore_state", widget_restore_state, 0); - rb_define_method(gWidget, "visible?", widget_visible, 0); - rb_define_method(gWidget, "reparent", widget_reparent, 1); - rb_define_method(gWidget, "popup", widget_popup, 2); - rb_define_method(gWidget, "intersect", widget_intersect, 2); - rb_define_method(gWidget, "basic", widget_basic, 0); - rb_define_method(gWidget, "get_name", widget_set_name, 0); - rb_define_method(gWidget, "set_name", widget_set_name, 1); - rb_define_method(gWidget, "set_parent", widget_set_parent, 1); - rb_define_method(gWidget, "set_sensitive", widget_set_sensitive, 1); - rb_define_method(gWidget, "set_usize", widget_set_usize, 2); - rb_define_method(gWidget, "set_uposition", widget_set_uposition, 2); - rb_define_method(gWidget, "set_style", widget_set_style, 1); - rb_define_method(gWidget, "set_events", widget_set_events, 1); - rb_define_method(gWidget, "set_extension_events", widget_set_eevents, 1); - rb_define_method(gWidget, "unparent", widget_unparent, 0); - rb_define_method(gWidget, "get_toplevel", widget_get_toplevel, 0); - rb_define_method(gWidget, "get_ancestor", widget_get_ancestor, 1); - rb_define_method(gWidget, "get_colormap", widget_get_colormap, 0); - rb_define_method(gWidget, "get_visual", widget_get_visual, 0); - rb_define_method(gWidget, "get_style", widget_get_style, 0); - rb_define_method(gWidget, "style", widget_get_style, 0); - rb_define_method(gWidget, "get_events", widget_get_events, 0); - rb_define_method(gWidget, "get_extension_events", widget_get_eevents, 0); - rb_define_method(gWidget, "get_pointer", widget_get_eevents, 0); - rb_define_method(gWidget, "ancestor?", widget_is_ancestor, 1); - rb_define_method(gWidget, "child?", widget_is_child, 1); - rb_define_method(gWidget, "window", widget_window, 0); - - rb_define_singleton_method(gWidget, "push_colomap", widget_push_cmap, 1); - rb_define_singleton_method(gWidget, "push_visual", widget_push_visual, 1); - rb_define_singleton_method(gWidget, "push_style", widget_push_style, 1); - rb_define_singleton_method(gWidget, "pop_colomap", widget_pop_cmap, 0); - rb_define_singleton_method(gWidget, "pop_visual", widget_pop_visual, 0); - rb_define_singleton_method(gWidget, "pop_style", widget_pop_style, 0); - - rb_define_singleton_method(gWidget, "set_default_colomap", - widget_set_default_cmap, 1); - rb_define_singleton_method(gWidget, "set_default_visual", - widget_set_default_visual, 1); - rb_define_singleton_method(gWidget, "set_default_style", - widget_set_default_style, 1); - rb_define_singleton_method(gWidget, "get_default_colomap", - widget_get_default_cmap, 0); - rb_define_singleton_method(gWidget, "get_default_visual", - widget_get_default_visual, 0); - rb_define_singleton_method(gWidget, "get_default_style", - widget_get_default_style, 0); - rb_define_singleton_method(gWidget, "set_default_colomap", - widget_set_default_cmap, 1); - rb_define_singleton_method(gWidget, "set_default_visual", - widget_set_default_visual, 1); - rb_define_singleton_method(gWidget, "set_default_style", - widget_set_default_style, 1); - rb_define_singleton_method(gWidget, "set_default_colomap", - widget_set_default_cmap, 1); - rb_define_singleton_method(gWidget, "set_default_visual", - widget_set_default_visual, 1); - rb_define_singleton_method(gWidget, "propagage_default_style", - widget_propagate_default_style, 0); - - /* Container */ - rb_define_method(gContainer, "border_width", cont_bwidth, 1); - rb_define_method(gContainer, "add", cont_add, 1); - rb_define_method(gContainer, "disable_resize", cont_disable_resize, 0); - rb_define_method(gContainer, "enable_resize", cont_enable_resize, 0); - rb_define_method(gContainer, "block_resize", cont_block_resize, 0); - rb_define_method(gContainer, "unblock_resize", cont_unblock_resize, 0); - rb_define_method(gContainer, "need_resize", cont_need_resize, 0); - rb_define_method(gContainer, "foreach", cont_foreach, -1); - rb_define_method(gContainer, "each", cont_each, 0); - rb_define_method(gContainer, "focus", cont_focus, 1); - rb_define_method(gContainer, "children", cont_children, 0); - - /* Bin */ - /* -- */ - - /* Alignment */ - rb_define_singleton_method(gAlignment, "new", align_s_new, 4); - rb_define_method(gAlignment, "set", align_set, 4); - - /* Misc */ - rb_define_method(gMisc, "set_alignment", misc_set_align, 2); - rb_define_method(gMisc, "set_padding", misc_set_padding, 2); - - /* Arrow */ - rb_define_singleton_method(gArrow, "new", arrow_s_new, 2); - rb_define_method(gArrow, "set", arrow_s_new, 2); - - /* Frame */ - rb_define_singleton_method(gFrame, "new", frame_s_new, 1); - rb_define_method(gFrame, "set_label", frame_set_label, 1); - rb_define_method(gFrame, "set_label_align", frame_set_label_align, 2); - rb_define_method(gFrame, "set_shadow_type", frame_set_shadow_type, 1); - - /* AspectFrame */ - rb_define_singleton_method(gAspectFrame, "new", aframe_s_new, 5); - rb_define_method(gAspectFrame, "set", aframe_set, 4); - - /* Data */ - /* -- */ - - /* Adjustment */ - rb_define_singleton_method(gAdjustment, "new", adj_s_new, 6); - - /* Box */ - rb_define_method(gBox, "pack_start", box_pack_start, -1); - rb_define_method(gBox, "pack_end", box_pack_end, -1); - - /* Button */ - rb_define_singleton_method(gButton, "new", button_s_new, -1); - rb_define_method(gButton, "pressed", button_pressed, 0); - rb_define_method(gButton, "released", button_released, 0); - rb_define_method(gButton, "clicked", button_clicked, 0); - rb_define_method(gButton, "enter", button_enter, 0); - rb_define_method(gButton, "leave", button_leave, 0); - - /* ToggleButton */ - rb_define_singleton_method(gTButton, "new", tbtn_s_new, -1); - rb_define_method(gTButton, "set_mode", tbtn_set_mode, 1); - rb_define_method(gTButton, "set_state", tbtn_set_state, 1); - rb_define_method(gTButton, "toggled", tbtn_toggled, 0); - - /* CheckButton */ - rb_define_singleton_method(gCButton, "new", cbtn_s_new, -1); - - /* RadioButton */ - rb_define_singleton_method(gCButton, "new", rbtn_s_new, -1); - rb_define_method(gCButton, "group", rbtn_group, 0); - - /* ButtonBox */ - rb_define_singleton_method(gBBox, "get_child_size_default", - bbox_get_child_size_default, 0); - rb_define_singleton_method(gBBox, "get_child_ipadding_default", - bbox_get_child_ipadding_default, 0); - rb_define_singleton_method(gBBox, "set_child_size_default", - bbox_set_child_size_default, 2); - rb_define_singleton_method(gBBox, "set_child_ipadding_default", - bbox_set_child_ipadding_default, 2); - rb_define_method(gBBox, "get_spacing", bbox_get_spacing, 0); - rb_define_method(gBBox, "get_layout", bbox_get_layout, 0); - rb_define_method(gBBox, "get_child_size", bbox_get_child_size, 0); - rb_define_method(gBBox, "get_child_ipadding", bbox_get_child_ipadding, 0); - rb_define_method(gBBox, "set_spacing", bbox_set_spacing, 1); - rb_define_method(gBBox, "set_layout", bbox_set_layout, 1); - rb_define_method(gBBox, "set_child_size", bbox_set_child_size, 2); - rb_define_method(gBBox, "set_child_ipadding", bbox_set_child_ipadding, 2); - - /* CList */ - rb_define_singleton_method(gCList, "new", clist_s_new, 1); - rb_define_method(gCList, "set_border", clist_set_border, 1); - rb_define_method(gCList, "set_selection_mode", clist_set_sel_mode, 1); - rb_define_method(gCList, "set_policy", clist_set_policy, 2); - rb_define_method(gCList, "freeze", clist_freeze, 0); - rb_define_method(gCList, "thaw", clist_thaw, 0); - rb_define_method(gCList, "set_column_title", clist_set_col_title, 2); - rb_define_method(gCList, "set_column_widget", clist_set_col_wigdet, 2); - rb_define_method(gCList, "set_column_justification", clist_set_col_just, 2); - rb_define_method(gCList, "set_column_width", clist_set_col_width, 2); - rb_define_method(gCList, "set_row_height", clist_set_row_height, 1); - rb_define_method(gCList, "moveto", clist_moveto, 4); - rb_define_method(gCList, "set_text", clist_set_text, 3); - rb_define_method(gCList, "set_pixmap", clist_set_text, 4); - rb_define_method(gCList, "set_pixtext", clist_set_pixtext, 6); - rb_define_method(gCList, "set_foreground", clist_set_foreground, 2); - rb_define_method(gCList, "set_background", clist_set_background, 2); - rb_define_method(gCList, "set_shift", clist_set_shift, 4); - rb_define_method(gCList, "append", clist_append, 1); - rb_define_method(gCList, "insert", clist_insert, 2); - rb_define_method(gCList, "remove", clist_remove, 1); - rb_define_method(gCList, "set_row_data", clist_set_row_data, 2); - rb_define_method(gCList, "get_row_data", clist_set_row_data, 1); - rb_define_method(gCList, "select_row", clist_select_row, 2); - rb_define_method(gCList, "unselect_row", clist_unselect_row, 2); - rb_define_method(gCList, "clear", clist_clear, 0); - - /* Window */ - rb_define_singleton_method(gWindow, "new", gwin_s_new, 1); - rb_define_method(gWindow, "set_title", gwin_set_title, 1); - rb_define_method(gWindow, "set_policy", gwin_set_policy, 3); - rb_define_method(gWindow, "set_wmclass", gwin_set_wmclass, 1); - rb_define_method(gWindow, "set_focus", gwin_set_focus, 1); - rb_define_method(gWindow, "set_default", gwin_set_focus, 1); - rb_define_method(gWindow, "add_accelerator_table", gwin_add_accel, 1); - rb_define_method(gWindow, "remove_accelerator_table", gwin_rm_accel, 1); - rb_define_method(gWindow, "position", gwin_position, 1); - - /* Dialog */ - rb_define_singleton_method(gDialog, "new", dialog_s_new, 0); - - /* FileSelection */ - rb_define_singleton_method(gFileSel, "new", fsel_s_new, 1); - rb_define_method(gFileSel, "set_filename", fsel_set_fname, 1); - rb_define_method(gFileSel, "get_filename", fsel_get_fname, 0); - rb_define_method(gFileSel, "ok_button", fsel_ok_button, 0); - rb_define_method(gFileSel, "cancel_button", fsel_cancel_button, 0); - rb_define_method(gFileSel, "help_button", fsel_help_button, 0); - - /* VBox */ - rb_define_singleton_method(gVBox, "new", vbox_s_new, -1); - - /* ColorSelection */ - rb_define_singleton_method(gColorSel, "new", colorsel_s_new, 0); - rb_define_method(gColorSel, "set_update_policy", colorsel_set_update_policy, 1); - rb_define_method(gColorSel, "set_opacity", colorsel_set_opacity, 1); - rb_define_method(gColorSel, "set_color", colorsel_set_color, 1); - rb_define_method(gColorSel, "get_color", colorsel_get_color, 0); - - /* ColorSelectionDialog */ - rb_define_singleton_method(gColorSelDialog, "new", cdialog_s_new, 1); - - /* Image */ - rb_define_singleton_method(gImage, "new", image_s_new, 2); - rb_define_method(gImage, "set", image_set, 2); - rb_define_method(gImage, "get", image_get, 0); - - /* DrawingArea */ - rb_define_singleton_method(gDrawArea, "new", darea_s_new, 0); - rb_define_method(gDrawArea, "size", darea_size, 2); - - /* Entry */ - rb_define_singleton_method(gEntry, "new", entry_s_new, 0); - rb_define_method(gEntry, "set_text", entry_set_text, 1); - - /* EventBox */ - rb_define_singleton_method(gEventBox, "new", eventbox_s_new, 0); - - /* Fixed */ - rb_define_singleton_method(gFixed, "new", fixed_s_new, 0); - rb_define_method(gFixed, "put", fixed_put, 3); - rb_define_method(gFixed, "move", fixed_move, 3); - - /* GammaCurve */ - rb_define_singleton_method(gGamma, "new", gamma_s_new, 0); - rb_define_method(gGamma, "gamma", gamma_gamma, 0); - - /* HButtonBox */ - rb_define_singleton_method(gHBBox, "new", hbbox_s_new, 0); - rb_define_singleton_method(gHBBox, "get_spacing_default", - hbbox_get_spacing_default, 0); - rb_define_singleton_method(gHBBox, "get_layout_default", - hbbox_get_spacing_default, 0); - rb_define_singleton_method(gHBBox, "set_spacing_default", - hbbox_set_spacing_default, 1); - rb_define_singleton_method(gHBBox, "set_layout_default", - hbbox_set_layout_default, 1); - - /* VButtonBox */ - rb_define_singleton_method(gVBBox, "new", vbbox_s_new, 0); - rb_define_singleton_method(gVBBox, "get_spacing_default", - vbbox_get_spacing_default, 0); - rb_define_singleton_method(gVBBox, "get_layout_default", - vbbox_get_spacing_default, 0); - rb_define_singleton_method(gVBBox, "set_spacing_default", - vbbox_set_spacing_default, 1); - rb_define_singleton_method(gVBBox, "set_layout_default", - vbbox_set_layout_default, 1); - - /* HBox */ - rb_define_singleton_method(gHBox, "new", hbox_s_new, -1); - - /* Paned */ - rb_define_method(gPaned, "add1", paned_add1, 1); - rb_define_method(gPaned, "add2", paned_add1, 1); - rb_define_method(gPaned, "handle_size", paned_handle_size, 1); - rb_define_method(gPaned, "gutter_size", paned_gutter_size, 1); - - /* HPaned */ - rb_define_singleton_method(gHPaned, "new", hpaned_s_new, 0); - - /* VPaned */ - rb_define_singleton_method(gVPaned, "new", vpaned_s_new, 0); - - /* Ruler */ - rb_define_method(gRuler, "set_metric", ruler_set_metric, 1); - rb_define_method(gRuler, "set_range", ruler_set_range, 4); - rb_define_method(gRuler, "draw_ticks", ruler_draw_ticks, 0); - rb_define_method(gRuler, "draw_pos", ruler_draw_pos, 0); - - /* HRuler */ - rb_define_singleton_method(gHRuler, "new", hruler_s_new, 0); - - /* VRuler */ - rb_define_singleton_method(gVRuler, "new", vruler_s_new, 0); - - /* Range */ - rb_define_method(gRange, "get_adjustment", range_get_adj, 0); - rb_define_method(gRange, "set_update_policy", range_set_update_policy, 1); - rb_define_method(gRange, "set_adjustment", range_set_adj, 1); - rb_define_method(gRange, "draw_background", range_draw_bg, 0); - rb_define_method(gRange, "draw_trough", range_draw_trough, 0); - rb_define_method(gRange, "draw_slider", range_draw_slider, 0); - rb_define_method(gRange, "draw_step_forw", range_draw_step_forw, 0); - rb_define_method(gRange, "draw_step_back", range_draw_step_back, 0); - rb_define_method(gRange, "slider_update", range_slider_update, 0); - rb_define_method(gRange, "trough_click", range_trough_click, 2); - rb_define_method(gRange, "draw_background", range_draw_bg, 2); - rb_define_method(gRange, "default_hslider_update", range_default_hslider_update, 0); - rb_define_method(gRange, "default_vslider_update", range_default_vslider_update, 0); - rb_define_method(gRange, "default_htrough_click", range_default_htrough_click, 2); - rb_define_method(gRange, "default_vtrough_click", range_default_vtrough_click, 2); - rb_define_method(gRange, "default_hmotion", range_default_hmotion, 2); - rb_define_method(gRange, "default_vmotion", range_default_vmotion, 2); - rb_define_method(gRange, "calc_value", range_calc_value, 1); - - /* Scale */ - rb_define_method(gScale, "set_digits", scale_set_digits, 1); - rb_define_method(gScale, "set_draw_value", scale_set_draw_value, 1); - rb_define_method(gScale, "set_value_pos", scale_set_value_pos, 1); - rb_define_method(gScale, "value_width", scale_value_width, 0); - rb_define_method(gScale, "draw_value", scale_draw_value, 0); - - /* HScale */ - rb_define_singleton_method(gHScale, "new", hscale_s_new, -1); - - /* VScale */ - rb_define_singleton_method(gVScale, "new", vscale_s_new, -1); - - /* Scrollbar */ - /* -- */ - - /* HScrollbar */ - rb_define_singleton_method(gHScrollbar, "new", hscrollbar_s_new, -1); - - /* VScrollbar */ - rb_define_singleton_method(gVScrollbar, "new", vscrollbar_s_new, -1); - - /* Separator */ - /* -- */ - - /* HSeparator */ - rb_define_singleton_method(gHSeparator, "new", hsep_s_new, 0); - - /* VSeparator */ - rb_define_singleton_method(gVSeparator, "new", vsep_s_new, 0); - - /* InputDialog */ - rb_define_singleton_method(gInputDialog, "new", idiag_s_new, 0); - - /* Label */ - rb_define_singleton_method(gLabel, "new", label_s_new, 1); - - /* List */ - rb_define_singleton_method(gList, "new", list_s_new, 0); - rb_define_method(gList, "set_selection_mode", list_set_sel_mode, 1); - rb_define_method(gList, "selection_mode", list_sel_mode, 1); - rb_define_method(gList, "selection", list_selection, 0); - rb_define_method(gList, "insert_items", list_insert_items, 2); - rb_define_method(gList, "append_items", list_append_items, 1); - rb_define_method(gList, "prepend_items", list_prepend_items, 1); - rb_define_method(gList, "remove_items", list_remove_items, 1); - rb_define_method(gList, "clear_items", list_clear_items, 2); - rb_define_method(gList, "select_item", list_select_item, 1); - rb_define_method(gList, "unselect_item", list_unselect_item, 1); - rb_define_method(gList, "select_child", list_select_child, 1); - rb_define_method(gList, "unselect_child", list_unselect_child, 1); - rb_define_method(gList, "child_position", list_child_position, 1); - - /* Item */ - rb_define_method(gItem, "select", item_select, 0); - rb_define_method(gItem, "deselect", item_deselect, 0); - rb_define_method(gItem, "toggle", item_toggle, 0); - - /* ListItem */ - rb_define_singleton_method(gListItem, "new", litem_s_new, -1); - - /* MenuShell */ - rb_define_method(gMenuShell, "append", mshell_append, 1); - rb_define_method(gMenuShell, "prepend", mshell_prepend, 1); - rb_define_method(gMenuShell, "insert", mshell_insert, 2); - rb_define_method(gMenuShell, "deactivate", mshell_deactivate, 0); - - /* Menu */ - rb_define_singleton_method(gMenu, "new", menu_s_new, 0); - rb_define_method(gMenu, "append", menu_append, 1); - rb_define_method(gMenu, "prepend", menu_prepend, 1); - rb_define_method(gMenu, "insert", menu_insert, 2); - rb_define_method(gMenu, "popup", menu_popup, 6); - rb_define_method(gMenu, "popdown", menu_popup, 0); - rb_define_method(gMenu, "get_active", menu_get_active, 0); - rb_define_method(gMenu, "set_active", menu_set_active, 1); - rb_define_method(gMenu, "set_accelerator_table", menu_set_acceltbl, 1); - - /* MenuBar */ - rb_define_singleton_method(gMenuBar, "new", mbar_s_new, 0); - rb_define_method(gMenuBar, "append", mbar_append, 1); - rb_define_method(gMenuBar, "prepend", mbar_prepend, 1); - rb_define_method(gMenuBar, "insert", mbar_insert, 2); - - /* MenuItem */ - rb_define_singleton_method(gMenuItem, "new", mitem_s_new, -1); - rb_define_method(gMenuItem, "set_submenu", mitem_set_submenu, 1); - rb_define_method(gMenuItem, "set_placement", mitem_set_placement, 1); - rb_define_method(gMenuItem, "accelerator_size", mitem_accelerator_size, 0); - rb_define_method(gMenuItem, "accelerator_text", mitem_accelerator_text, 0); - rb_define_method(gMenuItem, "configure", mitem_configure, 2); - rb_define_method(gMenuItem, "select", mitem_select, 0); - rb_define_method(gMenuItem, "deselect", mitem_deselect, 0); - rb_define_method(gMenuItem, "activate", mitem_activate, 0); - rb_define_method(gMenuItem, "right_justify", mitem_right_justify, 0); - - /* CheckMenuItem */ - rb_define_singleton_method(gCMenuItem, "new", cmitem_s_new, -1); - rb_define_method(gCMenuItem, "set_state", cmitem_set_state, 1); - rb_define_method(gCMenuItem, "set_show_toggle", cmitem_set_show_toggle, 1); - rb_define_method(gCMenuItem, "toggled", cmitem_toggled, 0); - - /* RadioMenuItem */ - rb_define_singleton_method(gRMenuItem, "new", rmitem_s_new, -1); - rb_define_method(gRMenuItem, "group", rmitem_group, 0); - - /* NoteBook */ - rb_define_singleton_method(gNotebook, "new", note_s_new, 0); - rb_define_method(gNotebook, "append_page", note_append_page, 2); - rb_define_method(gNotebook, "prepend_page", note_prepend_page, 2); - rb_define_method(gNotebook, "insert_page", note_insert_page, 3); - rb_define_method(gNotebook, "remove_page", note_remove_page, 1); - rb_define_method(gNotebook, "set_page", note_set_page, 1); - rb_define_method(gNotebook, "cur_page", note_cur_page, 0); - rb_define_method(gNotebook, "page", note_cur_page, 0); - rb_define_method(gNotebook, "next_page", note_next_page, 0); - rb_define_method(gNotebook, "prev_page", note_prev_page, 0); - rb_define_method(gNotebook, "set_tab_pos", note_set_tab_pos, 1); - rb_define_method(gNotebook, "tab_pos", note_tab_pos, 0); - rb_define_method(gNotebook, "set_show_tabs", note_set_show_tabs, 1); - rb_define_method(gNotebook, "show_tabs", note_show_tabs, 0); - rb_define_method(gNotebook, "set_show_border", note_set_show_border, 1); - rb_define_method(gNotebook, "show_border", note_show_border, 0); - - /* OptionMenu */ - rb_define_singleton_method(gOptionMenu, "new", omenu_s_new, 0); - rb_define_method(gOptionMenu, "get_menu", omenu_get_menu, 0); - rb_define_method(gOptionMenu, "set_menu", omenu_set_menu, 1); - rb_define_method(gOptionMenu, "remove_menu", omenu_set_menu, 0); - rb_define_method(gOptionMenu, "set_history", omenu_set_history, 1); - - /* Pixmap */ - rb_define_singleton_method(gPixmap, "new", pixmap_s_new, 2); - rb_define_method(gPixmap, "set", pixmap_set, 2); - rb_define_method(gPixmap, "get", pixmap_get, 0); - - /* Preview */ - rb_define_singleton_method(gPreview, "new", preview_s_new, 1); - rb_define_method(gPreview, "size", preview_size, 2); - rb_define_method(gPreview, "put", preview_size, 8); - rb_define_method(gPreview, "put_row", preview_size, 5); - rb_define_method(gPreview, "draw_row", preview_size, 4); - rb_define_method(gPreview, "set_expand", preview_set_expand, 1); - rb_define_singleton_method(gPreview, "set_gamma", preview_set_gamma, 1); - rb_define_singleton_method(gPreview, "set_color_cube", - preview_set_color_cube, 4); - rb_define_singleton_method(gPreview, "set_install_cmap", - preview_set_install_cmap, 1); - rb_define_singleton_method(gPreview, "set_reserved", - preview_set_reserved, 1); - rb_define_singleton_method(gPreview, "get_visual", preview_get_visual, 0); - rb_define_singleton_method(gPreview, "get_cmap", preview_get_cmap, 0); - rb_define_singleton_method(gPreview, "get_info", preview_get_info, 0); - - /* ProgressBar */ - rb_define_singleton_method(gProgressBar, "new", pbar_s_new, 0); - rb_define_method(gProgressBar, "update", pbar_update, 1); - - /* ScrolledWindow */ - rb_define_singleton_method(gScrolledWin, "new", scwin_s_new, -1); - rb_define_method(gScrolledWin, "set_policy", scwin_set_policy, 2); - - /* Table */ - rb_define_singleton_method(gTable, "new", tbl_s_new, -1); - rb_define_method(gTable, "attach", tbl_attach, -1); - rb_define_method(gTable, "set_row_spacing", tbl_set_row_spacing, 2); - rb_define_method(gTable, "set_col_spacing", tbl_set_col_spacing, 2); - rb_define_method(gTable, "set_row_spacings", tbl_set_row_spacings, 1); - rb_define_method(gTable, "set_col_spacings", tbl_set_col_spacings, 1); - - /* Text */ - rb_define_singleton_method(gText, "new", txt_s_new, -1); - rb_define_method(gText, "set_editable", txt_set_editable, 1); - rb_define_method(gText, "set_adjustment", txt_set_adjustment, 2); - rb_define_method(gText, "set_point", txt_set_point, 1); - rb_define_method(gText, "get_point", txt_get_point, 0); - rb_define_method(gText, "get_length", txt_get_length, 0); - rb_define_method(gText, "freeze", txt_freeze, 0); - rb_define_method(gText, "thaw", txt_thaw, 0); - rb_define_method(gText, "insert", txt_insert, 4); - rb_define_method(gText, "backward_delete", txt_backward_delete, 1); - rb_define_method(gText, "forward_delete", txt_forward_delete, 1); - - /* Toolbar */ - rb_define_singleton_method(gToolbar, "new", tbar_s_new, -1); - rb_define_method(gToolbar, "append_item", tbar_append_item, 4); - rb_define_method(gToolbar, "prepend_item", tbar_prepend_item, 4); - rb_define_method(gToolbar, "insert_item", tbar_append_item, 5); - rb_define_method(gToolbar, "append_space", tbar_append_space, 0); - rb_define_method(gToolbar, "prepend_space", tbar_prepend_space, 0); - rb_define_method(gToolbar, "insert_space", tbar_append_space, 1); - rb_define_method(gToolbar, "set_orientation", tbar_set_orientation, 1); - rb_define_method(gToolbar, "set_style", tbar_set_style, 1); - rb_define_method(gToolbar, "set_space_size", tbar_set_space_size, 1); - rb_define_method(gToolbar, "set_tooltips", tbar_set_tooltips, 1); - - /* Tooltips */ - rb_define_singleton_method(gTooltips, "new", ttips_s_new, 0); - rb_define_method(gTooltips, "set_tips", ttips_set_tips, 2); - rb_define_method(gTooltips, "set_delay", ttips_set_delay, 1); - rb_define_method(gTooltips, "enable", ttips_enable, 0); - rb_define_method(gTooltips, "disable", ttips_disable, 0); - - /* Tree */ - rb_define_singleton_method(gTree, "new", tree_s_new, 0); - rb_define_method(gTree, "append", tree_append, 1); - rb_define_method(gTree, "prepend", tree_prepend, 1); - rb_define_method(gTree, "insert", tree_insert, 2); - - /* TreeItem */ - rb_define_singleton_method(gTreeItem, "new", titem_s_new, -1); - rb_define_method(gTreeItem, "set_subtree", titem_set_subtree, 1); - rb_define_method(gTreeItem, "select", titem_select, 0); - rb_define_method(gTreeItem, "deselect", titem_deselect, 0); - rb_define_method(gTreeItem, "expand", titem_expand, 0); - rb_define_method(gTreeItem, "collapse", titem_collapse, 0); - - /* ViewPort */ - rb_define_singleton_method(gViewPort, "new", vport_s_new, -1); - rb_define_method(gViewPort, "get_hadjustment", vport_get_hadj, 0); - rb_define_method(gViewPort, "get_vadjustment", vport_get_vadj, 0); - rb_define_method(gViewPort, "set_hadjustment", vport_set_hadj, 1); - rb_define_method(gViewPort, "set_vadjustment", vport_set_vadj, 1); - rb_define_method(gViewPort, "set_shadow_type", vport_set_shadow, 1); - - /* AcceleratorTable */ - /* Style */ - - /* Gtk module */ - rb_define_module_function(mGtk, "main", gtk_m_main, 0); - rb_define_module_function(mGtk, "timeout_add", timeout_add, -1); - rb_define_module_function(mGtk, "timeout_remove", timeout_remove, 1); - rb_define_module_function(mGtk, "idle_add", idle_add, -1); - rb_define_module_function(mGtk, "idle_remove", idle_remove, 1); - - rb_define_module_function(mGtk, "set_warning_handler", - set_warning_handler, -1); - rb_define_module_function(mGtk, "set_message_handler", - set_message_handler, -1); - rb_define_module_function(mGtk, "set_print_handler", - set_print_handler, -1); - - /* Gdk module */ - /* GdkFont */ - rb_define_method(gdkFont, "==", gdkfnt_equal, 1); - - /* GdkBitmap */ - rb_define_singleton_method(gdkBitmap, "new", gdkbmap_s_new, 3); - rb_define_singleton_method(gdkBitmap, "create_from_data", - gdkbmap_create_from_data, 4); - - /* GdkPixmap */ - rb_define_singleton_method(gdkPixmap, "new", gdkpmap_s_new, 4); - rb_define_singleton_method(gdkPixmap, "create_from_xpm", - gdkpmap_create_from_xpm, 3); - rb_define_singleton_method(gdkPixmap, "create_from_xpm_d", - gdkpmap_create_from_xpm, 3); - - /* GdkWindow */ - - /* GdkImage */ - - rb_define_const(mGtk, "VISIBLE", INT2FIX(GTK_VISIBLE)); - rb_define_const(mGtk, "MAPPED", INT2FIX(GTK_MAPPED)); - rb_define_const(mGtk, "UNMAPPED", INT2FIX(GTK_UNMAPPED)); - rb_define_const(mGtk, "REALIZED", INT2FIX(GTK_REALIZED)); - rb_define_const(mGtk, "SENSITIVE", INT2FIX(GTK_SENSITIVE)); - rb_define_const(mGtk, "PARENT_SENSITIVE", INT2FIX(GTK_PARENT_SENSITIVE)); - rb_define_const(mGtk, "NO_WINDOW", INT2FIX(GTK_NO_WINDOW)); - rb_define_const(mGtk, "HAS_FOCUS", INT2FIX(GTK_HAS_FOCUS)); - rb_define_const(mGtk, "CAN_FOCUS", INT2FIX(GTK_CAN_FOCUS)); - rb_define_const(mGtk, "HAS_DEFAULT", INT2FIX(GTK_HAS_DEFAULT)); - rb_define_const(mGtk, "CAN_DEFAULT", INT2FIX(GTK_CAN_DEFAULT)); - rb_define_const(mGtk, "PROPAGATE_STATE", INT2FIX(GTK_PROPAGATE_STATE)); - rb_define_const(mGtk, "ANCHORED", INT2FIX(GTK_ANCHORED)); - rb_define_const(mGtk, "BASIC", INT2FIX(GTK_BASIC)); - rb_define_const(mGtk, "USER_STYLE", INT2FIX(GTK_USER_STYLE)); - rb_define_const(mGtk, "GRAB_ALL", INT2FIX(GTK_GRAB_ALL)); - rb_define_const(mGtk, "REDRAW_PENDING", INT2FIX(GTK_REDRAW_PENDING)); - rb_define_const(mGtk, "RESIZE_PENDING", INT2FIX(GTK_RESIZE_PENDING)); - rb_define_const(mGtk, "RESIZE_NEEDED", INT2FIX(GTK_RESIZE_NEEDED)); - rb_define_const(mGtk, "HAS_SHAPE_MASK", INT2FIX(GTK_HAS_SHAPE_MASK)); - - /* GtkWindowType */ - rb_define_const(mGtk, "WINDOW_TOPLEVEL", INT2FIX(GTK_WINDOW_TOPLEVEL)); - rb_define_const(mGtk, "WINDOW_DIALOG", INT2FIX(GTK_WINDOW_DIALOG)); - rb_define_const(mGtk, "WIN_POS_NONE", INT2FIX(GTK_WIN_POS_NONE)); - rb_define_const(mGtk, "WIN_POS_CENTER", INT2FIX(GTK_WIN_POS_CENTER)); - rb_define_const(mGtk, "WIN_POS_MOUSE", INT2FIX(GTK_WIN_POS_MOUSE)); - - /* GtkDirectionType */ - rb_define_const(mGtk, "DIR_TAB_FORWARD", INT2FIX(GTK_DIR_TAB_FORWARD)); - rb_define_const(mGtk, "DIR_TAB_BACKWARD", INT2FIX(GTK_DIR_TAB_BACKWARD)); - rb_define_const(mGtk, "DIR_UP", INT2FIX(GTK_DIR_UP)); - rb_define_const(mGtk, "DIR_DOWN", INT2FIX(GTK_DIR_DOWN)); - rb_define_const(mGtk, "DIR_LEFT", INT2FIX(GTK_DIR_LEFT)); - rb_define_const(mGtk, "DIR_RIGHT", INT2FIX(GTK_DIR_RIGHT)); - - /* GtkPolicyType */ - rb_define_const(mGtk, "POLICY_ALWAYS", INT2FIX(GTK_POLICY_ALWAYS)); - rb_define_const(mGtk, "POLICY_AUTOMATIC", INT2FIX(GTK_POLICY_AUTOMATIC)); - - /* GtkSelectionMode */ - rb_define_const(mGtk, "SELECTION_SINGLE", INT2FIX(GTK_SELECTION_SINGLE)); - rb_define_const(mGtk, "SELECTION_BROWSE", INT2FIX(GTK_SELECTION_BROWSE)); - rb_define_const(mGtk, "SELECTION_MULTIPLE", INT2FIX(GTK_SELECTION_MULTIPLE)); - rb_define_const(mGtk, "SELECTION_EXTENDED", INT2FIX(GTK_SELECTION_EXTENDED)); - /* GtkPositionType */ - rb_define_const(mGtk, "POS_LEFT", INT2FIX(GTK_POS_LEFT)); - rb_define_const(mGtk, "POS_RIGHT", INT2FIX(GTK_POS_RIGHT)); - rb_define_const(mGtk, "POS_TOP", INT2FIX(GTK_POS_TOP)); - rb_define_const(mGtk, "POS_BOTTOM", INT2FIX(GTK_POS_BOTTOM)); - - /* GtkShadowType */ - rb_define_const(mGtk, "SHADOW_NONE", INT2FIX(GTK_SHADOW_NONE)); - rb_define_const(mGtk, "SHADOW_IN", INT2FIX(GTK_SHADOW_IN)); - rb_define_const(mGtk, "SHADOW_OUT", INT2FIX(GTK_SHADOW_OUT)); - rb_define_const(mGtk, "SHADOW_ETCHED_IN", INT2FIX(GTK_SHADOW_ETCHED_IN)); - rb_define_const(mGtk, "SHADOW_ETCHED_OUT", INT2FIX(GTK_SHADOW_ETCHED_OUT)); - /* GtkStateType */ - rb_define_const(mGtk, "STATE_NORMAL", INT2FIX(GTK_STATE_NORMAL)); - rb_define_const(mGtk, "STATE_ACTIVE", INT2FIX(GTK_STATE_ACTIVE)); - rb_define_const(mGtk, "STATE_PRELIGHT", INT2FIX(GTK_STATE_PRELIGHT)); - rb_define_const(mGtk, "STATE_SELECTED", INT2FIX(GTK_STATE_SELECTED)); - rb_define_const(mGtk, "STATE_INSENSITIVE", INT2FIX(GTK_STATE_INSENSITIVE)); - /* GtkAttachOptions */ - rb_define_const(mGtk, "EXPAND", INT2FIX(GTK_EXPAND)); - rb_define_const(mGtk, "SHRINK", INT2FIX(GTK_SHRINK)); - rb_define_const(mGtk, "FILL", INT2FIX(GTK_FILL)); - /* GtkSubmenuDirection */ - rb_define_const(mGtk, "DIRECTION_LEFT", INT2FIX(GTK_DIRECTION_LEFT)); - rb_define_const(mGtk, "DIRECTION_RIGHT", INT2FIX(GTK_DIRECTION_RIGHT)); - /* GtkSubmenuPlacement */ - rb_define_const(mGtk, "TOP_BOTTOM", INT2FIX(GTK_TOP_BOTTOM)); - rb_define_const(mGtk, "LEFT_RIGHT", INT2FIX(GTK_LEFT_RIGHT)); - /* GtkMetricType */ - rb_define_const(mGtk, "PIXELS", INT2FIX(GTK_PIXELS)); - rb_define_const(mGtk, "INCHES", INT2FIX(GTK_INCHES)); - rb_define_const(mGtk, "CENTIMETERS", INT2FIX(GTK_CENTIMETERS)); - - /* GtkArrowType */ - rb_define_const(mGtk, "ARROW_UP", INT2FIX(GTK_ARROW_UP)); - rb_define_const(mGtk, "ARROW_DOWN", INT2FIX(GTK_ARROW_DOWN)); - rb_define_const(mGtk, "ARROW_LEFT", INT2FIX(GTK_ARROW_LEFT)); - rb_define_const(mGtk, "ARROW_RIGHT", INT2FIX(GTK_ARROW_RIGHT)); - - /* GtkPreviewType */ - rb_define_const(mGtk, "PREVIEW_COLOR", INT2FIX(GTK_PREVIEW_COLOR)); - rb_define_const(mGtk, "PREVIEW_GRAYSCALE", INT2FIX(GTK_PREVIEW_GRAYSCALE)); - - rb_define_const(mGtk, "BUTTONBOX_DEFAULT", INT2FIX(GTK_BUTTONBOX_DEFAULT)); - rb_define_const(mGtk, "BUTTONBOX_SPREAD", INT2FIX(GTK_BUTTONBOX_SPREAD)); - rb_define_const(mGtk, "BUTTONBOX_EDGE", INT2FIX(GTK_BUTTONBOX_EDGE)); - rb_define_const(mGtk, "BUTTONBOX_START", INT2FIX(GTK_BUTTONBOX_START)); - rb_define_const(mGtk, "BUTTONBOX_END", INT2FIX(GTK_BUTTONBOX_END)); - - /* GtkToolbarStyle */ - rb_define_const(mGtk, "TOOLBAR_ICONS", INT2FIX(GTK_TOOLBAR_ICONS)); - rb_define_const(mGtk, "TOOLBAR_TEXT", INT2FIX(GTK_TOOLBAR_TEXT)); - rb_define_const(mGtk, "TOOLBAR_BOTH", INT2FIX(GTK_TOOLBAR_BOTH)); - - /* GtkOrientation */ - rb_define_const(mGtk, "ORIENTATION_HORIZONTAL", INT2FIX(GTK_ORIENTATION_HORIZONTAL)); - rb_define_const(mGtk, "ORIENTATION_VERTICAL", INT2FIX(GTK_ORIENTATION_VERTICAL)); - - /* GdkExtensionMode */ - rb_define_const(mGdk, "EXTENSION_EVENTS_NONE", INT2FIX(GDK_EXTENSION_EVENTS_NONE)); - rb_define_const(mGdk, "EXTENSION_EVENTS_ALL", INT2FIX(GDK_EXTENSION_EVENTS_ALL)); - rb_define_const(mGdk, "EXTENSION_EVENTS_CURSOR", INT2FIX(GDK_EXTENSION_EVENTS_CURSOR)); - - argc = RARRAY(rb_argv)->len; - argv = ALLOCA_N(char*,argc+1); - argv[0] = RSTRING(rb_argv0)->ptr; - for (i=0;iptr[i]) == T_STRING) { - argv[i+1] = RSTRING(RARRAY(rb_argv)->ptr[i])->ptr; - } - else { - argv[i+1] = ""; - } - } - argc++; - { - /* Gdk modifies sighandlers, sigh */ - RETSIGTYPE (*sigfunc[7])(); - - sigfunc[0] = signal(SIGHUP, SIG_IGN); - sigfunc[1] = signal(SIGINT, SIG_IGN); - sigfunc[2] = signal(SIGQUIT, SIG_IGN); - sigfunc[3] = signal(SIGBUS, SIG_IGN); - sigfunc[4] = signal(SIGSEGV, SIG_IGN); - sigfunc[5] = signal(SIGPIPE, SIG_IGN); - sigfunc[6] = signal(SIGTERM, SIG_IGN); - - gdk_init(&argc, &argv); - - signal(SIGHUP, sigfunc[0]); - signal(SIGINT, sigfunc[1]); - signal(SIGQUIT, sigfunc[2]); - signal(SIGBUS, sigfunc[3]); - signal(SIGSEGV, sigfunc[4]); - signal(SIGPIPE, sigfunc[5]); - signal(SIGTERM, sigfunc[6]); - } - - for (i=1;iptr[i] = str_taint(str_new2(argv[i])); - } - RARRAY(rb_argv)->len = argc-1; - - id_gtkdata = rb_intern("gtkdata"); - id_relatives = rb_intern("relatives"); - id_call = rb_intern("call"); - gtk_idle_add((GtkFunction)idle, 0); - - g_set_error_handler(gtkerr); - g_set_warning_handler(gtkerr); - rb_global_variable(&warn_handler); - rb_global_variable(&mesg_handler); - rb_global_variable(&print_handler); -} diff --git a/ext/gtk/test.rb b/ext/gtk/test.rb deleted file mode 100644 index 52ce5db7e0..0000000000 --- a/ext/gtk/test.rb +++ /dev/null @@ -1,96 +0,0 @@ -require 'gtk' - -def create_menu(depth) - return nil if depth < 1 - - menu = Gtk::Menu::new() - group = nil - submenu = nil - - for i in 0..4 - buf = sprintf("item %2d - %d", depth, i+1) -# menuitem = Gtk::MenuItem::new(buf) - menuitem = Gtk::RadioMenuItem.new(group, buf) - group = menuitem.group - if depth % 2 - menuitem.set_show_toggle TRUE - end - menu.append menuitem - menuitem.show - if depth > 0 - unless submenu - submenu = create_menu(depth - 1) - end - menuitem.set_submenu submenu - end - end - return menu -end - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.signal_connect("destroy") do - exit -end -window.signal_connect("delete_event") do - exit -end -window.set_title("menus") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add box1 -box1.show - -menubar = Gtk::MenuBar::new() -box1.pack_start menubar, FALSE, TRUE, 0 -menubar.show - -menu = create_menu(2) -menuitem = Gtk::MenuItem::new("test\nline2") -menuitem.set_submenu menu -menubar.append menuitem -menuitem.show - -menuitem = Gtk::MenuItem::new("foo") -menuitem.set_submenu menu -menubar.append menuitem -menuitem.show - -menuitem = Gtk::MenuItem::new("bar") -menuitem.set_submenu menu -menubar.append menuitem -menuitem.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width 10 -box1.pack_start box2, TRUE, TRUE, 0 -box2.show - -optionmenu = Gtk::OptionMenu::new() -optionmenu.set_menu create_menu(1) -optionmenu.set_history 4 -box2.pack_start optionmenu, TRUE, TRUE, 0 -optionmenu.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test.xpm b/ext/gtk/test.xpm deleted file mode 100644 index 9b0d2efdb2..0000000000 --- a/ext/gtk/test.xpm +++ /dev/null @@ -1,92 +0,0 @@ -/* XPM */ -static char *openfile[] = { -/* width height num_colors chars_per_pixel */ -" 20 19 66 2", -/* colors */ -".. c None", -".# c #000000", -".a c #dfdfdf", -".b c #7f7f7f", -".c c #006f6f", -".d c #00efef", -".e c #009f9f", -".f c #004040", -".g c #00bfbf", -".h c #ff0000", -".i c #ffffff", -".j c #7f0000", -".k c #007070", -".l c #00ffff", -".m c #00a0a0", -".n c #004f4f", -".o c #00cfcf", -".p c #8f8f8f", -".q c #6f6f6f", -".r c #a0a0a0", -".s c #7f7f00", -".t c #007f7f", -".u c #5f5f5f", -".v c #707070", -".w c #00f0f0", -".x c #009090", -".y c #ffff00", -".z c #0000ff", -".A c #00afaf", -".B c #00d0d0", -".C c #00dfdf", -".D c #005f5f", -".E c #00b0b0", -".F c #001010", -".G c #00c0c0", -".H c #000f0f", -".I c #00007f", -".J c #005050", -".K c #002f2f", -".L c #dfcfcf", -".M c #dfd0d0", -".N c #006060", -".O c #00e0e0", -".P c #00ff00", -".Q c #002020", -".R c #dfc0c0", -".S c #008080", -".T c #001f1f", -".U c #003f3f", -".V c #007f00", -".W c #00000f", -".X c #000010", -".Y c #00001f", -".Z c #000020", -".0 c #00002f", -".1 c #000030", -".2 c #00003f", -".3 c #000040", -".4 c #00004f", -".5 c #000050", -".6 c #00005f", -".7 c #000060", -".8 c #00006f", -".9 c #000070", -"#. c #7f7f80", -"## c #9f9f9f", -/* pixels */ -"........................................", -"........................................", -"........................................", -".......................#.#.#............", -".....................#.......#...#......", -"...............................#.#......", -".......#.#.#.................#.#.#......", -".....#.y.i.y.#.#.#.#.#.#.#..............", -".....#.i.y.i.y.i.y.i.y.i.#..............", -".....#.y.i.y.i.y.i.y.i.y.#..............", -".....#.i.y.i.y.#.#.#.#.#.#.#.#.#.#.#....", -".....#.y.i.y.#.s.s.s.s.s.s.s.s.s.#......", -".....#.i.y.#.s.s.s.s.s.s.s.s.s.#........", -".....#.y.#.s.s.s.s.s.s.s.s.s.#..........", -".....#.#.s.s.s.s.s.s.s.s.s.#............", -".....#.#.#.#.#.#.#.#.#.#.#..............", -"........................................", -"........................................", -"........................................" -}; diff --git a/ext/gtk/test0.rb b/ext/gtk/test0.rb deleted file mode 100644 index 4ff802d6ca..0000000000 --- a/ext/gtk/test0.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.border_width(10) -button = Gtk::Button::new("Hello World") -button.signal_connect("clicked") do - print "hello world\n" - exit -end -window.add(button) -button.show -window.show -Gtk::main() diff --git a/ext/gtk/test1.rb b/ext/gtk/test1.rb deleted file mode 100644 index 7d24199580..0000000000 --- a/ext/gtk/test1.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("entry") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -entry = Gtk::Entry::new() -entry.set_text("hello world") -box2.pack_start(entry, TRUE, TRUE, 0) -entry.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show -window.show - -Gtk::main() diff --git a/ext/gtk/test2.rb b/ext/gtk/test2.rb deleted file mode 100644 index 170de96185..0000000000 --- a/ext/gtk/test2.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("list") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -scrolled_win = Gtk::ScrolledWindow::new() -scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC) -box2.pack_start(scrolled_win, TRUE, TRUE, 0) -scrolled_win.show - -list = Gtk::List::new() -list.set_selection_mode(Gtk::SELECTION_MULTIPLE) -list.set_selection_mode(Gtk::SELECTION_BROWSE) -scrolled_win.add(list) -list.show - -for i in [ - "hello", - "world", - "blah", - "foo", - "bar", - "argh", - "spencer", - "is a", - "wussy", - "programmer", - ] - list_item = Gtk::ListItem::new(i) - list.add(list_item) - list_item.show -end - -button = Gtk::Button::new("add") -button.set_flags(Gtk::CAN_FOCUS); -i = 1 -button.signal_connect("clicked") do - list_item = Gtk::ListItem::new(format("added item %d", i)) - list.add(list_item) - list_item.show - i += 1 -end -box2.pack_start(button, FALSE, TRUE, 0) -button.show - -button = Gtk::Button::new("remove") -button.set_flags(Gtk::CAN_FOCUS); -button.signal_connect("clicked") do - tmp_list = list.selection - list.remove_items(tmp_list) - for i in tmp_list - i.destroy - end -end -box2.pack_start(button, FALSE, TRUE, 0) -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test3.rb b/ext/gtk/test3.rb deleted file mode 100644 index d73f72f9fa..0000000000 --- a/ext/gtk/test3.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'gtk' - -window = Gtk::FileSelection::new("file selection dialog") -window.position(Gtk::WIN_POS_MOUSE) -window.border_width(0) - -window.ok_button.signal_connect("clicked") do - print window.get_filename, "\n" -end -window.cancel_button.signal_connect("clicked") do - window.destroy - exit -end -window.show - -Gtk::main() diff --git a/ext/gtk/test4.rb b/ext/gtk/test4.rb deleted file mode 100644 index da0000c420..0000000000 --- a/ext/gtk/test4.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("notebook") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -notebook = Gtk::Notebook::new() -notebook.set_tab_pos(Gtk::POS_TOP) -box2.pack_start(notebook, TRUE, TRUE, 0) -notebook.show - -for i in 1..5 - frame = Gtk::Frame::new(format("Page %d", i)) - frame.border_width(10) - frame.set_usize(200, 150) - frame.show - - label = Gtk::Label::new(format("Box %d", i)) - frame.add label - label.show - - label = Gtk::Label::new(format("Tab %d", i)) - notebook.append_page frame, label -end - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -button = Gtk::Button::new("next") -button.signal_connect("clicked") do - notebook.next_page -end -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::Button::new("prev") -button.signal_connect("clicked") do - notebook.prev_page -end -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::Button::new("rotate") -button.signal_connect("clicked") do - notebook.set_tab_pos((notebook.tab_pos+1)%4) -end -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test5.rb b/ext/gtk/test5.rb deleted file mode 100644 index 714232079b..0000000000 --- a/ext/gtk/test5.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -table = Gtk::Table::new(3, 3, FALSE) -table.set_row_spacings(5) -table.set_col_spacings(5) -table.border_width(10) -box1.pack_start(table, TRUE, TRUE, 0) -table.show - -button = [] -0.upto(8) do |i| - button.push Gtk::Button::new("button"+(i+1)) -end -0.upto(8) do |i| - button[i].signal_connect("clicked") do |w| - if button[i+1].visible? - button[i+1].hide - else - button[i+1].show - end - end - button[i].show -end -table.attach(button[0], 0, 1, 0, 1, nil, nil, 0, 0) -table.attach(button[1], 1, 2, 1, 2, nil, nil, 0, 0) -table.attach(button[2], 2, 3, 2, 3, nil, nil, 0, 0) -table.attach(button[3], 0, 1, 2, 3, nil, nil, 0, 0) -table.attach(button[4], 2, 3, 0, 1, nil, nil, 0, 0) -table.attach(button[5], 1, 2, 2, 3, nil, nil, 0, 0) -table.attach(button[6], 1, 2, 0, 1, nil, nil, 0, 0) -table.attach(button[7], 2, 3, 1, 2, nil, nil, 0, 0) -table.attach(button[8], 0, 1, 1, 2, nil, nil, 0, 0) - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -close = Gtk::Button::new("close") -close.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(close, TRUE, TRUE, 0) -close.set_flags(Gtk::CAN_DEFAULT); -close.grab_default -close.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test6.rb b/ext/gtk/test6.rb deleted file mode 100644 index a589530ab0..0000000000 --- a/ext/gtk/test6.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("toggle buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -button = Gtk::ToggleButton::new("button1") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::ToggleButton::new("button2") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::ToggleButton::new("button3") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -close = Gtk::Button::new("close") -close.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(close, TRUE, TRUE, 0) -close.set_flags(Gtk::CAN_DEFAULT); -close.grab_default -close.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test7.rb b/ext/gtk/test7.rb deleted file mode 100644 index 4d78648a3c..0000000000 --- a/ext/gtk/test7.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("check buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -button = Gtk::CheckButton::new("button1") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::CheckButton::new("button2") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::CheckButton::new("button3") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -close = Gtk::Button::new("close") -close.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(close, TRUE, TRUE, 0) -close.set_flags(Gtk::CAN_DEFAULT); -close.grab_default -close.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test8.rb b/ext/gtk/test8.rb deleted file mode 100644 index 4ac4b0b8ad..0000000000 --- a/ext/gtk/test8.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("radio buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width 10 -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -button = Gtk::RadioButton::new("button1") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::RadioButton::new(button, "button2") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::RadioButton::new(button, "button3") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -close = Gtk::Button::new("close") -close.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(close, TRUE, TRUE, 0) -close.set_flags(Gtk::CAN_DEFAULT); -close.grab_default -close.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test9.rb b/ext/gtk/test9.rb deleted file mode 100644 index 7bb3bf305e..0000000000 --- a/ext/gtk/test9.rb +++ /dev/null @@ -1,98 +0,0 @@ -require 'gtk' - -def create_bbox_window(horizontal, title, pos, spacing, cw, ch, layout) - window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) - window.set_title(title) - window.signal_connect("destroy") do - window.destroy - end - window.signal_connect("delete_event") do - window.hide - window.destroy - end - if horizontal - window.set_usize(550, 60) - window.set_uposition(150, pos) - else - window.set_usize(150, 400) - window.set_uposition(pos, 200) - end - box1 = Gtk::VBox::new(FALSE, 0) - window.add box1 - box1.show - if horizontal - bbox = Gtk::HButtonBox::new() - else - bbox = Gtk::VButtonBox::new() - end - bbox.set_layout layout - bbox.set_spacing spacing - bbox.set_child_size cw, ch - bbox.show - box1.border_width 25 - box1.pack_start(bbox, TRUE, TRUE, 0) - button = Gtk::Button::new("OK") - bbox.add button - button.signal_connect("clicked") do - window.hide - window.destroy - end - button.show - - button = Gtk::Button::new("Cancel") - bbox.add button - button.signal_connect("clicked") do - window.hide - window.destroy - end - button.show - - button = Gtk::Button::new("Help") - bbox.add button - button.show - - window.show -end - -def test_hbbox - create_bbox_window(TRUE, "Spread", 50, 40, 85, 25, Gtk::BUTTONBOX_SPREAD); - create_bbox_window(TRUE, "Edge", 250, 40, 85, 28, Gtk::BUTTONBOX_EDGE); - create_bbox_window(TRUE, "Start", 450, 40, 85, 25, Gtk::BUTTONBOX_START); - create_bbox_window(TRUE, "End", 650, 15, 30, 25, Gtk::BUTTONBOX_END); -end - -def test_vbbox - create_bbox_window(FALSE, "Spread", 50, 40, 85, 25, Gtk::BUTTONBOX_SPREAD); - create_bbox_window(FALSE, "Edge", 250, 40, 85, 28, Gtk::BUTTONBOX_EDGE); - create_bbox_window(FALSE, "Start", 450, 40, 85, 25, Gtk::BUTTONBOX_START); - create_bbox_window(FALSE, "End", 650, 15, 30, 25, Gtk::BUTTONBOX_END); -end - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.signal_connect("delete_event") do - window.destroy - exit -end -window.set_title("button box") -window.border_width(20) - -bbox = Gtk::HButtonBox::new() -window.add(bbox) -bbox.show - -button = Gtk::Button::new("Horizontal") -def button.clicked(*args) - test_hbbox -end -bbox.add button -button.show - -button = Gtk::Button::new("Vertical") -def button.clicked(*args) - test_vbbox -end -bbox.add button -button.show -window.show - -Gtk::main() diff --git a/ext/gtk/testa.rb b/ext/gtk/testa.rb deleted file mode 100644 index 00a6603dfd..0000000000 --- a/ext/gtk/testa.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("toolbar test") -window.set_policy(TRUE, TRUE, TRUE) -window.signal_connect("destroy") do - exit -end -window.signal_connect("delete_event") do - exit -end -window.border_width(0) -window.realize - -toolbar = Gtk::Toolbar::new(Gtk::ORIENTATION_HORIZONTAL, Gtk::TOOLBAR_BOTH) -toolbar.append_item "Horizontal", "Horizontal toolbar layout", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil, - #window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_orientation Gtk::ORIENTATION_HORIZONTAL -end -toolbar.append_item "Vertival", "Vertical toolbar layout", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil, #window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_orientation Gtk::ORIENTATION_VERTICAL -end -toolbar.append_space -toolbar.append_item "Icons", "Only show toolbar icons", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil, #window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_style Gtk::TOOLBAR_ICONS -end -toolbar.append_item "Text", "Only show toolbar text", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_style Gtk::TOOLBAR_TEXT -end -toolbar.append_item "Both", "Show toolbar icons and text", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil, #window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_style Gtk::TOOLBAR_BOTH -end -toolbar.append_space -toolbar.append_item "Small", "User small spaces", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_space_size 5 -end -toolbar.append_item "Big", "User big spaces", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_space_size 10 -end -toolbar.append_space -toolbar.append_item "Enable", "Enable tooltips", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_tooltips TRUE -end -toolbar.append_item "Disable", "Disable tooltips", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_tooltips FALSE -end -window.add toolbar -toolbar.show -window.show - -Gtk::main() diff --git a/ext/gtk/testb.rb b/ext/gtk/testb.rb deleted file mode 100644 index 4e707bcf87..0000000000 --- a/ext/gtk/testb.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.signal_connect("destroy") do - exit -end -window.signal_connect("delete_event") do - exit -end -window.set_title("buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add box1 -box1.show - -box2 = Gtk::HBox::new(FALSE, 5) -box2.border_width 10 -box1.pack_start box2, TRUE, TRUE, 0 -box2.show - -label = Gtk::Label::new("Hello World") -frame = Gtk::Frame::new("Frame 1") -box2.pack_start frame, TRUE, TRUE, 0 -frame.show - -box3 = Gtk::VBox::new(FALSE, 5) -box3.border_width 5 -frame.add box3 -box3.show - -button = Gtk::Button::new("switch") -button.signal_connect("clicked") do - label.reparent box3 -end -box3.pack_start button, FALSE, TRUE, 0 -button.show -box3.pack_start label, FALSE, TRUE, 0 -label.show - -frame = Gtk::Frame::new("Frame 2") -box2.pack_start frame, TRUE, TRUE, 0 -frame.show - -box4 = Gtk::VBox::new(FALSE, 5) -box4.border_width 5 -frame.add box4 -box4.show - -button = Gtk::Button::new("switch") -button.signal_connect("clicked") do - label.reparent box4 -end -box4.pack_start button, FALSE, TRUE, 0 -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -window.show - -Gtk::main() diff --git a/ext/gtk/testc.rb b/ext/gtk/testc.rb deleted file mode 100644 index 98c6466beb..0000000000 --- a/ext/gtk/testc.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.signal_connect("destroy") do - exit -end -window.signal_connect("delete_event") do - exit -end -window.set_title("pixmap") -window.border_width(0) -window.realize - -box1 = Gtk::VBox::new(FALSE, 0) -window.add box1 -box1.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width 10 -box1.pack_start box2, TRUE, TRUE, 0 -box2.show - -button = Gtk::Button::new() -box2.pack_start button, FALSE, FALSE, 0 -button.show - -style = button.style -pixmap, mask = Gdk::Pixmap::create_from_xpm(window.window, - nil, - #style.bg[Gtk::STATE_NORMAL], - "test.xpm") -pixmapwid = Gtk::Pixmap::new(pixmap, mask) -label = Gtk::Label::new("Pixmap\ntest") -box3 = Gtk::HBox::new(FALSE, 0) -box3.border_width 2 -box3.add pixmapwid -box3.add label -button.add box3 -pixmapwid.show -label.show -box3.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -window.show - -Gtk::main() diff --git a/ext/marshal/MANIFEST b/ext/marshal/MANIFEST deleted file mode 100644 index 54870ec71f..0000000000 --- a/ext/marshal/MANIFEST +++ /dev/null @@ -1,5 +0,0 @@ -MANIFEST -depend -extconf.rb -marshal.c -marshal.doc diff --git a/ext/marshal/depend b/ext/marshal/depend deleted file mode 100644 index c955eb2d59..0000000000 --- a/ext/marshal/depend +++ /dev/null @@ -1,2 +0,0 @@ -marshal.o: marshal.c ../../ruby.h ../../config.h ../../defines.h ../../io.h \ - ../../st.h diff --git a/ext/marshal/extconf.rb b/ext/marshal/extconf.rb deleted file mode 100644 index ab30bd117b..0000000000 --- a/ext/marshal/extconf.rb +++ /dev/null @@ -1 +0,0 @@ -create_makefile("marshal") diff --git a/ext/marshal/marshal.c b/ext/marshal/marshal.c deleted file mode 100644 index 99e87d0b5f..0000000000 --- a/ext/marshal/marshal.c +++ /dev/null @@ -1,850 +0,0 @@ -/************************************************ - - marshal.c - - - $Author$ - $Revision$ - $Date$ - created at: Thu Apr 27 16:30:01 JST 1995 - -************************************************/ - -#include "ruby.h" -#include "io.h" -#include "st.h" - -#define MARSHAL_MAJOR 4 -#define MARSHAL_MINOR 0 - -#define TYPE_NIL '0' -#define TYPE_TRUE 'T' -#define TYPE_FALSE 'F' -#define TYPE_FIXNUM 'i' - -#define TYPE_UCLASS 'C' -#define TYPE_OBJECT 'o' -#define TYPE_USERDEF 'u' -#define TYPE_FLOAT 'f' -#define TYPE_BIGNUM 'l' -#define TYPE_STRING '"' -#define TYPE_REGEXP '/' -#define TYPE_ARRAY '[' -#define TYPE_HASH '{' -#define TYPE_STRUCT 'S' -#define TYPE_MODULE 'M' - -#define TYPE_SYMBOL ':' -#define TYPE_SYMLINK ';' - -#define TYPE_LINK '@' - -extern VALUE cString; -extern VALUE cRegexp; -extern VALUE cArray; -extern VALUE cHash; - -VALUE rb_path2class(); - -static ID s_dump, s_load; - -struct dump_arg { - VALUE obj; - FILE *fp; - VALUE str; - st_table *symbol; - st_table *data; -}; - -struct dump_call_arg { - VALUE obj; - struct dump_arg *arg; - int limit; -}; - -static void w_long _((long, struct dump_arg*)); - -static void -w_byte(c, arg) - char c; - struct dump_arg *arg; -{ - if (arg->fp) putc(c, arg->fp); - else str_cat(arg->str, (UCHAR*)&c, 1); -} - -static void -w_bytes(s, n, arg) - char *s; - int n; - struct dump_arg *arg; -{ - w_long(n, arg); - if (arg->fp) { - fwrite(s, 1, n, arg->fp); - } - else { - str_cat(arg->str, s, n); - } -} - -static void -w_short(x, arg) - int x; - struct dump_arg *arg; -{ - int i; - - for (i=0; i> (i*8)) & 0xff, arg); - } -} - -static void -w_long(x, arg) - long x; - struct dump_arg *arg; -{ - char buf[sizeof(long)+1]; - int i, len = 0; - - if (x == 0) { - w_byte(0, arg); - return; - } - for (i=1;isymbol, id, &num)) { - w_byte(TYPE_SYMLINK, arg); - w_long(num, arg); - } - else { - w_byte(TYPE_SYMBOL, arg); - w_bytes(sym, strlen(sym), arg); - st_insert(arg->symbol, id, arg->symbol->num_entries); - } -} - -static void -w_unique(s, arg) - char *s; - struct dump_arg *arg; -{ - w_symbol(rb_intern(s), arg); -} - -static void w_object _((VALUE,struct dump_arg*,int)); -extern VALUE cIO, cBignum, cStruct; - -static int -hash_each(key, value, arg) - VALUE key, value; - struct dump_call_arg *arg; -{ - w_object(key, arg->arg, arg->limit); - w_object(value, arg->arg, arg->limit); - return ST_CONTINUE; -} - -static int -obj_each(id, value, arg) - ID id; - VALUE value; - struct dump_call_arg *arg; -{ - w_symbol(id, arg->arg); - w_object(value, arg->arg, arg->limit); - return ST_CONTINUE; -} - -static void -w_uclass(obj, class, arg) - VALUE obj, class; - struct dump_arg *arg; -{ - if (CLASS_OF(obj) != class) { - w_byte(TYPE_UCLASS, arg); - w_unique(rb_class2name(CLASS_OF(obj)), arg); - } -} - -static void -w_object(obj, arg, limit) - VALUE obj; - struct dump_arg *arg; - int limit; -{ - int n; - struct dump_call_arg c_arg; - - if (limit == 0) { - Fail("exceed depth limit"); - } - limit--; - c_arg.limit = limit; - c_arg.arg = arg; - - if (obj == Qnil) { - w_byte(TYPE_NIL, arg); - } - else if (obj == TRUE) { - w_byte(TYPE_TRUE, arg); - } - else if (obj == FALSE) { - w_byte(TYPE_FALSE, arg); - } - else if (FIXNUM_P(obj)) { -#if SIZEOF_LONG <= 4 - w_byte(TYPE_FIXNUM, arg); - w_long(FIX2INT(obj), arg); -#else - if (RSHIFT(obj, 32) == 0 || RSHIFT(obj, 32) == -1) { - w_byte(TYPE_FIXNUM, arg); - w_long(FIX2INT(obj), arg); - } - else { - obj = int2big(FIX2INT(obj)); - goto write_bignum; - } -#endif - } - else { - int num; - - if (st_lookup(arg->data, obj, &num)) { - w_byte(TYPE_LINK, arg); - w_long(num, arg); - return; - } - st_insert(arg->data, obj, arg->data->num_entries); - if (rb_respond_to(obj, s_dump)) { - VALUE v; - - w_byte(TYPE_USERDEF, arg); - w_unique(rb_class2name(CLASS_OF(obj)), arg); - v = rb_funcall(obj, s_dump, 1, limit); - if (TYPE(v) != T_STRING) { - TypeError("_dump_to must return String"); - } - w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg); - return; - } - - switch (BUILTIN_TYPE(obj)) { - case T_MODULE: - case T_CLASS: - w_byte(TYPE_MODULE, arg); - { - VALUE path = rb_class_path(obj); - w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg); - } - return; - - case T_FLOAT: - w_byte(TYPE_FLOAT, arg); - w_float(RFLOAT(obj)->value, arg); - return; - - case T_BIGNUM: - write_bignum: - w_byte(TYPE_BIGNUM, arg); - { - char sign = RBIGNUM(obj)->sign?'+':'-'; - int len = RBIGNUM(obj)->len; - USHORT *d = RBIGNUM(obj)->digits; - - w_byte(sign, arg); - w_long(len, arg); - while (len--) { - w_short(*d, arg); - d++; - } - } - return; - - case T_STRING: - w_uclass(obj, cString, arg); - w_byte(TYPE_STRING, arg); - w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg); - return; - - case T_REGEXP: - w_uclass(obj, cRegexp, arg); - w_byte(TYPE_REGEXP, arg); - w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg); - w_byte(FL_TEST(obj, FL_USER1), arg); - return; - - case T_ARRAY: - w_uclass(obj, cArray, arg); - w_byte(TYPE_ARRAY, arg); - { - int len = RARRAY(obj)->len; - VALUE *ptr = RARRAY(obj)->ptr; - - w_long(len, arg); - while (len--) { - w_object(*ptr, arg, limit); - ptr++; - } - } - break; - - case T_HASH: - w_uclass(obj, cHash, arg); - w_byte(TYPE_HASH, arg); - w_long(RHASH(obj)->tbl->num_entries, arg); - st_foreach(RHASH(obj)->tbl, hash_each, &c_arg); - break; - - case T_STRUCT: - w_byte(TYPE_STRUCT, arg); - { - int len = RSTRUCT(obj)->len; - char *path = rb_class2name(CLASS_OF(obj)); - VALUE mem; - int i; - - w_unique(path, arg); - w_long(len, arg); - mem = rb_ivar_get(CLASS_OF(obj), rb_intern("__member__")); - if (mem == Qnil) { - Fatal("non-initialized struct"); - } - for (i=0; iptr[i]), arg); - w_object(RSTRUCT(obj)->ptr[i], arg, limit); - } - } - break; - - case T_OBJECT: - w_byte(TYPE_OBJECT, arg); - { - VALUE class = CLASS_OF(obj); - char *path; - - if (FL_TEST(class, FL_SINGLETON)) { - TypeError("singleton can't be dumped"); - } - path = rb_class2name(class); - w_unique(path, arg); - if (ROBJECT(obj)->iv_tbl) { - w_long(ROBJECT(obj)->iv_tbl->num_entries, arg); - st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &c_arg); - } - else { - w_long(0, arg); - } - } - break; - - default: - TypeError("can't dump %s", rb_class2name(CLASS_OF(obj))); - break; - } - } -} - -static VALUE -dump(arg) - struct dump_call_arg *arg; -{ - w_object(arg->obj, arg->arg, arg->limit); -} - -static VALUE -dump_ensure(arg) - struct dump_arg *arg; -{ - st_free_table(arg->symbol); - st_free_table(arg->data); -} - -static VALUE -marshal_dump(argc, argv) - int argc; - VALUE argv; -{ - VALUE obj, port, a1, a2; - int limit = -1; - extern VALUE cIO; - struct dump_arg arg; - struct dump_call_arg c_arg; - - port = 0; - rb_scan_args(argc, argv, "12", &obj, &a1, &a2); - if (argc == 3) { - limit = NUM2INT(a2); - port = a1; - } - else if (argc == 2) { - if (FIXNUM_P(a1)) limit = FIX2INT(a1); - else port = a1; - } - if (port) { - if (obj_is_kind_of(port, cIO)) { - OpenFile *fptr; - - io_binmode(port); - GetOpenFile(port, fptr); - io_writable(fptr); - arg.fp = (fptr->f2) ? fptr->f2 : fptr->f; - } - else { - TypeError("instance of IO needed"); - } - } - else { - arg.fp = 0; - port = str_new(0, 0); - arg.str = port; - } - - arg.symbol = st_init_numtable(); - arg.data = st_init_numtable(); - c_arg.obj = obj; - c_arg.arg = &arg; - c_arg.limit = limit; - - w_byte(MARSHAL_MAJOR, &arg); - w_byte(MARSHAL_MINOR, &arg); - - rb_ensure(dump, &c_arg, dump_ensure, &arg); - - return port; -} - -struct load_arg { - FILE *fp; - UCHAR *ptr, *end; - st_table *symbol; - st_table *data; -}; - -static int -r_byte(arg) - struct load_arg *arg; -{ - if (arg->fp) return getc(arg->fp); - if (arg->ptr < arg->end) return *arg->ptr++; - return EOF; -} - -static USHORT -r_short(arg) - struct load_arg *arg; -{ - USHORT x; - int i; - - x = 0; - for (i=0; i 0) { - if (c > sizeof(long)) long_toobig((int)c); - x = 0; - for (i=0;i sizeof(long)) long_toobig((int)c); - x = -1; - for (i=0;ifp) { - len = fread(s, 1, len, arg->fp); - } - else { - if (arg->ptr + len > arg->end) { - len = arg->end - arg->ptr; - } - memcpy(s, arg->ptr, len); - arg->ptr += len; - } - - (s)[len] = '\0'; - *sp = s; - - return len; -} - -static ID -r_symbol(arg) - struct load_arg *arg; -{ - char *buf; - ID id; - char type; - - if (r_byte(arg) == TYPE_SYMLINK) { - int num = r_long(arg); - - if (st_lookup(arg->symbol, num, &id)) { - return id; - } - TypeError("bad symbol"); - } - r_bytes(buf, arg); - id = rb_intern(buf); - st_insert(arg->symbol, arg->symbol->num_entries, id); - - return id; -} - -static char* -r_unique(arg) - struct load_arg *arg; -{ - return rb_id2name(r_symbol(arg)); -} - -static VALUE -r_string(arg) - struct load_arg *arg; -{ - char *buf; - int len = r_bytes(buf, arg); - - return str_taint(str_new(buf, len)); -} - -static VALUE -r_regist(v, arg) - VALUE v; - struct load_arg *arg; -{ - st_insert(arg->data, arg->data->num_entries, v); - return v; -} - -static VALUE -r_object(arg) - struct load_arg *arg; -{ - VALUE v; - int type = r_byte(arg); - - switch (type) { - case EOF: - eof_error(); - return Qnil; - - case TYPE_LINK: - if (st_lookup(arg->data, r_long(arg), &v)) { - return v; - } - ArgError("dump format error (unlinked)"); - break; - - case TYPE_UCLASS: - { - VALUE c = rb_path2class(r_unique(arg)); - v = r_object(arg); - if (rb_special_const_p(v)) { - ArgError("dump format error (user class)"); - } - RBASIC(v)->class = c; - return v; - } - - case TYPE_NIL: - return Qnil; - - case TYPE_TRUE: - return TRUE; - - case TYPE_FALSE: - return FALSE; - - case TYPE_FIXNUM: - { - int i = r_long(arg); - return INT2FIX(i); - } - - case TYPE_FLOAT: - { -#ifndef atof - double atof(); -#endif - char *buf; - - r_bytes(buf, arg); - v = float_new(atof(buf)); - return r_regist(v, arg); - } - - case TYPE_BIGNUM: - { - int len; - USHORT *digits; - - NEWOBJ(big, struct RBignum); - OBJSETUP(big, cBignum, T_BIGNUM); - big->sign = (r_byte(arg) == '+'); - big->len = len = r_long(arg); - big->digits = digits = ALLOC_N(USHORT, len); - while (len--) { - *digits++ = r_short(arg); - } - big = RBIGNUM(big_norm((VALUE)big)); - if (TYPE(big) == T_BIGNUM) { - r_regist(big, arg); - } - return (VALUE)big; - } - - case TYPE_STRING: - return r_regist(r_string(arg), arg); - - case TYPE_REGEXP: - { - char *buf; - int len = r_bytes(buf, arg); - int ci = r_byte(arg); - return r_regist(reg_new(buf, len, ci), arg); - } - - case TYPE_ARRAY: - { - volatile int len = r_long(arg); - v = ary_new2(len); - r_regist(v, arg); - while (len--) { - ary_push(v, r_object(arg)); - } - return v; - } - - case TYPE_HASH: - { - int len = r_long(arg); - - v = hash_new(); - r_regist(v, arg); - while (len--) { - VALUE key = r_object(arg); - VALUE value = r_object(arg); - hash_aset(v, key, value); - } - return v; - } - - case TYPE_STRUCT: - { - VALUE class, mem, values; - int i, len; - int num = arg->data->num_entries; - - class = rb_path2class(r_unique(arg)); - mem = rb_ivar_get(class, rb_intern("__member__")); - if (mem == Qnil) { - Fatal("non-initialized struct"); - } - len = r_long(arg); - - values = ary_new2(len); - for (i=0; iptr[i] != INT2FIX(slot)) - TypeError("struct not compatible"); - struct_aset(v, INT2FIX(i), r_object(arg)); - } - return v; - } - break; - - case TYPE_USERDEF: - { - VALUE class; - int len; - - class = rb_path2class(r_unique(arg)); - if (rb_respond_to(class, s_load)) { - v = rb_funcall(class, s_load, 1, r_string(arg)); - return r_regist(v, arg); - } - TypeError("class %s needs to have method `_load_from'", - rb_class2name(class)); - } - break; - - case TYPE_OBJECT: - { - VALUE class; - int len; - - class = rb_path2class(r_unique(arg)); - len = r_long(arg); - v = obj_alloc(class); - r_regist(v, arg); - if (len > 0) { - while (len--) { - ID id = r_symbol(arg); - VALUE val = r_object(arg); - rb_ivar_set(v, id, val); - } - } - return v; - } - break; - - case TYPE_MODULE: - { - char *buf; - r_bytes(buf, arg); - return rb_path2class(buf); - } - - default: - ArgError("dump format error(0x%x)", type); - break; - } -} - -static VALUE -load(arg) - struct load_arg *arg; -{ - return r_object(arg); -} - -static VALUE -load_ensure(arg) - struct load_arg *arg; -{ - st_free_table(arg->symbol); - st_free_table(arg->data); -} - -static VALUE -marshal_load(self, port) - VALUE self, port; -{ - FILE *fp; - int major; - VALUE v; - OpenFile *fptr; - struct load_arg arg; - - if (TYPE(port) == T_STRING) { - arg.fp = 0; - arg.ptr = RSTRING(port)->ptr; - arg.end = arg.ptr + RSTRING(port)->len; - } - else { - if (obj_is_kind_of(port, cIO)) { - io_binmode(port); - GetOpenFile(port, fptr); - io_readable(fptr); - arg.fp = fptr->f; - } - else { - TypeError("instance of IO needed"); - } - } - - major = r_byte(&arg); - if (major == MARSHAL_MAJOR) { - if (r_byte(&arg) != MARSHAL_MINOR) { - Warning("Old marshal file format (can be read)"); - } - arg.symbol = st_init_numtable(); - arg.data = st_init_numtable(); - v = rb_ensure(load, &arg, load_ensure, &arg); - } - else { - TypeError("Old marshal file format (can't read)"); - } - - return v; -} - -Init_marshal() -{ - VALUE mMarshal = rb_define_module("Marshal"); - - s_dump = rb_intern("_dump_to"); - s_load = rb_intern("_load_from"); - rb_define_module_function(mMarshal, "dump", marshal_dump, -1); - rb_define_module_function(mMarshal, "load", marshal_load, 1); - rb_define_module_function(mMarshal, "restore", marshal_load, 1); -} diff --git a/ext/marshal/marshal.doc b/ext/marshal/marshal.doc deleted file mode 100644 index 7529e7942f..0000000000 --- a/ext/marshal/marshal.doc +++ /dev/null @@ -1,48 +0,0 @@ -.\" marshal.doc - -*- Indented-Text -*- created at: Tue May 16 12:18:08 JST 1995 - -** Marshal(モジュール) - -rubyオブジェクトをファイルに書き出したり,読みも度したりする機能を提供 -するモジュール.大部分のクラスのインスタンスを書き出す事ができるが,ファ -イルへの不可能なクラスも存在し(例:IO),そのようなクラスを書き出そうと -すると例外を発生させる. - -Methods: -Single Methods: - - dump(obj, port[, limit]) - - objを再帰的にファイルに書き出す.ファイルに書き出せないクラスのイ - ンスタンスをファイルに書き出そうとすると例外を発生させる.ファイル - に書き出せないクラスは以下の通り. - - Class, Module, Data - - また,これらのクラスを間接的に指すクラス(例えばIOのサブクラス)など - も書き出せない.portはIO(またはそのサブクラス)のインスタンスを指定 - する. - - 出力するオブジェクトがメソッド`_dump_to'を定義している場合には,ファ - イル出力はそのメソッドを使って行われる.メソッド`_dump_to'は引数と - して出力先のファイルオブジェクトを受け取る.インスタンスがメソッド - `_dump_to'を持つクラスは必ず同じフォーマットを読み戻す特異メソッド - `_load_from'を定義する必要がある. - - limitを指定した場合,limit段以上深くリンクしたオブジェクトをダンプ - できない(デフォルトは100レベル)。負のlimitを指定すると深さチェック - を行わない。 - - dumps(obj) - - dump()がファイルに書き出すのと同じ内容を含む文字列を返す. - - load(port) - - portからオブジェクトを読み込んで来て,元のオブジェクトと同じ状態を - もつオブジェクトを生成する.portは文字列かIO(またはそのサブクラス) - のインスタンスである. - -------------------------------------------------------- -Local variables: -fill-column: 70 -end: diff --git a/ext/tcltklib/extconf.rb b/ext/tcltklib/extconf.rb index 26e7fe7b09..bb7327db0b 100644 --- a/ext/tcltklib/extconf.rb +++ b/ext/tcltklib/extconf.rb @@ -1,9 +1,14 @@ # extconf.rb for tcltklib +require 'mkmf' + have_library("socket", "socket") have_library("nsl", "gethostbyname") +have_library("dl", "dlopen") +have_library("m", "log") -def search_file(var, include, *path) +$includes = [] +def search_header(include, *path) pwd = Dir.getwd begin for i in path.reverse! @@ -12,8 +17,10 @@ def search_file(var, include, *path) Dir.chdir path files = Dir[include] if files.size > 0 - var << path - return files.pop + unless $includes.include? path + $includes << path + end + return end end end @@ -22,58 +29,56 @@ def search_file(var, include, *path) end end -$includes = [] -search_file($includes, - "tcl.h", - "/usr/include/tcl*", - "/usr/include", - "/usr/local/include/tcl*", - "/usr/local/include") -search_file($includes, - "tk.h", - "/usr/include/tk*", - "/usr/include", - "/usr/local/include/tk*", - "/usr/local/include") -search_file($includes, - "X11/Xlib.h", - "/usr/include", - "/usr/X11*/include", - "/usr/include", - "/usr/X11*/include") +search_header("tcl.h", + "/usr/include/tcl*", + "/usr/include", + "/usr/local/include/tcl*", + "/usr/local/include") +search_header("tk.h", + "/usr/include/tk*", + "/usr/include", + "/usr/local/include/tk*", + "/usr/local/include") +search_header("X11/Xlib.h", + "/usr/include", + "/usr/X11*/include", + "/usr/include", + "/usr/X11*/include") $CFLAGS = "-Wall " + $includes.collect{|path| "-I" + path}.join(" ") $libraries = [] -tcllibfile = search_file($libraries, - "libtcl{,7*,8*}.{a,so}", - "/usr/lib", - "/usr/local/lib") -if tcllibfile - tcllibfile.sub!(/^lib/, '') - tcllibfile.sub!(/\.(a|so)$/, '') -end -tklibfile = search_file($libraries, - "libtk{,4*,8*}.{a,so}", - "/usr/lib", - "/usr/local/lib") -if tklibfile - tklibfile.sub!(/^lib/, '') - tklibfile.sub!(/\.(a|so)$/, '') +def search_lib(file, func, *path) + for i in path.reverse! + dir = Dir[i] + for path in dir + $LDFLAGS = $libraries.collect{|p| "-L" + p}.join(" ") + " -L" + path + files = Dir[path+"/"+file] + if files.size > 0 + for lib in files + lib = File::basename(lib) + lib.sub!(/^lib/, '') + lib.sub!(/\.(a|so)$/, '') + if have_library(lib, func) + unless $libraries.include? path + $libraries << path + end + return TRUE + end + end + end + end + end + return FALSE; end -search_file($libraries, - "libX11.{a,so}", - "/usr/lib", - "/usr/X11*/lib") -$LDFLAGS = $libraries.collect{|path| "-L" + path}.join(" ") - -have_library("dl", "dlopen") -if have_header("tcl.h") && - have_header("tk.h") && - have_library("X11", "XOpenDisplay") && - have_library("m", "log") && - have_library(tcllibfile, "Tcl_FindExecutable") && - have_library(tklibfile, "Tk_Init") +if have_header("tcl.h") && have_header("tk.h") && + search_lib("libX11.{a,so}", "XOpenDisplay", + "/usr/lib", "/usr/X11*/lib") && + search_lib("libtcl{,7*,8*}.{a,so}", "Tcl_FindExecutable", + "/usr/lib", "/usr/local/lib") && + search_lib("libtk{,4*,8*}.{a,so}", "Tk_Init", + "/usr/lib", "/usr/local/lib") + $LDFLAGS = $libraries.collect{|path| "-L" + path}.join(" ") create_makefile("tcltklib") end diff --git a/file.c b/file.c index b60ec65d55..fa4e94e1d1 100644 --- a/file.c +++ b/file.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Nov 15 12:24:34 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -305,6 +305,28 @@ stat_new(st) time_new(st->st_ctime, 0)); } +static int +rb_stat(file, st) + VALUE file; + struct stat *st; +{ + OpenFile *fptr; + + switch (TYPE(file)) { + case T_STRING: + Check_SafeStr(file); + return stat(RSTRING(file)->ptr, st); + break; + case T_FILE: + GetOpenFile(file, fptr); + return fstat(fileno(fptr->f), st); + break; + default: + Check_Type(file, T_STRING); + } + return -1; /* not reached */ +} + static VALUE file_s_stat(obj, fname) VALUE obj, fname; @@ -345,7 +367,7 @@ file_s_lstat(obj, fname) } return stat_new(&st); #else - rb_notimplement(); + rb_notimplement(); #endif } @@ -363,7 +385,7 @@ file_lstat(obj) } return stat_new(&st); #else - rb_notimplement(); + rb_notimplement(); #endif } @@ -446,8 +468,7 @@ test_d(obj, fname) struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (S_ISDIR(st.st_mode)) return TRUE; return FALSE; } @@ -463,8 +484,7 @@ test_p(obj, fname) struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (S_ISFIFO(st.st_mode)) return TRUE; #endif @@ -521,8 +541,7 @@ test_S(obj, fname) #ifdef S_ISSOCK struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (S_ISSOCK(st.st_mode)) return TRUE; #endif @@ -544,8 +563,7 @@ test_b(obj, fname) #ifdef S_ISBLK struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (S_ISBLK(st.st_mode)) return TRUE; #endif @@ -562,8 +580,7 @@ test_c(obj, fname) struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (S_ISBLK(st.st_mode)) return TRUE; return FALSE; @@ -575,8 +592,7 @@ test_e(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; return TRUE; } @@ -644,8 +660,7 @@ test_f(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (S_ISREG(st.st_mode)) return TRUE; return FALSE; } @@ -656,8 +671,7 @@ test_z(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (st.st_size == 0) return TRUE; return FALSE; } @@ -668,8 +682,7 @@ test_s(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (st.st_size == 0) return FALSE; return int2inum(st.st_size); } @@ -680,8 +693,7 @@ test_owned(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (st.st_uid == geteuid()) return TRUE; return FALSE; } @@ -692,8 +704,7 @@ test_rowned(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (st.st_uid == getuid()) return TRUE; return FALSE; } @@ -705,8 +716,7 @@ test_grpowned(obj, fname) #ifndef NT struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE; + if (rb_stat(fname, &st) < 0) return FALSE; if (st.st_gid == getegid()) return TRUE; #endif return FALSE; @@ -768,8 +778,7 @@ file_s_size(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) + if (rb_stat(fname, &st) < 0) rb_sys_fail(RSTRING(fname)->ptr); return int2inum(st.st_size); } @@ -781,8 +790,7 @@ file_s_ftype(obj, fname) struct stat st; char *t; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) + if (rb_stat(fname, &st) < 0) rb_sys_fail(RSTRING(fname)->ptr); if (S_ISREG(st.st_mode)) { @@ -825,8 +833,7 @@ file_s_atime(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) + if (rb_stat(fname, &st) < 0) rb_sys_fail(RSTRING(fname)->ptr); return time_new(st.st_atime, 0); } @@ -851,8 +858,7 @@ file_s_mtime(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) + if (rb_stat(fname, &st) < 0) rb_sys_fail(RSTRING(fname)->ptr); return time_new(st.st_mtime, 0); } @@ -877,8 +883,7 @@ file_s_ctime(obj, fname) { struct stat st; - Check_SafeStr(fname); - if (stat(RSTRING(fname)->ptr, &st) < 0) + if (rb_stat(fname, &st) < 0) rb_sys_fail(RSTRING(fname)->ptr); return time_new(st.st_ctime, 0); } @@ -1104,7 +1109,7 @@ file_s_symlink(obj, from, to) rb_sys_fail(RSTRING(from)->ptr); return TRUE; #else - rb_notimplement(); + rb_notimplement(); #endif } @@ -1446,7 +1451,16 @@ test_check(n, argc, argv) n+=1; if (n < argc) ArgError("Wrong # of arguments(%d for %d)", argc, n); for (i=1; iptr, &st) == -1) { + if (rb_stat(argv[1], &st) == -1) { rb_sys_fail(RSTRING(argv[1])->ptr); } @@ -1561,8 +1575,8 @@ f_test(argc, argv) struct stat st1, st2; CHECK(2); - if (stat(RSTRING(argv[1])->ptr, &st1) < 0) return FALSE; - if (stat(RSTRING(argv[2])->ptr, &st2) < 0) return FALSE; + if (rb_stat(argv[1], &st1) < 0) return FALSE; + if (rb_stat(argv[2], &st2) < 0) return FALSE; switch (cmd) { case '-': diff --git a/gc.c b/gc.c index 27065af1cb..bc3517e4d8 100644 --- a/gc.c +++ b/gc.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Oct 5 09:44:46 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -26,10 +26,6 @@ #endif #endif -#ifdef _AIX -#pragma alloca -#endif - #ifdef C_ALLOCA void *alloca(); #endif @@ -389,6 +385,7 @@ gc_mark(ptr) case NODE_IF: /* 1,2,3 */ case NODE_FOR: case NODE_ITER: + case NODE_CREF: gc_mark(obj->as.node.u2.node); /* fall through */ case NODE_BLOCK: /* 1,3 */ @@ -400,6 +397,9 @@ gc_mark(ptr) case NODE_DREGX_ONCE: case NODE_FBODY: case NODE_CALL: +#ifdef C_ALLOCA + case NODE_ALLOCA: +#endif gc_mark(obj->as.node.u1.node); /* fall through */ case NODE_SUPER: /* 3 */ diff --git a/hash.c b/hash.c index 49be7de6aa..ba531f4ded 100644 --- a/hash.c +++ b/hash.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Nov 22 18:51:18 JST 1993 - Copyright (C) 1993-1997 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/inits.c b/inits.c index 123b32c989..55db006bfe 100644 --- a/inits.c +++ b/inits.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 28 16:01:58 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/instruby.rb b/instruby.rb index 8fd77055f2..3d3f2a4173 100644 --- a/instruby.rb +++ b/instruby.rb @@ -33,5 +33,6 @@ IO.foreach 'MANIFEST' do |$_| File.install "config.h", archdir, 0644, TRUE end File.install "rbconfig.rb", archdir, 0644, TRUE +File.makedirs mandir, TRUE File.install "ruby.1", mandir, 0644, TRUE # vi:set sw=2: diff --git a/io.c b/io.c index f84e15e447..546ec45d18 100644 --- a/io.c +++ b/io.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 15 18:08:59 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -1001,7 +1001,8 @@ pipe_open(pname, mode) break; default: /* parent */ - { + if (pid < 0) rb_sys_fail(pname); + else { NEWOBJ(port, struct RFile); OBJSETUP(port, cIO, T_FILE); MakeOpenFile(port, fptr); diff --git a/io.h b/io.h index c671fca8ed..73acbd7812 100644 --- a/io.h +++ b/io.h @@ -7,7 +7,7 @@ $Date$ created at: Fri Nov 12 16:47:09 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/lib/Env.rb b/lib/Env.rb new file mode 100644 index 0000000000..e52501f801 --- /dev/null +++ b/lib/Env.rb @@ -0,0 +1,28 @@ +# Env.rb -- imports environment variables as global variables +# +# Usage: +# +# p $USER +# $USER = "matz" +# p ENV["USER"] + +for k,v in ENV + next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k + eval < [[dependant, method, *opt], ...], ...} - + RCS_ID='-$Header: /home/cvsroot/ruby/lib/finalize.rb,v 1.1.1.2.2.2 1998/01/19 05:08:24 matz Exp $-' + + # Dependency: {id => [[dependant, method, opt], ...], ...} + Dependency = {} + # 依存関係 R_method(obj, dependant) の追加 def add_dependency(obj, dependant, method = :finalize, *opt) ObjectSpace.call_finalizer(obj) - method = method.intern unless method.kind_of?(Integer) - assoc = [dependant, method].concat(opt) - if dep = @dependency[obj.id] + assoc = [dependant, method, opt] + if dep = Dependency[obj.id] dep.push assoc else - @dependency[obj.id] = [assoc] + Dependency[obj.id] = [assoc] end end alias add add_dependency - + # 依存関係 R_method(obj, dependant) の削除 - def delete_dependency(id, dependant, method = :finalize) - id = id.id unless id.kind_of?(Integer) - method = method.intern unless method.kind_of?(Integer) - for assoc in @dependency[id] - assoc.delete_if do - |d, m, *o| + def delete_dependency(obj, dependant, method = :finalize) + id = obj.id + for assoc in Dependency[id] + assoc.delete_if do |d,m,*o| d == dependant && m == method end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end alias delete delete_dependency - + # 依存関係 R_*(obj, dependant) の削除 - def delete_all_dependency(id, dependant) - id = id.id unless id.kind_of?(Integer) - method = method.intern unless method.kind_of?(Integer) - for assoc in @dependency[id] - assoc.delete_if do - |d, m, *o| + def delete_all_dependency(obj, dependant) + id = obj.id + for assoc in Dependency[id] + assoc.delete_if do |d,m,*o| d == dependant end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end - + # 依存関係 R_method(*, dependant) の削除 def delete_by_dependant(dependant, method = :finalize) method = method.intern unless method.kind_of?(Integer) @@ -95,100 +91,103 @@ module Finalizer delete(id, dependant, method) end end - + # 依存関係 R_*(*, dependant) の削除 def delete_all_by_dependant(dependant) - for id in @dependency.keys + for id in Dependency.keys delete_all_dependency(id, dependant) end end - - # 依存関連 R_method(obj, dependtant) で結ばれるdependantをfinalizeす + + # 依存関連 R_method(id, dependtant) で結ばれるdependantをfinalizeす # る. def finalize_dependency(id, dependant, method = :finalize) - id = id.id unless id.kind_of?(Integer) - method = method.intern unless method.kind_of?(Integer) - for assocs in @dependency[id] - assocs.delete_if do - |d, m, *o| - d.send(m, *o) if ret = d == dependant && m == method - ret + for assocs in Dependency[id] + assocs.delete_if do |d, m, *o| + if d == dependant && m == method + d.send(m, *o) + true + else + false + end end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end alias finalize finalize_dependency - - # 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. + + # 依存関連 R_*(id, dependtant) で結ばれるdependantをfinalizeする. def finalize_all_dependency(id, dependant) - id = id.id unless id.kind_of?(Integer) - method = method.intern unless method.kind_of?(Integer) - for assoc in @dependency[id] - assoc.delete_if do - |d, m, *o| - d.send(m, *o) if ret = d == dependant + for assoc in Dependency[id] + assoc.delete_if do |d, m, *o| + if d == dependant + d.send(m, *o) + true + else + false + end end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end - + # 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする. def finalize_by_dependant(dependant, method = :finalize) - method = method.intern unless method.kind_of?(Integer) - for id in @dependency.keys + for id in Dependency.keys finalize(id, dependant, method) end end - + # 依存関連 R_*(*, dependtant) で結ばれるdependantをfinalizeする. def fainalize_all_by_dependant(dependant) - for id in @dependency.keys + for id in Dependency.keys finalize_all_dependency(id, dependant) end end - + # Finalizerに登録されている全てのdependantをfinalizeする def finalize_all - for id, assocs in @dependency + for id, assocs in Dependency for dependant, method, *opt in assocs dependant.send(method, id, *opt) end assocs.clear end end - + # finalize_* を安全に呼び出すためのイテレータ def safe - old_status = Thread.critical - Thread.critical = TRUE - ObjectSpace.remove_finalizer(@proc) - yield - ObjectSpace.add_finalizer(@proc) - Thread.critical = old_status + old_status, Thread.critical = Thread.critical, true + ObjectSpace.remove_finalizer(Proc) + begin + yield + ensure + ObjectSpace.add_finalizer(Proc) + Thread.critical = old_status + end end - + # ObjectSpace#add_finalizerへの登録関数 def final_of(id) - if assocs = @dependency.delete(id) + if assocs = Dependency.delete(id) for dependant, method, *opt in assocs dependant.send(method, id, *opt) end end end - - @dependency = Hash.new - @proc = proc{|id| final_of(id)} - ObjectSpace.add_finalizer(@proc) + + Proc = proc{|id| final_of(id)} + ObjectSpace.add_finalizer(Proc) module_function :add module_function :add_dependency - + module_function :delete module_function :delete_dependency module_function :delete_all_dependency module_function :delete_by_dependant module_function :delete_all_by_dependant - + module_function :finalize module_function :finalize_dependency module_function :finalize_all_dependency @@ -197,9 +196,8 @@ module Finalizer module_function :finalize_all module_function :safe - + module_function :final_of private_class_method :final_of - -end +end diff --git a/lib/ftplib.rb b/lib/ftplib.rb index 34ee2f8d62..5f949f7099 100644 --- a/lib/ftplib.rb +++ b/lib/ftplib.rb @@ -1,7 +1,7 @@ ### ftplib.rb -*- Mode: ruby; tab-width: 8; -*- -## $Revision: 1.5 $ -## $Date: 1997/09/16 08:03:31 $ +## $Revision: 1.1.1.1.4.1 $ +## $Date: 1998/01/16 12:36:05 $ ## by maeda shugo ### Code: @@ -17,7 +17,7 @@ class FTPProtoError < FTPError; end class FTP - RCS_ID = '$Id: ftplib.rb,v 1.5 1997/09/16 08:03:31 shugo Exp $' + RCS_ID = '$Id: ftplib.rb,v 1.1.1.1.4.1 1998/01/16 12:36:05 matz Exp $ ' FTP_PORT = 21 CRLF = "\r\n" diff --git a/lib/mathn.rb b/lib/mathn.rb index fdf27f6771..b5cc9b818b 100644 --- a/lib/mathn.rb +++ b/lib/mathn.rb @@ -1,8 +1,8 @@ # # mathn.rb - # $Release Version: 0.5 $ -# $Revision: 1.1 $ -# $Date: 1997/07/03 04:43:47 $ +# $Revision: 1.1.1.1 $ +# $Date: 1998/01/16 04:05:49 $ # by Keiju ISHITSUKA(SHL Japan Inc.) # # -- diff --git a/lib/matrix.rb b/lib/matrix.rb index 394c66f098..53c8f8b19c 100644 --- a/lib/matrix.rb +++ b/lib/matrix.rb @@ -2,8 +2,8 @@ # # matrix.rb - # $Release Version: 1.0$ -# $Revision: 1.0 $ -# $Date: 97/05/23 11:35:28 $ +# $Revision: 1.1.1.1 $ +# $Date: 1998/01/16 04:05:49 $ # Original Version from Smalltalk-80 version # on July 23, 1985 at 8:37:17 am # by Keiju ISHITSUKA @@ -36,7 +36,7 @@ module ExceptionForMatrix end class Matrix - RCS_ID='-$Header: ruby-mode,v 1.2 91/04/20 17:24:57 keiju Locked $-' + RCS_ID='-$Header: /home/cvsroot/ruby/lib/matrix.rb,v 1.1.1.1 1998/01/16 04:05:49 matz Exp $-' include ExceptionForMatrix diff --git a/lib/mutex_m.rb b/lib/mutex_m.rb index 823888e72f..693da41675 100644 --- a/lib/mutex_m.rb +++ b/lib/mutex_m.rb @@ -1,8 +1,8 @@ # # mutex_m.rb - # $Release Version: 2.0$ -# $Revision: 1.2 $ -# $Date: 1997/07/25 02:43:21 $ +# $Revision: 1.1.1.1 $ +# $Date: 1998/01/16 04:05:49 $ # Original from mutex.rb # by Keiju ISHITSUKA(SHL Japan Inc.) # diff --git a/lib/rational.rb b/lib/rational.rb index d4112c2956..a8c8322abc 100644 --- a/lib/rational.rb +++ b/lib/rational.rb @@ -1,8 +1,8 @@ # # rational.rb - # $Release Version: 0.5 $ -# $Revision: 1.1 $ -# $Date: 1996/11/11 04:25:14 $ +# $Revision: 1.1.1.1 $ +# $Date: 1998/01/16 04:05:49 $ # by Keiju ISHITSUKA(SHL Japan Inc.) # # -- diff --git a/lib/sync.rb b/lib/sync.rb index b5a3fc32b3..a804ade133 100644 --- a/lib/sync.rb +++ b/lib/sync.rb @@ -43,7 +43,7 @@ unless defined? Thread fail "Thread not available for this ruby interpreter" end -require "finalize" +require "final" module Sync_m RCS_ID='-$Header$-' @@ -321,7 +321,11 @@ module Sync_m def For_primitive_object.extend_object(obj) super obj.sync_extended - Finalizer.add(obj, For_primitive_object, :sync_finalize) + # Changed to use `final.rb'. + # Finalizer.add(obj, For_primitive_object, :sync_finalize) + ObjectSpace.define_finalizer(obj) do |id| + For_primitive_object.sync_finalize(id) + end end def initialize diff --git a/lib/tempfile.rb b/lib/tempfile.rb new file mode 100644 index 0000000000..66d96200b5 --- /dev/null +++ b/lib/tempfile.rb @@ -0,0 +1,72 @@ +# +# $Id$ +# +# The class for temporary files. +# o creates a temporary file, which name is "basename.pid.n" with mode "w+". +# o Tempfile objects can be used like IO object. +# o with tmpfile.close(true) created temporary files are removed. +# o created files are also removed on script termination. +# o with Tempfile#open, you can reopen the temporary file. +# o file mode of the temporary files are 0600. + +require 'delegate' +require 'final' + +class Tempfile < SimpleDelegater + Max_try = 10 + + def initialize(basename, tmpdir = '/tmp') + umask = File.umask(0177) + begin + n = 0 + while true + begin + @tmpname = sprintf('%s/%s.%d.%d', tmpdir, basename, $$, n) + unless File.exist?(@tmpname) + File.symlink(tmpdir, @tmpname + '.lock') + break + end + rescue + raise "cannot generate tmpfile `%s'" % @tmpname if n >= Max_try + #sleep(1) + end + n += 1 + end + + @clean_files = proc {|id| + if File.exist?(@tmpname) + File.unlink(@tmpname) + end + if File.exist?(@tmpname + '.lock') + File.unlink(@tmpname + '.lock') + end + } + ObjectSpace.define_finalizer(self, @clean_files) + + @tmpfile = File.open(@tmpname, 'w+') + super(@tmpfile) + File.unlink(@tmpname + '.lock') + ensure + File.umask(umask) + end + end + + def Tempfile.open(*args) + Tempfile.new(*args) + end + + def open + @tmpfile.close if @tmpfile + @tmpfile = File.open(@tmpname, 'r+') + __setobj__(@tmpfile) + end + + def close(real=false) + @tmpfile.close if @tmpfile + @tmpfile = nil + if real + @clean_files.call + ObjectSpace.undefine_finalizer(self) + end + end +end diff --git a/lib/thwait.rb b/lib/thwait.rb index c638335f5d..4ddd9b46ee 100644 --- a/lib/thwait.rb +++ b/lib/thwait.rb @@ -1,8 +1,8 @@ # # thwait.rb - # $Release Version: $ -# $Revision: 1.1 $ -# $Date: 1997/08/18 03:13:14 $ +# $Revision: 1.1.1.1 $ +# $Date: 1998/01/16 04:05:50 $ # by Keiju ISHITSUKA(Nippon Rational Inc.) # # -- @@ -14,7 +14,7 @@ require "thread.rb" require "e2mmap.rb" class ThreadsWait - RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/thwait.rb,v 1.1 1997/08/18 03:13:14 keiju Exp keiju $-' + RCS_ID='-$Header: /home/cvsroot/ruby/lib/thwait.rb,v 1.1.1.1 1998/01/16 04:05:50 matz Exp $-' Exception2MessageMapper.extend_to(binding) def_exception("ErrWaitThreadsNothing", "Wait threads nothing.") diff --git a/lib/tk.rb b/lib/tk.rb index 2cbbec02a8..8bb6c7f842 100644 --- a/lib/tk.rb +++ b/lib/tk.rb @@ -241,6 +241,15 @@ module TkComm uninstall_cmd myid }) end + + def update(idle=nil) + if idle + tk_call 'update', 'idletasks' + else + tk_call 'update' + end + end + end module TkCore @@ -963,6 +972,7 @@ class TkRoot - -require "tkutil" -if defined? Thread - require "thread" -end - -module Tk - include TkUtil - extend Tk - - wish_path = nil - ENV['PATH'].split(":").each {|path| - for wish in ['wish4.2', 'wish4.1', 'wish4.0', 'wish'] - if File.exist? path+'/'+wish - wish_path = path+'/'+wish - break - end - break if wish_path - end - } - fail 'can\'t find wish' if not wish_path #' - - def Tk.tk_exit - if not PORT.closed? - PORT.print "exit\n" - PORT.close - end - end - -# PORT = open(format("|%s -n %s", wish_path, File.basename($0)), "w+"); - PORT = open(format("|%s", wish_path), "w+"); - trap "EXIT", proc{Tk.tk_exit} - trap "PIPE", "" - - def tk_write(*args) - printf PORT, *args; - PORT.print "\n" - PORT.flush - end - tk_write '\ -wm withdraw . -proc rb_out args { - puts [format %%s $args] - flush stdout -} -proc rb_ans arg { - if [catch $arg var] {puts "!$var"} {puts "=$var@@"} - flush stdout -} -proc tkerror args { exit } -proc keepalive {} { rb_out alive; after 120000 keepalive} -after 120000 keepalive' - - READABLE = [] - READ_CMD = {} - - def file_readable(port, cmd) - if cmd == nil - READABLE.delete port - else - READABLE.push port - end - READ_CMD[port] = cmd - end - - WRITABLE = [] - WRITE_CMD = {} - def file_writable(port, cmd) - if cmd == nil - WRITABLE.delete port - else - WRITABLE.push port - end - WRITE_CMD[port] = cmd - end - module_function :file_readable, :file_writable - - file_readable PORT, proc { - line = PORT.gets - exit if not line - Tk.dispatch(line.chop!) - } - - def error_at - frames = caller(1) - frames.delete_if do |c| - c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! - end - frames - end - - def tk_tcl2ruby(val) - case val - when /^-?\d+$/ - val.to_i - when /^\./ - $tk_window_list[val] - when /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - when / / - val.split.collect{|elt| - tk_tcl2ruby(elt) - } - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - - def tk_split_list(str) - idx = str.index('{') - return tk_tcl2ruby(str) if not idx - - list = tk_tcl2ruby(str[0,idx]) - str = str[idx+1..-1] - i = -1 - brace = 1 - str.each_byte {|c| - i += 1 - brace += 1 if c == ?{ - brace -= 1 if c == ?} - break if brace == 0 - } - if str[0, i] == ' ' - list.push ' ' - else - list.push tk_split_list(str[0, i]) - end - list += tk_split_list(str[i+1..-1]) - list - end - private :tk_tcl2ruby, :tk_split_list - - def bool(val) - case bool - when "1", 1, 'yes', 'true' - TRUE - else - FALSE - end - end - def number(val) - case val - when /^-?\d+$/ - val.to_i - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - def string(val) - if val == "{}" - '' - elsif val[0] == ?{ - val[1..-2] - else - val - end - end - def list(val) - tk_split_list(val) - end - def window(val) - $tk_window_list[val] - end - def procedure(val) - if val =~ /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - else - nil - end - end - private :bool, :number, :string, :list, :window, :procedure - - # mark for non-given arguments - None = Object.new - def None.to_s - 'None' - end - - $tk_event_queue = [] - def tk_call(str, *args) - args = args.collect{|s| - next if s == None - if s.kind_of?(Hash) - s = hash_kv(s).join(" ") - else - if not s - s = "0" - elsif s == TRUE - s = "1" - elsif s.kind_of?(TkObject) - s = s.path - elsif s.kind_of?(TkVariable) - s = s.id - else - s = s.to_s - s.gsub!(/["\\\$\[\]]/, '\\\\\0') #" - s.gsub!(/\{/, '\\\\173') - s.gsub!(/\}/, '\\\\175') - end - "\"#{s}\"" - end - } - str += " " - str += args.join(" ") - print str, "\n" if $DEBUG - tk_write 'rb_ans {%s}', str - while PORT.gets - print $_ if $DEBUG - $_.chop! - if /^=(.*)@@$/ - val = $1 - break - elsif /^=/ - val = $' + "\n" - while TRUE - PORT.readline - if ~/@@$/ - val += $' - return val - else - val += $_ - end - end - elsif /^!/ - $@ = error_at - msg = $' - if msg =~ /unknown option "-(.*)"/ - $! = NameError.new(format("undefined method `%s' for %s(%s)", - $1, self, self.type)) #`' - else - $! = RuntimeError.new(format("%s - %s", self.type, msg)) - end - fail - end - $tk_event_queue.push $_ - end - - while ev = $tk_event_queue.shift - Tk.dispatch ev - end - fail 'wish closed' if PORT.closed? -# tk_split_list(val) - val - end - - def hash_kv(keys) - conf = [] - if keys - for k, v in keys - conf.push("-#{k}") - v = install_cmd(v) if v.kind_of? Proc - conf.push(v) - end - end - conf - end - private :tk_call, :error_at, :hash_kv - - $tk_cmdid = 0 - def install_cmd(cmd) - return '' if cmd == '' # uninstall cmd - id = format("c%.4d", $tk_cmdid) - $tk_cmdid += 1 - $tk_cmdtbl[id] = cmd - @cmdtbl = [] if not @cmdtbl - @cmdtbl.push id - return format('rb_out %s', id) - end - def uninstall_cmd(id) - $tk_cmdtbl[id] = nil - end - private :install_cmd, :uninstall_cmd - - $tk_window_list = {} - class Event - def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy) - @serial = seq - @num = b - @focus = (f == 1) - @height = h - @keycode = k - @state = s - @time = t - @width = w - @x = x - @y = y - @char = aa - @send_event = (ee == 1) - @keysym = kk - @keysym_num = nn - @type = tt - @widget = ww - @x_root = xx - @y_root = yy - end - attr :serial - attr :num - attr :focus - attr :height - attr :keycode - attr :state - attr :time - attr :width - attr :x - attr :y - attr :char - attr :send_event - attr :keysym - attr :keysym_num - attr :type - attr :widget - attr :x_root - attr :y_root - end - - def install_bind(cmd, args=nil) - if args - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, *arg - }) - id + " " + args - else - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, Event.new(*arg) - }) - id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y" - end - end - - def _bind(path, context, cmd, args=nil) - begin - id = install_bind(cmd, args) - tk_call 'bind', path, "<#{context}>", id - rescue - $tk_cmdtbl[id] = nil - fail - end - end - private :install_bind, :_bind - - def bind_all(context, cmd=Proc.new, args=nil) - _bind 'all', context, cmd, args - end - - def pack(*args) - TkPack.configure *args - end - - $tk_cmdtbl = {} - - def after(ms, cmd=Proc.new) - myid = format("c%.4d", $tk_cmdid) - tk_call 'after', ms, - install_cmd(proc{ - TkUtil.eval_cmd cmd - uninstall_cmd myid - }) - end - - def update(idle=nil) - if idle - tk_call 'update', 'idletasks' - else - tk_call 'update' - end - end - - def dispatch(line) - if line =~ /^c\d+/ - cmd = $& - fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd] - args = tk_split_list($') - TkUtil.eval_cmd $tk_cmdtbl[cmd], *args - elsif line =~ /^alive$/ - # keep alive, do nothing - else - fail "malformed line <#{line}>" - end - end - - def mainloop - begin - tk_write 'after idle {wm deiconify .}' - while TRUE - rf, wf = select(READABLE, WRITABLE) - for f in rf - READ_CMD[f].call(f) if READ_CMD[f] - if f.closed? - READABLE.delete f - READ_CMD[f] = nil - end - end - for f in wf - WRITE_CMD[f].call(f) if WRITE_CMD[f] - if f.closed? - WRITABLE.delete f - WRITE_CMD[f] = nil - end - end - end - ensure - Tk.tk_exit - end - end - - def root - $tk_root - end - - def bell - tk_call 'bell' - end - module_function :after, :update, :dispatch, :mainloop, :root, :bell - - module Scrollable - def xscrollcommand(cmd=Proc.new) - configure_cmd 'xscrollcommand', cmd - end - def yscrollcommand(cmd=Proc.new) - configure_cmd 'yscrollcommand', cmd - end - end - - module Wm - def aspect(*args) - w = window(tk_call('wm', 'grid', path, *args)) - w.split.collect{|s|s.to_i} if args.length == 0 - end - def client(name=None) - tk_call 'wm', 'client', path, name - end - def colormapwindows(*args) - list(tk_call('wm', 'colormapwindows', path, *args)) - end - def wm_command(value=None) - string(tk_call('wm', 'command', path, value)) - end - def deiconify - tk_call 'wm', 'deiconify', path - end - def focusmodel(*args) - tk_call 'wm', 'focusmodel', path, *args - end - def frame - tk_call 'wm', 'frame', path - end - def geometry(*args) - list(tk_call('wm', 'geometry', path, *args)) - end - def grid(*args) - w = tk_call('wm', 'grid', path, *args) - list(w) if args.size == 0 - end - def group(*args) - tk_call 'wm', 'path', path, *args - end - def iconbitmap(*args) - tk_call 'wm', 'bitmap', path, *args - end - def iconify - tk_call 'wm', 'iconify' - end - def iconmask(*args) - tk_call 'wm', 'iconmask', path, *args - end - def iconname(*args) - tk_call 'wm', 'iconname', path, *args - end - def iconposition(*args) - w = tk_call('wm', 'iconposition', path, *args) - list(w) if args.size == 0 - end - def iconwindow(*args) - tk_call 'wm', 'iconwindow', path, *args - end - def maxsize(*args) - w = tk_call('wm', 'maxsize', path, *args) - list(w) if not args.size == 0 - end - def minsize(*args) - w = tk_call('wm', 'minsize', path, *args) - list(w) if args.size == 0 - end - def overrideredirect(bool=None) - if bool == None - bool(tk_call('wm', 'overrideredirect', path)) - else - tk_call 'wm', 'overrideredirect', path, bool - end - end - def positionfrom(*args) - tk_call 'wm', 'positionfrom', path, *args - end - def protocol(name, func=None) - func = install_cmd(func) if not func == None - tk_call 'wm', 'command', path, name, func - end - def resizable(*args) - w = tk_call('wm', 'resizable', path, *args) - if args.length == 0 - list(w).collect{|e| bool(e)} - end - end - def sizefrom(*args) - list(tk_call('wm', 'sizefrom', path, *args)) - end - def state - tk_call 'wm', 'state', path - end - def title(*args) - tk_call 'wm', 'title', path, *args - end - def transient(*args) - tk_call 'wm', 'transient', path, *args - end - def withdraw - tk_call 'wm', 'withdraw', path - end - end -end diff --git a/lib/tkmenubar.rb b/lib/tkmenubar.rb new file mode 100644 index 0000000000..441f3f5c03 --- /dev/null +++ b/lib/tkmenubar.rb @@ -0,0 +1,137 @@ +# +# tkmenubar.rb +# +# Copyright (C) 1998 maeda shugo. All rights reserved. +# This file can be distributed under the terms of the Ruby. + +# Usage: +# +# menu_spec = [ +# [['File', 0], +# ['Open', proc{puts('Open clicked')}, 0], +# '---', +# ['Quit', proc{exit}, 0]], +# [['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]] +# ] +# menubar = TkMenubar.new(nil, menu_spec, +# 'tearoff'=>false, +# 'foreground'=>'grey40', +# 'activeforeground'=>'red', +# 'font'=>'-adobe-helvetica-bold-r-*--12-*-iso8859-1') +# menubar.pack('side'=>'top', 'fill'=>'x') +# +# +# OR +# +# +# menubar = TkMenubar.new +# menubar.add_menu([['File', 0], +# ['Open', proc{puts('Open clicked')}, 0], +# '---', +# ['Quit', proc{exit}, 0]]) +# menubar.add_menu([['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]]) +# menubar.configure('tearoff', false) +# menubar.configure('foreground', 'grey40') +# menubar.configure('activeforeground', 'red') +# menubar.configure('font', '-adobe-helvetica-bold-r-*--12-*-iso8859-1') +# menubar.pack('side'=>'top', 'fill'=>'x') + +# The format of the menu_spec is: +# [ +# [ +# [button text, underline, accelerator], +# [menu label, command, underline, accelerator], +# '---', # separator +# ... +# ], +# ... +# ] + +# underline and accelerator are optional parameters. +# Hashes are OK instead of Arrays. + +# To use add_menu, configuration must be done by calling configure after +# adding all menus by add_menu, not by the constructor arguments. + +require "tk" + +class TkMenubar item_info) + end + end + + mbtn.menu(menu) + @menus.push([mbtn, menu]) + delegate('tearoff', menu) + delegate('foreground', mbtn, menu) + delegate('background', mbtn, menu) + delegate('disabledforeground', mbtn, menu) + delegate('activeforeground', mbtn, menu) + delegate('activebackground', mbtn, menu) + delegate('font', mbtn, menu) + delegate('kanjifont', mbtn, menu) + mbtn.pack('side' => 'left') + end + + def [](index) + return @menus[index] + end +end diff --git a/lib/tkthcore.rb b/lib/tkthcore.rb deleted file mode 100644 index a6648502bd..0000000000 --- a/lib/tkthcore.rb +++ /dev/null @@ -1,550 +0,0 @@ -# -# tkthcore.rb - Tk interface modue using thread -# $Date$ -# by Yukihiro Matsumoto - -require "tkutil" -require "thread" - -module Tk - include TkUtil - extend Tk - - def Tk.tk_exit - if not PORT.closed? - tk_write "exit" - PORT.close - end - end - - trap "EXIT", proc{Tk.tk_exit} - trap "PIPE", '' - - wish_path = nil - ENV['PATH'].split(":").each {|path| - for wish in ['wish4.2', 'wish4.1', 'wish4.0', 'wish'] - if File.exist? path+'/'+wish - wish_path = path+'/'+wish - break - end - break if wish_path - end - } - fail 'can\'t find wish' if not wish_path #' - - # mark for non-given arguments - None = Object.new - def None.to_s - 'None' - end - - Qin = Queue.new - Qout = Queue.new - Qwish = Queue.new - Qcmd = Queue.new - PORT = open(format("|%s -n %s", wish_path, File.basename($0)), "w+"); - - $tk_not_init = TRUE - - def Tk.init - $tk_not_init = FALSE - Thread.start do - loop do - while line = PORT.gets - line.chop! - if line =~ /^[=!]/ - Qwish.push line - else - Qcmd.push line - end - end - exit - end - end - - Thread.start do - ary = [PORT] - loop do - str = Qin.pop - print "Qin: ", str, "\n" if $DEBUG - tk_write 'if [catch {%s} var] {puts "!$var"} {puts "=$var@@"};flush stdout', str - line = tk_recv - Qout.push(line) - end - end - end - - $tk_event_queue = [] - def tk_recv() - val = nil - $_ = Qwish.pop - loop do - if /^=(.*)@@$/ - val = $1 - break - elsif /^=/ - val = $' + "\n" - while TRUE - PORT.readline - if ~/@@$/ - val += $' - return val - else - val += $_ - end - end - elsif /^!/ - $@ = error_at - msg = $' - if msg =~ /unknown option "-(.*)"/ - fail NameError, format("undefined method `%s' for %s(%s)", $1, self, self.type) #`' - else - fail format("%s - %s", self.type, msg) - end - end - end - - fail 'wish closed' if PORT.closed? -# tk_split_list(val) - val - end - - def tk_call(str, *args) - Tk.init if $tk_not_init - args = args.collect{|s| - next if s == None - if s.kind_of?(Hash) - s = hash_kv(s).join(" ") - else - if not s - s = "0" - elsif s == TRUE - s = "1" - elsif s.kind_of?(TkObject) - s = s.path - elsif s.kind_of?(TkVariable) - s = s.id - else - s = s.to_s - s.gsub!(/["\\\$\[\]]/, '\\\\\0') #" - s.gsub!(/\{/, '\\\\173') - s.gsub!(/\}/, '\\\\175') - end - "\"#{s}\"" - end - } - str += " " - str += args.join(" ") - Qin.push str - return Qout.pop - end - - def tk_write(*args) - PORT.printf *args; PORT.print "\n" - PORT.flush - end - module_function :tk_write, :tk_recv - tk_write '\ -wm withdraw . -proc rb_out args { - puts [format %%s $args] - flush stdout -} -proc tkerror args { exit } -proc keepalive {} { rb_out alive; after 120000 keepalive} -after 120000 keepalive' - - READ_TH = {} - def file_readable(port, cmd) - if cmd == nil - if READ_TH[port].has_key? - READ_TH[port].exit - READ_TH[port] = nil - end - else - READ_TH[port] = Thread.start{ - loop do - TkUtil.eval_cmd cmd - end - } - end - end - - WRITE_TH = {} - def file_writable(port, cmd) - if cmd == nil - if WRITE_TH[port].has_key? - WRITE_TH[port].exit - end - else - WRITE_TH[port] = Thread.start{ - loop do - TkUtil.eval_cmd cmd - end - } - end - end - module_function :file_readable, :file_writable - - def tk_tcl2ruby(val) - case val - when /^-?\d+$/ - val.to_i - when /^\./ - $tk_window_list[val] - when /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - when / / - val.split.collect{|elt| - tk_tcl2ruby(elt) - } - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - - def tk_split_list(str) - idx = str.index('{') - return tk_tcl2ruby(str) if not idx - - list = tk_tcl2ruby(str[0,idx]) - str = str[idx+1..-1] - i = -1 - brace = 1 - str.each_byte {|c| - i += 1 - brace += 1 if c == ?{ - brace -= 1 if c == ?} - break if brace == 0 - } - if str[0, i] == ' ' - list.push ' ' - else - list.push tk_split_list(str[0, i]) - end - list += tk_split_list(str[i+1..-1]) - list - end - private :tk_tcl2ruby, :tk_split_list - - def dispatch(line) - if line =~ /^c\d+/ - cmd = $& - fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd] - args = tk_split_list($') - TkUtil.eval_cmd $tk_cmdtbl[cmd], *args - elsif line =~ /^alive$/ - # keep alive, do nothing - else - fail "malformed line <#{line}>" - end - end - module_function :dispatch - - def error_at - frames = caller(1) - frames.delete_if do |c| - c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! - end - frames - end - - def bool(val) - case bool - when "1", 1, 'yes', 'true' - TRUE - else - FALSE - end - end - def number(val) - case val - when /^-?\d+$/ - val.to_i - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - def string(val) - if val == "{}" - '' - elsif val[0] == ?{ - val[1..-2] - else - val - end - end - def list(val) - tk_split_list(val) - end - def window(val) - $tk_window_list[val] - end - def procedure(val) - if val =~ /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - else - nil - end - end - private :bool, :number, :string, :list, :window, :procedure - - def hash_kv(keys) - conf = [] - if keys - for k, v in keys - conf.push("-#{k}") - v = install_cmd(v) if v.kind_of? Proc - conf.push(v) - end - end - conf - end - private :tk_call, :error_at, :hash_kv - - $tk_cmdid = 0 - def install_cmd(cmd) - return '' if cmd == '' # uninstall cmd - id = format("c%.4d", $tk_cmdid) - $tk_cmdid += 1 - $tk_cmdtbl[id] = cmd - @cmdtbl = [] if not @cmdtbl - @cmdtbl.push id - return format('rb_out %s', id) - end - def uninstall_cmd(id) - $tk_cmdtbl[id] = nil - end - private :install_cmd, :uninstall_cmd - - $tk_window_list = {} - class Event - def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy) - @serial = seq - @num = b - @focus = (f == 1) - @height = h - @keycode = k - @state = s - @time = t - @width = w - @x = x - @y = y - @char = aa - @send_event = (ee == 1) - @keysym = kk - @keysym_num = nn - @type = tt - @widget = ww - @x_root = xx - @y_root = yy - end - attr :serial - attr :num - attr :focus - attr :height - attr :keycode - attr :state - attr :time - attr :width - attr :x - attr :y - attr :char - attr :send_event - attr :keysym - attr :keysym_num - attr :type - attr :widget - attr :x_root - attr :y_root - end - - def install_bind(cmd, args=nil) - if args - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, *arg - }) - id + " " + args - else - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, Event.new(*arg) - }) - id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y" - end - end - - def _bind(path, context, cmd, args=nil) - begin - id = install_bind(cmd, args) - tk_call 'bind', path, "<#{context}>", id - rescue - $tk_cmdtbl[id] = nil - fail - end - end - private :install_bind, :_bind - - def bind_all(context, cmd=Proc.new, args=nil) - _bind 'all', context, cmd, args - end - - def pack(*args) - TkPack.configure *args - end - - $tk_cmdtbl = {} - - Qafter = Queue.new - def after(ms, cmd=Proc.new) - unless $tk_after_thread - $tk_after_thread = Thread.start{ - loop do - cmd = Qafter.pop - TkUtil.eval_cmd cmd - end - } - end - Thread.start do - sleep Float(ms)/1000 - Qafter.push cmd - end - end - - def update(idle=nil) - if idle - tk_call 'update', 'idletasks' - else - tk_call 'update' - end - end - - def root - $tk_root - end - - def bell - tk_call 'bell' - end - - def mainloop - begin - tk_call 'after', 'idle', 'wm deiconify .' - loop do - dispatch Qcmd.pop - end - ensure - Tk.tk_exit - end - end - module_function :after, :update, :dispatch, :mainloop, :root, :bell - - module Scrollable - def xscrollcommand(cmd=Proc.new) - configure_cmd 'xscrollcommand', cmd - end - def yscrollcommand(cmd=Proc.new) - configure_cmd 'yscrollcommand', cmd - end - end - - module Wm - def aspect(*args) - w = window(tk_call('wm', 'grid', path, *args)) - w.split.collect{|s|s.to_i} if args.length == 0 - end - def client(name=None) - tk_call 'wm', 'client', path, name - end - def colormapwindows(*args) - list(tk_call('wm', 'colormapwindows', path, *args)) - end - def wm_command(value=None) - string(tk_call('wm', 'command', path, value)) - end - def deiconify - tk_call 'wm', 'deiconify', path - end - def focusmodel(*args) - tk_call 'wm', 'focusmodel', path, *args - end - def frame - tk_call 'wm', 'frame', path - end - def geometry(*args) - list(tk_call('wm', 'geometry', path, *args)) - end - def grid(*args) - w = tk_call('wm', 'grid', path, *args) - list(w) if args.size == 0 - end - def group(*args) - tk_call 'wm', 'path', path, *args - end - def iconbitmap(*args) - tk_call 'wm', 'bitmap', path, *args - end - def iconify - tk_call 'wm', 'iconify' - end - def iconmask(*args) - tk_call 'wm', 'iconmask', path, *args - end - def iconname(*args) - tk_call 'wm', 'iconname', path, *args - end - def iconposition(*args) - w = tk_call('wm', 'iconposition', path, *args) - list(w) if args.size == 0 - end - def iconwindow(*args) - tk_call 'wm', 'iconwindow', path, *args - end - def maxsize(*args) - w = tk_call('wm', 'maxsize', path, *args) - list(w) if not args.size == 0 - end - def minsize(*args) - w = tk_call('wm', 'minsize', path, *args) - list(w) if args.size == 0 - end - def overrideredirect(bool=None) - if bool == None - bool(tk_call('wm', 'overrideredirect', path)) - else - tk_call 'wm', 'overrideredirect', path, bool - end - end - def positionfrom(*args) - tk_call 'wm', 'positionfrom', path, *args - end - def protocol(name, func=None) - func = install_cmd(func) if not func == None - tk_call 'wm', 'command', path, name, func - end - def resizable(*args) - w = tk_call('wm', 'resizable', path, *args) - if args.length == 0 - list(w).collect{|e| bool(e)} - end - end - def sizefrom(*args) - list(tk_call('wm', 'sizefrom', path, *args)) - end - def state - tk_call 'wm', 'state', path - end - def title(*args) - tk_call 'wm', 'title', path, *args - end - def transient(*args) - tk_call 'wm', 'transient', path, *args - end - def withdraw - tk_call 'wm', 'withdraw', path - end - end -end diff --git a/math.c b/math.c index 0e427035f4..775bddaf16 100644 --- a/math.c +++ b/math.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 25 14:12:56 JST 1994 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/missing/dir.h b/missing/dir.h index 34be77b9c0..6cf5318fa9 100644 --- a/missing/dir.h +++ b/missing/dir.h @@ -1,11 +1,14 @@ -/* $RCSfile: dir.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:10 $ +/* $RCSfile: dir.h,v $$Revision: 1.1.1.2 $$Date: 1998/01/16 04:14:54 $ * * (C) Copyright 1987, 1990 Diomidis Spinellis. * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * - * $Log: dir.h,v $ + * $Log: dir.h,v $ + * Revision 1.1.1.2 1998/01/16 04:14:54 matz + * *** empty log message *** + * * Revision 4.0.1.1 91/06/07 11:22:10 lwall * patch4: new copyright notice * @@ -61,14 +64,17 @@ void rewinddir(DIR *dirp); void closedir(DIR *dirp); #endif /* __DIR_INCLUDED */ -/* $RCSfile: dir.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:10 $ +/* $RCSfile: dir.h,v $$Revision: 1.1.1.2 $$Date: 1998/01/16 04:14:54 $ * * (C) Copyright 1987, 1990 Diomidis Spinellis. * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * - * $Log: dir.h,v $ + * $Log: dir.h,v $ + * Revision 1.1.1.2 1998/01/16 04:14:54 matz + * *** empty log message *** + * * Revision 4.0.1.1 91/06/07 11:22:10 lwall * patch4: new copyright notice * @@ -122,14 +128,17 @@ void rewinddir(DIR *dirp); void closedir(DIR *dirp); #endif /* __DIR_INCLUDED */ -/* $RCSfile: dir.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:10 $ +/* $RCSfile: dir.h,v $$Revision: 1.1.1.2 $$Date: 1998/01/16 04:14:54 $ * * (C) Copyright 1987, 1990 Diomidis Spinellis. * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * - * $Log: dir.h,v $ + * $Log: dir.h,v $ + * Revision 1.1.1.2 1998/01/16 04:14:54 matz + * *** empty log message *** + * * Revision 4.0.1.1 91/06/07 11:22:10 lwall * patch4: new copyright notice * diff --git a/node.h b/node.h index cdb354c007..832b8ca827 100644 --- a/node.h +++ b/node.h @@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 15:14:02 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -101,6 +101,9 @@ enum node_type { NODE_TAG, NODE_NEWLINE, NODE_POSTEXE, +#ifdef C_ALLOCA + NODE_ALLOCA, +#endif }; typedef struct RNode { diff --git a/numeric.c b/numeric.c index b0d5f7f522..4bc9a604ec 100644 --- a/numeric.c +++ b/numeric.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 13 18:33:09 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/object.c b/object.c index 2e614b3a41..b515b45202 100644 --- a/object.c +++ b/object.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Jul 15 12:01:24 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -386,7 +386,7 @@ static VALUE mod_to_s(class) VALUE class; { - return rb_class_path(class); + return str_dup(rb_class_path(class)); } static VALUE @@ -721,6 +721,15 @@ f_string(obj, arg) return rb_funcall(arg, rb_intern("to_s"), 0); } +char* +str2cstr(str) + VALUE str; +{ + if (NIL_P(str)) return NULL; + Check_Type(str, T_STRING); + return RSTRING(str)->ptr; +} + VALUE rb_String(val) VALUE val; diff --git a/pack.c b/pack.c index 20d12d4003..52a0dd5027 100644 --- a/pack.c +++ b/pack.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Feb 10 15:17:05 JST 1994 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/parse.y b/parse.y index 4bf13cf398..99bbf8e1c4 100644 --- a/parse.y +++ b/parse.y @@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 18:02:42 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -175,8 +175,8 @@ static void top_local_setup(); %type variable symbol operation assoc_kw %type cname fname op rest_arg %type f_arg -%token oUPLUS /* unary+ */ -%token MINUS /* unary- */ +%token UPLUS /* unary+ */ +%token UMINUS /* unary- */ %token POW /* ** */ %token CMP /* <=> */ %token EQ /* == */ @@ -458,10 +458,6 @@ lhs : variable { $$ = attrset($1, $3, 0); } - | primary '.' CONSTANT - { - $$ = attrset($1, $3, 0); - } | backref { backref_error($1); @@ -1988,6 +1984,15 @@ parse_qstring(term) return STRING; } +static int +parse_quotedword(term) + int term; +{ + if (parse_qstring(term) == 0) return 0; + yylval.node = NEW_CALL(NEW_STR(yylval.val), rb_intern("split"), 0); + return DSTRING; +} + char *strdup(); static int @@ -2041,6 +2046,7 @@ here_document(term) free(eos); return 0; } + sourceline++; if (strncmp(eos, RSTRING(line)->ptr, len) == 0 && (RSTRING(line)->ptr[len] == '\n' || RSTRING(line)->ptr[len] == '\r')) { @@ -2049,7 +2055,6 @@ here_document(term) lex_pbeg = lex_p = RSTRING(line)->ptr; lex_pend = lex_p + RSTRING(line)->len; - sourceline++; switch (parse_string(term, '\n')) { case STRING: case XSTRING: @@ -2600,11 +2605,6 @@ retry: c = LPAREN; lex_state = EXPR_BEG; } - else if (lex_state == EXPR_ARG && space_seen) { - arg_ambiguous(); - c = LPAREN; - lex_state = EXPR_BEG; - } else { lex_state = EXPR_BEG; } @@ -2686,6 +2686,9 @@ retry: case 'q': return parse_qstring(term); + case 'w': + return parse_quotedword(term); + case 'x': return parse_string('`', term); @@ -2693,7 +2696,7 @@ retry: return parse_regx(term); default: - yyerror("unknown type of string `%c'", c); + yyerror("unknown type of %string"); return 0; } } diff --git a/process.c b/process.c index 9d50fea8bf..5a7ce36b47 100644 --- a/process.c +++ b/process.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 14:30:50 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -579,6 +579,7 @@ rb_syswait(pid) { RETSIGTYPE (*hfunc)(), (*qfunc)(), (*ifunc)(); int status; + int i; #ifdef SIGHUP hfunc = signal(SIGHUP, SIG_IGN); @@ -588,7 +589,9 @@ rb_syswait(pid) #endif ifunc = signal(SIGINT, SIG_IGN); - if (rb_waitpid(pid, 0, &status) < 0) rb_sys_fail("wait"); + do { + i = rb_waitpid(pid, 0, &status); + } while (i == -1 && errno == EINTR); #ifdef SIGHUP signal(SIGHUP, hfunc); diff --git a/random.c b/random.c index d0a5756b69..8674dd0bad 100644 --- a/random.c +++ b/random.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Dec 24 16:39:21 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/range.c b/range.c index 9596e07f93..121acfe5a6 100644 --- a/range.c +++ b/range.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Aug 19 17:46:47 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/re.c b/re.c index cb0ade9aaf..83fb94afb1 100644 --- a/re.c +++ b/re.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 18:24:49 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -69,7 +69,7 @@ static char casetable[] = { >>> "You lose. You will need a translation table for your character set." <<< #endif -#define min(a,b) (((a)>(b))?(b):(a)) +#define MIN(a,b) (((a)>(b))?(b):(a)) int str_cicmp(str1, str2) @@ -78,7 +78,7 @@ str_cicmp(str1, str2) int len, i; char *p1, *p2; - len = min(RSTRING(str1)->len, RSTRING(str2)->len); + len = MIN(RSTRING(str1)->len, RSTRING(str2)->len); p1 = RSTRING(str1)->ptr; p2 = RSTRING(str2)->ptr; for (i = 0; i < len; i++, p1++, p2++) { diff --git a/re.h b/re.h index 8769d6ef39..dd93168ab1 100644 --- a/re.h +++ b/re.h @@ -7,7 +7,7 @@ $Date$ created at: Thu Sep 30 14:18:32 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/regex.c b/regex.c new file mode 100644 index 0000000000..152eebbf6d --- /dev/null +++ b/regex.c @@ -0,0 +1,3389 @@ +/* Extended regular expression matching and search library. + Copyright (C) 1985, 1989-90 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto) + Last change: May 21, 1993 by t^2 */ + + +/* To test, compile with -Dtest. This Dtestable feature turns this into + a self-contained program which reads a pattern, describes how it + compiles, then reads a string and searches for it. + + On the other hand, if you compile with both -Dtest and -Dcanned you + can run some tests we've already thought of. */ + +/* We write fatal error messages on standard error. */ +#include + +/* isalpha(3) etc. are used for the character classes. */ +#include +#include + +#include "config.h" +#include "defines.h" + +#ifdef __STDC__ +#define P(s) s +#define MALLOC_ARG_T size_t +#else +#define P(s) () +#define MALLOC_ARG_T unsigned +#define volatile +#define const +#endif + +/* #define NO_ALLOCA /* try it out for now */ +#ifndef NO_ALLOCA +/* Make alloca work the best possible way. */ +#ifdef __GNUC__ +#ifndef atarist +#ifndef alloca +#define alloca __builtin_alloca +#endif +#endif /* atarist */ +#else +#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__) +#include +#else +char *alloca(); +#endif +#endif /* __GNUC__ */ + +#ifdef _AIX +#pragma alloca +#endif + +#ifdef HAVE_STRING_H +# include +#else +# include +#endif + +#define RE_ALLOCATE alloca +#define FREE_VARIABLES() alloca(0) + +#define FREE_AND_RETURN_VOID(stackb) return +#define FREE_AND_RETURN(stackb,val) return(val) +#define DOUBLE_STACK(stackx,stackb,len,type) \ + (stackx = (type*) alloca(2 * len * sizeof(type)), \ + /* Only copy what is in use. */ \ + (type*) memcpy(stackx, stackb, len * sizeof (type))) +#else /* NO_ALLOCA defined */ + +#define RE_ALLOCATE malloc + +#define FREE_VAR(var) if (var) free(var); var = NULL +#define FREE_VARIABLES() \ + do { \ + FREE_VAR(regstart); \ + FREE_VAR(regend); \ + FREE_VAR(best_regstart); \ + FREE_VAR(best_regend); \ + FREE_VAR(reg_info); \ + } while (0) + +#define FREE_AND_RETURN_VOID(stackb) free(stackb);return +#define FREE_AND_RETURN(stackb,val) free(stackb);return(val) +#define DOUBLE_STACK(stackx,stackb,len,type) \ + (type*)xrealloc(stackb, 2 * len * sizeof(type)) +#endif /* NO_ALLOCA */ + +#define RE_TALLOC(n,t) ((t*)RE_ALLOCATE((n)*sizeof(t))) +#define TMALLOC(n,t) ((t*)xmalloc((n)*sizeof(t))) +#define TREALLOC(s,n,t) (s=((t*)xrealloc(s,(n)*sizeof(t)))) + +#define EXPAND_FAIL_STACK(stackx,stackb,len) \ + do {\ + /* Roughly double the size of the stack. */ \ + stackx = DOUBLE_STACK(stackx,stackb,len,unsigned char*); \ + /* Rearrange the pointers. */ \ + stackp = stackx + (stackp - stackb); \ + stackb = stackx; \ + stacke = stackb + 2 * len; \ + } while (0); \ + +/* Get the interface, including the syntax bits. */ +#include "regex.h" + +/* Subroutines for re_compile_pattern. */ +static void store_jump P((char *, int, char *)); +static void insert_jump P((int, char *, char *, char *)); +static void store_jump_n P((char *, int, char *, unsigned)); +static void insert_jump_n P((int, char *, char *, char *, unsigned)); +static void insert_op P((int, char *, char *)); +static void insert_op_2 P((int, char *, char *, int, int)); +static int memcmp_translate P((unsigned char *, unsigned char *, + int, unsigned char *)); + +/* Define the syntax stuff, so we can do the \<, \>, etc. */ + +/* This must be nonzero for the wordchar and notwordchar pattern + commands in re_match_2. */ +#ifndef Sword +#define Sword 1 +#endif + +#define SYNTAX(c) re_syntax_table[c] + +static char re_syntax_table[256]; +static void init_syntax_once P((void)); + +#undef P + +#include "util.h" + +static void +init_syntax_once() +{ + register int c; + static int done = 0; + + if (done) + return; + + memset(re_syntax_table, 0, sizeof re_syntax_table); + + for (c = 'a'; c <= 'z'; c++) + re_syntax_table[c] = Sword; + + for (c = 'A'; c <= 'Z'; c++) + re_syntax_table[c] = Sword; + + for (c = '0'; c <= '9'; c++) + re_syntax_table[c] = Sword; + + re_syntax_table['_'] = Sword; + + /* Add specific syntax for ISO Latin-1. */ + for (c = 0300; c <= 0377; c++) + re_syntax_table[c] = Sword; + re_syntax_table[0327] = 0; + re_syntax_table[0367] = 0; + + done = 1; +} + +/* Sequents are missing isgraph. */ +#ifndef isgraph +#define isgraph(c) (isprint((c)) && !isspace((c))) +#endif + +/* These are the command codes that appear in compiled regular + expressions, one per byte. Some command codes are followed by + argument bytes. A command code can specify any interpretation + whatsoever for its arguments. Zero-bytes may appear in the compiled + regular expression. + + The value of `exactn' is needed in search.c (search_buffer) in emacs. + So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of + `exactn' we use here must also be 1. */ + +enum regexpcode + { + unused=0, + exactn=1, /* Followed by one byte giving n, then by n literal bytes. */ + begline, /* Fail unless at beginning of line. */ + endline, /* Fail unless at end of line. */ + begbuf, /* Succeeds if at beginning of buffer (if emacs) or at beginning + of string to be matched (if not). */ + endbuf, /* Analogously, for end of buffer/string. */ + jump, /* Followed by two bytes giving relative address to jump to. */ + on_failure_jump, /* Followed by two bytes giving relative address of + place to resume at in case of failure. */ + finalize_jump, /* Throw away latest failure point and then jump to + address. */ + maybe_finalize_jump, /* Like jump but finalize if safe to do so. + This is used to jump back to the beginning + of a repeat. If the command that follows + this jump is clearly incompatible with the + one at the beginning of the repeat, such that + we can be sure that there is no use backtracking + out of repetitions already completed, + then we finalize. */ + dummy_failure_jump, /* Jump, and push a dummy failure point. This + failure point will be thrown away if an attempt + is made to use it for a failure. A + construct + makes this before the first repeat. Also + use it as an intermediary kind of jump when + compiling an or construct. */ + succeed_n, /* Used like on_failure_jump except has to succeed n times; + then gets turned into an on_failure_jump. The relative + address following it is useless until then. The + address is followed by two bytes containing n. */ + jump_n, /* Similar to jump, but jump n times only; also the relative + address following is in turn followed by yet two more bytes + containing n. */ + try_next, /* Jump to next pattern for the first time, + leaving this pattern on the failure stack. */ + finalize_push, /* Finalize stack and push the beginning of the pattern + on the stack to retry (used for non-greedy match) */ + finalize_push_n, /* Similar to finalize_push, buf finalize n time only */ + set_number_at, /* Set the following relative location to the + subsequent number. */ + anychar, /* Matches any (more or less) one character. */ + charset, /* Matches any one char belonging to specified set. + First following byte is number of bitmap bytes. + Then come bytes for a bitmap saying which chars are in. + Bits in each byte are ordered low-bit-first. + A character is in the set if its bit is 1. + A character too large to have a bit in the map + is automatically not in the set. */ + charset_not, /* Same parameters as charset, but match any character + that is not one of those specified. */ + start_memory, /* Start remembering the text that is matched, for + storing in a memory register. Followed by one + byte containing the register number. Register numbers + must be in the range 0 through RE_NREGS. */ + stop_memory, /* Stop remembering the text that is matched + and store it in a memory register. Followed by + one byte containing the register number. Register + numbers must be in the range 0 through RE_NREGS. */ + start_nowidth, /* Save string point to the stack. */ + stop_nowidth, /* Restore string place at the point start_nowidth. */ + pop_and_fail, /* Fail after popping nowidth entry from stack. */ + duplicate, /* Match a duplicate of something remembered. + Followed by one byte containing the index of the memory + register. */ + wordchar, /* Matches any word-constituent character. */ + notwordchar, /* Matches any char that is not a word-constituent. */ + wordbeg, /* Succeeds if at word beginning. */ + wordend, /* Succeeds if at word end. */ + wordbound, /* Succeeds if at a word boundary. */ + notwordbound,/* Succeeds if not at a word boundary. */ + }; + + +/* Number of failure points to allocate space for initially, + when matching. If this number is exceeded, more space is allocated, + so it is not a hard limit. */ + +#ifndef NFAILURES +#define NFAILURES 80 +#endif + +#if defined(CHAR_UNSIGNED) || defined(__CHAR_UNSIGNED__) +#define SIGN_EXTEND_CHAR(c) ((c)>(char)127?(c)-256:(c)) /* for IBM RT */ +#endif +#ifndef SIGN_EXTEND_CHAR +#define SIGN_EXTEND_CHAR(x) (x) +#endif + + +/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ +#define STORE_NUMBER(destination, number) \ + { (destination)[0] = (number) & 0377; \ + (destination)[1] = (number) >> 8; } + +/* Same as STORE_NUMBER, except increment the destination pointer to + the byte after where the number is stored. Watch out that values for + DESTINATION such as p + 1 won't work, whereas p will. */ +#define STORE_NUMBER_AND_INCR(destination, number) \ + { STORE_NUMBER(destination, number); \ + (destination) += 2; } + + +/* Put into DESTINATION a number stored in two contingous bytes starting + at SOURCE. */ +#define EXTRACT_NUMBER(destination, source) \ + { (destination) = *(source) & 0377; \ + (destination) += SIGN_EXTEND_CHAR (*(char *)((source) + 1)) << 8; } + +/* Same as EXTRACT_NUMBER, except increment the pointer for source to + point to second byte of SOURCE. Note that SOURCE has to be a value + such as p, not, e.g., p + 1. */ +#define EXTRACT_NUMBER_AND_INCR(destination, source) \ + { EXTRACT_NUMBER(destination, source); \ + (source) += 2; } + + +/* Specify the precise syntax of regexps for compilation. This provides + for compatibility for various utilities which historically have + different, incompatible syntaxes. + + The argument SYNTAX is a bit-mask comprised of the various bits + defined in regex.h. */ + +long +re_set_syntax(syntax) + long syntax; +{ + long ret; + + ret = re_syntax_options; + re_syntax_options = syntax; + return ret; +} + +/* Set by re_set_syntax to the current regexp syntax to recognize. */ +long re_syntax_options = DEFAULT_MBCTYPE; + + +/* Macros for re_compile_pattern, which is found below these definitions. */ + +/* Fetch the next character in the uncompiled pattern---translating it + if necessary. Also cast from a signed character in the constant + string passed to us by the user to an unsigned char that we can use + as an array index (in, e.g., `translate'). */ +#define PATFETCH(c) \ + do {if (p == pend) goto end_of_pattern; \ + c = (unsigned char) *p++; \ + if (translate) c = (unsigned char)translate[c]; \ + } while (0) + +/* Fetch the next character in the uncompiled pattern, with no + translation. */ +#define PATFETCH_RAW(c) \ + do {if (p == pend) goto end_of_pattern; \ + c = (unsigned char) *p++; \ + } while (0) + +/* Go backwards one character in the pattern. */ +#define PATUNFETCH p-- + + +/* If the buffer isn't allocated when it comes in, use this. */ +#define INIT_BUF_SIZE 28 + +/* Make sure we have at least N more bytes of space in buffer. */ +#define GET_BUFFER_SPACE(n) \ + { \ + while (b - bufp->buffer + (n) >= bufp->allocated) \ + EXTEND_BUFFER; \ + } + +/* Make sure we have one more byte of buffer space and then add CH to it. */ +#define BUFPUSH(ch) \ + { \ + GET_BUFFER_SPACE(1); \ + *b++ = (char)(ch); \ + } + +/* Extend the buffer by twice its current size via reallociation and + reset the pointers that pointed into the old allocation to point to + the correct places in the new allocation. If extending the buffer + results in it being larger than 1 << 16, then flag memory exhausted. */ +#define EXTEND_BUFFER \ + { char *old_buffer = bufp->buffer; \ + if (bufp->allocated == (1L<<16)) goto too_big; \ + bufp->allocated *= 2; \ + if (bufp->allocated > (1L<<16)) bufp->allocated = (1L<<16); \ + bufp->buffer = (char *) xrealloc (bufp->buffer, bufp->allocated); \ + if (bufp->buffer == 0) \ + goto memory_exhausted; \ + b = (b - old_buffer) + bufp->buffer; \ + if (fixup_jump) \ + fixup_jump = (fixup_jump - old_buffer) + bufp->buffer; \ + if (laststart) \ + laststart = (laststart - old_buffer) + bufp->buffer; \ + begalt = (begalt - old_buffer) + bufp->buffer; \ + if (pending_exact) \ + pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ + } + + +/* Set the bit for character C in a character set list. */ +#define SET_LIST_BIT(c) \ + (b[(unsigned char)(c) / BYTEWIDTH] \ + |= 1 << ((unsigned char)(c) % BYTEWIDTH)) + +/* Get the next unsigned number in the uncompiled pattern. */ +#define GET_UNSIGNED_NUMBER(num) \ + { if (p != pend) \ + { \ + PATFETCH(c); \ + while (isdigit(c)) \ + { \ + if (num < 0) \ + num = 0; \ + num = num * 10 + c - '0'; \ + if (p == pend) \ + break; \ + PATFETCH(c); \ + } \ + } \ + } + + +#define STORE_MBC(p, c) \ + ((p)[0] = (unsigned char)(c >> 8), (p)[1] = (unsigned char)(c)) +#define STORE_MBC_AND_INCR(p, c) \ + (*(p)++ = (unsigned char)(c >> 8), *(p)++ = (unsigned char)(c)) + +#define EXTRACT_MBC(p) \ + ((unsigned short)((unsigned char)(p)[0] << 8 | (unsigned char)(p)[1])) +#define EXTRACT_MBC_AND_INCR(p) \ + ((unsigned short)((p) += 2, (unsigned char)(p)[-2] << 8 | (unsigned char)(p)[-1])) + +#define EXTRACT_UNSIGNED(p) \ + ((unsigned char)(p)[0] | (unsigned char)(p)[1] << 8) +#define EXTRACT_UNSIGNED_AND_INCR(p) \ + ((p) += 2, (unsigned char)(p)[-2] | (unsigned char)(p)[-1] << 8) + +/* Handle (mb)?charset(_not)?. + + Structure of mbcharset(_not)? in compiled pattern. + + struct { + unsinged char id; mbcharset(_not)? + unsigned char sbc_size; + unsigned char sbc_map[sbc_size]; same as charset(_not)? up to here. + unsigned short mbc_size; number of intervals. + struct { + unsigned short beg; beginning of interval. + unsigned short end; end of interval. + } intervals[mbc_size]; + }; */ + +static void +set_list_bits(c1, c2, b) + unsigned short c1, c2; + unsigned char *b; +{ + unsigned char sbc_size = b[-1]; + unsigned short mbc_size = EXTRACT_UNSIGNED(&b[sbc_size]); + unsigned short beg, end, upb; + + if (c1 > c2) + return; + if ((int)c1 < 1 << BYTEWIDTH) { + upb = c2; + if (1 << BYTEWIDTH <= (int)upb) + upb = (1 << BYTEWIDTH) - 1; /* The last single-byte char */ + if (sbc_size <= (unsigned short)(upb / BYTEWIDTH)) { + /* Allocate maximum size so it never happens again. */ + /* NOTE: memcpy() would not work here. */ + memmove(&b[(1 << BYTEWIDTH) / BYTEWIDTH], &b[sbc_size], 2 + mbc_size*4); + memset(&b[sbc_size], 0, (1 << BYTEWIDTH) / BYTEWIDTH - sbc_size); + b[-1] = sbc_size = (1 << BYTEWIDTH) / BYTEWIDTH; + } + for (; c1 <= upb; c1++) + if (!ismbchar(c1)) + SET_LIST_BIT(c1); + if ((int)c2 < 1 << BYTEWIDTH) + return; + c1 = 0x8000; /* The first wide char */ + } + b = &b[sbc_size + 2]; + + for (beg = 0, upb = mbc_size; beg < upb; ) { + unsigned short mid = (unsigned short)(beg + upb) >> 1; + + if ((int)c1 - 1 > (int)EXTRACT_MBC(&b[mid*4 + 2])) + beg = mid + 1; + else + upb = mid; + } + + for (end = beg, upb = mbc_size; end < upb; ) { + unsigned short mid = (unsigned short)(end + upb) >> 1; + + if ((int)c2 >= (int)EXTRACT_MBC(&b[mid*4]) - 1) + end = mid + 1; + else + upb = mid; + } + + if (beg != end) { + if (c1 > EXTRACT_MBC(&b[beg*4])) + c1 = EXTRACT_MBC(&b[beg*4]); + if (c2 < EXTRACT_MBC(&b[(end - 1)*4])) + c2 = EXTRACT_MBC(&b[(end - 1)*4]); + } + if (end < mbc_size && end != beg + 1) + /* NOTE: memcpy() would not work here. */ + memmove(&b[(beg + 1)*4], &b[end*4], (mbc_size - end)*4); + STORE_MBC(&b[beg*4 + 0], c1); + STORE_MBC(&b[beg*4 + 2], c2); + mbc_size += beg - end + 1; + STORE_NUMBER(&b[-2], mbc_size); +} + +static int +is_in_list(c, b) + unsigned short c; + const unsigned char *b; +{ + unsigned short size; + unsigned short i, j; + int result = 0; + + size = *b++; + if ((int)c < 1<= 1<>BYTEWIDTH; + } + while (size>0 && b[size*4-2] == 0xff) { + size--; + if (b[size*4+1] <= i && i <= b[size*4+3]) { + result = 2; + break; + } + } + } + for (i = 0, j = size; i < j; ) { + unsigned short k = (unsigned short)(i + j) >> 1; + + if (c > EXTRACT_MBC(&b[k*4+2])) + i = k + 1; + else + j = k; + } + if (i < size && EXTRACT_MBC(&b[i*4]) <= c + && ((unsigned char)c != '\n' && (unsigned char)c != '\0')) + return 1; + return result; +} + +static void +print_partial_compiled_pattern(start, end) + unsigned char *start; + unsigned char *end; +{ + int mcnt, mcnt2; + unsigned char *p = start; + unsigned char *pend = end; + + if (start == NULL) + { + printf ("(null)\n"); + return; + } + + /* Loop over pattern commands. */ + while (p < pend) + { + switch ((enum regexpcode) *p++) + { + case unused: + printf ("/unused"); + break; + + case exactn: + mcnt = *p++; + printf ("/exactn/%d", mcnt); + do + { + putchar('/'); + printf("%c", *p++); + } + while (--mcnt); + break; + + case start_memory: + mcnt = *p++; + printf ("/start_memory/%d", mcnt); + break; + + case stop_memory: + mcnt = *p++; + printf ("/stop_memory/%d", mcnt); + break; + + case start_nowidth: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf ("/start_nowidth//%d", mcnt); + break; + + case stop_nowidth: + printf ("/stop_nowidth//"); + p += 2; + break; + + case pop_and_fail: + printf ("/pop_and_fail"); + break; + + case duplicate: + printf ("/duplicate/%d", *p++); + break; + + case anychar: + printf ("/anychar"); + break; + + case charset: + case charset_not: + { + register int c; + + printf ("/charset%s", + (enum regexpcode) *(p - 1) == charset_not ? "_not" : ""); + + mcnt = *p; + printf("/%d", mcnt); + for (c = 0; c < mcnt; c++) + { + unsigned bit; + unsigned char map_byte = p[1 + c]; + + putchar ('/'); + + for (bit = 0; bit < BYTEWIDTH; bit++) + if (map_byte & (1 << bit)) + printf("%c", c * BYTEWIDTH + bit); + } + p += mcnt + 1; + mcnt = EXTRACT_UNSIGNED(p); + p += 2; + while (mcnt--) { + int beg = *p++; + int end = *p++; + printf("/%c%c-%c%c", beg>>BYTEWIDTH, beg&0xff, end>>BYTEWIDTH, end&0xff); + } + break; + } + + case begline: + printf ("/begline"); + break; + + case endline: + printf ("/endline"); + break; + + case on_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf ("/on_failure_jump//%d", mcnt); + break; + + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf ("/dummy_failure_jump//%d", mcnt); + break; + + case finalize_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf ("/finalize_jump//%d", mcnt); + break; + + case maybe_finalize_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf ("/maybe_finalize_jump//%d", mcnt); + break; + + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf ("/jump//%d", mcnt); + break; + + case succeed_n: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + EXTRACT_NUMBER_AND_INCR (mcnt2, p); + printf ("/succeed_n//%d//%d", mcnt, mcnt2); + break; + + case jump_n: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + EXTRACT_NUMBER_AND_INCR (mcnt2, p); + printf ("/jump_n//%d//%d", mcnt, mcnt2); + break; + + case set_number_at: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + EXTRACT_NUMBER_AND_INCR (mcnt2, p); + printf ("/set_number_at//%d//%d", mcnt, mcnt2); + break; + + case try_next: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf ("/try_next//%d", mcnt); + break; + + case finalize_push: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf ("/finalize_push//%d", mcnt); + break; + + case finalize_push_n: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + EXTRACT_NUMBER_AND_INCR (mcnt2, p); + printf ("/finalize_push_n//%d//%d", mcnt, mcnt2); + break; + + case wordbound: + printf ("/wordbound"); + break; + + case notwordbound: + printf ("/notwordbound"); + break; + + case wordbeg: + printf ("/wordbeg"); + break; + + case wordend: + printf ("/wordend"); + + case wordchar: + printf ("/wordchar"); + break; + + case notwordchar: + printf ("/notwordchar"); + break; + + case begbuf: + printf ("/begbuf"); + break; + + case endbuf: + printf ("/endbuf"); + break; + + default: + printf ("?%d", *(p-1)); + } + } + printf ("/\n"); +} + + +static void +print_compiled_pattern(bufp) + struct re_pattern_buffer *bufp; +{ + unsigned char *buffer = bufp->buffer; + + print_partial_compiled_pattern (buffer, buffer + bufp->used); +} + +static char* +calculate_must_string(start, end) + unsigned char *start; + unsigned char *end; +{ + int mcnt, mcnt2; + int max = 0; + unsigned char *p = start; + unsigned char *pend = end; + unsigned char *must = 0; + + if (start == NULL) return 0; + + /* Loop over pattern commands. */ + while (p < pend) + { + switch ((enum regexpcode) *p++) + { + case unused: + break; + + case exactn: + mcnt = *p; + if (mcnt > max) { + must = p; + } + p += mcnt+1; + break; + + case start_memory: + case stop_memory: + case duplicate: + p++; + break; + + case start_nowidth: + case stop_nowidth: + case pop_and_fail: + case anychar: + case begline: + case endline: + case wordbound: + case notwordbound: + case wordbeg: + case wordend: + case wordchar: + case notwordchar: + case begbuf: + case endbuf: + break; + + case charset: + case charset_not: + mcnt = *p++; + p += mcnt; + EXTRACT_NUMBER_AND_INCR (mcnt, p); + while (mcnt--) { + EXTRACT_NUMBER_AND_INCR (mcnt2, p); + EXTRACT_NUMBER_AND_INCR (mcnt2, p); + } + break; + + case on_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + if (mcnt > 0) p += mcnt; + if ((enum regexpcode)p[-3] == jump) { + p -= 3; + EXTRACT_NUMBER_AND_INCR (mcnt, p); + if (mcnt > 0) p += mcnt; + } + break; + + case dummy_failure_jump: + case succeed_n: + case try_next: + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + if (mcnt > 0) p += mcnt; + break; + + case finalize_jump: + case maybe_finalize_jump: + case finalize_push: + p += 2; + break; + + case jump_n: + case set_number_at: + case finalize_push_n: + p += 4; + break; + + default: + break; + } + } + return must; +} + + +/* re_compile_pattern takes a regular-expression string + and converts it into a buffer full of byte commands for matching. + + PATTERN is the address of the pattern string + SIZE is the length of it. + BUFP is a struct re_pattern_buffer * which points to the info + on where to store the byte commands. + This structure contains a char * which points to the + actual space, which should have been obtained with malloc. + re_compile_pattern may use realloc to grow the buffer space. + + The number of bytes of commands can be found out by looking in + the `struct re_pattern_buffer' that bufp pointed to, after + re_compile_pattern returns. */ + +char * +re_compile_pattern(pattern, size, bufp) + char *pattern; + size_t size; + struct re_pattern_buffer *bufp; +{ + register char *b = bufp->buffer; + register char *p = pattern; + char *pend = pattern + size; + register unsigned c, c1; + char *p0; + int numlen; + + /* Address of the count-byte of the most recently inserted `exactn' + command. This makes it possible to tell whether a new exact-match + character can be added to that command or requires a new `exactn' + command. */ + + char *pending_exact = 0; + + /* Address of the place where a forward-jump should go to the end of + the containing expression. Each alternative of an `or', except the + last, ends with a forward-jump of this sort. */ + + char *fixup_jump = 0; + + /* Address of start of the most recently finished expression. + This tells postfix * where to find the start of its operand. */ + + char *laststart = 0; + + /* In processing a repeat, 1 means zero matches is allowed. */ + + char zero_times_ok; + + /* In processing a repeat, 1 means many matches is allowed. */ + + char many_times_ok; + + /* In processing a repeat, 1 means non-greedy matches. */ + + char greedy; + + /* Address of beginning of regexp, or inside of last \(. */ + + char *begalt = b; + + /* In processing an interval, at least this many matches must be made. */ + int lower_bound; + + /* In processing an interval, at most this many matches can be made. */ + int upper_bound; + + /* Stack of information saved by \( and restored by \). + Five stack elements are pushed by each \(: + First, the value of b. + Second, the value of fixup_jump. + Third, the value of begalt. + Fourth, the value of regnum. + Fifth, the type of the paren. */ + + int *stackb = RE_TALLOC(40, int); + int *stackp = stackb; + int *stacke = stackb + 40; + int *stackt; + + /* Counts \('s as they are encountered. Remembered for the matching \), + where it becomes the register number to put in the stop_memory + command. */ + + int regnum = 1; + int range = 0; + + /* How to translate the characters in the pattern. */ + char *translate = bufp->translate; + + bufp->fastmap_accurate = 0; + + /* Initialize the syntax table. */ + init_syntax_once(); + + if (bufp->allocated == 0) + { + bufp->allocated = INIT_BUF_SIZE; + if (bufp->buffer) + /* EXTEND_BUFFER loses when bufp->allocated is 0. */ + bufp->buffer = (char *) xrealloc (bufp->buffer, INIT_BUF_SIZE); + else + /* Caller did not allocate a buffer. Do it for them. */ + bufp->buffer = (char *) xmalloc(INIT_BUF_SIZE); + if (!bufp->buffer) goto memory_exhausted; + begalt = b = bufp->buffer; + } + + while (p != pend) + { + PATFETCH(c); + + switch (c) + { + case '$': + { + char *p1 = p; + /* When testing what follows the $, + look past the \-constructs that don't consume anything. */ + if (! (re_syntax_options & RE_CONTEXT_INDEP_OPS)) + while (p1 != pend) + { + if (*p1 == '\\' && p1 + 1 != pend + && (p1[1] == 'b' || p1[1] == 'B')) + p1 += 2; + else + break; + } + if (re_syntax_options & RE_TIGHT_VBAR) + { + if (! (re_syntax_options & RE_CONTEXT_INDEP_OPS) && p1 != pend) + goto normal_char; + /* Make operand of last vbar end before this `$'. */ + if (fixup_jump) + store_jump(fixup_jump, jump, b); + fixup_jump = 0; + BUFPUSH(endline); + break; + } + /* $ means succeed if at end of line, but only in special contexts. + If validly in the middle of a pattern, it is a normal character. */ + + if (p1 == pend || *p1 == '\n' + || (re_syntax_options & RE_CONTEXT_INDEP_OPS) + || (re_syntax_options & RE_NO_BK_PARENS + ? *p1 == ')' + : *p1 == '\\' && p1[1] == ')') + || (re_syntax_options & RE_NO_BK_VBAR + ? *p1 == '|' + : *p1 == '\\' && p1[1] == '|')) + { + BUFPUSH(endline); + break; + } + goto normal_char; + } + case '^': + /* ^ means succeed if at beg of line, but only if no preceding + pattern. */ + + if ((re_syntax_options & RE_CONTEXTUAL_INVALID_OPS) && laststart) + goto invalid_pattern; + if (laststart && p - 2 >= pattern && p[-2] != '\n' + && !(re_syntax_options & RE_CONTEXT_INDEP_OPS)) + goto normal_char; + if (re_syntax_options & RE_TIGHT_VBAR) + { + if (p != pattern + 1 + && ! (re_syntax_options & RE_CONTEXT_INDEP_OPS)) + goto normal_char; + BUFPUSH(begline); + begalt = b; + } + else + { + BUFPUSH(begline); + } + break; + + case '+': + case '?': + if (re_syntax_options & RE_LIMITED_OPS) + goto normal_char; + case '*': + /* If there is no previous pattern, char not special. */ + if (!laststart) { + if (re_syntax_options & RE_CONTEXTUAL_INVALID_OPS) + goto invalid_pattern; + else if (! (re_syntax_options & RE_CONTEXT_INDEP_OPS)) + goto normal_char; + } + /* If there is a sequence of repetition chars, + collapse it down to just one. */ + zero_times_ok = c != '+'; + many_times_ok = c != '?'; + greedy = 1; + if (p != pend) { + PATFETCH(c); + switch (c) { + case '?': + greedy = 0; + break; + case '*': + case '+': + goto nested_meta; + default: + PATUNFETCH; + break; + } + } + + repeat: + /* Star, etc. applied to an empty pattern is equivalent + to an empty pattern. */ + if (!laststart) + break; + + /* Now we know whether or not zero matches is allowed + and also whether or not two or more matches is allowed. */ + if (many_times_ok) { + /* If more than one repetition is allowed, put in at the + end a backward relative jump from b to before the next + jump we're going to put in below (which jumps from + laststart to after this jump). */ + GET_BUFFER_SPACE(3); + store_jump(b,greedy?maybe_finalize_jump:finalize_push,laststart-3); + b += 3; /* Because store_jump put stuff here. */ + } + + /* On failure, jump from laststart to next pattern, which will be the + end of the buffer after this jump is inserted. */ + GET_BUFFER_SPACE(3); + insert_jump(on_failure_jump, laststart, b + 3, b); + b += 3; + + if (zero_times_ok) { + if (greedy == 0) { + GET_BUFFER_SPACE(3); + insert_jump(try_next, laststart, b + 3, b); + b += 3; + } + } + else { + /* At least one repetition is required, so insert a + `dummy_failure_jump' before the initial + `on_failure_jump' instruction of the loop. This + effects a skip over that instruction the first time + we hit that loop. */ + GET_BUFFER_SPACE(3); + insert_jump(dummy_failure_jump, laststart, laststart + 6, b); + b += 3; + } + break; + + case '.': + laststart = b; + BUFPUSH(anychar); + break; + + case '[': + if (p == pend) + goto invalid_pattern; + while (b - bufp->buffer + > bufp->allocated - 9 - (1 << BYTEWIDTH) / BYTEWIDTH) + EXTEND_BUFFER; + + laststart = b; + if (*p == '^') + { + BUFPUSH(charset_not); + p++; + } + else + BUFPUSH(charset); + p0 = p; + + BUFPUSH((1 << BYTEWIDTH) / BYTEWIDTH); + /* Clear the whole map */ + memset(b, 0, (1 << BYTEWIDTH) / BYTEWIDTH + 2); + + if ((re_syntax_options & RE_HAT_NOT_NEWLINE) && b[-2] == charset_not) + SET_LIST_BIT('\n'); + + + /* Read in characters and ranges, setting map bits. */ + for (;;) + { + int size; + unsigned last = (unsigned)-1; + + if ((size = EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH]))) { + /* Ensure the space is enough to hold another interval + of multi-byte chars in charset(_not)?. */ + size = (1 << BYTEWIDTH) / BYTEWIDTH + 2 + size*4 + 4; + while (b + size + 1 > bufp->buffer + bufp->allocated) + EXTEND_BUFFER; + } + range_retry: + PATFETCH(c); + + if (c == ']') { + if (p == p0 + 1) { + /* If this is an empty bracket expression. */ + if ((re_syntax_options & RE_NO_EMPTY_BRACKETS) + && p == pend) + goto invalid_pattern; + } + else + /* Stop if this isn't merely a ] inside a bracket + expression, but rather the end of a bracket + expression. */ + break; + } + if (ismbchar(c)) { + PATFETCH(c1); + c = c << BYTEWIDTH | c1; + } + + /* \ escapes characters when inside [...]. */ + if (c == '\\') { + PATFETCH(c); + switch (c) { + case 'w': + for (c = 0; c < (1 << BYTEWIDTH); c++) + if (SYNTAX(c) == Sword) + SET_LIST_BIT(c); + last = -1; + continue; + + case 'W': + for (c = 0; c < (1 << BYTEWIDTH); c++) + if (SYNTAX(c) != Sword) + SET_LIST_BIT(c); + if (re_syntax_options & RE_MBCTYPE_MASK) { + set_list_bits(0x8000, 0xffff, (unsigned char*)b); + } + last = -1; + continue; + + case 's': + for (c = 0; c < 256; c++) + if (isspace(c)) + SET_LIST_BIT(c); + last = -1; + continue; + + case 'S': + for (c = 0; c < 256; c++) + if (!isspace(c)) + SET_LIST_BIT(c); + if (re_syntax_options & RE_MBCTYPE_MASK) { + set_list_bits(0x8000, 0xffff, (unsigned char*)b); + } + last = -1; + continue; + + case 'd': + for (c = '0'; c <= '9'; c++) + SET_LIST_BIT(c); + last = -1; + continue; + + case 'D': + for (c = 0; c < 256; c++) + if (!isdigit(c)) + SET_LIST_BIT(c); + if (re_syntax_options & RE_MBCTYPE_MASK) { + set_list_bits(0x8000, 0xffff, (unsigned char*)b); + } + last = -1; + continue; + + case 'x': + c = scan_hex(p, 2, &numlen); + if ((re_syntax_options & RE_MBCTYPE_MASK) && c > 0x7f) + c = 0xff00 | c; + p += numlen; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + PATUNFETCH; + c = scan_oct(p, 3, &numlen); + if ((re_syntax_options & RE_MBCTYPE_MASK) && ismbchar(c)) + c = 0xff00 | c; + p += numlen; + break; + + default: + if (ismbchar(c)) { + PATFETCH(c1); + c = c << 8 | c1; + } + break; + } + } + + /* Get a range. */ + if (range) { + if (last > c) + goto invalid_pattern; + + if ((re_syntax_options & RE_NO_HYPHEN_RANGE_END) + && c == '-' && *p != ']') + goto invalid_pattern; + + range = 0; + if (last < 1 << BYTEWIDTH && c < 1 << BYTEWIDTH) { + for (;last<=c;last++) + SET_LIST_BIT(last); + } + else { + set_list_bits(last, c, (unsigned char*)b); + } + } + else if (p[0] == '-' && p[1] != ']') { + last = c; + PATFETCH(c1); + range = 1; + goto range_retry; + } + else if (c < 1 << BYTEWIDTH) + SET_LIST_BIT(c); + else + set_list_bits(c, c, (unsigned char*)b); + } + + /* Discard any character set/class bitmap bytes that are all + 0 at the end of the map. Decrement the map-length byte too. */ + while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) + b[-1]--; + if (b[-1] != (1 << BYTEWIDTH) / BYTEWIDTH) + memmove(&b[b[-1]], &b[(1 << BYTEWIDTH) / BYTEWIDTH], + 2 + EXTRACT_UNSIGNED (&b[(1 << BYTEWIDTH) / BYTEWIDTH])*4); + b += b[-1] + 2 + EXTRACT_UNSIGNED (&b[b[-1]])*4; + break; + + case '(': + PATFETCH(c); + if (c == '?') { + PATFETCH(c); + switch (c) { + case '#': + case 'i': + case 'm': + case 's': + case 'x': + for (;;) { + PATFETCH(c); + if (c == ')') break; + } + c = '#'; + break; + + case ':': + case '=': + case '!': + break; + + default: + FREE_AND_RETURN(stackb, "undefined (?...) sequence"); + } + } + else { + PATUNFETCH; + c = '('; + } + if (c == '#') break; + if (stackp+6 >= stacke) { + int *stackx; + unsigned int len = stacke - stackb; + + stackx = DOUBLE_STACK(stackx,stackb,len,int); + /* Rearrange the pointers. */ + stackp = stackx + (stackp - stackb); + stackb = stackx; + stacke = stackb + 2 * len; + } + + /* Laststart should point to the start_memory that we are about + to push (unless the pattern has RE_NREGS or more ('s). */ + /* obsolete: now RE_NREGS is just a default register size. */ + *stackp++ = b - bufp->buffer; + *stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0; + *stackp++ = begalt - bufp->buffer; + switch (c) { + case '(': + BUFPUSH(start_memory); + BUFPUSH(regnum); + *stackp++ = regnum++; + /* too many ()'s to fit in a byte. (max 254) */ + if (regnum >= RE_REG_MAX) goto too_big; + break; + + case '=': + case '!': + BUFPUSH(start_nowidth); + *stackp++ = b - bufp->buffer; + BUFPUSH(0); /* temporary value */ + BUFPUSH(0); + if (c == '=') break; + + BUFPUSH(on_failure_jump); + *stackp++ = b - bufp->buffer; + BUFPUSH(0); /* temporary value */ + BUFPUSH(0); + break; + + case ':': + default: + break; + } + *stackp++ = c; + fixup_jump = 0; + laststart = 0; + begalt = b; + break; + + case ')': + if (stackp == stackb) goto unmatched_close; + switch (c = *--stackp) { + case '(': + if (fixup_jump) + store_jump(fixup_jump, jump, b); + BUFPUSH(stop_memory); + BUFPUSH(stackp[-1]); + stackp--; + break; + + case '!': + BUFPUSH(pop_and_fail); + /* back patch */ + STORE_NUMBER(bufp->buffer+stackp[-1], b - bufp->buffer - stackp[-1] - 2); + stackp--; + /* fall through */ + case '=': + BUFPUSH(stop_nowidth); + /* tell stack-pos place to start_nowidth */ + STORE_NUMBER(bufp->buffer+stackp[-1], b - bufp->buffer - stackp[-1] - 2); + BUFPUSH(0); /* space to hold stack pos */ + BUFPUSH(0); + stackp--; + break; + + case ':': + default: + break; + } + begalt = *--stackp + bufp->buffer; + stackp--; + fixup_jump = *stackp ? *stackp + bufp->buffer - 1 : 0; + laststart = *--stackp + bufp->buffer; + if (c == '!' || c == '=') laststart = b; + break; + + case '|': + /* Insert before the previous alternative a jump which + jumps to this alternative if the former fails. */ + GET_BUFFER_SPACE(6); + insert_jump(on_failure_jump, begalt, b + 6, b); + pending_exact = 0; + b += 3; + /* The alternative before the previous alternative has a + jump after it which gets executed if it gets matched. + Adjust that jump so it will jump to the previous + alternative's analogous jump (put in below, which in + turn will jump to the next (if any) alternative's such + jump, etc.). The last such jump jumps to the correct + final destination. */ + if (fixup_jump) + store_jump(fixup_jump, jump, b); + + /* Leave space for a jump after previous alternative---to be + filled in later. */ + fixup_jump = b; + b += 3; + + laststart = 0; + begalt = b; + break; + + case '{': + /* If there is no previous pattern, this isn't an interval. */ + if (!laststart) + { + if (re_syntax_options & RE_CONTEXTUAL_INVALID_OPS) + goto invalid_pattern; + else + goto normal_backsl; + } + /* It also isn't an interval if not preceded by an re + matching a single character or subexpression, or if + the current type of intervals can't handle back + references and the previous thing is a back reference. */ + if (! (*laststart == anychar + || *laststart == charset + || *laststart == charset_not + || *laststart == wordchar + || *laststart == notwordchar + || *laststart == start_memory + || (*laststart == exactn + && (laststart[1] == 1 + || laststart[1] == 2 && ismbchar(laststart[2]))) + || (! (re_syntax_options & RE_NO_BK_REFS) + && *laststart == duplicate))) + { + /* Posix extended syntax is handled in previous + statement; this is for Posix basic syntax. */ + if (re_syntax_options & RE_INTERVALS) + goto invalid_pattern; + + goto normal_backsl; + } + lower_bound = -1; /* So can see if are set. */ + upper_bound = -1; + GET_UNSIGNED_NUMBER(lower_bound); + if (c == ',') { + GET_UNSIGNED_NUMBER(upper_bound); + if (upper_bound < 0) + upper_bound = RE_DUP_MAX; + } + if (upper_bound < 0) + upper_bound = lower_bound; + if (c != '}' || lower_bound < 0 || upper_bound > RE_DUP_MAX + || lower_bound > upper_bound + || (p != pend && *p == '{')) { + goto invalid_pattern; + } + greedy = 1; + if (p != pend) { + PATFETCH(c); + if (c == '?') greedy = 0; + else PATUNFETCH; + } + + /* If upper_bound is zero, don't want to succeed at all; + jump from laststart to b + 3, which will be the end of + the buffer after this jump is inserted. */ + + if (upper_bound == 0) { + GET_BUFFER_SPACE(3); + insert_jump(jump, laststart, b + 3, b); + b += 3; + break; + } + + if (lower_bound == 0) { + zero_times_ok = 1; + if (upper_bound == RE_DUP_MAX) { + many_times_ok = 1; + goto repeat; + } + if (upper_bound == 1) { + many_times_ok = 0; + goto repeat; + } + } + if (lower_bound == 1 && upper_bound == RE_DUP_MAX) { + many_times_ok = 1; + zero_times_ok = 0; + goto repeat; + } + + /* Star, etc. applied to an empty pattern is equivalent + to an empty pattern. */ + if (!laststart) + break; + + { /* If the upper bound is > 1, we need to insert + more at the end of the loop. */ + unsigned slots_needed = upper_bound == 1 ? 5 : 10; + + GET_BUFFER_SPACE(5); + /* Initialize lower bound of the `succeed_n', even + though it will be set during matching by its + attendant `set_number_at' (inserted next), + because `re_compile_fastmap' needs to know. + Jump to the `jump_n' we might insert below. */ + insert_jump_n(succeed_n, laststart, b + slots_needed, + b, lower_bound); + b += 5; /* Just increment for the succeed_n here. */ + + /* Code to initialize the lower bound. Insert + before the `succeed_n'. The `5' is the last two + bytes of this `set_number_at', plus 3 bytes of + the following `succeed_n'. */ + GET_BUFFER_SPACE(5); + insert_op_2(set_number_at, laststart, b, 5, lower_bound); + b += 5; + + if (upper_bound > 1) + { /* More than one repetition is allowed, so + append a backward jump to the `succeed_n' + that starts this interval. + + When we've reached this during matching, + we'll have matched the interval once, so + jump back only `upper_bound - 1' times. */ + GET_BUFFER_SPACE(5); + store_jump_n(b, greedy?jump_n:finalize_push_n, laststart + 5, upper_bound - 1); + b += 5; + + /* The location we want to set is the second + parameter of the `jump_n'; that is `b-2' as + an absolute address. `laststart' will be + the `set_number_at' we're about to insert; + `laststart+3' the number to set, the source + for the relative address. But we are + inserting into the middle of the pattern -- + so everything is getting moved up by 5. + Conclusion: (b - 2) - (laststart + 3) + 5, + i.e., b - laststart. + + We insert this at the beginning of the loop + so that if we fail during matching, we'll + reinitialize the bounds. */ + GET_BUFFER_SPACE(5); + insert_op_2(set_number_at, laststart, b, b - laststart, upper_bound - 1); + b += 5; + + GET_BUFFER_SPACE(5); + BUFPUSH(set_number_at); + STORE_NUMBER_AND_INCR(b, -5); + STORE_NUMBER_AND_INCR(b, upper_bound - 1); + } + pending_exact = 0; + } + break; + + case '\\': + if (p == pend) goto invalid_pattern; + /* Do not translate the character after the \, so that we can + distinguish, e.g., \B from \b, even if we normally would + translate, e.g., B to b. */ + PATFETCH_RAW(c); + switch (c) + { + case 's': + case 'S': + case 'd': + case 'D': + while (b - bufp->buffer + > bufp->allocated - 9 - (1 << BYTEWIDTH) / BYTEWIDTH) + EXTEND_BUFFER; + + laststart = b; + if (c == 's' || c == 'd') { + BUFPUSH(charset); + } + else { + BUFPUSH(charset_not); + } + + BUFPUSH((1 << BYTEWIDTH) / BYTEWIDTH); + memset(b, 0, (1 << BYTEWIDTH) / BYTEWIDTH + 2); + if (c == 's' || c == 'S') { + SET_LIST_BIT(' '); + SET_LIST_BIT('\t'); + SET_LIST_BIT('\n'); + SET_LIST_BIT('\r'); + SET_LIST_BIT('\f'); + } + else { + char cc; + + for (cc = '0'; cc <= '9'; cc++) { + SET_LIST_BIT(cc); + } + } + + while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) + b[-1]--; + if (b[-1] != (1 << BYTEWIDTH) / BYTEWIDTH) + memmove(&b[b[-1]], &b[(1 << BYTEWIDTH) / BYTEWIDTH], + 2 + EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH])*4); + b += b[-1] + 2 + EXTRACT_UNSIGNED(&b[b[-1]])*4; + break; + + case 'w': + laststart = b; + BUFPUSH(wordchar); + break; + + case 'W': + laststart = b; + BUFPUSH(notwordchar); + break; + + case '<': + BUFPUSH(wordbeg); + break; + + case '>': + BUFPUSH(wordend); + break; + + case 'b': + BUFPUSH(wordbound); + break; + + case 'B': + BUFPUSH(notwordbound); + break; + + case 'A': + BUFPUSH(begbuf); + break; + + case 'Z': + BUFPUSH(endbuf); + break; + + /* hex */ + case 'x': + c1 = 0; + c = scan_hex(p, 2, &numlen); + p += numlen; + if ((re_syntax_options & RE_MBCTYPE_MASK) && c > 0x7f) + c1 = 0xff; + goto numeric_char; + + /* octal */ + case '0': + c1 = 0; + c = scan_oct(p, 3, &numlen); + p += numlen; + if ((re_syntax_options & RE_MBCTYPE_MASK) && c > 0x7f) + c1 = 0xff; + goto numeric_char; + + /* back-ref or octal */ + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + { + char *p_save; + + PATUNFETCH; + p_save = p; + + c1 = 0; + GET_UNSIGNED_NUMBER(c1); + if (p < pend) PATUNFETCH; + + if (c1 >= regnum) { + /* need to get octal */ + p = p_save; + c = scan_oct(p_save, 3, &numlen); + p = p_save + numlen; + c1 = 0; + if ((re_syntax_options & RE_MBCTYPE_MASK) && c > 0x7f) + c1 = 0xff; + goto numeric_char; + } + } + + /* Can't back reference to a subexpression if inside of it. */ + for (stackt = stackp - 2; stackt > stackb; stackt -= 5) + if (*stackt == c1) + goto normal_char; + laststart = b; + BUFPUSH(duplicate); + BUFPUSH(c1); + break; + + default: + normal_backsl: + goto normal_char; + } + break; + + default: + normal_char: /* Expects the character in `c'. */ + c1 = 0; + if (ismbchar(c)) { + c1 = c; + PATFETCH(c); + } + else if (c > 0x7f) { + c1 = 0xff; + } + numeric_char: + if (!pending_exact || pending_exact + *pending_exact + 1 != b + || *pending_exact >= (c1 ? 0176 : 0177) + || *p == '+' || *p == '?' + || *p == '*' || *p == '^' + || *p == '{') + { + laststart = b; + BUFPUSH(exactn); + pending_exact = b; + BUFPUSH(0); + } + if (c1) { + BUFPUSH(c1); + (*pending_exact)++; + } + BUFPUSH(c); + (*pending_exact)++; + } + } + + if (fixup_jump) + store_jump(fixup_jump, jump, b); + + if (stackp != stackb) goto unmatched_open; + + bufp->used = b - bufp->buffer; + bufp->re_nsub = regnum; + bufp->must = calculate_must_string(bufp->buffer, b); + FREE_AND_RETURN(stackb, 0); + + invalid_char: + FREE_AND_RETURN(stackb, "invalid character in regular expression"); + + invalid_pattern: + FREE_AND_RETURN(stackb, "invalid regular expression"); + + unmatched_open: + FREE_AND_RETURN(stackb, "unmatched ("); + + unmatched_close: + FREE_AND_RETURN(stackb, "unmatched )"); + + end_of_pattern: + FREE_AND_RETURN(stackb, "premature end of regular expression"); + + too_big: + FREE_AND_RETURN(stackb, "regular expression too big"); + + memory_exhausted: + FREE_AND_RETURN(stackb, "memory exhausted"); + + nested_meta: + FREE_AND_RETURN(stackb, "nested *?+ in regexp"); +} + + +/* Store a jump of the form . + Store in the location FROM a jump operation to jump to relative + address FROM - TO. OPCODE is the opcode to store. */ + +static void +store_jump(from, opcode, to) + char *from, *to; + int opcode; +{ + from[0] = (char)opcode; + STORE_NUMBER(from + 1, to - (from + 3)); +} + + +/* Open up space before char FROM, and insert there a jump to TO. + CURRENT_END gives the end of the storage not in use, so we know + how much data to copy up. OP is the opcode of the jump to insert. + + If you call this function, you must zero out pending_exact. */ + +static void +insert_jump(op, from, to, current_end) + int op; + char *from, *to, *current_end; +{ + register char *pfrom = current_end; /* Copy from here... */ + register char *pto = current_end + 3; /* ...to here. */ + + while (pfrom != from) + *--pto = *--pfrom; + store_jump(from, op, to); +} + + +/* Store a jump of the form . + + Store in the location FROM a jump operation to jump to relative + address FROM - TO. OPCODE is the opcode to store, N is a number the + jump uses, say, to decide how many times to jump. + + If you call this function, you must zero out pending_exact. */ + +static void +store_jump_n(from, opcode, to, n) + char *from, *to; + int opcode; + unsigned n; +{ + from[0] = (char)opcode; + STORE_NUMBER(from + 1, to - (from + 3)); + STORE_NUMBER(from + 3, n); +} + + +/* Similar to insert_jump, but handles a jump which needs an extra + number to handle minimum and maximum cases. Open up space at + location FROM, and insert there a jump to TO. CURRENT_END gives the + end of the storage in use, so we know how much data to copy up. OP is + the opcode of the jump to insert. + + If you call this function, you must zero out pending_exact. */ + +static void +insert_jump_n(op, from, to, current_end, n) + int op; + char *from, *to, *current_end; + unsigned n; +{ + register char *pfrom = current_end; /* Copy from here... */ + register char *pto = current_end + 5; /* ...to here. */ + + while (pfrom != from) + *--pto = *--pfrom; + store_jump_n(from, op, to, n); +} + + +/* Open up space at location THERE, and insert operation OP. + CURRENT_END gives the end of the storage in use, so + we know how much data to copy up. + + If you call this function, you must zero out pending_exact. */ + +static void +insert_op(op, there, current_end) + int op; + char *there, *current_end; +{ + register char *pfrom = current_end; /* Copy from here... */ + register char *pto = current_end + 1; /* ...to here. */ + + while (pfrom != there) + *--pto = *--pfrom; + + there[0] = (char)op; +} + + +/* Open up space at location THERE, and insert operation OP followed by + NUM_1 and NUM_2. CURRENT_END gives the end of the storage in use, so + we know how much data to copy up. + + If you call this function, you must zero out pending_exact. */ + +static void +insert_op_2(op, there, current_end, num_1, num_2) + int op; + char *there, *current_end; + int num_1, num_2; +{ + register char *pfrom = current_end; /* Copy from here... */ + register char *pto = current_end + 5; /* ...to here. */ + + while (pfrom != there) + *--pto = *--pfrom; + + there[0] = (char)op; + STORE_NUMBER(there + 1, num_1); + STORE_NUMBER(there + 3, num_2); +} + + +#define trans_eq(c1, c2, translate) (translate?(translate[c1]==translate[c2]):((c1)==(c2))) +static int +must_match(little, lend, big, bend, translate) + unsigned char *little, *lend; + unsigned char *big, *bend; + unsigned char *translate; +{ + int c; + + while (little < lend && big < bend) { + c = *little++; + if (c == 0xff) { + if (!trans_eq(*big++, *little++, translate)) break; + continue; + } + if (!trans_eq(*big++, c, translate)) break; + } + if (little == lend) return 1; + return 0; +} + +static int +must_instr(little, llen, big, blen, translate) + unsigned char *little; + int llen; + unsigned char *big; + int blen; + char *translate; +{ + unsigned char *bend = big + blen; + register int c; + int fescape = 0; + + if (blen < llen) + return 0; + + c = *little; + if (c == 0xff) { + c = *++little; + fescape = 1; + } + else if (translate && !ismbchar(c)) { + c = translate[c]; + } + + while (big < bend) { + /* look for first character */ + if (fescape) { + while (big < bend) { + if (*big == c) break; + big++; + } + } + else if (translate && !ismbchar(c)) { + while (big < bend) { + if (ismbchar(*big)) big++; + else if (translate[*big] == c) break; + big++; + } + } + else { + while (big < bend) { + if (*big == c) break; + if (ismbchar(*big)) big++; + big++; + } + } + + if (must_match(little, little+llen, big, bend, translate)) + return 1; + + if (ismbchar(*big)) big++; + big++; + } + return 0; +} + + +/* Given a pattern, compute a fastmap from it. The fastmap records + which of the (1 << BYTEWIDTH) possible characters can start a string + that matches the pattern. This fastmap is used by re_search to skip + quickly over totally implausible text. + + The caller must supply the address of a (1 << BYTEWIDTH)-byte data + area as bufp->fastmap. + The other components of bufp describe the pattern to be used. */ +void +re_compile_fastmap(bufp) + struct re_pattern_buffer *bufp; +{ + unsigned char *pattern = (unsigned char *) bufp->buffer; + int size = bufp->used; + register char *fastmap = bufp->fastmap; + register unsigned char *p = pattern; + register unsigned char *pend = pattern + size; + register int j, k; + unsigned char *translate = (unsigned char *)bufp->translate; + unsigned is_a_succeed_n; + + unsigned char **stackb = RE_TALLOC(NFAILURES, unsigned char*); + unsigned char **stackp = stackb; + unsigned char **stacke = stackb + NFAILURES; + + memset(fastmap, 0, (1 << BYTEWIDTH)); + bufp->fastmap_accurate = 1; + bufp->can_be_null = 0; + + while (p) + { + is_a_succeed_n = 0; + if (p == pend) + { + bufp->can_be_null = 1; + break; + } +#ifdef SWITCH_ENUM_BUG + switch ((int) ((enum regexpcode)*p++)) +#else + switch ((enum regexpcode)*p++) +#endif + { + case exactn: + if (p[1] == 0xff) { + if (translate) + fastmap[translate[p[2]]] = 2; + else + fastmap[p[2]] = 2; + } + else if (translate) + fastmap[translate[p[1]]] = 1; + else + fastmap[p[1]] = 1; + break; + + case begline: + case begbuf: + case endbuf: + case wordbound: + case notwordbound: + case wordbeg: + case wordend: + case pop_and_fail: + continue; + + case endline: + if (translate) + fastmap[translate['\n']] = 1; + else + fastmap['\n'] = 1; + + if (bufp->can_be_null == 0) + bufp->can_be_null = 2; + break; + + case jump_n: + case finalize_jump: + case maybe_finalize_jump: + case jump: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR(j, p); + p += j; + if (j > 0) + continue; + /* Jump backward reached implies we just went through + the body of a loop and matched nothing. + Opcode jumped to should be an on_failure_jump. + Just treat it like an ordinary jump. + For a * loop, it has pushed its failure point already; + If so, discard that as redundant. */ + + if ((enum regexpcode) *p != on_failure_jump + && (enum regexpcode) *p != try_next + && (enum regexpcode) *p != finalize_push + && (enum regexpcode) *p != finalize_push_n) + continue; + p++; + EXTRACT_NUMBER_AND_INCR(j, p); + p += j; + if (stackp != stackb && *stackp == p) + stackp--; /* pop */ + continue; + + case start_nowidth: + case stop_nowidth: + case finalize_push: + p += 2; + continue; + + case finalize_push_n: + p += 4; + continue; + + case try_next: + case on_failure_jump: + handle_on_failure_jump: + EXTRACT_NUMBER_AND_INCR(j, p); + if (p + j < pend) { + if (stackp == stacke) { + unsigned char **stackx; + unsigned int len = stacke - stackb; + + EXPAND_FAIL_STACK(stackx, stackb, len); + } + *++stackp = p + j; /* push */ + } + else { + bufp->can_be_null = 1; + } + if (is_a_succeed_n) + EXTRACT_NUMBER_AND_INCR(k, p); /* Skip the n. */ + continue; + + case succeed_n: + is_a_succeed_n = 1; + /* Get to the number of times to succeed. */ + EXTRACT_NUMBER(k, p + 2); + /* Increment p past the n for when k != 0. */ + if (k == 0) { + p += 4; + } + else { + goto handle_on_failure_jump; + } + continue; + + case set_number_at: + p += 4; + continue; + + case start_memory: + case stop_memory: + p++; + continue; + + case duplicate: + bufp->can_be_null = 1; + fastmap['\n'] = 1; + case anychar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (j != '\n') + fastmap[j] = 1; + if (bufp->can_be_null) + { + FREE_AND_RETURN_VOID(stackb); + } + /* Don't return; check the alternative paths + so we can set can_be_null if appropriate. */ + break; + + case wordchar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX(j) == Sword) + fastmap[j] = 1; + break; + + case notwordchar: + for (j = 0; j < 0x80; j++) + if (SYNTAX(j) != Sword) + fastmap[j] = 1; + for (j = 0x80; j < (1 << BYTEWIDTH); j++) + fastmap[j] = 1; + break; + + case charset: + /* NOTE: Charset for single-byte chars never contain + multi-byte char. See set_list_bits(). */ + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) + { + if (translate) + fastmap[translate[j]] = 1; + else + fastmap[j] = 1; + } + { + unsigned short size; + unsigned c, end; + + p += p[-1] + 2; + size = EXTRACT_UNSIGNED(&p[-2]); + for (j = 0; j < (int)size; j++) { + if ((unsigned char)p[j*4] == 0xff) { + for (c = (unsigned char)p[j*4+1], + end = (unsigned char)p[j*4+3]; + c <= end; c++) { + fastmap[c] = 2; + } + } + else { + /* set bits for 1st bytes of multi-byte chars. */ + for (c = (unsigned char)p[j*4], + end = (unsigned char)p[j*4 + 2]; + c <= end; c++) { + /* NOTE: Charset for multi-byte chars might contain + single-byte chars. We must reject them. */ + if (ismbchar(c)) + fastmap[c] = 1; + } + } + } + } + break; + + case charset_not: + /* S: set of all single-byte chars. + M: set of all first bytes that can start multi-byte chars. + s: any set of single-byte chars. + m: any set of first bytes that can start multi-byte chars. + + We assume S+M = U. + ___ _ _ + s+m = (S*s+M*m). */ + /* Chars beyond end of map must be allowed */ + /* NOTE: Charset_not for single-byte chars might contain + multi-byte chars. See set_list_bits(). */ + for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) + if (!ismbchar(j)) + fastmap[j] = 1; + + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) + { + if (!ismbchar(j)) + fastmap[j] = 1; + } + { + unsigned short size; + unsigned char c, beg; + + p += p[-1] + 2; + size = EXTRACT_UNSIGNED(&p[-2]); + if (size == 0) { + for (j = 0x80; j < (1 << BYTEWIDTH); j++) + if (ismbchar(j)) + fastmap[j] = 1; + } + for (j = 0,c = 0x80;j < (int)size; j++) { + if ((unsigned char)p[j*4] == 0xff) { + for (beg = (unsigned char)p[j*4+1]; c < beg; c++) + fastmap[c] = 2; + c = (unsigned char)p[j*4+3] + 1; + } + else { + for (beg = (unsigned char)p[j*4 + 0]; c < beg; c++) + if (ismbchar(c)) + fastmap[c] = 1; + c = (unsigned char)p[j*4 + 2] + 1; + } + } + } + break; + + case unused: /* pacify gcc -Wall */ + break; + } + + /* Get here means we have successfully found the possible starting + characters of one path of the pattern. We need not follow this + path any farther. Instead, look at the next alternative + remembered in the stack. */ + if (stackp != stackb) + p = *stackp--; /* pop */ + else + break; + } + FREE_AND_RETURN_VOID(stackb); +} + + +/* Using the compiled pattern in BUFP->buffer, first tries to match + STRING, starting first at index STARTPOS, then at STARTPOS + 1, and + so on. RANGE is the number of places to try before giving up. If + RANGE is negative, it searches backwards, i.e., the starting + positions tried are STARTPOS, STARTPOS - 1, etc. STRING is of SIZE. + In REGS, return the indices of STRING that matched the entire + BUFP->buffer and its contained subexpressions. + + The value returned is the position in the strings at which the match + was found, or -1 if no match was found, or -2 if error (such as + failure stack overflow). */ + +int +re_search(bufp, string, size, startpos, range, regs) + struct re_pattern_buffer *bufp; + char *string; + int size, startpos, range; + struct re_registers *regs; +{ + register char *fastmap = bufp->fastmap; + register unsigned char *translate = (unsigned char *) bufp->translate; + int val, anchor = 0; + + /* Check for out-of-range starting position. */ + if (startpos < 0 || startpos > size) + return -1; + + /* If the search isn't to be a backwards one, don't waste time in a + search for a pattern that must be anchored. */ + if (bufp->used>0) { + switch ((enum regexpcode)bufp->buffer[0]) { + case begbuf: + if (range > 0) { + if (startpos > 0) + return -1; + else + return re_match(bufp, string, size, 0, regs); + } + break; + + case begline: + if (startpos == 0) { + val = re_match(bufp, string, size, 0, regs); + if (val >= 0) return 0; + } + anchor = 1; + break; + + default: + break; + } + } +#if 1 + if (range > 0 + && bufp->must + && !must_instr(bufp->must+1, bufp->must[0], + string+startpos, size-startpos, + translate)) { + return -1; + } +#endif + /* Update the fastmap now if not correct already. */ + if (fastmap && !bufp->fastmap_accurate) { + re_compile_fastmap(bufp); + } + + for (;;) + { + /* If a fastmap is supplied, skip quickly over characters that + cannot possibly be the start of a match. Note, however, that + if the pattern can possibly match the null string, we must + test it at each starting point so that we take the first null + string we get. */ + + if (fastmap && startpos < size + && bufp->can_be_null != 1 && !(anchor && startpos == 0)) + { + if (range > 0) /* Searching forwards. */ + { + register unsigned char *p, c; + int irange = range; + + p = (unsigned char *)string+startpos; + + while (range > 0) { + c = *p++; + if (ismbchar(c)) { + if (fastmap[c]) + break; + c = *p++; + range--; + if (fastmap[c] == 2) + break; + } + else + if (fastmap[translate ? translate[c] : c]) + break; + range--; + } + startpos += irange - range; + } + else /* Searching backwards. */ + { + register unsigned char c; + + c = string[startpos]; + c &= 0xff; + if (translate ? !fastmap[translate[c]] : !fastmap[c]) + goto advance; + } + } + + if (anchor && startpos > 0 && startpos < size + && string[startpos-1] != '\n') goto advance; + + if (fastmap && startpos == size && range >= 0 + && (bufp->can_be_null == 0 || + (bufp->can_be_null == 2 && size > 0 + && string[startpos-1] == '\n'))) + return -1; + + val = re_match(bufp, string, size, startpos, regs); + if (val >= 0) + return startpos; + if (val == -2) + return -2; + +#ifndef NO_ALLOCA +#ifdef cALLOCA + alloca(0); +#endif /* cALLOCA */ +#endif /* NO_ALLOCA */ + + advance: + if (!range) + break; + else if (range > 0) { + const char *d = string + startpos; + + if (ismbchar(*d)) { + range--, startpos++; + if (!range) + break; + } + range--, startpos++; + } + else { + range++, startpos--; + { + const char *s, *d, *p; + + s = string; d = string + startpos; + for (p = d; p-- > s && ismbchar(*p); ) + /* --p >= s would not work on 80[12]?86. + (when the offset of s equals 0 other than huge model.) */ + ; + if (!((d - p) & 1)) { + if (!range) + break; + range++, startpos--; + } + } + } + } + return -1; +} + + + + +/* The following are used for re_match, defined below: */ + +/* Roughly the maximum number of failure points on the stack. Would be + exactly that if always pushed MAX_NUM_FAILURE_ITEMS each time we failed. */ + +int re_max_failures = 2000; + +/* Routine used by re_match. */ +/* static int memcmp_translate(); *//* already declared */ + + +/* Structure and accessing macros used in re_match: */ + +struct register_info +{ + unsigned is_active : 1; + unsigned matched_something : 1; +}; + +#define IS_ACTIVE(R) ((R).is_active) +#define MATCHED_SOMETHING(R) ((R).matched_something) + + +/* Macros used by re_match: */ + +/* I.e., regstart, regend, and reg_info. */ + +#define NUM_REG_ITEMS 3 + +/* We push at most this many things on the stack whenever we + fail. The `+ 2' refers to PATTERN_PLACE and STRING_PLACE, which are + arguments to the PUSH_FAILURE_POINT macro. */ + +#define MAX_NUM_FAILURE_ITEMS (num_regs * NUM_REG_ITEMS + 2) + + +/* We push this many things on the stack whenever we fail. */ + +#define NUM_FAILURE_ITEMS (last_used_reg * NUM_REG_ITEMS + 2) + + +/* This pushes most of the information about the current state we will want + if we ever fail back to it. */ + +#define PUSH_FAILURE_POINT(pattern_place, string_place) \ + { \ + long last_used_reg, this_reg; \ + \ + /* Find out how many registers are active or have been matched. \ + (Aside from register zero, which is only set at the end.) */ \ + for (last_used_reg = num_regs - 1; last_used_reg > 0; last_used_reg--)\ + if (regstart[last_used_reg] != (unsigned char *)(-1L)) \ + break; \ + \ + if (stacke - stackp <= NUM_FAILURE_ITEMS) \ + { \ + unsigned char **stackx; \ + unsigned int len = stacke - stackb; \ + if (len > re_max_failures * MAX_NUM_FAILURE_ITEMS) \ + { \ + FREE_VARIABLES(); \ + FREE_AND_RETURN(stackb,(-2)); \ + } \ + \ + /* Roughly double the size of the stack. */ \ + EXPAND_FAIL_STACK(stackx, stackb, len); \ + } \ + \ + /* Now push the info for each of those registers. */ \ + for (this_reg = 1; this_reg <= last_used_reg; this_reg++) \ + { \ + *stackp++ = regstart[this_reg]; \ + *stackp++ = regend[this_reg]; \ + *stackp++ = (unsigned char *)®_info[this_reg]; \ + } \ + \ + /* Push how many registers we saved. */ \ + *stackp++ = (unsigned char *)last_used_reg; \ + \ + *stackp++ = pattern_place; \ + *stackp++ = string_place; \ + *stackp++ = (unsigned char *)0; /* non-greedy flag */ \ + } + + +/* This pops what PUSH_FAILURE_POINT pushes. */ + +#define POP_FAILURE_POINT() \ + { \ + int temp; \ + stackp -= 3; /* Remove failure points (and flag). */ \ + temp = (int) *--stackp; /* How many regs pushed. */ \ + temp *= NUM_REG_ITEMS; /* How much to take off the stack. */ \ + stackp -= temp; /* Remove the register info. */ \ + } + +#define PREFETCH if (d == dend) goto fail + +/* Call this when have matched something; it sets `matched' flags for the + registers corresponding to the subexpressions of which we currently + are inside. */ +#define SET_REGS_MATCHED \ + { unsigned this_reg; \ + for (this_reg = 0; this_reg < num_regs; this_reg++) \ + { \ + if (IS_ACTIVE(reg_info[this_reg])) \ + MATCHED_SOMETHING(reg_info[this_reg]) = 1; \ + else \ + MATCHED_SOMETHING(reg_info[this_reg]) = 0; \ + } \ + } + +#define AT_STRINGS_BEG(d) (d == string) +#define AT_STRINGS_END(d) (d == dend) + +#define AT_WORD_BOUNDARY(d) \ + (AT_STRINGS_BEG(d) || AT_STRINGS_END(d) || IS_A_LETTER(d - 1) != IS_A_LETTER(d)) + +/* We have two special cases to check for: + 1) if we're past the end of string1, we have to look at the first + character in string2; + 2) if we're before the beginning of string2, we have to look at the + last character in string1; we assume there is a string1, so use + this in conjunction with AT_STRINGS_BEG. */ +#define IS_A_LETTER(d) (SYNTAX(*(d)) == Sword) + +static void +init_regs(regs, num_regs) + struct re_registers *regs; + unsigned num_regs; +{ + int i; + + regs->num_regs = num_regs; + if (num_regs < RE_NREGS) + num_regs = RE_NREGS; + + if (regs->allocated == 0) { + regs->beg = TMALLOC(num_regs, int); + regs->end = TMALLOC(num_regs, int); + regs->allocated = num_regs; + } + else if (regs->allocated < num_regs) { + TREALLOC(regs->beg, num_regs, int); + TREALLOC(regs->end, num_regs, int); + } + for (i=0; ibeg[i] = regs->end[i] = -1; + } +} + +/* Match the pattern described by BUFP against STRING, which is of + SIZE. Start the match at index POS in STRING. In REGS, return the + indices of STRING that matched the entire BUFP->buffer and its + contained subexpressions. + + If bufp->fastmap is nonzero, then it had better be up to date. + + The reason that the data to match are specified as two components + which are to be regarded as concatenated is so this function can be + used directly on the contents of an Emacs buffer. + + -1 is returned if there is no match. -2 is returned if there is an + error (such as match stack overflow). Otherwise the value is the + length of the substring which was matched. */ + +int +re_match(bufp, string_arg, size, pos, regs) + struct re_pattern_buffer *bufp; + char *string_arg; + int size, pos; + struct re_registers *regs; +{ + register unsigned char *p = (unsigned char *) bufp->buffer; + + /* Pointer to beyond end of buffer. */ + register unsigned char *pend = p + bufp->used; + + unsigned num_regs = bufp->re_nsub; + + unsigned char *string = (unsigned char *) string_arg; + + register unsigned char *d, *dend; + register int mcnt; /* Multipurpose. */ + unsigned char *translate = (unsigned char *) bufp->translate; + unsigned is_a_jump_n = 0; + + /* Failure point stack. Each place that can handle a failure further + down the line pushes a failure point on this stack. It consists of + restart, regend, and reg_info for all registers corresponding to the + subexpressions we're currently inside, plus the number of such + registers, and, finally, two char *'s. The first char * is where to + resume scanning the pattern; the second one is where to resume + scanning the strings. If the latter is zero, the failure point is a + ``dummy''; if a failure happens and the failure point is a dummy, it + gets discarded and the next next one is tried. */ + + unsigned char **stackb; + unsigned char **stackp; + unsigned char **stacke; + + + /* Information on the contents of registers. These are pointers into + the input strings; they record just what was matched (on this + attempt) by a subexpression part of the pattern, that is, the + regnum-th regstart pointer points to where in the pattern we began + matching and the regnum-th regend points to right after where we + stopped matching the regnum-th subexpression. (The zeroth register + keeps track of what the whole pattern matches.) */ + + unsigned char **regstart = RE_TALLOC(num_regs, unsigned char*); + unsigned char **regend = RE_TALLOC(num_regs, unsigned char*); + + /* The is_active field of reg_info helps us keep track of which (possibly + nested) subexpressions we are currently in. The matched_something + field of reg_info[reg_num] helps us tell whether or not we have + matched any of the pattern so far this time through the reg_num-th + subexpression. These two fields get reset each time through any + loop their register is in. */ + + struct register_info *reg_info = RE_TALLOC(num_regs, struct register_info); + + /* The following record the register info as found in the above + variables when we find a match better than any we've seen before. + This happens as we backtrack through the failure points, which in + turn happens only if we have not yet matched the entire string. */ + + unsigned best_regs_set = 0; + unsigned char **best_regstart = RE_TALLOC(num_regs, unsigned char*); + unsigned char **best_regend = RE_TALLOC(num_regs, unsigned char*); + + if (regs) { + init_regs(regs, num_regs); + } + + /* Initialize the stack. */ + stackb = RE_TALLOC(MAX_NUM_FAILURE_ITEMS * NFAILURES, unsigned char*); + stackp = stackb; + stacke = &stackb[MAX_NUM_FAILURE_ITEMS * NFAILURES]; + +#ifdef DEBUG_REGEX + fprintf (stderr, "Entering re_match(%s%s)\n", string1_arg, string2_arg); +#endif + + /* Initialize subexpression text positions to -1 to mark ones that no + \( or ( and \) or ) has been seen for. Also set all registers to + inactive and mark them as not having matched anything or ever + failed. */ + for (mcnt = 0; mcnt < num_regs; mcnt++) { + regstart[mcnt] = regend[mcnt] = (unsigned char *) (-1L); + IS_ACTIVE(reg_info[mcnt]) = 0; + MATCHED_SOMETHING(reg_info[mcnt]) = 0; + } + + /* Set up pointers to ends of strings. + Don't allow the second string to be empty unless both are empty. */ + + + /* `p' scans through the pattern as `d' scans through the data. `dend' + is the end of the input string that `d' points within. `d' is + advanced into the following input string whenever necessary, but + this happens before fetching; therefore, at the beginning of the + loop, `d' can be pointing at the end of a string, but it cannot + equal string2. */ + + d = string + pos, dend = string + size; + + + /* This loops over pattern commands. It exits by returning from the + function if match is complete, or it drops through if match fails + at this starting point in the input data. */ + + for (;;) + { +#ifdef DEBUG_REGEX + fprintf(stderr, + "regex loop(%d): matching 0x%02d\n", + p - (unsigned char *) bufp->buffer, + *p); +#endif + is_a_jump_n = 0; + /* End of pattern means we might have succeeded. */ + if (p == pend) + { + /* If not end of string, try backtracking. Otherwise done. */ + if (d != dend) + { + if (stackp != stackb) + { + /* More failure points to try. */ + + /* If exceeds best match so far, save it. */ + if (! best_regs_set || (d > best_regend[0])) + { + best_regs_set = 1; + best_regend[0] = d; /* Never use regstart[0]. */ + + for (mcnt = 1; mcnt < num_regs; mcnt++) + { + best_regstart[mcnt] = regstart[mcnt]; + best_regend[mcnt] = regend[mcnt]; + } + } + goto fail; + } + /* If no failure points, don't restore garbage. */ + else if (best_regs_set) + { + restore_best_regs: + /* Restore best match. */ + d = best_regend[0]; + + for (mcnt = 0; mcnt < num_regs; mcnt++) + { + regstart[mcnt] = best_regstart[mcnt]; + regend[mcnt] = best_regend[mcnt]; + } + } + } + + /* If caller wants register contents data back, convert it + to indices. */ + if (regs) + { + regs->beg[0] = pos; + regs->end[0] = d - string; + for (mcnt = 1; mcnt < num_regs; mcnt++) + { + if (regend[mcnt] == (unsigned char *)(-1L)) + { + regs->beg[mcnt] = -1; + regs->end[mcnt] = -1; + continue; + } + regs->beg[mcnt] = regstart[mcnt] - string; + regs->end[mcnt] = regend[mcnt] - string; + } + } + FREE_VARIABLES(); + FREE_AND_RETURN(stackb, (d - pos - string)); + } + + /* Otherwise match next pattern command. */ +#ifdef SWITCH_ENUM_BUG + switch ((int)((enum regexpcode)*p++)) +#else + switch ((enum regexpcode)*p++) +#endif + { + + /* \( [or `(', as appropriate] is represented by start_memory, + \) by stop_memory. Both of those commands are followed by + a register number in the next byte. The text matched + within the \( and \) is recorded under that number. */ + case start_memory: + regstart[*p] = d; + IS_ACTIVE(reg_info[*p]) = 1; + MATCHED_SOMETHING(reg_info[*p]) = 0; + p++; + continue; + + case stop_memory: + regend[*p] = d; + IS_ACTIVE(reg_info[*p]) = 0; + + /* If just failed to match something this time around with a sub- + expression that's in a loop, try to force exit from the loop. */ + if ((! MATCHED_SOMETHING(reg_info[*p]) + || (enum regexpcode) p[-3] == start_memory) + && (p + 1) != pend) + { + register unsigned char *p2 = p + 1; + mcnt = 0; + switch (*p2++) + { + case jump_n: + is_a_jump_n = 1; + case finalize_jump: + case maybe_finalize_jump: + case jump: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR(mcnt, p2); + if (is_a_jump_n) + p2 += 2; + break; + } + p2 += mcnt; + + /* If the next operation is a jump backwards in the pattern + to an on_failure_jump, exit from the loop by forcing a + failure after pushing on the stack the on_failure_jump's + jump in the pattern, and d. */ + if (mcnt < 0 && (enum regexpcode) *p2++ == on_failure_jump) + { + EXTRACT_NUMBER_AND_INCR(mcnt, p2); + PUSH_FAILURE_POINT(p2 + mcnt, d); + goto fail; + } + } + p++; + continue; + + /* \ has been turned into a `duplicate' command which is + followed by the numeric value of as the register number. */ + case duplicate: + { + int regno = *p++; /* Get which register to match against */ + register unsigned char *d2, *dend2; + + /* Where in input to try to start matching. */ + d2 = regstart[regno]; + + /* Where to stop matching; if both the place to start and + the place to stop matching are in the same string, then + set to the place to stop, otherwise, for now have to use + the end of the first string. */ + + dend2 = regend[regno]; + for (;;) + { + /* At end of register contents => success */ + if (d2 == dend2) break; + + /* If necessary, advance to next segment in data. */ + PREFETCH; + + /* How many characters left in this segment to match. */ + mcnt = dend - d; + + /* Want how many consecutive characters we can match in + one shot, so, if necessary, adjust the count. */ + if (mcnt > dend2 - d2) + mcnt = dend2 - d2; + + /* Compare that many; failure if mismatch, else move + past them. */ + if (translate + ? memcmp_translate(d, d2, mcnt, translate) + : memcmp((char *)d, (char *)d2, mcnt)) + goto fail; + d += mcnt, d2 += mcnt; + } + } + break; + + case start_nowidth: + PUSH_FAILURE_POINT(0, d); + EXTRACT_NUMBER_AND_INCR(mcnt, p); + STORE_NUMBER(p+mcnt, stackp - stackb); + continue; + + case stop_nowidth: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + stackp = stackb + mcnt; + d = stackp[-2]; + POP_FAILURE_POINT(); + continue; + + case pop_and_fail: + EXTRACT_NUMBER(mcnt, p+1); + stackp = stackb + mcnt; + POP_FAILURE_POINT(); + goto fail; + + case anychar: + PREFETCH; + /* Match anything but a newline, maybe even a null. */ + if (ismbchar(*d)) { + if (d + 1 == dend || d[1] == '\n' || d[1] == '\0') + goto fail; + SET_REGS_MATCHED; + d += 2; + break; + } + if ((translate ? translate[*d] : *d) == '\n' + || ((re_syntax_options & RE_DOT_NOT_NULL) + && (translate ? translate[*d] : *d) == '\000')) + goto fail; + SET_REGS_MATCHED; + d++; + break; + + case charset: + case charset_not: + { + int not; /* Nonzero for charset_not. */ + int half; /* 2 if need to match latter half of mbc */ + int c; + + PREFETCH; + c = (unsigned char)*d; + if (ismbchar(c)) { + if (d + 1 != dend) { + c <<= 8; + c |= (unsigned char)d[1]; + } + } + else if (translate) + c = (unsigned char)translate[c]; + + half = not = is_in_list(c, p); + if (*(p - 1) == (unsigned char)charset_not) { + not = !not; + } + + p += 1 + *p + 2 + EXTRACT_UNSIGNED(&p[1 + *p])*4; + + if (!not) goto fail; + SET_REGS_MATCHED; + + d++; + if (half != 2 && d != dend && c >= 1 << BYTEWIDTH) + d++; + break; + } + + case begline: + if (size == 0 + || d == string + || (d && d[-1] == '\n')) + break; + else + goto fail; + + case endline: + if (d == dend || *d == '\n') + break; + goto fail; + + /* Match at the very beginning of the string. */ + case begbuf: + if (AT_STRINGS_BEG(d)) + break; + goto fail; + + /* Match at the very end of the data. */ + case endbuf: + if (AT_STRINGS_END(d)) + break; + goto fail; + + /* `or' constructs are handled by starting each alternative with + an on_failure_jump that points to the start of the next + alternative. Each alternative except the last ends with a + jump to the joining point. (Actually, each jump except for + the last one really jumps to the following jump, because + tensioning the jumps is a hassle.) */ + + /* The start of a stupid repeat has an on_failure_jump that points + past the end of the repeat text. This makes a failure point so + that on failure to match a repetition, matching restarts past + as many repetitions have been found with no way to fail and + look for another one. */ + + /* A smart repeat is similar but loops back to the on_failure_jump + so that each repetition makes another failure point. */ + + case on_failure_jump: + on_failure: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + PUSH_FAILURE_POINT(p + mcnt, d); + continue; + + /* The end of a smart repeat has a maybe_finalize_jump back. + Change it either to a finalize_jump or an ordinary jump. */ + case maybe_finalize_jump: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + { + register unsigned char *p2 = p; + /* Compare what follows with the beginning of the repeat. + If we can establish that there is nothing that they would + both match, we can change to finalize_jump. */ + while (p2 + 1 != pend + && (*p2 == (unsigned char)stop_memory + || *p2 == (unsigned char)start_memory)) + p2 += 2; /* Skip over reg number. */ + if (p2 == pend) + p[-3] = (unsigned char)finalize_jump; + else if (*p2 == (unsigned char)exactn + || *p2 == (unsigned char)endline) + { + register int c = *p2 == (unsigned char)endline ? '\n' : p2[2]; + register unsigned char *p1 = p + mcnt; + /* p1[0] ... p1[2] are an on_failure_jump. + Examine what follows that. */ + if (p1[3] == (unsigned char)exactn && p1[5] != c) + p[-3] = (unsigned char)finalize_jump; + else if (p1[3] == (unsigned char)charset + || p1[3] == (unsigned char)charset_not) { + int not; + if (ismbchar(c)) + c = c << 8 | p2[3]; + /* `is_in_list()' is TRUE if c would match */ + /* That means it is not safe to finalize. */ + not = is_in_list(c, p1 + 4); + if (p1[3] == (unsigned char)charset_not) + not = !not; + if (!not) + p[-3] = (unsigned char)finalize_jump; + } + } + } + p -= 2; /* Point at relative address again. */ + if (p[-1] != (unsigned char)finalize_jump) + { + p[-1] = (unsigned char)jump; + goto nofinalize; + } + /* Note fall through. */ + + /* The end of a stupid repeat has a finalize_jump back to the + start, where another failure point will be made which will + point to after all the repetitions found so far. */ + + /* Take off failure points put on by matching on_failure_jump + because didn't fail. Also remove the register information + put on by the on_failure_jump. */ + case finalize_jump: + POP_FAILURE_POINT(); + /* Note fall through. */ + + /* Jump without taking off any failure points. */ + case jump: + nofinalize: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + p += mcnt; + continue; + + case dummy_failure_jump: + /* Normally, the on_failure_jump pushes a failure point, which + then gets popped at finalize_jump. We will end up at + finalize_jump, also, and with a pattern of, say, `a+', we + are skipping over the on_failure_jump, so we have to push + something meaningless for finalize_jump to pop. */ + PUSH_FAILURE_POINT(0, 0); + goto nofinalize; + + /* Have to succeed matching what follows at least n times. Then + just handle like an on_failure_jump. */ + case succeed_n: + EXTRACT_NUMBER(mcnt, p + 2); + /* Originally, this is how many times we HAVE to succeed. */ + if (mcnt > 0) + { + mcnt--; + p += 2; + STORE_NUMBER_AND_INCR(p, mcnt); + PUSH_FAILURE_POINT(0, 0); + } + else if (mcnt == 0) + { + p[2] = unused; + p[3] = unused; + goto on_failure; + } + continue; + + case jump_n: + EXTRACT_NUMBER(mcnt, p + 2); + /* Originally, this is how many times we CAN jump. */ + if (mcnt) + { + mcnt--; + STORE_NUMBER(p + 2, mcnt); + goto nofinalize; /* Do the jump without taking off + any failure points. */ + } + /* If don't have to jump any more, skip over the rest of command. */ + else + p += 4; + continue; + + case set_number_at: + { + register unsigned char *p1; + + EXTRACT_NUMBER_AND_INCR(mcnt, p); + p1 = p + mcnt; + EXTRACT_NUMBER_AND_INCR(mcnt, p); + STORE_NUMBER(p1, mcnt); + continue; + } + + case try_next: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + if (p + mcnt < pend) { + PUSH_FAILURE_POINT(p, d); + stackp[-1] = (unsigned char*)1; + } + p += mcnt; + continue; + + case finalize_push: + POP_FAILURE_POINT(); + EXTRACT_NUMBER_AND_INCR(mcnt, p); + PUSH_FAILURE_POINT(p + mcnt, d); + stackp[-1] = (unsigned char*)1; + continue; + + case finalize_push_n: + EXTRACT_NUMBER(mcnt, p + 2); + /* Originally, this is how many times we CAN jump. */ + if (mcnt) { + mcnt--; + STORE_NUMBER(p + 2, mcnt); + POP_FAILURE_POINT(); + EXTRACT_NUMBER_AND_INCR(mcnt, p); + PUSH_FAILURE_POINT(p + mcnt, d); + stackp[-1] = (unsigned char*)1; + p += 7; /* skip n and set_number_at after destination */ + } + /* If don't have to push any more, skip over the rest of command. */ + else + p += 4; + continue; + + /* Ignore these. Used to ignore the n of succeed_n's which + currently have n == 0. */ + case unused: + continue; + + case wordbound: + if (AT_WORD_BOUNDARY(d)) + break; + goto fail; + + case notwordbound: + if (AT_WORD_BOUNDARY(d)) + goto fail; + break; + + case wordbeg: + if (IS_A_LETTER(d) && (AT_STRINGS_BEG(d) || !IS_A_LETTER(d - 1))) + break; + goto fail; + + case wordend: + if (!AT_STRINGS_BEG(d) && IS_A_LETTER(d - 1) + && (!IS_A_LETTER(d) || AT_STRINGS_END(d))) + break; + goto fail; + + case wordchar: + PREFETCH; + if (!IS_A_LETTER(d)) + goto fail; + d++; + SET_REGS_MATCHED; + break; + + case notwordchar: + PREFETCH; + if (IS_A_LETTER(d)) + goto fail; + if (ismbchar(*d) && d + 1 != dend) + d++; + d++; + SET_REGS_MATCHED; + break; + + case exactn: + /* Match the next few pattern characters exactly. + mcnt is how many characters to match. */ + mcnt = *p++; + /* This is written out as an if-else so we don't waste time + testing `translate' inside the loop. */ + if (translate) + { + do + { + unsigned char c; + + PREFETCH; + c = *d++; + if (*p == 0xff) { + p++; + if (!--mcnt + || d == dend + || (unsigned char)*d++ != (unsigned char)*p++) + goto fail; + continue; + } + if (ismbchar(c)) { + if (c != (unsigned char)*p++ + || !--mcnt /* redundant check if pattern was + compiled properly. */ + || d == dend + || (unsigned char)*d++ != (unsigned char)*p++) + goto fail; + continue; + } + /* compiled code translation needed for ruby */ + if ((unsigned char)translate[c] + != (unsigned char)translate[*p++]) + goto fail; + } + while (--mcnt); + } + else + { + do + { + PREFETCH; + if (*p == 0xff) {p++; mcnt--;} + if (*d++ != *p++) goto fail; + } + while (--mcnt); + } + SET_REGS_MATCHED; + break; + } + if (stackp != stackb && (int)stackp[-1] == 1) + POP_FAILURE_POINT(); + continue; /* Successfully executed one pattern command; keep going. */ + + /* Jump here if any matching operation fails. */ + fail: + if (stackp != stackb) + /* A restart point is known. Restart there and pop it. */ + { + short last_used_reg, this_reg; + + /* If this failure point is from a dummy_failure_point, just + skip it. */ + if (stackp[-3] == 0) { + POP_FAILURE_POINT(); + goto fail; + } + stackp--; /* discard flag */ + d = *--stackp; + p = *--stackp; + /* Restore register info. */ + last_used_reg = (long) *--stackp; + + /* Make the ones that weren't saved -1 or 0 again. */ + for (this_reg = num_regs - 1; this_reg > last_used_reg; this_reg--) + { + regend[this_reg] = (unsigned char *)(-1L); + regstart[this_reg] = (unsigned char *)(-1L); + IS_ACTIVE(reg_info[this_reg]) = 0; + MATCHED_SOMETHING(reg_info[this_reg]) = 0; + } + + /* And restore the rest from the stack. */ + for ( ; this_reg > 0; this_reg--) + { + reg_info[this_reg] = *(struct register_info *) *--stackp; + regend[this_reg] = *--stackp; + regstart[this_reg] = *--stackp; + } + } + else + break; /* Matching at this starting point really fails. */ + } + + if (best_regs_set) + goto restore_best_regs; + + FREE_AND_RETURN(stackb,(-1)); /* Failure to match. */ +} + + +static int +memcmp_translate(s1, s2, len, translate) + unsigned char *s1, *s2; + register int len; + unsigned char *translate; +{ + register unsigned char *p1 = s1, *p2 = s2, c; + while (len) + { + c = *p1++; + if (ismbchar(c)) { + if (c != *p2++ || !--len || *p1++ != *p2++) + return 1; + } + else + if (translate[c] != translate[*p2++]) + return 1; + len--; + } + return 0; +} + +void +re_copy_registers(regs1, regs2) + struct re_registers *regs1, *regs2; +{ + int i; + + if (regs1 == regs2) return; + if (regs1->allocated == 0) { + regs1->beg = TMALLOC(regs2->num_regs, int); + regs1->end = TMALLOC(regs2->num_regs, int); + regs1->allocated = regs2->num_regs; + } + else if (regs1->allocated < regs2->num_regs) { + TREALLOC(regs1->beg, regs2->num_regs, int); + TREALLOC(regs1->end, regs2->num_regs, int); + regs1->allocated = regs2->num_regs; + } + for (i=0; inum_regs; i++) { + regs1->beg[i] = regs2->beg[i]; + regs1->end[i] = regs2->end[i]; + } + regs1->num_regs = regs2->num_regs; +} + +void +re_free_registers(regs) + struct re_registers *regs; +{ + if (regs->allocated == 0) return; + if (regs->beg) free(regs->beg); + if (regs->end) free(regs->end); +} diff --git a/ruby.c b/ruby.c index 6e748f249d..03b29ff7b8 100644 --- a/ruby.c +++ b/ruby.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 12:47:31 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -475,7 +475,7 @@ load_file(fname, script) char *path; char *pend = RSTRING(line)->ptr + RSTRING(line)->len; - p = RSTRING(line)->ptr + 2; /* skip `#!' */ + p = RSTRING(line)->ptr + 1; /* skip `#!' */ if (pend[-1] == '\n') pend--; /* chomp line */ if (pend[-1] == '\r') pend--; *pend = '\0'; diff --git a/ruby.h b/ruby.h index ac53f620a9..a3e3f47dc9 100644 --- a/ruby.h +++ b/ruby.h @@ -6,7 +6,7 @@ $Date$ created at: Thu Jun 10 14:26:32 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto *************************************************/ @@ -165,6 +165,9 @@ int num2int _((VALUE)); double num2dbl _((VALUE)); #define NUM2DBL(x) num2dbl((VALUE)(x)) +char *str2cstr _((VALUE)); +#define STR2CSTR(x) str2cstr((VALUE)(x)) + VALUE rb_newobj _((void)); #define NEWOBJ(obj,type) type *obj = (type*)rb_newobj() #define OBJSETUP(obj,c,t) {\ diff --git a/sample/io.rb b/sample/io.rb deleted file mode 100644 index 0b38d2112d..0000000000 --- a/sample/io.rb +++ /dev/null @@ -1,44 +0,0 @@ -# IO test -# usage: ruby io.rb file.. - -home = ENV["HOME"] -home.sub("m", "&&") -print(home, "\n") -print(home.reverse, "\n") - -if File.s("io.rb") - print(File.s("io.rb"), ": io.rb\n") -end - -$/="f\n" -for i in "abc\n\ndef\nghi\n" - print("tt: ", i) -end - -printf("%s:(%d)%s\n", $0, ARGV.length, ARGV[0]) -passwd = open(ARGV[0], "r") -#printf("%s", passwd.find{i|i =~ /\*/}) - -n = 1 -for i in passwd #.grep(/^\*/) - printf("%6d: %s", n, i) - n = n + 1; -end - -fp = open("|-", "r") - -if fp == nil - for i in 1..5 - print(i, "\n") - end -else - for line in fp - print(line) - end -end - -def printUsage() - if $USAGE - apply($USAGE); - end -end diff --git a/sample/rbc.rb b/sample/rbc.rb index 88a5b2d069..485b558adb 100644 --- a/sample/rbc.rb +++ b/sample/rbc.rb @@ -2,8 +2,8 @@ # # rbc.rb - # $Release Version: 0.6 $ -# $Revision: 1.2 $ -# $Date: 1997/11/27 13:46:06 $ +# $Revision: 1.1.1.1 $ +# $Date: 1998/01/16 04:14:56 $ # by Keiju ISHITSUKA(Nippon Rational Inc.) # # -- @@ -32,7 +32,7 @@ require "e2mmap.rb" $stdout.sync = TRUE module BC_APPLICATION__ - RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/ruby/RCS/rbc.rb,v 1.2 1997/11/27 13:46:06 keiju Exp keiju $-' + RCS_ID='-$Header: /home/cvsroot/ruby/sample/rbc.rb,v 1.1.1.1 1998/01/16 04:14:56 matz Exp $-' extend Exception2MessageMapper def_exception :UnrecognizedSwitch, "Unrecognized switch: %s" diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el index 0f56477ea0..f5bc1d1b3b 100644 --- a/sample/ruby-mode.el +++ b/sample/ruby-mode.el @@ -632,8 +632,8 @@ An end of a defun is found by moving forward from the beginning of one." '("\\(^\\|[^_]\\)\\b\\([A-Z]+[a-zA-Z0-9_]*\\)" 2 font-lock-type-face) ;; functions - '("^\\s *def[ \t]+.*$" - 0 font-lock-function-name-face)) + '("^\\s *def[ \t]+[^ \t(]*" + 0 font-lock-function-name-face t)) "*Additional expressions to highlight in ruby mode.") (if (and (>= (string-to-int emacs-version) 20) (not (featurep 'xemacs))) diff --git a/sprintf.c b/sprintf.c index 7862a469e8..07f8a42694 100644 --- a/sprintf.c +++ b/sprintf.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 15 10:39:26 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/st.c b/st.c new file mode 100644 index 0000000000..6b25bc854b --- /dev/null +++ b/st.c @@ -0,0 +1,435 @@ +/* This is a general purpose hash table package written by Peter Moore @ UCB. */ + +static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; + +#include "config.h" +#include +#include "st.h" + +#define ST_DEFAULT_MAX_DENSITY 5 +#define ST_DEFAULT_INIT_TABLE_SIZE 11 + + /* + * DEFAULT_MAX_DENSITY is the default for the largest we allow the + * average number of items per bin before increasing the number of + * bins + * + * DEFAULT_INIT_TABLE_SIZE is the default for the number of bins + * allocated initially + * + */ +static int numcmp(); +static int numhash(); +static struct st_hash_type type_numhash = { + numcmp, + numhash, +}; + +extern int strcmp(); +static int strhash(); +static struct st_hash_type type_strhash = { + strcmp, + strhash, +}; + +void *xmalloc(); +void *xcalloc(); +void *xrealloc(); +static void rehash(); + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define nil(type) ((type*)0) +#define alloc(type) (type*)xmalloc((unsigned)sizeof(type)) +#define Calloc(n,s) (char*)xcalloc((n),(s)) + +#define EQUAL(table, x, y) ((*table->type->compare)(x, y) == 0) + +#define do_hash(key, table) (*(table)->type->hash)((key), (table)->num_bins) + +st_table* +st_init_table_with_size(type, size) + struct st_hash_type *type; + int size; +{ + st_table *tbl; + + if (size == 0) size = ST_DEFAULT_INIT_TABLE_SIZE; + else size /= ST_DEFAULT_MAX_DENSITY*0.87; + + if (size < ST_DEFAULT_INIT_TABLE_SIZE) + size = ST_DEFAULT_INIT_TABLE_SIZE; + + tbl = alloc(st_table); + tbl->type = type; + tbl->num_entries = 0; + tbl->num_bins = size; + tbl->bins = (st_table_entry **)Calloc(size, sizeof(st_table_entry*)); + return tbl; +} + +st_table* +st_init_table(type) + struct st_hash_type *type; +{ + return st_init_table_with_size(type, 0); +} + +st_table* +st_init_numtable() +{ + return st_init_table(&type_numhash); +} + +st_table* +st_init_strtable() +{ + return st_init_table(&type_strhash); +} + +void +st_free_table(table) + st_table *table; +{ + register st_table_entry *ptr, *next; + int i; + + for(i = 0; i < table->num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != nil(st_table_entry)) { + next = ptr->next; + free((char*)ptr); + ptr = next; + } + } + free((char*)table->bins); + free((char*)table); +} + +#define PTR_NOT_EQUAL(table, ptr, key) \ +(ptr != nil(st_table_entry) && !EQUAL(table, key, (ptr)->key)) + +#define FIND_ENTRY(table, ptr, hash_val) \ +ptr = (table)->bins[hash_val];\ +if (PTR_NOT_EQUAL(table, ptr, key)) {\ + while (PTR_NOT_EQUAL(table, ptr->next, key)) {\ + ptr = ptr->next;\ + }\ + ptr = ptr->next;\ +} + +int +st_lookup(table, key, value) + st_table *table; + register char *key; + char **value; +{ + int hash_val; + register st_table_entry *ptr; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, ptr, hash_val); + + if (ptr == nil(st_table_entry)) { + return 0; + } else { + if (value != nil(char*)) *value = ptr->record; + return 1; + } +} + +#define ADD_DIRECT(table, key, value, hash_val, tbl)\ +{\ + if (table->num_entries/table->num_bins > ST_DEFAULT_MAX_DENSITY) {\ + rehash(table);\ + hash_val = do_hash(key, table);\ + }\ + \ + tbl = alloc(st_table_entry);\ + \ + tbl->key = key;\ + tbl->record = value;\ + tbl->next = table->bins[hash_val];\ + table->bins[hash_val] = tbl;\ + table->num_entries++;\ +} + +int +st_insert(table, key, value) + register st_table *table; + register char *key; + char *value; +{ + int hash_val; + st_table_entry *tbl; + register st_table_entry *ptr; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, ptr, hash_val); + + if (ptr == nil(st_table_entry)) { + ADD_DIRECT(table,key,value,hash_val,tbl); + return 0; + } else { + ptr->record = value; + return 1; + } +} + +void +st_add_direct(table, key, value) + st_table *table; + char *key; + char *value; +{ + int hash_val; + st_table_entry *tbl; + + hash_val = do_hash(key, table); + ADD_DIRECT(table, key, value, hash_val, tbl); +} + +int +st_find_or_add(table, key, slot) + st_table *table; + char *key; + char ***slot; +{ + int hash_val; + st_table_entry *tbl, *ptr; + + hash_val = do_hash(key, table); + + FIND_ENTRY(table, ptr, hash_val); + + if (ptr == nil(st_table_entry)) { + ADD_DIRECT(table, key, (char*)0, hash_val, tbl) + if (slot != nil(char**)) *slot = &tbl->record; + return 0; + } else { + if (slot != nil(char**)) *slot = &ptr->record; + return 1; + } +} + +static void +rehash(table) + register st_table *table; +{ + register st_table_entry *ptr, *next, **old_bins = table->bins; + int i, old_num_bins = table->num_bins, hash_val; + + table->num_bins = 1.79*old_num_bins; + + if (table->num_bins%2 == 0) { + table->num_bins += 1; + } + + table->num_entries = 0; + table->bins = (st_table_entry **) + Calloc((unsigned)table->num_bins, sizeof(st_table_entry*)); + + for(i = 0; i < old_num_bins ; i++) { + ptr = old_bins[i]; + while (ptr != nil(st_table_entry)) { + next = ptr->next; + hash_val = do_hash(ptr->key, table); + ptr->next = table->bins[hash_val]; + table->bins[hash_val] = ptr; + table->num_entries++; + ptr = next; + } + } + free((char*)old_bins); +} + +st_table* +st_copy(old_table) + st_table *old_table; +{ + st_table *new_table; + st_table_entry *ptr, *tbl; + int i, num_bins = old_table->num_bins; + + new_table = alloc(st_table); + if (new_table == nil(st_table)) { + return nil(st_table); + } + + *new_table = *old_table; + new_table->bins = (st_table_entry**) + Calloc((unsigned)num_bins, sizeof(st_table_entry*)); + + if (new_table->bins == nil(st_table_entry*)) { + free((char*)new_table); + return nil(st_table); + } + + for(i = 0; i < num_bins ; i++) { + new_table->bins[i] = nil(st_table_entry); + ptr = old_table->bins[i]; + while (ptr != nil(st_table_entry)) { + tbl = alloc(st_table_entry); + if (tbl == nil(st_table_entry)) { + free((char*)new_table->bins); + free((char*)new_table); + return nil(st_table); + } + *tbl = *ptr; + tbl->next = new_table->bins[i]; + new_table->bins[i] = tbl; + ptr = ptr->next; + } + } + return new_table; +} + +int +st_delete(table, key, value) + register st_table *table; + register char **key; + char **value; +{ + int hash_val; + st_table_entry *tmp; + register st_table_entry *ptr; + + hash_val = do_hash(*key, table); + + ptr = table->bins[hash_val]; + + if (ptr == nil(st_table_entry)) { + if (value != nil(char*)) *value = nil(char); + return 0; + } + + if (EQUAL(table, *key, ptr->key)) { + table->bins[hash_val] = ptr->next; + table->num_entries--; + if (value != nil(char*)) *value = ptr->record; + *key = ptr->key; + free((char*)ptr); + return 1; + } + + for(; ptr->next != nil(st_table_entry); ptr = ptr->next) { + if (EQUAL(table, ptr->next->key, *key)) { + tmp = ptr->next; + ptr->next = ptr->next->next; + table->num_entries--; + if (value != nil(char*)) *value = tmp->record; + *key = tmp->key; + free((char*)tmp); + return 1; + } + } + + return 0; +} + +int +st_delete_safe(table, key, value, never) + register st_table *table; + register char **key; + char **value; + char *never; +{ + int hash_val; + register st_table_entry *ptr; + + hash_val = do_hash(*key, table); + + ptr = table->bins[hash_val]; + + if (ptr == nil(st_table_entry)) { + if (value != nil(char*)) *value = nil(char); + return 0; + } + + if (EQUAL(table, *key, ptr->key)) { + table->num_entries--; + *key = ptr->key; + if (value != nil(char*)) *value = ptr->record; + ptr->key = ptr->record = never; + return 1; + } + + for(; ptr->next != nil(st_table_entry); ptr = ptr->next) { + if (EQUAL(table, ptr->next->key, *key)) { + table->num_entries--; + *key = ptr->key; + if (value != nil(char*)) *value = ptr->record; + ptr->key = ptr->record = never; + return 1; + } + } + + return 0; +} + +void +st_foreach(table, func, arg) + st_table *table; + enum st_retval (*func)(); + char *arg; +{ + st_table_entry *ptr, *last, *tmp; + enum st_retval retval; + int i; + + for(i = 0; i < table->num_bins; i++) { + last = nil(st_table_entry); + for(ptr = table->bins[i]; ptr != nil(st_table_entry);) { + retval = (*func)(ptr->key, ptr->record, arg); + switch (retval) { + case ST_CONTINUE: + last = ptr; + ptr = ptr->next; + break; + case ST_STOP: + return; + case ST_DELETE: + tmp = ptr; + if (last == nil(st_table_entry)) { + table->bins[i] = ptr->next; + } else { + last->next = ptr->next; + } + ptr = ptr->next; + free((char*)tmp); + table->num_entries--; + } + } + } +} + +static int +strhash(string, modulus) + register char *string; + int modulus; +{ + register int val = 0; + register int c; + + while ((c = *string++) != '\0') { + val = val*997 + c; + } + + return ((val < 0) ? -val : val)%modulus; +} + +static int +numcmp(x, y) + int x, y; +{ + return x != y; +} + +static int +numhash(n, modulus) + int n; + int modulus; +{ + return n % modulus; +} diff --git a/st.h b/st.h new file mode 100644 index 0000000000..c27b110ce1 --- /dev/null +++ b/st.h @@ -0,0 +1,52 @@ +/* This is a general purpose hash table package written by Peter Moore @ UCB. */ + +/* @(#) st.h 5.1 89/12/14 */ + +#ifndef ST_INCLUDED + +#define ST_INCLUDED + +typedef struct st_table_entry st_table_entry; + +struct st_table_entry { + char *key; + char *record; + st_table_entry *next; +}; + +typedef struct st_table st_table; + +struct st_hash_type { + int (*compare)(); + int (*hash)(); +}; + +struct st_table { + struct st_hash_type *type; + int num_bins; + int num_entries; + st_table_entry **bins; +}; + +#define st_is_member(table,key) st_lookup(table,key,(char **) 0) + +enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; + +st_table *st_init_table(); +st_table *st_init_table_with_size(); +st_table *st_init_numtable(); +st_table *st_init_strtable(); +int st_delete(), st_delete_safe(), st_insert(); +int st_lookup(), st_find_or_add(); +void st_foreach(), st_add_direct(), st_free_table(); +st_table *st_copy(); + +#define ST_NUMCMP ((int (*)()) 0) +#define ST_NUMHASH ((int (*)()) -2) + +#define st_numcmp ST_NUMCMP +#define st_numhash ST_NUMHASH + +int st_strhash(); + +#endif /* ST_INCLUDED */ diff --git a/string.c b/string.c index 3c3d24f3cf..8c5b4eb76b 100644 --- a/string.c +++ b/string.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 17:12:58 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/time.c b/time.c index 1749c32319..f1b40a3606 100644 --- a/time.c +++ b/time.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 28 14:31:59 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/util.c b/util.c index 21e0a55639..527ce87d03 100644 --- a/util.c +++ b/util.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Mar 10 17:22:34 JST 1995 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ diff --git a/util.h b/util.h index 570d894ccb..78f8169fdb 100644 --- a/util.h +++ b/util.h @@ -6,7 +6,7 @@ $Date$ created at: Thu Mar 9 11:55:53 JST 1995 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ #ifndef UTIL_H diff --git a/variable.c b/variable.c index 0115b87d68..fa3a79516f 100644 --- a/variable.c +++ b/variable.c @@ -97,14 +97,14 @@ fc_i(key, value, res) } static VALUE -find_class_path(cls) - VALUE cls; +find_class_path(klass) + VALUE klass; { struct fc_result arg; arg.name = 0; arg.path = 0; - arg.klass = cls; + arg.klass = klass; arg.track = cObject; arg.prev = 0; if (RCLASS(cObject)->iv_tbl) { @@ -114,30 +114,24 @@ find_class_path(cls) st_foreach(class_tbl, fc_i, &arg); } if (arg.name) { - rb_iv_set(cls, "__classpath__", arg.path); + rb_iv_set(klass, "__classpath__", arg.path); return arg.path; } return Qnil; } static VALUE -classname(cls) - VALUE cls; +classname(klass) + VALUE klass; { VALUE path; - while (TYPE(cls) == T_ICLASS || FL_TEST(cls, FL_SINGLETON)) { - cls = (VALUE)RCLASS(cls)->super; - } - path = rb_iv_get(cls, "__classpath__"); - if (NIL_P(path)) { - path = rb_iv_get(cls, "__classid__"); - if (!NIL_P(path)) { - path = str_new2(rb_id2name(FIX2INT(path))); - } + while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) { + klass = (VALUE)RCLASS(klass)->super; } + path = rb_iv_get(klass, "__classpath__"); if (NIL_P(path)) { - path = find_class_path(cls); + path = find_class_path(klass); if (NIL_P(path)) { return 0; } @@ -153,30 +147,30 @@ mod_name(mod) { VALUE path = classname(mod); - if (path) return path; + if (path) return str_dup(path); return str_new(0,0); } VALUE -rb_class_path(cls) - VALUE cls; +rb_class_path(klass) + VALUE klass; { - VALUE path = classname(cls); + VALUE path = classname(klass); if (path) return path; else { char buf[256]; char *s = "Class"; - if (TYPE(cls) == T_MODULE) s = "Module"; - sprintf(buf, "#<%s 0x%x>", s, cls); + if (TYPE(klass) == T_MODULE) s = "Module"; + sprintf(buf, "#<%s 0x%x>", s, klass); return str_new2(buf); } } void -rb_set_class_path(cls, under, name) - VALUE cls, under; +rb_set_class_path(klass, under, name) + VALUE klass, under; char *name; { VALUE str; @@ -189,7 +183,7 @@ rb_set_class_path(cls, under, name) str_cat(str, "::", 2); str_cat(str, name, strlen(name)); } - rb_iv_set(cls, "__classpath__", str); + rb_iv_set(klass, "__classpath__", str); } VALUE @@ -203,18 +197,13 @@ rb_path2class(path) } void -rb_name_class(cls, id) - VALUE cls; +rb_name_class(klass, id) + VALUE klass; ID id; { extern VALUE cString; - if (cString) { - rb_iv_set(cls, "__classpath__", str_new2(rb_id2name(id))); - } - else { - rb_iv_set(cls, "__classid__", INT2FIX(id)); - } + rb_iv_set(klass, "__classpath__", str_new2(rb_id2name(id))); } static st_table *autoload_tbl = 0; @@ -235,17 +224,17 @@ rb_autoload_id(id, filename) } void -rb_autoload(cls, filename) - char *cls, *filename; +rb_autoload(klass, filename) + char *klass, *filename; { - rb_autoload_id(rb_intern(cls), filename); + rb_autoload_id(rb_intern(klass), filename); } VALUE -f_autoload(obj, cls, file) - VALUE obj, cls, file; +f_autoload(obj, klass, file) + VALUE obj, klass, file; { - ID id = rb_to_id(cls); + ID id = rb_to_id(klass); Check_Type(file, T_STRING); rb_autoload_id(id, RSTRING(file)->ptr); @@ -253,10 +242,10 @@ f_autoload(obj, cls, file) } char * -rb_class2name(cls) - VALUE cls; +rb_class2name(klass) + VALUE klass; { - return RSTRING(rb_class_path(cls))->ptr; + return RSTRING(rb_class_path(klass))->ptr; } struct trace_var { @@ -817,41 +806,41 @@ obj_remove_instance_variable(obj, name) } VALUE -rb_const_get_at(cls, id) - VALUE cls; +rb_const_get_at(klass, id) + VALUE klass; ID id; { VALUE value; - if (RCLASS(cls)->iv_tbl && st_lookup(RCLASS(cls)->iv_tbl, id, &value)) { + if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &value)) { return value; } - if (cls == cObject) { - return rb_const_get(cls, id); + if (klass == cObject) { + return rb_const_get(klass, id); } NameError("Uninitialized constant %s::%s", - RSTRING(rb_class_path(cls))->ptr, + RSTRING(rb_class_path(klass))->ptr, rb_id2name(id)); /* not reached */ } VALUE -rb_const_get(cls, id) - VALUE cls; +rb_const_get(klass, id) + VALUE klass; ID id; { VALUE value; VALUE tmp; - tmp = cls; + tmp = klass; while (tmp) { if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) { return value; } tmp = RCLASS(tmp)->super; } - if (BUILTIN_TYPE(cls) == T_MODULE) { + if (BUILTIN_TYPE(klass) == T_MODULE) { return rb_const_get(cObject, id); } @@ -867,13 +856,13 @@ rb_const_get(cls, id) module = str_new2(modname); free(modname); f_require(0, module); - return rb_const_get(cls, id); + return rb_const_get(klass, id); } /* Uninitialized constant */ - if (cls && cls != cObject) + if (klass && klass != cObject) NameError("Uninitialized constant %s::%s", - RSTRING(rb_class_path(cls))->ptr, + RSTRING(rb_class_path(klass))->ptr, rb_id2name(id)); else { NameError("Uninitialized constant %s",rb_id2name(id)); @@ -947,15 +936,15 @@ mod_const_of(mod, ary) } int -rb_const_defined_at(cls, id) - VALUE cls; +rb_const_defined_at(klass, id) + VALUE klass; ID id; { - if (RCLASS(cls)->iv_tbl && st_lookup(RCLASS(cls)->iv_tbl, id, 0)) { + if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, 0)) { return TRUE; } - if (cls == cObject) { - return rb_const_defined(cls, id); + if (klass == cObject) { + return rb_const_defined(klass, id); } return FALSE; } @@ -970,15 +959,15 @@ rb_autoload_defined(id) } int -rb_const_defined(cls, id) - VALUE cls; +rb_const_defined(klass, id) + VALUE klass; ID id; { - while (cls) { - if (RCLASS(cls)->iv_tbl && st_lookup(RCLASS(cls)->iv_tbl, id, 0)) { + while (klass) { + if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, 0)) { return TRUE; } - cls = RCLASS(cls)->super; + klass = RCLASS(klass)->super; } if (st_lookup(class_tbl, id, 0)) return TRUE; @@ -986,24 +975,24 @@ rb_const_defined(cls, id) } void -rb_const_set(cls, id, val) - VALUE cls; +rb_const_set(klass, id, val) + VALUE klass; ID id; VALUE val; { - if (!RCLASS(cls)->iv_tbl) { - RCLASS(cls)->iv_tbl = new_idhash(); + if (!RCLASS(klass)->iv_tbl) { + RCLASS(klass)->iv_tbl = new_idhash(); } - else if (st_lookup(RCLASS(cls)->iv_tbl, id, 0)) { + else if (st_lookup(RCLASS(klass)->iv_tbl, id, 0)) { NameError("already initialized constant %s", rb_id2name(id)); } - st_insert(RCLASS(cls)->iv_tbl, id, val); + st_insert(RCLASS(klass)->iv_tbl, id, val); } void -rb_define_const(cls, name, val) - VALUE cls; +rb_define_const(klass, name, val) + VALUE klass; char *name; VALUE val; { @@ -1011,7 +1000,7 @@ rb_define_const(cls, name, val) if (!rb_is_const_id(id)) { NameError("wrong constant name %s", name); } - rb_const_set(cls, id, val); + rb_const_set(klass, id, val); } void diff --git a/version.c b/version.c index 71f531c963..7f1832a4af 100644 --- a/version.c +++ b/version.c @@ -7,7 +7,7 @@ $Date$ created at: Thu Sep 30 20:08:01 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -31,6 +31,6 @@ show_version() void show_copyright() { - fprintf(stderr, "ruby - Copyright (C) 1993-1997 Yukihiro Matsumoto\n"); + fprintf(stderr, "ruby - Copyright (C) 1993-1998 Yukihiro Matsumoto\n"); exit(0); } diff --git a/version.h b/version.h index b737876434..0c921244af 100644 --- a/version.h +++ b/version.h @@ -1,2 +1,2 @@ -#define RUBY_VERSION "1.1b5" -#define VERSION_DATE "98/01/16" +#define RUBY_VERSION "1.1b6" +#define VERSION_DATE "98/01/23" diff --git a/win32/sdbm.c b/win32/sdbm.c index 0e4673bbb5..39fbb72d40 100644 --- a/win32/sdbm.c +++ b/win32/sdbm.c @@ -8,7 +8,7 @@ */ #ifndef lint -/*char sdbm_rcsid[] = "$Id: sdbm.c,v 1.16 90/12/13 13:01:31 oz Exp $";*/ +/*char sdbm_rcsid[] = "$Id: sdbm.c,v 1.1.1.1 1998/01/16 04:14:57 matz Exp $";*/ #endif #include "sdbm.h" @@ -634,7 +634,7 @@ register DBM *db; */ #ifndef lint -/*char pair_rcsid[] = "$Id: pair.c,v 1.10 90/12/13 13:00:35 oz Exp $";*/ +/*char pair_rcsid[] = "$Id: sdbm.c,v 1.1.1.1 1998/01/16 04:14:57 matz Exp $";*/ #endif #ifndef BSD42 -- cgit v1.2.3