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

prototypes

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@210 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1998-05-14 04:10:39 +00:00
parent ae2fe781dd
commit c250849216
19 changed files with 714 additions and 553 deletions

4
README
View file

@ -3,7 +3,7 @@
Ruby is the interpreted scripting language for quick and
easy object-oriented programming. It has many features to
process text files and to do system management tasks (as in
perl). It is simple, straight-forward, and extensible.
Perl). It is simple, straight-forward, and extensible.
* Features of Ruby
@ -97,7 +97,7 @@ You can redistribute it and/or modify it under either the terms of the GPL
are not written by the author, so that they are not under this terms.
They are gc.c(partly), utils.c(partly), regex.[ch], fnmatch.[ch],
glob.c, st.[ch] and some files under the ./missing directory. See
each files for the copying condition.
each file for the copying condition.
5. The scripts and library files supplied as input to or produced as
output from the software do not automatically fall under the

View file

@ -1,21 +1,16 @@
.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
This document explains how to make extention modules for ruby.
This document explains how to make extention modules for Ruby.
1Basic knowledge
In C, variables have types and data do not have types. In contrast,
ruby variables do not have static type and data themselves have
Ruby variables do not have static type and data themselves have
types. So, data need to be converted across the languages.
Data in ruby represented C type `VALUE'. Each VALUE data have its
Data in Ruby represented C type `VALUE'. Each VALUE data have its
data-type.
rubyのデータはVALUEというCの型で表現されますVALUE型のデー
タはそのデータタイプを自分で知っています.このデータタイプと
いうのはデータ(オブジェクト)の実際の構造を意味していてruby
のクラスとはまた違ったものです.
To retrieve an C data from the VALUE, you need to:
(1) Identify VALUE's data type
@ -38,7 +33,7 @@ Ruby interpreter has data-types as below:
T_ARRAY array
T_FIXNUM Fixnum(31bit integer)
T_HASH assosiative array
T_STRUCT (ruby) structure
T_STRUCT (Ruby) structure
T_BIGNUM multi precision integer
T_TRUE true
T_FALSE false
@ -90,12 +85,12 @@ There are faster check-macros for fixnums and nil.
1.3 Convert VALUE into C data
データタイプがT_NIL, T_FALSE, T_TRUEである時データはそれぞ
れnil, FALSE, TRUEです.このデータタイプのオブジェクトはひと
れnil, false, trueです.このデータタイプのオブジェクトはひと
つずつしか存在しません.
データタイプがT_FIXNUMの時これは31bitのサイズを持つ整数で
FIXNUMをCの整数に変換するためにはマクロ「FIX2INT()」を使
いますそれからFIXNUMに限らずrubyのデータを整数に変換する
いますそれからFIXNUMに限らずRubyのデータを整数に変換する
「NUM2INT()」というマクロがあります.このマクロはデータタイ
プのチェック無しで使えます(整数に変換できない場合には例外が
発生する)
@ -116,7 +111,7 @@ ruby.h
とします配列の場合にはそれぞれ「RARRAT(str)->len」
「RARRAT(str)->ptr」となります
rubyの構造体を直接アクセスする時に気をつけなければならないこ
Rubyの構造体を直接アクセスする時に気をつけなければならないこ
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
ないことです.直接変更した場合,オブジェクトの内容の整合性が
とれなくなって,思わぬバグの原因になります.
@ -137,10 +132,10 @@ VALUE
うかわかるわけです(ポインタのLSBが立っていないことを仮定して
いる)
ですからFIXNUM以外のrubyのオブジェクトの構造体は単にVALUE
ですからFIXNUM以外のRubyのオブジェクトの構造体は単にVALUE
にキャストするだけでVALUEに変換出来ますただし任意の構造
体がVALUEにキャスト出来るわけではありませんキャストするの
rubyの知っている構造体(ruby.hで定義されているstruct RXxxx
Rubyの知っている構造体(ruby.hで定義されているstruct RXxxx
のもの)だけにしておいてください.
FIXNUMに関しては変換マクロを経由する必要がありますCの整数
@ -153,11 +148,11 @@ FIXNUM
INT2NUM()は整数がFIXNUMの範囲に収まらない場合Bignumに変換
してくれます(が,少し遅い)
1.5 Manipulate ruby data
1.5 Manipulate Ruby data
先程も述べた通り,rubyの構造体をアクセスする時に内容の更新を
行うことは勧められません.で,rubyのデータを操作する時には
rubyが用意している関数を用いてください
先程も述べた通り,Rubyの構造体をアクセスする時に内容の更新を
行うことは勧められません.で,Rubyのデータを操作する時には
Rubyが用意している関数を用いてください
ここではもっとも使われるであろう文字列と配列の生成/操作を行
い関数をあげます(全部ではないです)
@ -166,16 +161,16 @@ ruby
str_new(char *ptr, int len)
Creates a new ruby string.
Creates a new Ruby string.
str_new2(char *ptr)
Creates a new ruby string from C string. This is equivalent to
Creates a new Ruby string from C string. This is equivalent to
str_new(ptr, strlen(ptr)).
str_cat(VALUE str, char *ptr, int len)
Appends len bytes data from ptr to the ruby string.
Appends len bytes data from ptr to the Ruby string.
Array functions
@ -205,17 +200,17 @@ ruby
Array operations. The first argument to each functions must be an
array. They may dump core if other types given.
2. Extend ruby with C
2. Extend Ruby with C
原理的にrubyで書けることはCでも書けますrubyそのものがCで記
原理的にRubyで書けることはCでも書けますRubyそのものがCで記
述されているんですから,当然といえば当然なんですけど.ここで
rubyの拡張に使うことが多いだろうと予測される機能を中心に紹
Rubyの拡張に使うことが多いだろうと予測される機能を中心に紹
介します.
2.1 Add new features to ruby
2.1 Add new features to Ruby
rubyで提供されている関数を使えばrubyインタプリタに新しい機能
を追加することができます.rubyでは以下の機能を追加する関数が
Rubyで提供されている関数を使えばRubyインタプリタに新しい機能
を追加することができます.Rubyでは以下の機能を追加する関数が
提供されています.
* クラス,モジュール
@ -247,7 +242,7 @@ ruby
念のため説明すると「特異メソッド」とは,その特定のオブジェク
トに対してだけ有効なメソッドです.rubyではよくSmalltalkにお
トに対してだけ有効なメソッドです.RubyではよくSmalltalkにお
けるクラスメソッドとして,クラスに対する特異メソッドが使われ
ます.
@ -258,7 +253,7 @@ ruby
argcが負の時は引数の数ではなく形式を指定したことになります
argcが-1の時は引数を配列に入れて渡されますargcが-2の時は引
数はrubyの配列として渡されます
数はRubyの配列として渡されます
メソッドを定義する関数はもう二つありますひとつはprivateメ
ソッドを定義する関数で引数はrb_define_method()と同じです.
@ -304,21 +299,21 @@ private
前者は特定のクラス/モジュールに属する定数を定義するもの,後
者はグローバルな定数を定義するものです.
2.2 Use ruby features from C
2.2 Use Ruby features from C
既に『1.5 rubyのデータを操作する』で一部紹介したような関数を
使えば,rubyの機能を実現している関数を直接呼び出すことが出来
既に『1.5 Rubyのデータを操作する』で一部紹介したような関数を
使えば,Rubyの機能を実現している関数を直接呼び出すことが出来
ます.
# このような関数の一覧表はいまのところありません.ソースを見
# るしかないですね.
それ以外にもrubyの機能を呼び出す方法はいくつかあります
それ以外にもRubyの機能を呼び出す方法はいくつかあります
2.2.1 rubyのプログラムをevalする
2.2.1 Rubyのプログラムをevalする
Cからrubyの機能を呼び出すもっとも簡単な方法として文字列で
与えられたrubyのプログラムを評価する関数があります
CからRubyの機能を呼び出すもっとも簡単な方法として文字列で
与えられたRubyのプログラムを評価する関数があります
VALUE rb_eval_string(char *str)
@ -327,11 +322,11 @@ C
2.2.2 ID or Symbol
Cから文字列を経由せずにrubyのメソッドを呼び出すこともできま
す.その前に,rubyインタプリタ内でメソッドや変数名を指定する
Cから文字列を経由せずにRubyのメソッドを呼び出すこともできま
す.その前に,Rubyインタプリタ内でメソッドや変数名を指定する
時に使われているIDについて説明しておきましょう
IDとは変数名メソッド名を表す整数ですrubyの中では
IDとは変数名メソッド名を表す整数ですRubyの中では
:識別子
@ -342,9 +337,9 @@ ID
を使います.また一文字の演算子はその文字コードがそのままシン
ボルになっています.
2.2.3 Invoke ruby method from C
2.2.3 Invoke Ruby method from C
Cから文字列を経由せずにrubyのメソッドを呼び出すためには以下
Cから文字列を経由せずにRubyのメソッドを呼び出すためには以下
の関数を使います.
VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)
@ -373,13 +368,13 @@ id
クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ
れている関数を使ってください.
3. Informatin sharing between ruby and C
3. Informatin sharing between Ruby and C
C言語とrubyの間で情報を共有する方法について解説します
C言語とRubyの間で情報を共有する方法について解説します
3.1 Ruby constant that Cから参照できるrubyの定数
3.1 Ruby constant that Cから参照できるRubyの定数
Following ruby constants can be referred from C.
Following Ruby constants can be referred from C.
TRUE
FALSE
@ -390,19 +385,19 @@ Boolean values. FALSE is false in the C also (i.e. 0).
Ruby nil in C scope.
3.2 Global variables shared between C and ruby
3.2 Global variables shared between C and Ruby
Cとrubyで大域変数を使って情報を共有できます共有できる大域
CとRubyで大域変数を使って情報を共有できます共有できる大域
変数にはいくつかの種類があります.そのなかでもっとも良く使わ
れると思われるのはrb_define_variable()です.
void rb_define_variable(char *name, VALUE *var)
この関数はrubyとCとで共有する大域変数を定義します変数名が
この関数はRubyとCとで共有する大域変数を定義します変数名が
`$'で始まらない時には自動的に追加されます.この変数の値を変
更すると自動的にrubyの対応する変数の値も変わります
更すると自動的にRubyの対応する変数の値も変わります
またruby側からは更新できない変数もありますこのread onlyの
またRuby側からは更新できない変数もありますこのread onlyの
変数は以下の関数で定義します.
void rb_define_readonly_variable(char *name, VALUE *var)
@ -421,13 +416,13 @@ setter
# getterもsetterも0ならばrb_define_variable()と同じになる.
それからCの関数によって実現されるrubyの大域変数を定義する
それからCの関数によって実現されるRubyの大域変数を定義する
関数があります.
void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)())
この関数によって定義されたrubyの大域変数が参照された時には
この関数によって定義されたRubyの大域変数が参照された時には
getterが変数に値がセットされた時にはsetterが呼ばれます
The prototypes of the getter and setter functions are as following:
@ -435,14 +430,14 @@ The prototypes of the getter and setter functions are as following:
(*getter)(ID id, void *data, struct global_entry* entry);
(*setter)(VALUE val, ID id, void *data, struct global_entry* entry);
3.3 Encapsulate C data into ruby object
3.3 Encapsulate C data into Ruby object
Cの世界で定義されたデータ(構造体)をrubyのオブジェクトとして
Cの世界で定義されたデータ(構造体)をRubyのオブジェクトとして
取り扱いたい場合がありえますこのような場合にはDataという
rubyオブジェクトにCの構造体(へのポインタ)をくるむことでruby
RubyオブジェクトにCの構造体(へのポインタ)をくるむことでRuby
オブジェクトとして取り扱えるようになります.
Dataオブジェクトを生成して構造体をrubyオブジェクトにカプセル
Dataオブジェクトを生成して構造体をRubyオブジェクトにカプセル
化するためには,以下のマクロを使います.
Data_Wrap_Struct(class,mark,free,ptr)
@ -450,7 +445,7 @@ Data
このマクロの戻り値は生成されたDataオブジェクトです
classはこのDataオブジェクトのクラスですptrはカプセル化する
Cの構造体へのポインタですmarkはこの構造体がrubyのオブジェ
Cの構造体へのポインタですmarkはこの構造体がRubyのオブジェ
クトへの参照がある時に使う関数です.そのような参照を含まない
時には0を指定します
@ -483,14 +478,14 @@ C
4Example - Create dbm module
ここまでの説明でとりあえず拡張モジュールは作れるはずです.
rubyのextディレクトリにすでに含まれているdbmモジュールを例に
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
して段階的に説明します.
(1) make the directory
% mkdir ext/dbm
rubyを展開したディレクトリの下extディレクトリの中に拡張モ
Rubyを展開したディレクトリの下extディレクトリの中に拡張モ
ジュール用のディレクトリを作ります.名前は適当に選んで構いま
せん.
@ -522,7 +517,7 @@ MANIFEST
ル生成時に中間的に生成される「モジュール名.o」というファイル
とが衝突するからです.
rubyは拡張モジュールをロードする時に「Init_モジュール名」と
Rubyは拡張モジュールをロードする時に「Init_モジュール名」と
いう関数を自動的に実行しますdbmモジュールの場合「Init_dbm」
です.この関数の中でクラス,モジュール,メソッド,定数などの
定義を行いますdbm.cから一部引用します
@ -550,7 +545,7 @@ Init_dbm()
--
DBMモジュールはdbmのデータと対応するオブジェクトになるはずで
すからCの世界のdbmをrubyの世界に取り込む必要があります
すからCの世界のdbmをRubyの世界に取り込む必要があります
dbm.cではData_Make_Structを以下のように使っています
@ -600,7 +595,7 @@ fdbm_delete(obj, keystr)
引数の数が固定のタイプは第1引数がself第2引数以降がメソッド
の引数となります.
引数の数が不定のものはCの配列で受けるものとrubyの配列で受け
引数の数が不定のものはCの配列で受けるものとRubyの配列で受け
るものとがありますdbmモジュールの中でCの配列で受けるもの
はDBMのクラスメソッドであるopen()です.これを実装している関
数fdbm_s_open()はこうなっています.
@ -634,7 +629,7 @@ fdbm_s_open(argc, argv, class)
2つまで許されるという意味になります省略されている時の
変数の値はnil(C言語のレベルではQnil)になります.
rubyの配列で引数を受け取るものはindexesがあります実装はこ
Rubyの配列で引数を受け取るものはindexesがあります実装はこ
うです.
--
@ -647,14 +642,14 @@ fdbm_indexes(obj, args)
}
--
第1引数はself第2引数はrubyの配列ですここではキャストを減
第1引数はself第2引数はRubyの配列ですここではキャストを減
らすため struct RArray* で受けていますがVALUEでも同じこと
です.
** 注意事項
rubyと共有はしないがrubyのオブジェクトを格納する可能性のある
Cの大域変数は以下の関数を使ってrubyインタプリタに変数の存在
Rubyと共有はしないがRubyのオブジェクトを格納する可能性のある
Cの大域変数は以下の関数を使ってRubyインタプリタに変数の存在
を教えてあげてくださいでないとGCでトラブルを起こします
void rb_global_variable(VALUE *var)
@ -665,7 +660,7 @@ C
make時に実行されますなければ適当にMakefileが生成されます
extconf.rbはモジュールのコンパイルに必要な条件のチェックなど
を行うことが目的ですextconf.rbの中では以下のruby関数を使う
を行うことが目的ですextconf.rbの中では以下のRuby関数を使う
ことが出来ます.
have_library(lib, func): ライブラリの存在チェック
@ -704,31 +699,31 @@ make
(8) make
rubyのディレクトリでmakeを実行するとMakefileを生成からmake
必要によってはそのモジュールのrubyへのリンクまで自動的に実行
Rubyのディレクトリでmakeを実行するとMakefileを生成からmake
必要によってはそのモジュールのRubyへのリンクまで自動的に実行
してくれますextconf.rbを書き換えるなどしてMakefileの再生成
が必要な時はまたrubyディレクトリでmakeしてください
が必要な時はまたRubyディレクトリでmakeしてください
(9) debug
まあデバッグしないと動かないでしょうねext/Setupにディレ
クトリ名を書くと静的にリンクするのでデバッガが使えるようにな
ります.その分コンパイルが遅くなりますけど.
You may need to debug the module. The modules can be linked
statically by adding directory name in the ext/Setup file,
so that you can inspect the module by the debugger.
(10) done, now you have the extension module
後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお
使いください.rubyの作者は拡張モジュールに関して一切の権利を
使いください.Rubyの作者は拡張モジュールに関して一切の権利を
主張しません.
Appendix A. rubyのソースコードの分類
Appendix A. Rubyのソースコードの分類
rubyのソースはいくつかに分類することが出来ますこのうちクラ
Rubyのソースはいくつかに分類することが出来ますこのうちクラ
スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ
ています.これらのソースは今までの説明でほとんど理解できると
思います.
coore ruby language
ruby language core
class.c
error.c
@ -780,13 +775,13 @@ class library
Appendix B. 拡張用関数リファレンス
C言語からrubyの機能を利用するAPIは以下の通りである
C言語からRubyの機能を利用するAPIは以下の通りである
** 型
VALUE
rubyオブジェクトを表現する型必要に応じてキャストして用いる
Rubyオブジェクトを表現する型必要に応じてキャストして用いる
組み込み型を表現するCの型はruby.hに記述してあるRで始まる構造
体であるVALUE型をこれらにキャストするためにRで始まる構造体
名を全て大文字にした名前のマクロが用意されている.
@ -809,9 +804,9 @@ const: FALSE object
Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval)
Cの任意のポインタをカプセル化したrubyオブジェクトを返す
のポインタがrubyからアクセスされなくなった時freeで指定した
関数が呼ばれる.また,このポインタの指すデータが他のrubyオブ
Cの任意のポインタをカプセル化したRubyオブジェクトを返す
のポインタがRubyからアクセスされなくなった時freeで指定した
関数が呼ばれる.また,このポインタの指すデータが他のRubyオブ
ジェクトを指している場合markに指定する関数でマークする必要
がある.
@ -828,20 +823,20 @@ data
VALUE rb_define_class(char *name, VALUE super)
superのサブクラスとして新しいrubyクラスを定義する
superのサブクラスとして新しいRubyクラスを定義する
VALUE rb_define_class_under(VALUE module, char *name, VALUE super)
superのサブクラスとして新しいrubyクラスを定義しmoduleの定
superのサブクラスとして新しいRubyクラスを定義しmoduleの定
数として定義する.
VALUE rb_define_module(char *name)
新しいrubyモジュールを定義する
新しいRubyモジュールを定義する
VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
新しいrubyモジュールを定義しmoduleの定数として定義する
新しいRubyモジュールを定義しmoduleの定数として定義する
void rb_include_module(VALUE class, VALUE module)
@ -856,20 +851,20 @@ super
void rb_define_variable(char *name, VALUE *var)
rubyとCとで共有するグローバル変数を定義する変数名が`$'で始
まらない時には自動的に追加されるnameとしてrubyの識別子とし
て許されない文字(例えば` ')を含む場合にはrubyプログラムから
RubyとCとで共有するグローバル変数を定義する変数名が`$'で始
まらない時には自動的に追加されるnameとしてRubyの識別子とし
て許されない文字(例えば` ')を含む場合にはRubyプログラムから
は見えなくなる.
void rb_define_readonly_variable(char *name, VALUE *var)
rubyとCとで共有するread onlyのグローバル変数を定義するread
RubyとCとで共有するread onlyのグローバル変数を定義するread
onlyであること以外はrb_define_variable()と同じ.
void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)())
関数によって実現されるruby変数を定義する変数が参照された時
関数によって実現されるRuby変数を定義する変数が参照された時
にはgetterが変数に値がセットされた時にはsetterが呼ばれる
void rb_define_hooked_variable(char *name, VALUE *var,
@ -882,7 +877,7 @@ only
void rb_global_variable(VALUE *var)
GCのためrubyプログラムからはアクセスされないが, rubyオブジェ
GCのためRubyプログラムからはアクセスされないが, Rubyオブジェ
クトを含む大域変数をマークする.
** クラス定数
@ -906,7 +901,7 @@ GC
メソッドを定義するargcはselfを除く引数の数argcが-1の時,
関数には引数の数(selfを含まない)を第1引数, 引数の配列を第2引
数とする形式で与えられる(第3引数はself)argcが-2の時, 第1引
数がself, 第2引数がargs(argsは引数を含むrubyの配列)という形
数がself, 第2引数がargs(argsは引数を含むRubyの配列)という形
式で与えられる.
rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
@ -927,7 +922,7 @@ argc,argv
数に対応する引数が与えられていない場合は変数にQnilが代入され
る.
** rubyメソッド呼び出し
** Rubyメソッド呼び出し
VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)
@ -939,7 +934,7 @@ argc,argv
VALUE rb_eval_string(char *str)
文字列をrubyとスクリプトしてコンパイル・実行する
文字列をRubyとスクリプトしてコンパイル・実行する
ID rb_intern(char *name)
@ -959,7 +954,7 @@ class
VALUE rb_iv_get(VALUE obj, char *name)
objのインスタンス変数の値を得る`@'で始まらないインスタンス
変数は rubyプログラムからアクセスできない「隠れた」インスタ
変数は Rubyプログラムからアクセスできない「隠れた」インスタ
ンス変数になる.
VALUE rb_iv_set(VALUE obj, char *name, VALUE val)
@ -1013,22 +1008,23 @@ verbose
況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外
処理は一切行なわれない.
** rubyの初期化・実行
** Rubyの初期化・実行
rubyをアプリケーションに埋め込む場合には以下のインタフェース
Rubyをアプリケーションに埋め込む場合には以下のインタフェース
を使う.通常の拡張モジュールには必要ない.
void ruby_init(int argc, char **argv, char **envp)
rubyインタプリタの初期化を行なう
Rubyインタプリタの初期化を行なう
void ruby_run()
rubyインタプリタを実行する
Rubyインタプリタを実行する
void ruby_script(char *name)
rubyのスクリプト名($0)を設定する.
Rubyのスクリプト名($0)を設定する.
Appendix B. extconf.rbで使える関数たち

View file

@ -1,18 +1,18 @@
.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
rubyの拡張モジュールの作り方を説明します
Rubyの拡張モジュールの作り方を説明します
1基礎知識
Cの変数には型がありデータには型がありませんですから
とえばポインタをintの変数に代入するとその値は整数として取
り扱われます.逆にrubyの変数には型がなくデータに型がありま
この違いのためCとrubyは相互に変換しなければお互いの
り扱われます.逆にRubyの変数には型がなくデータに型がありま
この違いのためCとRubyは相互に変換しなければお互いの
データをアクセスできません.
rubyのデータはVALUEというCの型で表現されますVALUE型のデー
RubyのデータはVALUEというCの型で表現されますVALUE型のデー
タはそのデータタイプを自分で知っています.このデータタイプと
いうのはデータ(オブジェクト)の実際の構造を意味していて,ruby
いうのはデータ(オブジェクト)の実際の構造を意味していて,Ruby
のクラスとはまた違ったものです.
VALUEからCにとって意味のあるデータを取り出すためには
@ -25,7 +25,7 @@ VALUE
1.1 データタイプ
rubyにはユーザが使う可能性のある以下のタイプがあります
Rubyにはユーザが使う可能性のある以下のタイプがあります
T_NIL nil
T_OBJECT 通常のオブジェクト
@ -37,7 +37,7 @@ ruby
T_ARRAY 配列
T_FIXNUM Fixnum(31bit長整数)
T_HASH 連想配列
T_STRUCT (rubyの)構造体
T_STRUCT (Rubyの)構造体
T_BIGNUM 多倍長整数
T_FILE 入出力
T_TRUE 真
@ -99,7 +99,7 @@ FIXNUM
データタイプがT_FIXNUMの時これは31bitのサイズを持つ整数で
FIXNUMをCの整数に変換するためにはマクロ「FIX2INT()」を使
いますそれからFIXNUMに限らずrubyのデータを整数に変換する
いますそれからFIXNUMに限らずRubyのデータを整数に変換する
「NUM2INT()」というマクロがあります.このマクロはデータタイ
プのチェック無しで使えます(整数に変換できない場合には例外が
発生する)
@ -123,7 +123,7 @@ ruby.h
とします配列の場合にはそれぞれ「RARRAY(str)->len」
「RARRAY(str)->ptr」となります
rubyの構造体を直接アクセスする時に気をつけなければならないこ
Rubyの構造体を直接アクセスする時に気をつけなければならないこ
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
ないことです.直接変更した場合,オブジェクトの内容の整合性が
とれなくなって,思わぬバグの原因になります.
@ -144,10 +144,10 @@ VALUE
うかわかるわけです(ポインタのLSBが立っていないことを仮定して
いる)
ですからFIXNUM以外のrubyのオブジェクトの構造体は単にVALUE
ですからFIXNUM以外のRubyのオブジェクトの構造体は単にVALUE
にキャストするだけでVALUEに変換出来ますただし任意の構造
体がVALUEにキャスト出来るわけではありませんキャストするの
rubyの知っている構造体(ruby.hで定義されているstruct RXxxx
Rubyの知っている構造体(ruby.hで定義されているstruct RXxxx
のもの)だけです.
FIXNUMに関しては変換マクロを経由する必要がありますCの整数
@ -160,11 +160,11 @@ FIXNUM
INT2NUM()は整数がFIXNUMの範囲に収まらない場合Bignumに変換
してくれます(が,少し遅い)
1.5 rubyのデータを操作する
1.5 Rubyのデータを操作する
先程も述べた通り,rubyの構造体をアクセスする時に内容の更新を
行うことは勧められません.で,rubyのデータを操作する時には
rubyが用意している関数を用いてください
先程も述べた通り,Rubyの構造体をアクセスする時に内容の更新を
行うことは勧められません.で,Rubyのデータを操作する時には
Rubyが用意している関数を用いてください
ここではもっとも使われるであろう文字列と配列の生成/操作を行
い関数をあげます(全部ではないです)
@ -173,16 +173,16 @@ ruby
str_new(char *ptr, int len)
新しいrubyの文字列を生成する
新しいRubyの文字列を生成する
str_new2(char *ptr)
Cの文字列からrubyの文字列を生成するこの関数の機能は
Cの文字列からRubyの文字列を生成するこの関数の機能は
str_new(ptr, strlen(ptr))と同等である.
str_cat(VALUE str, char *ptr, int len)
rubyの文字列strにlenバイトの文字列ptrを追加する
Rubyの文字列strにlenバイトの文字列ptrを追加する
配列に対する関数
@ -212,17 +212,17 @@ ruby
Arrayの同名のメソッドと同じ働きをする関数第1引数は必ず
配列でなければならない.
2rubyの機能を使う
2Rubyの機能を使う
原理的にrubyで書けることはCでも書けますrubyそのものがCで記
原理的にRubyで書けることはCでも書けますRubyそのものがCで記
述されているんですから,当然といえば当然なんですけど.ここで
rubyの拡張に使うことが多いだろうと予測される機能を中心に紹
Rubyの拡張に使うことが多いだろうと予測される機能を中心に紹
介します.
2.1 rubyに機能を追加する
2.1 Rubyに機能を追加する
rubyで提供されている関数を使えばrubyインタプリタに新しい機能
を追加することができます.rubyでは以下の機能を追加する関数が
Rubyで提供されている関数を使えばRubyインタプリタに新しい機能
を追加することができます.Rubyでは以下の機能を追加する関数が
提供されています.
* クラス,モジュール
@ -260,7 +260,7 @@ ruby
念のため説明すると「特異メソッド」とは,その特定のオブジェク
トに対してだけ有効なメソッドです.rubyではよくSmalltalkにお
トに対してだけ有効なメソッドです.RubyではよくSmalltalkにお
けるクラスメソッドとして,クラスに対する特異メソッドが使われ
ます.
@ -272,7 +272,7 @@ ruby
argcが負の時は引数の数ではなく形式を指定したことになります
argcが-1の時は引数を配列に入れて渡されますargcが-2の時は引
数はrubyの配列として渡されます
数はRubyの配列として渡されます
メソッドを定義する関数はもう二つありますひとつはprivateメ
ソッドを定義する関数で引数はrb_define_method()と同じです.
@ -318,21 +318,21 @@ private
前者は特定のクラス/モジュールに属する定数を定義するもの,後
者はグローバルな定数を定義するものです.
2.2 rubyの機能をCから呼び出す
2.2 Rubyの機能をCから呼び出す
既に『1.5 rubyのデータを操作する』で一部紹介したような関数を
使えば,rubyの機能を実現している関数を直接呼び出すことが出来
既に『1.5 Rubyのデータを操作する』で一部紹介したような関数を
使えば,Rubyの機能を実現している関数を直接呼び出すことが出来
ます.
# このような関数の一覧表はいまのところありません.ソースを見
# るしかないですね.
それ以外にもrubyの機能を呼び出す方法はいくつかあります
それ以外にもRubyの機能を呼び出す方法はいくつかあります
2.2.1 rubyのプログラムをevalする
2.2.1 Rubyのプログラムをevalする
Cからrubyの機能を呼び出すもっとも簡単な方法として文字列で
与えられたrubyのプログラムを評価する関数があります
CからRubyの機能を呼び出すもっとも簡単な方法として文字列で
与えられたRubyのプログラムを評価する関数があります
VALUE rb_eval_string(char *str)
@ -341,11 +341,11 @@ C
2.2.2 IDまたはシンボル
Cから文字列を経由せずにrubyのメソッドを呼び出すこともできま
す.その前に,rubyインタプリタ内でメソッドや変数名を指定する
Cから文字列を経由せずにRubyのメソッドを呼び出すこともできま
す.その前に,Rubyインタプリタ内でメソッドや変数名を指定する
時に使われているIDについて説明しておきましょう
IDとは変数名メソッド名を表す整数ですrubyの中では
IDとは変数名メソッド名を表す整数ですRubyの中では
:識別子
@ -354,14 +354,14 @@ ID
rb_intern(char *name)
を使います.また一文字の演算子はその文字コードがそのままシン
ボルになっています.rubyから引数として与えられたシンボル(ま
ボルになっています.Rubyから引数として与えられたシンボル(ま
たは文字列)をIDに変換するには以下の関数を使います
rb_to_id(VALUE symbol)
2.2.3 Cからrubyのメソッドを呼び出す
2.2.3 CからRubyのメソッドを呼び出す
Cから文字列を経由せずにrubyのメソッドを呼び出すためには以下
Cから文字列を経由せずにRubyのメソッドを呼び出すためには以下
の関数を使います.
VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)
@ -372,7 +372,7 @@ C
VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)
VALUE rb_apply(VALUE recv, ID mid, VALUE args)
applyには引数としてrubyの配列を与えます
applyには引数としてRubyの配列を与えます
2.2.4 変数/定数を参照/更新する
@ -395,13 +395,13 @@ id
クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ
れている関数を使ってください.
3rubyとCとの情報共有
3RubyとCとの情報共有
C言語とrubyの間で情報を共有する方法について解説します
C言語とRubyの間で情報を共有する方法について解説します
3.1 Cから参照できるrubyの定数
3.1 Cから参照できるRubyの定数
以下のrubyの定数はCのレベルから参照できる
以下のRubyの定数はCのレベルから参照できる
TRUE
FALSE
@ -412,19 +412,19 @@ C
C言語から見た「nil」
3.2 Cとrubyで共有される大域変数
3.2 CとRubyで共有される大域変数
Cとrubyで大域変数を使って情報を共有できます共有できる大域
CとRubyで大域変数を使って情報を共有できます共有できる大域
変数にはいくつかの種類があります.そのなかでもっとも良く使わ
れると思われるのはrb_define_variable()です.
void rb_define_variable(char *name, VALUE *var)
この関数はrubyとCとで共有する大域変数を定義します変数名が
この関数はRubyとCとで共有する大域変数を定義します変数名が
`$'で始まらない時には自動的に追加されます.この変数の値を変
更すると自動的にrubyの対応する変数の値も変わります
更すると自動的にRubyの対応する変数の値も変わります
またruby側からは更新できない変数もありますこのread onlyの
またRuby側からは更新できない変数もありますこのread onlyの
変数は以下の関数で定義します.
void rb_define_readonly_variable(char *name, VALUE *var)
@ -443,13 +443,13 @@ setter
# getterもsetterも0ならばrb_define_variable()と同じになる.
それからCの関数によって実現されるrubyの大域変数を定義する
それからCの関数によって実現されるRubyの大域変数を定義する
関数があります.
void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)())
この関数によって定義されたrubyの大域変数が参照された時には
この関数によって定義されたRubyの大域変数が参照された時には
getterが変数に値がセットされた時にはsetterが呼ばれます
getterとsetterの仕様は以下の通りです
@ -457,14 +457,14 @@ getter
(*getter)(ID id, void *data, struct global_entry* entry);
(*setter)(VALUE val, ID id, void *data, struct global_entry* entry);
3.3 Cのデータをrubyオブジェクトにする
3.3 CのデータをRubyオブジェクトにする
Cの世界で定義されたデータ(構造体)をrubyのオブジェクトとして
Cの世界で定義されたデータ(構造体)をRubyのオブジェクトとして
取り扱いたい場合がありえますこのような場合にはDataという
rubyオブジェクトにCの構造体(へのポインタ)をくるむことでruby
RubyオブジェクトにCの構造体(へのポインタ)をくるむことでRuby
オブジェクトとして取り扱えるようになります.
Dataオブジェクトを生成して構造体をrubyオブジェクトにカプセル
Dataオブジェクトを生成して構造体をRubyオブジェクトにカプセル
化するためには,以下のマクロを使います.
Data_Wrap_Struct(class,mark,free,ptr)
@ -472,7 +472,7 @@ Data
このマクロの戻り値は生成されたDataオブジェクトです
classはこのDataオブジェクトのクラスですptrはカプセル化する
Cの構造体へのポインタですmarkはこの構造体がrubyのオブジェ
Cの構造体へのポインタですmarkはこの構造体がRubyのオブジェ
クトへの参照がある時に使う関数です.そのような参照を含まない
時には0を指定します
@ -505,16 +505,16 @@ C
4例題 - dbmパッケージを作る
ここまでの説明でとりあえず拡張モジュールは作れるはずです.
rubyのextディレクトリにすでに含まれているdbmモジュールを例に
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
して段階的に説明します.
(1) ディレクトリを作る
% mkdir ext/dbm
ruby 1.1からは任意のディレクトリでダイナミックライブラリを作
ることができるようになりました.rubyに静的にリンクする場合に
rubyを展開したディレクトリの下extディレクトリの中に拡張
Ruby 1.1からは任意のディレクトリでダイナミックライブラリを作
ることができるようになりました.Rubyに静的にリンクする場合に
Rubyを展開したディレクトリの下extディレクトリの中に拡張
モジュール用のディレクトリを作る必要があります.名前は適当に
選んで構いません.
@ -548,7 +548,7 @@ MANIFEST
ル生成時に中間的に生成される「モジュール名.o」というファイル
とが衝突するからです.
rubyは拡張モジュールをロードする時に「Init_モジュール名」と
Rubyは拡張モジュールをロードする時に「Init_モジュール名」と
いう関数を自動的に実行しますdbmモジュールの場合「Init_dbm」
です.この関数の中でクラス,モジュール,メソッド,定数などの
定義を行いますdbm.cから一部引用します
@ -576,7 +576,7 @@ Init_dbm()
--
DBMモジュールはdbmのデータと対応するオブジェクトになるはずで
すからCの世界のdbmをrubyの世界に取り込む必要があります
すからCの世界のdbmをRubyの世界に取り込む必要があります
dbm.cではData_Make_Structを以下のように使っています
@ -626,7 +626,7 @@ fdbm_delete(obj, keystr)
引数の数が固定のタイプは第1引数がself第2引数以降がメソッド
の引数となります.
引数の数が不定のものはCの配列で受けるものとrubyの配列で受け
引数の数が不定のものはCの配列で受けるものとRubyの配列で受け
るものとがありますdbmモジュールの中でCの配列で受けるもの
はDBMのクラスメソッドであるopen()です.これを実装している関
数fdbm_s_open()はこうなっています.
@ -660,7 +660,7 @@ fdbm_s_open(argc, argv, class)
2つまで許されるという意味になります省略されている時の
変数の値はnil(C言語のレベルではQnil)になります.
rubyの配列で引数を受け取るものはindexesがあります実装はこ
Rubyの配列で引数を受け取るものはindexesがあります実装はこ
うです.
--
@ -673,14 +673,14 @@ fdbm_indexes(obj, args)
}
--
第1引数はself第2引数はrubyの配列ですここではキャストを減
第1引数はself第2引数はRubyの配列ですここではキャストを減
らすため struct RArray* で受けていますがVALUEでも同じこと
です.
** 注意事項
rubyと共有はしないがrubyのオブジェクトを格納する可能性のある
Cの大域変数は以下の関数を使ってrubyインタプリタに変数の存在
Rubyと共有はしないがRubyのオブジェクトを格納する可能性のある
Cの大域変数は以下の関数を使ってRubyインタプリタに変数の存在
を教えてあげてくださいでないとGCでトラブルを起こします
void rb_global_variable(VALUE *var)
@ -689,7 +689,7 @@ C
Makefileを作る場合の雛型になるextconf.rbというファイルを作り
ますextconf.rbはモジュールのコンパイルに必要な条件のチェッ
クなどを行うことが目的ですextconf.rbの中では以下のruby関数
クなどを行うことが目的ですextconf.rbの中では以下のRuby関数
を使うことが出来ます.
have_library(lib, func): ライブラリの存在チェック
@ -706,7 +706,7 @@ Makefile
ンパイルしない時にはcreate_makefileを呼ばなければMakefileは
生成されず,コンパイルも行われません.
モジュールがruby 1.1専用である場合には
モジュールがRuby 1.1専用である場合には
require 'mkmf'
@ -745,7 +745,7 @@ Makefile
としてください.
ディレクトリをext以下に用意した場合にはruby全体のmakeの時に
ディレクトリをext以下に用意した場合にはRuby全体のmakeの時に
自動的にMakefileが生成されますのでこのステップは不要です
(9) makeする
@ -753,15 +753,15 @@ Makefile
動的リンクライブラリを生成する場合にはその場でmakeしてくださ
い.必要であれば make install でインストールされます.
ext以下にディレクトリを用意した場合はrubyのディレクトリで
ext以下にディレクトリを用意した場合はRubyのディレクトリで
makeを実行するとMakefileを生成からmake必要によってはそのモ
ジュールのrubyへのリンクまで自動的に実行してくれます
ジュールのRubyへのリンクまで自動的に実行してくれます
extconf.rbを書き換えるなどしてMakefileの再生成が必要な時はま
rubyディレクトリでmakeしてください
Rubyディレクトリでmakeしてください
動的リンクライブラリはmake installでrubyライブラリのディレク
トリの下にコピーされます.もしモジュールと協調して使うrubyで
記述されたプログラムがあり,rubyライブラリに置きたい場合には
動的リンクライブラリはmake installでRubyライブラリのディレク
トリの下にコピーされます.もしモジュールと協調して使うRubyで
記述されたプログラムがあり,Rubyライブラリに置きたい場合には
拡張モジュール用のディレクトリの下に lib というディレクトリ
を作り,そこに 拡張子 .rb のファイルを置いておけば同時にイン
ストールされます.
@ -775,17 +775,17 @@ extconf.rb
(11) できあがり
後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお
使いください.rubyの作者は拡張モジュールに関して一切の権利を
使いください.Rubyの作者は拡張モジュールに関して一切の権利を
主張しません.
Appendix A. rubyのソースコードの分類
Appendix A. Rubyのソースコードの分類
rubyのソースはいくつかに分類することが出来ますこのうちクラ
Rubyのソースはいくつかに分類することが出来ますこのうちクラ
スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ
ています.これらのソースは今までの説明でほとんど理解できると
思います.
ruby言語のコア
Ruby言語のコア
class.c
error.c
@ -804,7 +804,7 @@ ruby
st.c
util.c
rubyコマンドの実装
Rubyコマンドの実装
dmyext.c
inits.c
@ -838,13 +838,13 @@ ruby
Appendix B. 拡張用関数リファレンス
C言語からrubyの機能を利用するAPIは以下の通りである
C言語からRubyの機能を利用するAPIは以下の通りである
** 型
VALUE
rubyオブジェクトを表現する型必要に応じてキャストして用いる
Rubyオブジェクトを表現する型必要に応じてキャストして用いる
組み込み型を表現するCの型はruby.hに記述してあるRで始まる構造
体であるVALUE型をこれらにキャストするためにRで始まる構造体
名を全て大文字にした名前のマクロが用意されている.
@ -867,9 +867,9 @@ ruby
Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval)
Cの任意のポインタをカプセル化したrubyオブジェクトを返す
のポインタがrubyからアクセスされなくなった時freeで指定した
関数が呼ばれる.また,このポインタの指すデータが他のrubyオブ
Cの任意のポインタをカプセル化したRubyオブジェクトを返す
のポインタがRubyからアクセスされなくなった時freeで指定した
関数が呼ばれる.また,このポインタの指すデータが他のRubyオブ
ジェクトを指している場合markに指定する関数でマークする必要
がある.
@ -905,20 +905,20 @@ data
VALUE rb_define_class(char *name, VALUE super)
superのサブクラスとして新しいrubyクラスを定義する
superのサブクラスとして新しいRubyクラスを定義する
VALUE rb_define_class_under(VALUE module, char *name, VALUE super)
superのサブクラスとして新しいrubyクラスを定義しmoduleの定
superのサブクラスとして新しいRubyクラスを定義しmoduleの定
数として定義する.
VALUE rb_define_module(char *name)
新しいrubyモジュールを定義する
新しいRubyモジュールを定義する
VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
新しいrubyモジュールを定義しmoduleの定数として定義する
新しいRubyモジュールを定義しmoduleの定数として定義する
void rb_include_module(VALUE class, VALUE module)
@ -933,20 +933,20 @@ super
void rb_define_variable(char *name, VALUE *var)
rubyとCとで共有するグローバル変数を定義する変数名が`$'で始
まらない時には自動的に追加されるnameとしてrubyの識別子とし
て許されない文字(例えば` ')を含む場合にはrubyプログラムから
RubyとCとで共有するグローバル変数を定義する変数名が`$'で始
まらない時には自動的に追加されるnameとしてRubyの識別子とし
て許されない文字(例えば` ')を含む場合にはRubyプログラムから
は見えなくなる.
void rb_define_readonly_variable(char *name, VALUE *var)
rubyとCとで共有するread onlyのグローバル変数を定義するread
RubyとCとで共有するread onlyのグローバル変数を定義するread
onlyであること以外はrb_define_variable()と同じ.
void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)())
関数によって実現されるruby変数を定義する変数が参照された時
関数によって実現されるRuby変数を定義する変数が参照された時
にはgetterが変数に値がセットされた時にはsetterが呼ばれる
void rb_define_hooked_variable(char *name, VALUE *var,
@ -959,7 +959,7 @@ only
void rb_global_variable(VALUE *var)
GCのためrubyプログラムからはアクセスされないが, rubyオブジェ
GCのためRubyプログラムからはアクセスされないが, Rubyオブジェ
クトを含む大域変数をマークする.
** クラス定数
@ -983,7 +983,7 @@ GC
メソッドを定義するargcはselfを除く引数の数argcが-1の時,
関数には引数の数(selfを含まない)を第1引数, 引数の配列を第2引
数とする形式で与えられる(第3引数はself)argcが-2の時, 第1引
数がself, 第2引数がargs(argsは引数を含むrubyの配列)という形
数がself, 第2引数がargs(argsは引数を含むRubyの配列)という形
式で与えられる.
rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
@ -1004,7 +1004,7 @@ argc,argv
数に対応する引数が与えられていない場合は変数にQnilが代入され
る.
** rubyメソッド呼び出し
** Rubyメソッド呼び出し
VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)
@ -1016,7 +1016,7 @@ argc,argv
VALUE rb_eval_string(char *str)
文字列をrubyとスクリプトしてコンパイル・実行する
文字列をRubyとスクリプトしてコンパイル・実行する
ID rb_intern(char *name)
@ -1036,7 +1036,7 @@ class
VALUE rb_iv_get(VALUE obj, char *name)
objのインスタンス変数の値を得る`@'で始まらないインスタンス
変数は rubyプログラムからアクセスできない「隠れた」インスタ
変数は Rubyプログラムからアクセスできない「隠れた」インスタ
ンス変数になる.定数は大文字の名前を持つクラス(またはモジュー
ル)のインスタンス変数として実装されている.
@ -1095,22 +1095,22 @@ exception
況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外
処理は一切行なわれない.
** rubyの初期化・実行
** Rubyの初期化・実行
rubyをアプリケーションに埋め込む場合には以下のインタフェース
Rubyをアプリケーションに埋め込む場合には以下のインタフェース
を使う.通常の拡張モジュールには必要ない.
void ruby_init(int argc, char **argv, char **envp)
rubyインタプリタの初期化を行なう
Rubyインタプリタの初期化を行なう
void ruby_run()
rubyインタプリタを実行する
Rubyインタプリタを実行する
void ruby_script(char *name)
rubyのスクリプト名($0)を設定する.
Rubyのスクリプト名($0)を設定する.
Appendix B. extconf.rbで使える関数たち

View file

@ -5,7 +5,7 @@ Ruby
すから,オブジェクト指向プログラミングを手軽に行う事が出来ま
す.もちろん通常の手続き型のプログラミングも可能です.
Rubyはテキスト処理関係の能力などに優れperlと同じくらい強力
Rubyはテキスト処理関係の能力などに優れPerlと同じくらい強力
です.さらにシンプルな文法と,例外処理やイテレータなどの機構
によって,より分かりやすいプログラミングが出来ます.

View file

@ -81,7 +81,7 @@ ary_new()
return ary_new2(ARY_DEFAULT_SIZE);
}
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
@ -90,7 +90,7 @@ ary_new()
#endif
VALUE
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
ary_new3(int n, ...)
#else
ary_new3(n, va_alist)

View file

@ -565,7 +565,7 @@ rb_define_attr(klass, name, read, write)
rb_attr(klass, rb_intern(name), read, write, FALSE);
}
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
@ -575,7 +575,7 @@ rb_define_attr(klass, name, read, write)
#include <ctype.h>
int
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
rb_scan_args(int argc, VALUE *argv, char *fmt, ...)
#else
rb_scan_args(argc, argv, fmt, va_alist)

View file

@ -1,4 +1,10 @@
#define THREAD 1
#define SIZEOF_INT 4
#define SIZEOF_LONG 4
#define SIZEOF_VOIDP 4
#define HAVE_PROTOTYPES 1
#define HAVE_STDARG_PROTOTYPES 1
#define HAVE_ATTR_NORETURN 1
#define HAVE_DIRENT_H 1
#define HAVE_UNISTD_H 1
#define HAVE_LIMITS_H 1

652
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -72,6 +72,50 @@ AC_PROG_MAKE_SET
# checks for UNIX variants that set C preprocessor variables
AC_MINIX
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(void*)
AC_MSG_CHECKING(for prototypes)
AC_CACHE_VAL(rb_cv_have_prototypes,
[AC_TRY_COMPILE([int foo(int x) { return 0; }], [return foo(10);],
rb_cv_have_prototypes=yes,
rb_cv_have_prototypes=no)])
AC_MSG_RESULT($rb_cv_have_prototypes)
if test "$rb_cv_have_prototypes" = yes; then
AC_DEFINE(HAVE_PROTOTYPES)
fi
AC_MSG_CHECKING(for variable length prototypes and stdarg.h)
AC_CACHE_VAL(rb_cv_stdarg,
[AC_TRY_COMPILE([
#include <stdarg.h>
int foo(int x, ...) {
va_list va;
va_start(va, x);
va_arg(va, int);
va_arg(va, char *);
va_arg(va, double);
return 0;
}
], [return foo(10, "", 3.14);],
rb_cv_stdarg=yes,
rb_cv_stdarg=no)])
AC_MSG_RESULT($rb_cv_stdarg)
if test "$rb_cv_stdarg" = yes; then
AC_DEFINE(HAVE_STDARG_PROTOTYPES)
fi
AC_MSG_CHECKING(for gcc attribute noreturn)
AC_CACHE_VAL(rb_cv_have_attr_noreturn,
[AC_TRY_COMPILE([void exit(int x) __attribute__ ((noreturn));], [],
rb_cv_have_attr_noreturn=yes,
rb_cv_have_attr_noreturn=no)])
AC_MSG_RESULT($rb_cv_have_attr_noreturn)
if test "$rb_cv_have_attr_noreturn" = yes; then
AC_DEFINE(HAVE_ATTR_NORETURN)
fi
dnl Checks for libraries.
case "$host_os" in
nextstep*) ;;
@ -88,8 +132,7 @@ AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/file.h sys/ioctl.h pwd.h \
sys/select.h sys/time.h sys/times.h sys/param.h sys/wait.h\
syscall.h a.out.h string.h utime.h memory.h\
varargs.h stdarg.h)
syscall.h a.out.h string.h utime.h memory.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
@ -100,10 +143,6 @@ AC_STRUCT_ST_BLOCKS
LIBOBJS="$save_LIBOBJS"
AC_STRUCT_ST_RDEV
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(void*)
dnl Checks for library functions.
AC_TYPE_GETGROUPS
AC_TYPE_SIGNAL

32
error.c
View file

@ -13,7 +13,7 @@
#include "ruby.h"
#include "env.h"
#include <stdio.h>
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
@ -58,7 +58,7 @@ err_print(fmt, args)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
Error(char *fmt, ...)
#else
Error(fmt, va_alist)
@ -75,7 +75,7 @@ Error(fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
Error_Append(char *fmt, ...)
#else
Error_Append(fmt, va_alist)
@ -93,7 +93,7 @@ Error_Append(fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
Warn(char *fmt, ...)
#else
Warn(fmt, va_alist)
@ -113,7 +113,7 @@ Warn(fmt, va_alist)
/* Warning() reports only in verbose mode */
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
Warning(char *fmt, ...)
#else
Warning(fmt, va_alist)
@ -134,7 +134,7 @@ Warning(fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
Bug(char *fmt, ...)
#else
Bug(fmt, va_alist)
@ -182,10 +182,6 @@ static struct types {
-1, 0,
};
#ifndef __STDC__
extern void TypeError();
#endif
void
rb_check_type(x, t)
VALUE x;
@ -537,7 +533,7 @@ Init_Exception()
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
Raise(VALUE exc, char *fmt, ...)
#else
Raise(exc, fmt, va_alist)
@ -550,7 +546,7 @@ Raise(exc, fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
TypeError(char *fmt, ...)
#else
TypeError(fmt, va_alist)
@ -562,7 +558,7 @@ TypeError(fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
ArgError(char *fmt, ...)
#else
ArgError(fmt, va_alist)
@ -574,7 +570,7 @@ ArgError(fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
NameError(char *fmt, ...)
#else
NameError(fmt, va_alist)
@ -586,7 +582,7 @@ NameError(fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
IndexError(char *fmt, ...)
#else
IndexError(fmt, va_alist)
@ -598,7 +594,7 @@ IndexError(fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
Fail(char *fmt, ...)
#else
Fail(fmt, va_alist)
@ -618,7 +614,7 @@ rb_notimplement()
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
LoadError(char *fmt, ...)
#else
LoadError(fmt, va_alist)
@ -630,7 +626,7 @@ LoadError(fmt, va_alist)
}
void
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
Fatal(char *fmt, ...)
#else
Fatal(fmt, va_alist)

3
eval.c
View file

@ -2684,6 +2684,7 @@ rb_iter_break()
JUMP_TAG(TAG_BREAK);
}
static void rb_longjmp _((int, VALUE)) NORETURN;
static VALUE make_backtrace _((void));
static void
@ -3614,7 +3615,7 @@ f_send(argc, argv, recv)
#endif
VALUE
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
rb_funcall(VALUE recv, ID mid, int n, ...)
#else
rb_funcall(recv, mid, n, va_alist)

View file

@ -1172,7 +1172,7 @@ static GtkObject*
try_get_gobject(self)
VALUE self;
{
return (GtkObject*)rb_rescue(get_gobject, self, nil, Qnil);
return (GtkObject*)rb_rescue((VALUE(*)())get_gobject, self, nil, 0);
}
static VALUE

View file

@ -7,7 +7,7 @@ void memclear _((register VALUE*, register int));
VALUE assoc_new _((VALUE, VALUE));
VALUE ary_new _((void));
VALUE ary_new2 _((int));
VALUE ary_new3 _((int,...));
VALUE ary_new3 __((int,...));
VALUE ary_new4 _((int, VALUE *));
VALUE ary_freeze _((VALUE));
VALUE ary_aref(int, VALUE*, VALUE);
@ -84,11 +84,11 @@ VALUE enum_length _((VALUE));
VALUE exc_new _((VALUE, char*, unsigned int));
VALUE exc_new2 _((VALUE, char*));
VALUE exc_new3 _((VALUE, VALUE));
void TypeError _((char*, ...));
void ArgError _((char*, ...));
void NameError _((char*, ...));
void IndexError _((char*, ...));
void LoadError _((char*, ...));
void TypeError __((char*, ...)) NORETURN;
void ArgError __((char*, ...)) NORETURN;
void NameError __((char*, ...)) NORETURN;
void IndexError __((char*, ...)) NORETURN;
void LoadError __((char*, ...)) NORETURN;
/* eval.c */
void rb_remove_method _((VALUE, char*));
void rb_disable_super _((VALUE, char*));
@ -260,8 +260,8 @@ VALUE str_upto _((VALUE, VALUE));
VALUE str_inspect _((VALUE));
VALUE str_split _((VALUE, char*));
/* struct.c */
VALUE struct_new _((VALUE, ...));
VALUE struct_define _((char*, ...));
VALUE struct_new __((VALUE, ...));
VALUE struct_define __((char*, ...));
VALUE struct_alloc _((VALUE, VALUE));
VALUE struct_aref _((VALUE, VALUE));
VALUE struct_aset _((VALUE, VALUE, VALUE));

6
pack.c
View file

@ -322,7 +322,7 @@ pack_pack(ary, fmt)
from = NEXTFROM;
if (NIL_P(from)) l = 0;
else {
l = NUM2UINT(from);
l = NUM2ULONG(from);
}
str_cat(res, (char*)&l, sizeof(long));
}
@ -349,7 +349,7 @@ pack_pack(ary, fmt)
from = NEXTFROM;
if (NIL_P(from)) l = 0;
else {
l = NUM2UINT(from);
l = NUM2ULONG(from);
}
l = htonl(l);
str_cat(res, (char*)&l, sizeof(long));
@ -377,7 +377,7 @@ pack_pack(ary, fmt)
from = NEXTFROM;
if (NIL_P(from)) l = 0;
else {
l = NUM2UINT(from);
l = NUM2ULONG(from);
}
l = htovl(l);
str_cat(res, (char*)&l, sizeof(long));

View file

@ -3603,12 +3603,8 @@ int current_mbctype = MBCTYPE_ASCII;
#endif
void
#ifdef __STDC__
mbcinit(int mbctype)
#else
mbcinit(mbctype)
int mbctype;
#endif
{
switch (mbctype) {
case MBCTYPE_ASCII:

51
ruby.h
View file

@ -31,10 +31,6 @@ extern "C" {
# include <strings.h>
#endif
#if defined(__MWERKS__) && defined(__cplusplus)
# define NEED_PROTO
#endif
#ifndef __STDC__
# define volatile
# ifdef __GNUC__
@ -42,15 +38,26 @@ extern "C" {
# else
# define const
# endif
#else
# define NEED_PROTO
#endif
#ifdef NEED_PROTO
#ifdef HAVE_PROTOTYPES
# define _(args) args
#else
# define _(args) ()
#endif
#ifdef HAVE_STDARG_PROTOTYPES
# define __(args) args
#else
# define __(args) ()
#endif
#ifdef HAVE_ATTR_NORETURN
# define NORETURN __attribute__ ((noreturn))
#else
# define NORETURN
#endif
#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
#include <alloca.h>
#endif
@ -435,8 +442,8 @@ char *rb_class2name _((VALUE));
void rb_p _((VALUE));
VALUE rb_eval_string _((char*));
VALUE rb_funcall _((VALUE, ID, int, ...));
int rb_scan_args _((int, VALUE*, char*, ...));
VALUE rb_funcall __((VALUE, ID, int, ...));
int rb_scan_args __((int, VALUE*, char*, ...));
VALUE rb_iv_get _((VALUE, char *));
VALUE rb_iv_set _((VALUE, char *, VALUE));
@ -451,20 +458,20 @@ extern VALUE verbose, debug;
int rb_safe_level _((void));
void rb_set_safe_level _((int));
void Raise _((VALUE, char*, ...));
void Fail _((char*, ...));
void Fatal _((char*, ...));
void Bug _((char*, ...));
void rb_sys_fail _((char *));
void rb_iter_break _((void));
void rb_exit _((int));
void rb_raise _((VALUE));
void rb_fatal _((VALUE));
void rb_notimplement _((void));
void Raise __((VALUE, char*, ...)) NORETURN;
void Fail __((char*, ...)) NORETURN;
void Fatal __((char*, ...)) NORETURN;
void Bug __((char*, ...)) NORETURN;
void rb_sys_fail _((char *)) NORETURN;
void rb_iter_break _((void)) NORETURN;
void rb_exit _((int)) NORETURN;
void rb_raise _((VALUE)) NORETURN;
void rb_fatal _((VALUE)) NORETURN;
void rb_notimplement _((void)) NORETURN;
void Error _((char*, ...));
void Warn _((char*, ...));
void Warning _((char*, ...)); /* reports if `-w' specified */
void Error __((char*, ...));
void Warn __((char*, ...));
void Warning __((char*, ...)); /* reports if `-w' specified */
VALUE rb_each _((VALUE));
VALUE rb_yield _((VALUE));

View file

@ -165,7 +165,7 @@ make_struct(name, member, klass)
return nstr;
}
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
@ -174,7 +174,7 @@ make_struct(name, member, klass)
#endif
VALUE
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
struct_define(char *name, ...)
#else
struct_define(name, va_alist)
@ -249,7 +249,7 @@ struct_alloc(klass, values)
}
VALUE
#ifdef __STDC__
#ifdef HAVE_STDARG_PROTOTYPES
struct_new(VALUE klass, ...)
#else
struct_new(klass, va_alist)

View file

@ -1,4 +1,10 @@
#define THREAD 1
#define SIZEOF_INT 4
#define SIZEOF_LONG 4
#define SIZEOF_VOIDP 4
#define HAVE_PROTOTYPES 1
#define HAVE_STDARG_PROTOTYPES 1
#define HAVE_ATTR_NORETURN 1
/* #define HAVE_DIRENT_H 1 */
/* #define HAVE_UNISTD_H 1 */
#define HAVE_STDLIB_H 1

View file

@ -126,6 +126,7 @@ EXPORTS
rb_define_method
rb_undef_method
rb_define_private_method
rb_define_protected_method
rb_singleton_class
rb_define_singleton_method
rb_define_module_function
@ -143,6 +144,7 @@ EXPORTS
; error.c
Error
Error_Append
Warn
Warning
Bug
rb_check_type
@ -161,8 +163,11 @@ EXPORTS
rb_sys_fail
;eval.c
rb_clear_cache
rb_add_method
rb_alias
rb_add_method
rb_remove_method
rb_disable_super
rb_enable_super
rb_method_boundp
dyna_var_defined
dyna_var_ref
@ -261,7 +266,8 @@ EXPORTS
num_coerce_bin
float_new
flo_pow
num2int
num2long
num2ulong
num2fix
fix2str
fix_to_s