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

This commit was generated by cvs2svn to compensate for changes in r11,

which included commits to RCS files with non-trunk default branches.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1998-01-16 12:19:22 +00:00
parent 62e41d3f2e
commit 7ea2ceddb8
79 changed files with 8922 additions and 8253 deletions

4506
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,4 @@
COPYING
ChangeLog
MANIFEST
Makefile.in
@ -32,10 +33,16 @@ glob.c
hash.c
inits.c
install-sh
instruby.rb
intern.h
io.c
io.h
keywords
lex.c
main.c
marshal.c
math.c
mkconfig.rb
node.h
numeric.c
object.c
@ -51,6 +58,7 @@ regex.h
ruby.1
ruby.c
ruby.h
rubytest.rb
sig.h
signal.c
sprintf.c
@ -78,34 +86,41 @@ lib/cgi-lib.rb
lib/complex.rb
lib/date.rb
lib/debug.rb
lib/delegate.rb
lib/e2mmap.rb
lib/e2mmap1_0.rb
lib/eregex.rb
lib/find.rb
lib/finalize.rb
lib/ftplib.rb
lib/ftools.rb
lib/getopts.rb
lib/importenv.rb
lib/jcode.rb
lib/mailread.rb
lib/mathn.rb
lib/matrix.rb
lib/mkmf.rb
lib/mutex_m.rb
lib/observer.rb
lib/ostruct.rb
lib/parsearg.rb
lib/parsedate.rb
lib/ping.rb
lib/pstore.rb
lib/rational.rb
lib/shellwords.rb
lib/sync.rb
lib/thread.rb
lib/thwait.rb
lib/tk.rb
lib/tkcore.rb
lib/tkcanvas.rb
lib/tkclass.rb
lib/tkdialog.rb
lib/tkentry.rb
lib/tkscrollbox.rb
lib/tktext.rb
lib/tkthcore.rb
lib/tracer.rb
lib/weakref.rb
missing/alloca.c
missing/crypt.c
missing/dir.h
@ -126,6 +141,7 @@ missing/strtol.c
missing/strtoul.c
missing/x68.c
sample/biorhythm.rb
sample/cbreak.rb
sample/clnt.rb
sample/dbmtest.rb
sample/dir.rb
@ -141,7 +157,6 @@ sample/freq.rb
sample/from.rb
sample/fullpath.rb
sample/getopts.test
sample/io.rb
sample/less.rb
sample/list.rb
sample/list2.rb
@ -155,6 +170,7 @@ sample/occur.rb
sample/occur2.rb
sample/philos.rb
sample/pi.rb
sample/rbc.rb
sample/rcs.awk
sample/rcs.dat
sample/rcs.rb
@ -180,6 +196,8 @@ win32/Makefile
win32/config.h
win32/ntsetup.bat
win32/ruby.def
win32/sdbm.c
win32/sdbm.h
x68/fconvert.c
x68/select.c
x68/_dtos18.c

View file

@ -7,9 +7,6 @@ VPATH = @srcdir@:@srcdir@/missing
CC = @CC@
YACC = @YACC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
PURIFY =
@SET_MAKE@
@ -18,14 +15,6 @@ LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
LIBS = @LIBS@ $(EXTLIBS)
MISSING = @LIBOBJS@ @ALLOCA@
program_transform_name = -e @program_transform_name@
RUBY_INSTALL_NAME = `t='$(program_transform_name)'; echo ruby | sed $$t`
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@/$(RUBY_INSTALL_NAME)
binsuffix = @binsuffix@
#### End of system configuration section. ####
@ -33,7 +22,7 @@ binsuffix = @binsuffix@
LIBRUBY = libruby.a
EXTOBJS = dmyext.o
EXTOBJS =
MAINOBJ = main.o
@ -54,6 +43,7 @@ OBJS = array.o \
inits.o \
io.o \
math.o \
marshal.o \
numeric.o \
object.o \
pack.o \
@ -75,15 +65,12 @@ OBJS = array.o \
version.o \
$(MISSING)
all: miniruby$(binsuffix) @srcdir@/ext/Setup
@if test -z "$$UNDER_EXTMAKE_RB"; \
then echo "Compiling ext modules"; \
UNDER_EXTMAKE_RB=yes; export UNDER_EXTMAKE_RB; \
cd ext; ../miniruby ./extmk.rb @EXTSTATIC@; fi
all: miniruby$(binsuffix) rbconfig.rb
@cd ext; ../miniruby$(binsuffix) ./extmk.rb @EXTSTATIC@
miniruby$(binsuffix): $(OBJS) $(MAINOBJ) $(EXTOBJS)
miniruby$(binsuffix): $(OBJS) $(MAINOBJ) dmyext.o
@rm -f $@
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(LIBS) -o miniruby
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) dmyext.o $(LIBS) -o miniruby
ruby$(binsuffix): $(LIBRUBY) $(MAINOBJ) $(EXTOBJS)
@rm -f $@
@ -93,36 +80,31 @@ $(LIBRUBY): $(OBJS) dmyext.o
@AR@ rcu $(LIBRUBY) $(OBJS) dmyext.o
@-@RANLIB@ $(LIBRUBY) 2> /dev/null || true
install:; $(INSTALL_PROGRAM) ruby$(binsuffix) $(bindir)/$(RUBY_INSTALL_NAME)$(binsuffix)
@-@STRIP@ $(bindir)/$(RUBY_INSTALL_NAME)$(binsuffix)
@test -d $(libdir) || mkdir $(libdir)
cd ext; ../miniruby ./extmk.rb install
@for rb in `grep '^lib/' @srcdir@/MANIFEST`; do \
$(INSTALL_DATA) @srcdir@/$$rb $(libdir); \
done
install: rbconfig.rb
./miniruby$(binsuffix) $(srcdir)/instruby.rb
clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ)
clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ) rbconfig.rb
@rm -f ext/extinit.c ext/extinit.o dmyext.o
cd ext; ../miniruby ./extmk.rb clean
@if test -f ./miniruby; then cd ext; ../miniruby ./extmk.rb clean; fi
realclean: clean
@rm -f Makefile ext/extmk.rb ext/config.cache parse.c
@rm -f Makefile ext/extmk.rb ext/config.cache
@rm -f config.cache config.h config.log config.status
@rm -f core ruby$(binsuffix) miniruby$(binsuffix) parse.c *~ *.core gmon.out
@rm -f parse.c lex.c *~ core *.core gmon.out
@rm -f ruby$(binsuffix) miniruby$(binsuffix)
test:; @-./ruby @srcdir@/sample/test.rb > ./ruby_test 2>&1; \
if grep '^end of test' ./ruby_test > /dev/null; then \
echo "test succeeded"; \
else \
grep '^sample/test.rb' ./ruby_test; \
grep '^not' ./ruby_test; \
echo "test failed";\
fi;\
rm -f ./ruby_test
test: miniruby$(binsuffix)
@./miniruby$(binsuffix) $(srcdir)/rubytest.rb
rbconfig.rb: config.status miniruby$(binsuffix)
@./miniruby$(binsuffix) $(srcdir)/mkconfig.rb rbconfig.rb
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
lex.c: keywords
gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ keywords > lex.c
parse.c: parse.y
$(YACC) $<
mv -f y.tab.c parse.c
@ -178,42 +160,40 @@ x68.o: @srcdir@/missing/x68.c
# Prevent GNU make v3 from overflowing arg limit on SysV.
.NOEXPORT:
###
parse.o : parse.y ruby.h defines.h config.h env.h node.h st.h regex.h
parse.o : parse.y ruby.h defines.h config.h intern.h env.h node.h st.h regex.h lex.c
###
array.o: array.c ruby.h config.h defines.h
bignum.o: bignum.c ruby.h config.h defines.h
class.o: class.c ruby.h config.h defines.h node.h st.h
compar.o: compar.c ruby.h config.h defines.h
dir.o: dir.c ruby.h config.h defines.h
array.o: array.c ruby.h config.h defines.h intern.h
bignum.o: bignum.c ruby.h config.h defines.h intern.h
class.o: class.c ruby.h config.h defines.h intern.h node.h st.h
compar.o: compar.c ruby.h config.h defines.h intern.h
dir.o: dir.c ruby.h config.h defines.h intern.h
dln.o: dln.c config.h defines.h dln.h st.h
dmyext.o: dmyext.c
enum.o: enum.c ruby.h config.h defines.h
error.o: error.c ruby.h config.h defines.h env.h
eval.o: eval.c ruby.h config.h defines.h env.h node.h sig.h st.h dln.h
file.o: file.c ruby.h config.h defines.h io.h sig.h
fnmatch.o: fnmatch.c config.h fnmatch.h
gc.o: gc.c ruby.h config.h defines.h env.h sig.h st.h node.h re.h regex.h
glob.o: glob.c config.h fnmatch.h
hash.o: hash.c ruby.h config.h defines.h st.h
inits.o: inits.c ruby.h config.h defines.h
io.o: io.c ruby.h config.h defines.h io.h sig.h
enum.o: enum.c ruby.h config.h defines.h intern.h
error.o: error.c ruby.h config.h defines.h intern.h env.h
eval.o: eval.c ruby.h config.h defines.h intern.h env.h node.h sig.h st.h dln.h
file.o: file.c ruby.h config.h defines.h intern.h io.h sig.h
gc.o: gc.c ruby.h config.h defines.h intern.h env.h sig.h st.h node.h re.h regex.h
hash.o: hash.c ruby.h config.h defines.h intern.h st.h
inits.o: inits.c ruby.h config.h defines.h intern.h
io.o: io.c ruby.h config.h defines.h intern.h io.h sig.h
main.o: main.c
math.o: math.c ruby.h config.h defines.h
numeric.o: numeric.c ruby.h config.h defines.h
object.o: object.c ruby.h config.h defines.h st.h
pack.o: pack.c ruby.h config.h defines.h
process.o: process.c ruby.h config.h defines.h sig.h st.h
random.o: random.c ruby.h config.h defines.h
range.o: range.c ruby.h config.h defines.h
re.o: re.c ruby.h config.h defines.h re.h regex.h
regex.o: regex.c config.h defines.h regex.h util.h
ruby.o: ruby.c ruby.h config.h defines.h re.h regex.h dln.h
signal.o: signal.c ruby.h config.h defines.h sig.h
sprintf.o: sprintf.c ruby.h config.h defines.h
marshal.o: marshal.c ruby.h config.h defines.h intern.h io.h sig.h st.h
math.o: math.c ruby.h config.h defines.h intern.h
numeric.o: numeric.c ruby.h config.h defines.h intern.h
object.o: object.c ruby.h config.h defines.h intern.h st.h
pack.o: pack.c ruby.h config.h defines.h intern.h
process.o: process.c ruby.h config.h defines.h intern.h sig.h st.h
random.o: random.c ruby.h config.h defines.h intern.h
range.o: range.c ruby.h config.h defines.h intern.h
re.o: re.c ruby.h config.h defines.h intern.h re.h regex.h
ruby.o: ruby.c ruby.h config.h defines.h intern.h re.h regex.h dln.h
signal.o: signal.c ruby.h config.h defines.h intern.h sig.h
sprintf.o: sprintf.c ruby.h config.h defines.h intern.h
st.o: st.c config.h st.h
string.o: string.c ruby.h config.h defines.h re.h regex.h
struct.o: struct.c ruby.h config.h defines.h
time.o: time.c ruby.h config.h defines.h
util.o: util.c defines.h config.h util.h
variable.o: variable.c ruby.h config.h defines.h env.h st.h
version.o: version.c ruby.h config.h defines.h version.h
string.o: string.c ruby.h config.h defines.h intern.h re.h regex.h
struct.o: struct.c ruby.h config.h defines.h intern.h
time.o: time.c ruby.h config.h defines.h intern.h
util.o: util.c defines.h intern.h config.h util.h
variable.o: variable.c ruby.h config.h defines.h intern.h env.h st.h
version.o: version.c ruby.h config.h defines.h intern.h version.h

69
README
View file

@ -5,7 +5,7 @@ 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.
* Features of ruby
* Features of Ruby
+ Simple Syntax
+ *Normal* Object-Oriented features(ex. class, method calls)
@ -17,17 +17,15 @@ perl). It is simple, straight-forward, and extensible.
+ Dynamic Loading of Object files(on some architecture)
+ Highly Portable(works on many UNIX machines)
* How to get ruby
* How to get Ruby
** by ftp
The ruby distribution can be found on
The Ruby distribution can be found on
ftp://ftp.netlab.co.jp/pub/lang/ruby/
* How to compile and install
This is what you need to do to compile and install ruby:
This is what you need to do to compile and install Ruby:
1. Run ./configure, which will generate config.h and Makefile.
@ -41,40 +39,61 @@ This is what you need to do to compile and install ruby:
4. Run make.
5. Optionally, run 'make test' to check that the compiled ruby
5. Optionally, run 'make test' to check that the compiled Ruby
interpreter works well. If you see the message "test succeeded",
your ruby works as it should.
your Ruby works as it should (hopefully).
6. Run 'make install'
If you fail to compile ruby, please send the detailed error report with
If you fail to compile Ruby, please send the detailed error report with
the error log and machine/OS type, to help others.
* Copying
Ruby is copyrighted by Yukihiro Matsumoto <matz@ruby.club.co.jp>.
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
You can redistribute it and/or modify it under either the terms of the GPL
(see COPYING file), or the conditions below:
This source is distributed under the conditions blow:
1. You may make and give away verbatim copies of the source form of the
software without restriction, provided that you duplicate all of the
original copyright notices and associated disclaimers.
1. You may make and give away verbatim copies of the source form of
the software without restriction, provided that you do not modify
the original distribution files.
2. You may modify your copy of the software in any way, provided that
you do at least ONE of the following:
If you want to distribute the modified version in any way, contact
the author.
a) place your modifications in the Public Domain or otherwise make them
Freely Available, such as by posting said modifications to Usenet
or an equivalent medium, or by allowing the author to include your
modifications in the software.
2. You may distribute the software in object code or executable
form, provided that you distribute it with instructions on where
to get the software.
b) use the modified software only within your corporation or organization.
3. You may modify the software in any way, provided that you do not
distribute the modified version.
c) rename any non-standard executables so the names do not conflict
with standard executables, which must also be provided.
d) make other distribution arrangements with the author.
3. You may distribute the software in object code or executable
form, provided that you do at least ONE of the following:
a) distribute the executables and library files of the software,
together with instructions (in the manual page or equivalent)
on where to get the original distribution.
b) accompany the distribution with the machine-readable source of
the software.
c) give non-standard executables non-standard names, with
instructions on where to get the original software
distribution.
d) make other distribution arrangements with the author.
4. You may modify and include the part of the software into any other
software (possibly commercial). But some files in the distribution
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 somme files under the ./missing directory. See
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.
5. The scripts and library files supplied as input to or produced as
@ -88,9 +107,9 @@ This source is distributed under the conditions blow:
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
* ruby home-page
* Ruby home-page
The URL of the ruby home-page is:
The URL of the Ruby home-page is:
http://www.netlab.co.jp/ruby/

View file

@ -9,6 +9,7 @@ Ruby
です.さらにシンプルな文法と,例外処理やイテレータなどの機構
によって,より分かりやすいプログラミングが出来ます.
* Rubyの特長
+ シンプルな文法
@ -21,6 +22,7 @@ Ruby
+ ダイナミックローディング (アーキテクチャによる)
+ 移植性が高い多くのUNIX上で動く
* 入手法
** ftpで
@ -29,6 +31,7 @@ Ruby
ftp://ftp.netlab.co.jp/pub/lang/ruby/
* ホームページ
RubyのホームページのURLは
@ -37,6 +40,7 @@ Ruby
です.
* メイリングリスト
Rubyに関わる話題のためのメイリングリストを開設しました
@ -46,6 +50,7 @@ Ruby
です.このアドレスにメイルを送れば,自動的に登録されます.
* コンパイル・インストール
以下の手順で行ってください.
@ -80,13 +85,14 @@ Ruby
シンOSの種類を含むできるだけ詳しいレポートを作者に送ってく
ださると他の方のためにもなります.
* 移植
UNIXであればconfigureがほとんどの差異を吸収してくれるはずで
すが,思わぬ見落としがあった場合(あるに違いない),作者にその
ことをレポートすれば,解決できるかも知れません.
アークテクチャにもっとも依存するのはGC部ですrubyのGCは対象
アークテクチャにもっとも依存するのはGC部ですRubyのGCは対象
のアーキテクチャがsetjmp()によって全てのレジスタを jmp_bufに
格納することとjmp_bufとスタックが32bitアラインメントされて
いることを仮定しています.特に前者が成立しない場合の対応は非
@ -95,50 +101,63 @@ UNIX
クするコードを追加するだけで済みます「defined(THINK_C)」で
括られている部分を参考にしてください
# 実際にはrubyはThink Cではコンパイルできません
# 実際にはRubyはThink Cではコンパイルできません
レジスタウィンドウを持つCPUではレジスタウィンドウをスタッ
クにフラッシュするアセンブラコードを追加する必要があるかも知
れません.
* 配布条件
作者は以下の条件のもとにrubyを配布します
RUbyはフリーソフトウェアですGPL(the GNU General Public
Licence)または以下に示す条件でRubyを再配布できますGPLにつ
いてはCOPYINGファイルを参照して下さい
+ 再配布
1. 複製は制限なく自由です.
配布した状態を維持する限り自由です.変更を行ったものを再
配布することを希望する時には作者に連絡してください
2. 以下の条件のいずれかを満たす時に手元のRubyのソースを自
由に変更できます
変更を行なわないrubyをコンパイルしたバイナリの配布は禁止
しませんが,バイナリを受け取った人がソースを入手できるよ
うに,ソースの入手法を明示してください.
(a) ネットニューズにポストしたり,作者に変更を送付する
などの方法で,変更を公開する
+ 変更
(b) 変更したRubyを自分の所属する組織内部だけで使う
再配布を行わない限り,いかなる目的であれ自由です.ただし,
機能拡張やバグ修正は作者へのフィードバックを期待します
(もちろん強制ではありません)
(c) 変更点を明示したうえ,ソフトウェアの名前を変更する.
そのソフトウェアを配布する時にはもとのRubyも同時に
配布する
+ 他のプログラムへの引用
(d) その他の変更条件を作者と合意する
いかなる目的であれ自由ですただしrubyに含まれる他の作
者によるコードは,それぞれの作者の意向による制限が加えら
れます具体的にはgc.c(一部)util.c(一部)regex.[ch]
fnmatch.[ch]glob.cst.[ch]と./missingディレクトリ下の
ファイル群が該当します.
3. 以下の条件のいずれかを満たす時にRubyをオブジェクトコー
ドや実行形式でも配布できます.
+ Rubyスクリプトの権利
(a) バイナリを受け取った人がソースを入手できるようにソー
スの入手法を明示する
全てのrubyスクリプトの権利はそれぞれの著作者に属します
作者はこれらに関して一切の権利を主張しませんまたrubyに
組み込むための拡張モジュールに関しても同様です.
(b) 機械可読なソースコードを添付する
+ 無保証
(c) 変更を行ったバイナリは名前を変更したうえ,ソースの
入手法を明示する
(d) その他の配布条件を作者と合意する
4. 他のプログラムへの引用はいかなる目的であれ自由です.た
だしRubyに含まれる他の作者によるコードはそれぞれの
作者の意向による制限が加えられます具体的にはgc.c(一部)
util.c(一部)st.[ch]regex.[ch], fnmatch.[ch], glob.c
および./missingディレクトリ下のファイル群が該当します
5. Rubyへの入力となるスクリプトおよびRubyからの出力の権
利はRubyの作者ではなくそれぞれの入出力を生成した人に
属しますまたRubyに組み込むための拡張モジュールにつ
いても同様です.
6. Rubyは無保証です作者はRubyをサポートする意志はありま
すがRuby自身のバグあるいはRubyスクリプトのバグなどか
ら発生するいかなる損害に対しても責任を持ちません.
Rubyは無保証です作者はrubyをサポートする意志はあります
ruby自身のバグあるいはrubyスクリプトのバグなどから発
生するいかなる損害に対しても責任を持ちません.
* 著者

548
array.c

File diff suppressed because it is too large Load diff

358
bignum.c
View file

@ -18,8 +18,8 @@ VALUE cBignum;
#define BDIGITS(x) RBIGNUM(x)->digits
#define BITSPERDIG (sizeof(USHORT)*CHAR_BIT)
#define BIGRAD (1L << BITSPERDIG)
#define DIGSPERLONG ((UINT)(sizeof(long)/sizeof(USHORT)))
#define BIGUP(x) ((unsigned long)(x) << BITSPERDIG)
#define DIGSPERINT ((UINT)(sizeof(INT)/sizeof(USHORT)))
#define BIGUP(x) ((UINT)(x) << BITSPERDIG)
#define BIGDN(x) ((x) >> BITSPERDIG)
#define BIGLO(x) ((x) & (BIGRAD-1))
@ -42,19 +42,19 @@ bignew_1(class, len, sign)
VALUE
big_clone(x)
struct RBignum *x;
VALUE x;
{
VALUE z = bignew_1(CLASS_OF(x), x->len, x->sign);
VALUE z = bignew_1(CLASS_OF(x), RBIGNUM(x)->len, RBIGNUM(x)->sign);
MEMCPY(BDIGITS(z), BDIGITS(x), USHORT, x->len);
return (VALUE)z;
MEMCPY(BDIGITS(z), BDIGITS(x), USHORT, RBIGNUM(x)->len);
return z;
}
void
big_2comp(x) /* get 2's complement */
struct RBignum *x;
VALUE x;
{
UINT i = x->len;
UINT i = RBIGNUM(x)->len;
USHORT *ds = BDIGITS(x);
long num;
@ -64,26 +64,26 @@ big_2comp(x) /* get 2's complement */
num += (long)ds[i];
ds[i++] = BIGLO(num);
num = BIGDN(num);
} while (i < x->len);
} while (i < RBIGNUM(x)->len);
if (ds[0] == 1 || ds[0] == 0) {
for (i=1;i<x->len;i++) {
for (i=1;i<RBIGNUM(x)->len;i++) {
if (ds[i] != 0) return;
}
REALLOC_N(BDIGITS(x), USHORT, x->len++);
REALLOC_N(BDIGITS(x), USHORT, RBIGNUM(x)->len++);
ds = BDIGITS(x);
ds[x->len-1] = 1;
ds[RBIGNUM(x)->len-1] = 1;
}
}
static VALUE
bignorm(x)
struct RBignum *x;
VALUE x;
{
UINT len = x->len;
UINT len = RBIGNUM(x)->len;
USHORT *ds = BDIGITS(x);
while (len-- && !ds[len]) ;
x->len = ++len;
RBIGNUM(x)->len = ++len;
if (len*sizeof(USHORT) < sizeof(VALUE) ||
(len*sizeof(USHORT) == sizeof(VALUE) &&
@ -92,19 +92,19 @@ bignorm(x)
while (len--) {
num = BIGUP(num) + ds[len];
}
if (x->sign) {
if (RBIGNUM(x)->sign) {
if (POSFIXABLE(num)) return INT2FIX(num);
}
else if (NEGFIXABLE(-num)) return INT2FIX(-num);
}
return (VALUE)x;
return x;
}
VALUE
big_norm(x)
VALUE x;
{
return bignorm(x);
return bignorm(RBIGNUM(x));
}
VALUE
@ -113,38 +113,38 @@ uint2big(n)
{
UINT i = 0;
USHORT *digits;
struct RBignum *big;
VALUE big;
i = 0;
big = (struct RBignum*)bignew(DIGSPERLONG, 1);
big = bignew(DIGSPERINT, 1);
digits = BDIGITS(big);
while (i < DIGSPERLONG) {
while (i < DIGSPERINT) {
digits[i++] = BIGLO(n);
n = BIGDN(n);
}
i = DIGSPERLONG;
i = DIGSPERINT;
while (i-- && !digits[i]) ;
big->len = i+1;
return (VALUE)big;
RBIGNUM(big)->len = i+1;
return big;
}
VALUE
int2big(n)
int n;
INT n;
{
int neg = 0;
struct RBignum *big;
INT neg = 0;
VALUE big;
if (n < 0) {
n = -n;
neg = 1;
}
big = (struct RBignum*)uint2big(n);
big = uint2big(n);
if (neg) {
big->sign = 0;
RBIGNUM(big)->sign = 0;
}
return (VALUE)big;
return big;
}
VALUE
@ -157,7 +157,7 @@ uint2inum(n)
VALUE
int2inum(n)
int n;
INT n;
{
if (FIXABLE(n)) return INT2FIX(n);
return int2big(n);
@ -209,7 +209,7 @@ str2inum(str, base)
if (POSFIXABLE(val)) {
if (sign) return INT2FIX(val);
else {
int result = -(int)val;
INT result = -(INT)val;
return INT2FIX(result);
}
}
@ -219,7 +219,7 @@ str2inum(str, base)
return big;
}
}
len = (len/(sizeof(USHORT)*CHAR_BIT))+1;
len = (len/BITSPERDIG)+1;
z = bignew(len, sign);
zds = BDIGITS(z);
@ -264,7 +264,7 @@ str2inum(str, base)
static char hexmap[] = "0123456789abcdef";
VALUE
big2str(x, base)
struct RBignum *x;
VALUE x;
int base;
{
VALUE t;
@ -276,7 +276,7 @@ big2str(x, base)
if (FIXNUM_P(x)) {
return fix2str(x, base);
}
i = x->len;
i = RBIGNUM(x)->len;
if (i == 0) return str_new2("0");
if (base == 10) {
j = (sizeof(USHORT)/sizeof(char)*CHAR_BIT*i*241L)/800+2;
@ -305,7 +305,7 @@ big2str(x, base)
ss = str_new(0, j);
s = RSTRING(ss)->ptr;
s[0] = x->sign ? '+' : '-';
s[0] = RBIGNUM(x)->sign ? '+' : '-';
while (i && j) {
int k = i;
unsigned long num = 0;
@ -324,8 +324,8 @@ big2str(x, base)
}
}
while (s[j] == '0') j++;
RSTRING(ss)->len -= x->sign?j:j-1;
memmove(x->sign?s:s+1, s+j, RSTRING(ss)->len);
RSTRING(ss)->len -= RBIGNUM(x)->sign?j:j-1;
memmove(RBIGNUM(x)->sign?s:s+1, s+j, RSTRING(ss)->len);
s[RSTRING(ss)->len] = '\0';
return ss;
@ -333,17 +333,17 @@ big2str(x, base)
static VALUE
big_to_s(x)
struct RBignum *x;
VALUE x;
{
return big2str(x, 10);
}
int
INT
big2int(x)
struct RBignum *x;
VALUE x;
{
unsigned long num;
UINT len = x->len;
UINT num;
UINT len = RBIGNUM(x)->len;
USHORT *ds;
if (len > sizeof(long)/sizeof(USHORT))
@ -354,7 +354,7 @@ big2int(x)
num = BIGUP(num);
num += ds[len];
}
if (!x->sign) return -num;
if (!RBIGNUM(x)->sign) return -num;
return num;
}
@ -393,16 +393,16 @@ dbl2big(d)
double
big2dbl(x)
struct RBignum *x;
VALUE x;
{
double d = 0.0;
UINT i = x->len;
UINT i = RBIGNUM(x)->len;
USHORT *ds = BDIGITS(x);
while (i--) {
d = ds[i] + BIGRAD*d;
}
if (!x->sign) d = -d;
if (!RBIGNUM(x)->sign) d = -d;
return d;
}
@ -415,13 +415,13 @@ big_to_f(x)
static VALUE
big_cmp(x, y)
struct RBignum *x, *y;
VALUE x, y;
{
int xlen = x->len;
int xlen = RBIGNUM(x)->len;
switch (TYPE(y)) {
case T_FIXNUM:
y = (struct RBignum*)int2big(FIX2INT(y));
y = int2big(FIX2INT(y));
break;
case T_BIGNUM:
@ -431,18 +431,18 @@ big_cmp(x, y)
return num_coerce_bin(x, y);
}
if (x->sign > y->sign) return INT2FIX(1);
if (x->sign < y->sign) return INT2FIX(-1);
if (xlen < y->len)
return (x->sign) ? INT2FIX(-1) : INT2FIX(1);
if (xlen > y->len)
return (x->sign) ? INT2FIX(1) : INT2FIX(-1);
if (RBIGNUM(x)->sign > RBIGNUM(y)->sign) return INT2FIX(1);
if (RBIGNUM(x)->sign < RBIGNUM(y)->sign) return INT2FIX(-1);
if (xlen < RBIGNUM(y)->len)
return (RBIGNUM(x)->sign) ? INT2FIX(-1) : INT2FIX(1);
if (xlen > RBIGNUM(y)->len)
return (RBIGNUM(x)->sign) ? INT2FIX(1) : INT2FIX(-1);
while(xlen-- && (BDIGITS(x)[xlen]==BDIGITS(y)[xlen]));
if (-1 == xlen) return INT2FIX(0);
return (BDIGITS(x)[xlen] > BDIGITS(y)[xlen]) ?
(x->sign ? INT2FIX(1) : INT2FIX(-1)) :
(x->sign ? INT2FIX(-1) : INT2FIX(1));
(RBIGNUM(x)->sign ? INT2FIX(1) : INT2FIX(-1)) :
(RBIGNUM(x)->sign ? INT2FIX(-1) : INT2FIX(1));
}
static VALUE
@ -455,26 +455,26 @@ big_eq(x, y)
static VALUE
big_uminus(x)
struct RBignum *x;
VALUE x;
{
VALUE z = big_clone(x);
RBIGNUM(z)->sign = !x->sign;
RBIGNUM(z)->sign = !RBIGNUM(x)->sign;
return bignorm(z);
}
static VALUE
big_neg(x)
struct RBignum *x;
VALUE x;
{
VALUE z = big_clone(x);
UINT i = x->len;
UINT i = RBIGNUM(x)->len;
USHORT *ds = BDIGITS(z);
if (!x->sign) big_2comp(z);
if (!RBIGNUM(x)->sign) big_2comp(z);
while (i--) ds[i] = ~ds[i];
if (x->sign) big_2comp(z);
if (RBIGNUM(x)->sign) big_2comp(z);
RBIGNUM(z)->sign = !RBIGNUM(z)->sign;
return bignorm(z);
@ -482,19 +482,19 @@ big_neg(x)
static VALUE
bigsub(x, y)
struct RBignum *x, *y;
VALUE x, y;
{
struct RBignum *z = 0;
VALUE z = 0;
USHORT *zds;
long num;
UINT i;
i = x->len;
i = RBIGNUM(x)->len;
/* if x is larger than y, swap */
if (x->len < y->len) {
if (RBIGNUM(x)->len < RBIGNUM(y)->len) {
z = x; x = y; y = z; /* swap x y */
}
else if (x->len == y->len) {
else if (RBIGNUM(x)->len == RBIGNUM(y)->len) {
while (i > 0) {
i--;
if (BDIGITS(x)[i] > BDIGITS(y)[i]) {
@ -507,20 +507,20 @@ bigsub(x, y)
}
}
z = (struct RBignum*)bignew(x->len, (z == 0)?1:0);
z = bignew(RBIGNUM(x)->len, (z == 0)?1:0);
zds = BDIGITS(z);
for (i = 0, num = 0; i < y->len; i++) {
for (i = 0, num = 0; i < RBIGNUM(y)->len; i++) {
num += (long)BDIGITS(x)[i] - BDIGITS(y)[i];
zds[i] = BIGLO(num);
num = BIGDN(num);
}
while (num && i < x->len) {
while (num && i < RBIGNUM(x)->len) {
num += BDIGITS(x)[i];
zds[i++] = BIGLO(num);
num = BIGDN(num);
}
while (i < x->len) {
while (i < RBIGNUM(x)->len) {
zds[i] = BDIGITS(x)[i];
i++;
}
@ -530,39 +530,40 @@ bigsub(x, y)
static VALUE
bigadd(x, y, sign)
struct RBignum *x, *y;
VALUE x, y;
char sign;
{
struct RBignum *z;
VALUE z;
long num;
UINT i, len;
if (x->sign == (y->sign ^ sign)) {
if (y->sign == sign) return bigsub(y, x);
if (RBIGNUM(x)->sign == (RBIGNUM(y)->sign ^ sign)) {
if (RBIGNUM(y)->sign == sign) return bigsub(y, x);
return bigsub(x, y);
}
if (x->len > y->len) {
len = x->len + 1;
if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
len = RBIGNUM(x)->len + 1;
z = x; x = y; y = z;
}
else {
len = y->len + 1;
len = RBIGNUM(y)->len + 1;
}
z = (struct RBignum*)bignew(len, sign==y->sign);
z = bignew(len, sign==RBIGNUM(y)->sign);
if (x->len > y->len) {
struct RBignum* t = x; x = y; y = t;
}
for (i = 0, num = 0; i < x->len; i++) {
num += (long)(BDIGITS(x)[i]) + BDIGITS(y)[i];
len = RBIGNUM(x)->len;
for (i = 0, num = 0; i < len; i++) {
num += (long)(BDIGITS(x)[i] + BDIGITS(y)[i]);
BDIGITS(z)[i] = BIGLO(num);
num = BIGDN(num);
}
while (num && i < y->len) {
len = RBIGNUM(y)->len;
while (num && i < len) {
num += BDIGITS(y)[i];
BDIGITS(z)[i++] = BIGLO(num);
num = BIGDN(num);
}
while (i < y->len) {
while (i < len) {
BDIGITS(z)[i] = BDIGITS(y)[i];
i++;
}
@ -611,17 +612,17 @@ big_minus(x, y)
VALUE
big_mul(x, y)
struct RBignum *x, *y;
VALUE x, y;
{
UINT i = 0, j;
unsigned long n = 0;
VALUE z;
USHORT *zds;
if (FIXNUM_P(x)) x = (struct RBignum*)int2big(FIX2INT(x));
if (FIXNUM_P(x)) x = int2big(FIX2INT(x));
switch (TYPE(y)) {
case T_FIXNUM:
y = (struct RBignum*)int2big(FIX2INT(y));
y = int2big(FIX2INT(y));
break;
case T_BIGNUM:
@ -634,15 +635,15 @@ big_mul(x, y)
return num_coerce_bin(x, y);
}
j = x->len + y->len + 1;
z = bignew(j, x->sign==y->sign);
j = RBIGNUM(x)->len + RBIGNUM(y)->len + 1;
z = bignew(j, RBIGNUM(x)->sign==RBIGNUM(y)->sign);
zds = BDIGITS(z);
while (j--) zds[j] = 0;
for (i = 0; i < x->len; i++) {
for (i = 0; i < RBIGNUM(x)->len; i++) {
unsigned long dd = BDIGITS(x)[i];
if (dd == 0) continue;
n = 0;
for (j = 0; j < y->len; j++) {
for (j = 0; j < RBIGNUM(y)->len; j++) {
int ee = n + dd * BDIGITS(y)[j];
n = zds[i + j] + ee;
if (ee) zds[i + j] = BIGLO(n);
@ -658,10 +659,10 @@ big_mul(x, y)
static void
bigdivmod(x, y, div, mod)
struct RBignum *x, *y;
VALUE x, y;
VALUE *div, *mod;
{
UINT nx = x->len, ny = y->len, i, j;
UINT nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len, i, j;
VALUE z;
USHORT *xds, *yds, *zds, *tds;
unsigned long t2;
@ -688,17 +689,17 @@ bigdivmod(x, y, div, mod)
}
if (div) *div = bignorm(z);
if (mod) {
if (!y->sign) t2 = -t2;
if (!RBIGNUM(y)->sign) t2 = -t2;
*mod = INT2FIX(t2);
}
return;
}
z = bignew(nx==ny?nx+2:nx+1, x->sign==y->sign);
z = bignew(nx==ny?nx+2:nx+1, RBIGNUM(x)->sign==RBIGNUM(y)->sign);
zds = BDIGITS(z);
if (nx==ny) zds[nx+1] = 0;
while (!yds[ny-1]) ny--;
if ((dd = BIGRAD/(int)(yds[ny-1]+1)) != 1) {
y = (struct RBignum*)big_clone(y);
y = big_clone(y);
tds = BDIGITS(y);
j = 0;
num = 0;
@ -771,7 +772,7 @@ bigdivmod(x, y, div, mod)
}
}
RBIGNUM(*mod)->len = ny;
RBIGNUM(*mod)->sign = y->sign;
RBIGNUM(*mod)->sign = RBIGNUM(y)->sign;
*mod = bignorm(*mod);
}
}
@ -897,7 +898,7 @@ big_pow(x, y)
VALUE
big_and(x, y)
struct RBignum *x, *y;
VALUE x, y;
{
VALUE z;
USHORT *ds1, *ds2, *zds;
@ -905,35 +906,35 @@ big_and(x, y)
char sign;
if (FIXNUM_P(y)) {
y = (struct RBignum*)int2big(FIX2INT(y));
y = int2big(FIX2INT(y));
}
else {
Check_Type(y, T_BIGNUM);
}
if (!y->sign) {
y = (struct RBignum*)big_clone(y);
if (!RBIGNUM(y)->sign) {
y = big_clone(y);
big_2comp(y);
}
if (!x->sign) {
x = (struct RBignum*)big_clone(x);
if (!RBIGNUM(x)->sign) {
x = big_clone(x);
big_2comp(x);
}
if (x->len > y->len) {
l1 = y->len;
l2 = x->len;
if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
l1 = RBIGNUM(y)->len;
l2 = RBIGNUM(x)->len;
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
sign = y->sign;
sign = RBIGNUM(y)->sign;
}
else {
l1 = x->len;
l2 = y->len;
l1 = RBIGNUM(x)->len;
l2 = RBIGNUM(y)->len;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
sign = x->sign;
sign = RBIGNUM(x)->sign;
}
z = bignew(l2, x->sign && y->sign);
z = bignew(l2, RBIGNUM(x)->sign && RBIGNUM(y)->sign);
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
@ -948,7 +949,7 @@ big_and(x, y)
VALUE
big_or(x, y)
struct RBignum *x, *y;
VALUE x, y;
{
VALUE z;
USHORT *ds1, *ds2, *zds;
@ -956,35 +957,35 @@ big_or(x, y)
char sign;
if (FIXNUM_P(y)) {
y = (struct RBignum*)int2big(FIX2INT(y));
y = int2big(FIX2INT(y));
}
else {
Check_Type(y, T_BIGNUM);
}
if (!y->sign) {
y = (struct RBignum*)big_clone(y);
if (!RBIGNUM(y)->sign) {
y = big_clone(y);
big_2comp(y);
}
if (!x->sign) {
x = (struct RBignum*)big_clone(x);
if (!RBIGNUM(x)->sign) {
x = big_clone(x);
big_2comp(x);
}
if (x->len > y->len) {
l1 = y->len;
l2 = x->len;
if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
l1 = RBIGNUM(y)->len;
l2 = RBIGNUM(x)->len;
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
sign = y->sign;
sign = RBIGNUM(y)->sign;
}
else {
l1 = x->len;
l2 = y->len;
l1 = RBIGNUM(x)->len;
l2 = RBIGNUM(y)->len;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
sign = x->sign;
sign = RBIGNUM(x)->sign;
}
z = bignew(l2, x->sign || y->sign);
z = bignew(l2, RBIGNUM(x)->sign || RBIGNUM(y)->sign);
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
@ -1000,7 +1001,7 @@ big_or(x, y)
VALUE
big_xor(x, y)
struct RBignum *x, *y;
VALUE x, y;
{
VALUE z;
USHORT *ds1, *ds2, *zds;
@ -1008,37 +1009,37 @@ big_xor(x, y)
char sign;
if (FIXNUM_P(y)) {
y = (struct RBignum*)int2big(FIX2INT(y));
y = int2big(FIX2INT(y));
}
else {
Check_Type(y, T_BIGNUM);
}
if (!y->sign) {
y = (struct RBignum*)big_clone(y);
if (!RBIGNUM(y)->sign) {
y = big_clone(y);
big_2comp(y);
}
if (!x->sign) {
x = (struct RBignum*)big_clone(x);
if (!RBIGNUM(x)->sign) {
x = big_clone(x);
big_2comp(x);
}
if (x->len > y->len) {
l1 = y->len;
l2 = x->len;
if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
l1 = RBIGNUM(y)->len;
l2 = RBIGNUM(x)->len;
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
sign = y->sign;
sign = RBIGNUM(y)->sign;
}
else {
l1 = x->len;
l2 = y->len;
l1 = RBIGNUM(x)->len;
l2 = RBIGNUM(y)->len;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
sign = x->sign;
sign = RBIGNUM(x)->sign;
}
x->sign = x->sign?1:0;
y->sign = y->sign?1:0;
z = bignew(l2, !(x->sign ^ y->sign));
RBIGNUM(x)->sign = RBIGNUM(x)->sign?1:0;
RBIGNUM(y)->sign = RBIGNUM(y)->sign?1:0;
z = bignew(l2, !(RBIGNUM(x)->sign ^ RBIGNUM(y)->sign));
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
@ -1056,21 +1057,20 @@ static VALUE big_rshift();
VALUE
big_lshift(x, y)
struct RBignum *x;
VALUE y;
VALUE x, y;
{
USHORT *xds, *zds;
int shift = NUM2INT(y);
UINT s1 = shift/(sizeof(USHORT)*CHAR_BIT);
UINT s2 = shift%(sizeof(USHORT)*CHAR_BIT);
UINT s1 = shift/BITSPERDIG;
UINT s2 = shift%BITSPERDIG;
VALUE z;
unsigned long num = 0;
UINT len, i;
if (shift < 0) return big_rshift(x, INT2FIX(-shift));
xds = BDIGITS(x);
len = x->len;
z = bignew(len+s1+1, x->sign);
len = RBIGNUM(x)->len;
z = bignew(len+s1+1, RBIGNUM(x)->sign);
zds = BDIGITS(z);
for (i=0; i<s1; i++) {
*zds++ = 0;
@ -1086,27 +1086,27 @@ big_lshift(x, y)
static VALUE
big_rshift(x, y)
struct RBignum *x;
VALUE y;
VALUE x, y;
{
USHORT *xds, *zds;
int shift = NUM2INT(y);
UINT s1 = shift/(sizeof(USHORT)*CHAR_BIT);
UINT s2 = shift%(sizeof(USHORT)*CHAR_BIT);
UINT s1 = shift/BITSPERDIG;
UINT s2 = shift%BITSPERDIG;
VALUE z;
unsigned long num = 0;
UINT i = x->len, j;
UINT i = RBIGNUM(x)->len;
UINT j;
if (shift < 0) return big_lshift(x, INT2FIX(-shift));
if (s1 > x->len) {
if (x->sign)
if (s1 > RBIGNUM(x)->len) {
if (RBIGNUM(x)->sign)
return INT2FIX(0);
else
return INT2FIX(-1);
}
xds = BDIGITS(x);
i = x->len; j = i - s1;
z = bignew(j, x->sign);
i = RBIGNUM(x)->len; j = i - s1;
z = bignew(j, RBIGNUM(x)->sign);
zds = BDIGITS(z);
while (i--, j--) {
num = (num | xds[i]) >> s2;
@ -1118,24 +1118,23 @@ big_rshift(x, y)
static VALUE
big_aref(x, y)
struct RBignum *x;
VALUE y;
VALUE x, y;
{
USHORT *xds;
int shift = NUM2INT(y);
UINT s1, s2;
if (shift < 0) return INT2FIX(0);
s1 = shift/(sizeof(USHORT)*CHAR_BIT);
s2 = shift%(sizeof(USHORT)*CHAR_BIT);
s1 = shift/BITSPERDIG;
s2 = shift%BITSPERDIG;
if (!x->sign) {
if (s1 >= x->len) return INT2FIX(1);
x = (struct RBignum*)big_clone(x);
if (!RBIGNUM(x)->sign) {
if (s1 >= RBIGNUM(x)->len) return INT2FIX(1);
x = big_clone(x);
big_2comp(x);
}
else {
if (s1 >= x->len) return INT2FIX(0);
if (s1 >= RBIGNUM(x)->len) return INT2FIX(0);
}
xds = BDIGITS(x);
if (xds[s1] & (1<<s2))
@ -1145,13 +1144,13 @@ big_aref(x, y)
static VALUE
big_hash(x)
struct RBignum *x;
VALUE x;
{
int i, len, key;
USHORT *digits;
key = 0; digits = BDIGITS(x);
for (i=0,len=x->len; i<x->len; i++) {
for (i=0,len=RBIGNUM(x)->len; i<RBIGNUM(x)->len; i++) {
key ^= *digits++;
}
return INT2FIX(key);
@ -1159,8 +1158,7 @@ big_hash(x)
static VALUE
big_coerce(x, y)
struct RBignum *x;
VALUE y;
VALUE x, y;
{
if (FIXNUM_P(y)) {
return assoc_new(int2big(FIX2INT(y)), x);
@ -1173,11 +1171,11 @@ big_coerce(x, y)
static VALUE
big_abs(x)
struct RBignum *x;
VALUE x;
{
if (!x->sign) {
x = (struct RBignum*)big_clone(x);
x->sign = 1;
if (!RBIGNUM(x)->sign) {
x = big_clone(x);
RBIGNUM(x)->sign = 1;
}
return (VALUE)x;
}
@ -1188,12 +1186,12 @@ big_abs(x)
VALUE
big_rand(max)
struct RBignum *max;
VALUE max;
{
struct RBignum *v;
int len;
len = max->len;
len = RBIGNUM(max)->len;
v = RBIGNUM(bignew(len,1));
while (len--) {
#ifdef HAVE_RANDOM
@ -1208,9 +1206,9 @@ big_rand(max)
static VALUE
big_size(big)
struct RBignum *big;
VALUE big;
{
return INT2FIX(big->len*2);
return INT2FIX(RBIGNUM(big)->len*sizeof(USHORT));
}
void

341
class.c
View file

@ -22,28 +22,27 @@ extern VALUE cModule;
VALUE
class_new(super)
struct RClass *super;
VALUE super;
{
NEWOBJ(cls, struct RClass);
OBJSETUP(cls, cClass, T_CLASS);
NEWOBJ(klass, struct RClass);
OBJSETUP(klass, cClass, T_CLASS);
cls->super = super;
cls->iv_tbl = 0;
cls->m_tbl = 0; /* safe GC */
cls->m_tbl = new_idhash();
klass->super = super;
klass->iv_tbl = 0;
klass->m_tbl = 0; /* safe GC */
klass->m_tbl = new_idhash();
return (VALUE)cls;
return (VALUE)klass;
}
VALUE
singleton_class_new(super)
struct RClass *super;
VALUE super;
{
struct RClass *cls = (struct RClass*)class_new(super);
VALUE klass = class_new(super);
FL_SET(cls, FL_SINGLETON);
return (VALUE)cls;
FL_SET(klass, FL_SINGLETON);
return klass;
}
static int
@ -57,40 +56,50 @@ clone_method(mid, body, tbl)
}
VALUE
singleton_class_clone(class)
struct RClass *class;
singleton_class_clone(klass)
VALUE klass;
{
if (!FL_TEST(class, FL_SINGLETON))
return (VALUE)class;
if (!FL_TEST(klass, FL_SINGLETON))
return klass;
else {
/* copy singleton(unnamed) class */
NEWOBJ(clone, struct RClass);
CLONESETUP(clone, class);
CLONESETUP(clone, klass);
clone->super = class->super;
clone->super = RCLASS(klass)->super;
clone->iv_tbl = 0;
clone->m_tbl = 0;
clone->m_tbl = new_idhash();
st_foreach(class->m_tbl, clone_method, clone->m_tbl);
st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl);
FL_SET(clone, FL_SINGLETON);
return (VALUE)clone;
}
}
void
singleton_class_attached(klass, obj)
VALUE klass, obj;
{
if (FL_TEST(klass, FL_SINGLETON))
rb_iv_set(klass, "__attached__", obj);
}
VALUE
rb_define_class_id(id, super)
ID id;
struct RBasic *super;
VALUE super;
{
struct RClass *cls;
VALUE klass;
if (!super) super = (struct RBasic*)cClass;
cls = (struct RClass*)class_new(super);
rb_name_class(cls, id);
if (!super) super = cObject;
klass = class_new(super);
rb_name_class(klass, id);
/* make metaclass */
RBASIC(cls)->class = singleton_class_new(super->class);
RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class);
singleton_class_attached(RBASIC(klass)->class, klass);
rb_funcall(super, rb_intern("inherited"), 1, klass);
return (VALUE)cls;
return (VALUE)klass;
}
VALUE
@ -98,14 +107,14 @@ rb_define_class(name, super)
char *name;
VALUE super;
{
VALUE class;
VALUE klass;
ID id;
id = rb_intern(name);
class = rb_define_class_id(id, super);
st_add_direct(rb_class_tbl, id, class);
klass = rb_define_class_id(id, super);
st_add_direct(rb_class_tbl, id, klass);
return class;
return klass;
}
VALUE
@ -114,15 +123,15 @@ rb_define_class_under(under, name, super)
char *name;
VALUE super;
{
VALUE class;
VALUE klass;
ID id;
id = rb_intern(name);
class = rb_define_class_id(id, super);
rb_const_set(under, id, class);
rb_set_class_path(class, under, name);
klass = rb_define_class_id(id, super);
rb_const_set(under, id, klass);
rb_set_class_path(klass, under, name);
return class;
return klass;
}
VALUE
@ -144,11 +153,11 @@ rb_define_module_id(id)
ID id;
{
extern st_table *rb_class_tbl;
struct RClass *mdl = (struct RClass*)module_new();
VALUE mdl = module_new();
rb_name_class(mdl, id);
return (VALUE)mdl;
return mdl;
}
VALUE
@ -181,31 +190,31 @@ rb_define_module_under(under, name)
return module;
}
static struct RClass *
static VALUE
include_class_new(module, super)
struct RClass *module, *super;
VALUE module, super;
{
NEWOBJ(cls, struct RClass);
OBJSETUP(cls, cClass, T_ICLASS);
NEWOBJ(klass, struct RClass);
OBJSETUP(klass, cClass, T_ICLASS);
cls->m_tbl = module->m_tbl;
cls->iv_tbl = module->iv_tbl;
cls->super = super;
klass->m_tbl = RCLASS(module)->m_tbl;
klass->iv_tbl = RCLASS(module)->iv_tbl;
klass->super = super;
if (TYPE(module) == T_ICLASS) {
RBASIC(cls)->class = RBASIC(module)->class;
RBASIC(klass)->class = RBASIC(module)->class;
}
else {
RBASIC(cls)->class = (VALUE)module;
RBASIC(klass)->class = module;
}
return cls;
return (VALUE)klass;
}
void
rb_include_module(class, module)
VALUE class, module;
rb_include_module(klass, module)
VALUE klass, module;
{
struct RClass *p;
VALUE p;
if (NIL_P(module)) return;
@ -217,71 +226,233 @@ rb_include_module(class, module)
Check_Type(module, T_MODULE);
}
if (class == module) return;
if (klass == module) return;
rb_clear_cache();
while (module) {
/* ignore if the module included already in superclasses */
for (p = RCLASS(class)->super; p; p = p->super) {
if (BUILTIN_TYPE(p) == T_ICLASS && p->m_tbl == RCLASS(module)->m_tbl)
for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
if (BUILTIN_TYPE(p) == T_ICLASS &&
RCLASS(p)->m_tbl == RCLASS(module)->m_tbl)
return;
}
RCLASS(class)->super = include_class_new(module, RCLASS(class)->super);
class = (VALUE)RCLASS(class)->super;
module = (VALUE)RCLASS(module)->super;
RCLASS(klass)->super =
include_class_new(module, RCLASS(klass)->super);
klass = RCLASS(klass)->super;
module = RCLASS(module)->super;
}
}
VALUE
mod_included_modules(mod)
VALUE mod;
{
VALUE ary = ary_new();
VALUE p;
for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
if (BUILTIN_TYPE(p) == T_ICLASS) {
ary_push(ary, RBASIC(p)->class);
}
}
return ary;
}
VALUE
mod_ancestors(mod)
VALUE mod;
{
VALUE ary = ary_new();
VALUE p;
for (p = mod; p; p = RCLASS(p)->super) {
if (BUILTIN_TYPE(p) == T_ICLASS) {
ary_push(ary, RBASIC(p)->class);
}
else {
ary_push(ary, p);
}
}
return ary;
}
static int
ins_methods_i(key, body, ary)
ID key;
NODE *body;
VALUE ary;
{
if (!body->nd_noex) {
VALUE name = str_new2(rb_id2name(key));
if (!ary_includes(ary, name)) {
if (!body->nd_body) {
ary_push(ary, Qnil);
}
ary_push(ary, name);
}
}
else if (nd_type(body->nd_body) == NODE_ZSUPER) {
ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key)));
}
return ST_CONTINUE;
}
static int
ins_methods_priv_i(key, body, ary)
ID key;
NODE *body;
VALUE ary;
{
if (!body->nd_body) {
ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key)));
}
else if (body->nd_noex) {
VALUE name = str_new2(rb_id2name(key));
if (!ary_includes(ary, name)) {
ary_push(ary, name);
}
}
else if (nd_type(body->nd_body) == NODE_ZSUPER) {
ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key)));
}
return ST_CONTINUE;
}
static VALUE
method_list(mod, option, func)
VALUE mod;
int option;
int (*func)();
{
VALUE ary;
VALUE klass;
VALUE *p, *q, *pend;
ary = ary_new();
for (klass = mod; klass; klass = RCLASS(klass)->super) {
st_foreach(RCLASS(klass)->m_tbl, func, ary);
if (!option) break;
}
p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
while (p < pend) {
if (*p == Qnil) {
p+=2;
continue;
}
*q++ = *p++;
}
RARRAY(ary)->len = q - RARRAY(ary)->ptr;
return ary;
}
VALUE
class_instance_methods(argc, argv, mod)
int argc;
VALUE *argv;
VALUE mod;
{
VALUE option;
rb_scan_args(argc, argv, "01", &option);
return method_list(mod, RTEST(option), ins_methods_i);
}
VALUE
class_private_instance_methods(argc, argv, mod)
int argc;
VALUE *argv;
VALUE mod;
{
VALUE option;
rb_scan_args(argc, argv, "01", &option);
return method_list(mod, RTEST(option), ins_methods_priv_i);
}
VALUE
obj_singleton_methods(obj)
VALUE obj;
{
VALUE ary;
VALUE klass;
VALUE *p, *q, *pend;
ary = ary_new();
klass = CLASS_OF(obj);
while (klass && FL_TEST(klass, FL_SINGLETON)) {
st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
klass = RCLASS(klass)->super;
}
p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
while (p < pend) {
if (*p == Qnil) {
p+=2;
continue;
}
*q++ = *p++;
}
RARRAY(ary)->len = q - RARRAY(ary)->ptr;
return ary;
}
void
rb_define_method_id(class, name, func, argc)
struct RClass *class;
rb_define_method_id(klass, name, func, argc)
VALUE klass;
ID name;
VALUE (*func)();
int argc;
{
rb_add_method(class, name, NEW_CFUNC(func, argc), NOEX_PUBLIC);
rb_add_method(klass, name, NEW_CFUNC(func, argc), NOEX_PUBLIC);
}
void
rb_define_method(class, name, func, argc)
VALUE class;
rb_define_method(klass, name, func, argc)
VALUE klass;
char *name;
VALUE (*func)();
int argc;
{
rb_add_method(class, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC);
rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC);
}
void
rb_undef_method(class, name)
VALUE class;
rb_undef_method(klass, name)
VALUE klass;
char *name;
{
rb_add_method(class, rb_intern(name), 0, NOEX_PUBLIC);
rb_add_method(klass, rb_intern(name), 0, NOEX_PUBLIC);
}
void
rb_define_private_method(class, name, func, argc)
struct RClass *class;
rb_define_private_method(klass, name, func, argc)
VALUE klass;
char *name;
VALUE (*func)();
int argc;
{
rb_add_method(class, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
}
VALUE
rb_singleton_class(obj)
struct RBasic *obj;
VALUE obj;
{
if (rb_special_const_p((VALUE)obj)) {
if (rb_special_const_p(obj)) {
TypeError("cannot define singleton");
}
if (FL_TEST(obj->class, FL_SINGLETON)) {
return (VALUE)obj->class;
if (FL_TEST(RBASIC(obj)->class, FL_SINGLETON)) {
return (VALUE)RBASIC(obj)->class;
}
return obj->class = singleton_class_new(obj->class);
RBASIC(obj)->class = singleton_class_new(RBASIC(obj)->class);
singleton_class_attached(RBASIC(obj)->class, obj);
return RBASIC(obj)->class;
}
void
@ -305,7 +476,7 @@ rb_define_module_function(module, name, func, argc)
rb_define_singleton_method(module, name, func, argc);
}
VALUE mKernel;
extern VALUE mKernel;
void
rb_define_global_function(name, func, argc)
@ -317,18 +488,18 @@ rb_define_global_function(name, func, argc)
}
void
rb_define_alias(class, name1, name2)
VALUE class;
rb_define_alias(klass, name1, name2)
VALUE klass;
char *name1, *name2;
{
rb_alias(class, rb_intern(name1), rb_intern(name2));
rb_alias(klass, rb_intern(name1), rb_intern(name2));
}
void
rb_define_attr(class, id, pub)
VALUE class;
rb_define_attr(klass, id, read, write)
VALUE klass;
ID id;
int pub;
int read, write;
{
char *name;
char *buf;
@ -341,11 +512,11 @@ rb_define_attr(class, id, pub)
attreq = rb_intern(buf);
sprintf(buf, "@%s", name);
attriv = rb_intern(buf);
if (!rb_method_boundp(class, attr, NOEX_PRIVATE)) {
rb_add_method(class, attr, NEW_IVAR(attriv), 0);
if (read) {
rb_add_method(klass, attr, NEW_IVAR(attriv), 0);
}
if (pub && !rb_method_boundp(class, attreq, NOEX_PRIVATE)) {
rb_add_method(class, attreq, NEW_ATTRSET(attriv), 0);
if (write) {
rb_add_method(klass, attreq, NEW_ATTRSET(attriv), 0);
}
}

View file

@ -38,7 +38,7 @@
#define FLUSH_REGISTER_WINDOWS /* empty */
#endif
#ifdef __human68k__
#if defined(__human68k__) || defined(__CYGWIN32__)
#undef HAVE_RANDOM
#undef HAVE_SETITIMER
#endif

40
dir.c
View file

@ -13,15 +13,16 @@
#include "ruby.h"
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/stat.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#else
# define MAXPATHLEN 1024
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_DIRENT_H
# include <dirent.h>
@ -60,22 +61,21 @@ free_dir(dir)
static VALUE
dir_s_open(dir_class, dirname)
VALUE dir_class;
struct RString *dirname;
VALUE dir_class, dirname;
{
VALUE obj;
DIR *dirp;
Check_SafeStr(dirname);
dirp = opendir(dirname->ptr);
dirp = opendir(RSTRING(dirname)->ptr);
if (dirp == NULL) {
if (errno == EMFILE || errno == ENFILE) {
gc();
dirp = opendir(dirname->ptr);
gc_gc();
dirp = opendir(RSTRING(dirname)->ptr);
}
if (dirp == NULL) {
rb_sys_fail(dirname->ptr);
rb_sys_fail(RSTRING(dirname)->ptr);
}
}
@ -178,7 +178,7 @@ dir_s_chdir(argc, argv, obj)
rb_secure(2);
rb_scan_args(argc, argv, "01", &path);
if (path) {
if (!NIL_P(path)) {
Check_SafeStr(path);
dist = RSTRING(path)->ptr;
}
@ -259,13 +259,12 @@ dir_s_mkdir(argc, argv, obj)
static VALUE
dir_s_rmdir(obj, dir)
VALUE obj;
struct RString *dir;
VALUE obj, dir;
{
rb_secure(2);
Check_SafeStr(dir);
if (rmdir(dir->ptr) < 0)
rb_sys_fail(dir->ptr);
if (rmdir(RSTRING(dir)->ptr) < 0)
rb_sys_fail(RSTRING(dir)->ptr);
return TRUE;
}
@ -342,18 +341,18 @@ push_braces(ary, s)
}
static VALUE
dir_s_glob(dir, str)
VALUE dir;
struct RString *str;
dir_s_glob(dir, vstr)
VALUE dir, vstr;
{
char *p, *pend;
char buf[MAXPATHLEN];
char *t, *t0;
int nest;
VALUE ary;
struct RString *str;
Check_SafeStr(str);
Check_SafeStr(vstr);
str = RSTRING(vstr);
ary = ary_new();
p = str->ptr;
@ -386,8 +385,7 @@ dir_s_glob(dir, str)
static VALUE
dir_foreach(io, dirname)
VALUE io;
struct RString *dirname;
VALUE io, dirname;
{
VALUE dir;

71
dln.c
View file

@ -24,6 +24,12 @@ char *dln_argv0;
#include <alloca.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
void *xmalloc();
void *xcalloc();
void *xrealloc();
@ -47,15 +53,8 @@ void *xrealloc();
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif
#ifndef NT
char *strdup();
char *getenv();
#endif
@ -1069,7 +1068,6 @@ dln_sym(name)
#ifdef _AIX
#include <ctype.h> /* for isdigit() */
#include <errno.h> /* for global errno */
#include <string.h> /* for strerror() */
#include <sys/ldr.h>
#endif
@ -1077,6 +1075,10 @@ dln_sym(name)
/*#include <mach-o/rld.h>*/
#endif
#ifdef _WIN32
#include <windows.h>
#endif
static char *
dln_strerror()
{
@ -1104,6 +1106,20 @@ dln_strerror()
#ifdef USE_DLN_DLOPEN
return (char*)dlerror();
#endif
#ifdef _WIN32
static char message[1024];
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
message,
sizeof message,
NULL);
return message;
#endif
}
@ -1159,6 +1175,43 @@ void
dln_load(file)
char *file;
{
#ifdef _WIN32
HINSTANCE handle;
char winfile[255];
void (*init_fct)();
char buf[MAXPATHLEN];
/* Load the file as an object one */
init_funcname(buf, file);
#ifdef __CYGWIN32__
cygwin32_conv_to_win32_path(file, winfile);
#else
strcpy(winfile, file);
#endif
/* Load file */
if ((handle =
LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
printf("LoadLibraryExA\n");
goto failed;
}
#ifdef __CYGWIN32__
init_fct = (void(*)())GetProcAddress(handle, "impure_setup");
if (init_fct)
init_fct(_impure_ptr);
#endif
if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {
printf("GetProcAddress %s\n", buf);
goto failed;
}
/* Call the init code */
(*init_fct)();
return;
#else
#ifdef USE_DLN_A_OUT
if (load(file) == -1) {
goto failed;
@ -1175,7 +1228,6 @@ dln_load(file)
{
void *handle;
void (*init_fct)();
int len = strlen(file);
# ifndef RTLD_LAZY
# define RTLD_LAZY 1
@ -1280,6 +1332,7 @@ dln_load(file)
#endif
#endif /* USE_DLN_A_OUT */
#endif
#if !defined(_AIX) && !defined(NeXT)
failed:
LoadError("%s - %s", dln_strerror(), file);

68
enum.c
View file

@ -15,29 +15,31 @@
VALUE mEnumerable;
static ID id_each, id_eqq, id_cmp;
void
VALUE
rb_each(obj)
VALUE obj;
{
rb_funcall(obj, id_each, 0, 0);
return rb_funcall(obj, id_each, 0, 0);
}
static void
static VALUE
grep_i(i, arg)
VALUE i, *arg;
{
if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) {
ary_push(arg[1], i);
}
return Qnil;
}
static void
static VALUE
grep_iter_i(i, pat)
VALUE i, pat;
{
if (RTEST(rb_funcall(pat, id_eqq, 1, i))) {
rb_yield(i);
}
return Qnil;
}
static VALUE
@ -52,7 +54,7 @@ enum_grep(obj, pat)
VALUE tmp, arg[2];
arg[0] = pat; arg[1] = tmp = ary_new();
rb_iterate(rb_each, obj, grep_i, arg);
rb_iterate(rb_each, obj, grep_i, (VALUE)arg);
return tmp;
}
@ -63,7 +65,7 @@ struct find_arg {
VALUE val;
};
static void
static VALUE
find_i(i, arg)
VALUE i;
struct find_arg *arg;
@ -71,14 +73,15 @@ find_i(i, arg)
if (RTEST(rb_yield(i))) {
arg->found = TRUE;
arg->val = i;
rb_break();
rb_iter_break();
}
return Qnil;
}
static VALUE
enum_find(argc, argv, obj)
int argc;
VALUE argv;
VALUE* argv;
VALUE obj;
{
struct find_arg arg;
@ -86,7 +89,7 @@ enum_find(argc, argv, obj)
rb_scan_args(argc, argv, "01", &if_none);
arg.found = FALSE;
rb_iterate(rb_each, obj, find_i, &arg);
rb_iterate(rb_each, obj, find_i, (VALUE)&arg);
if (arg.found) {
return arg.val;
}
@ -96,13 +99,14 @@ enum_find(argc, argv, obj)
return Qnil;
}
static void
static VALUE
find_all_i(i, tmp)
VALUE i, tmp;
{
if (RTEST(rb_yield(i))) {
ary_push(tmp, i);
}
return Qnil;
}
static VALUE
@ -117,7 +121,7 @@ enum_find_all(obj)
return tmp;
}
static void
static VALUE
collect_i(i, tmp)
VALUE i, tmp;
{
@ -127,6 +131,7 @@ collect_i(i, tmp)
if (RTEST(retval)) {
ary_push(tmp, retval);
}
return Qnil;
}
static VALUE
@ -141,11 +146,12 @@ enum_collect(obj)
return tmp;
}
static void
static VALUE
reverse_i(i, tmp)
VALUE i, tmp;
{
ary_unshift(tmp, i);
return Qnil;
}
static VALUE
@ -160,11 +166,12 @@ enum_reverse(obj)
return tmp;
}
static void
static VALUE
enum_all(i, ary)
VALUE i, ary;
{
ary_push(ary, i);
return Qnil;
}
static VALUE
@ -186,7 +193,7 @@ enum_sort(obj)
return ary_sort(enum_to_a(obj));
}
static void
static VALUE
min_i(i, min)
VALUE i, *min;
{
@ -199,9 +206,10 @@ min_i(i, min)
if (FIX2INT(cmp) < 0)
*min = i;
}
return Qnil;
}
static void
static VALUE
min_ii(i, min)
VALUE i, *min;
{
@ -214,6 +222,7 @@ min_ii(i, min)
if (FIX2INT(cmp) < 0)
*min = i;
}
return Qnil;
}
static VALUE
@ -222,11 +231,11 @@ enum_min(obj)
{
VALUE min = Qnil;
rb_iterate(rb_each, obj, iterator_p()?min_ii:min_i, &min);
rb_iterate(rb_each, obj, iterator_p()?min_ii:min_i, (VALUE)&min);
return min;
}
static void
static VALUE
max_i(i, max)
VALUE i, *max;
{
@ -239,9 +248,10 @@ max_i(i, max)
if (FIX2INT(cmp) > 0)
*max = i;
}
return Qnil;
}
static void
static VALUE
max_ii(i, max)
VALUE i, *max;
{
@ -254,6 +264,7 @@ max_ii(i, max)
if (FIX2INT(cmp) > 0)
*max = i;
}
return Qnil;
}
static VALUE
@ -262,7 +273,7 @@ enum_max(obj)
{
VALUE max = Qnil;
rb_iterate(rb_each, obj, iterator_p()?max_ii:max_i, &max);
rb_iterate(rb_each, obj, iterator_p()?max_ii:max_i, (VALUE)&max);
return max;
}
@ -272,18 +283,19 @@ struct i_v_pair {
int found;
};
static void
static VALUE
index_i(item, iv)
VALUE item;
struct i_v_pair *iv;
{
if (rb_equal(item, iv->v)) {
iv->found = 1;
rb_break();
rb_iter_break();
}
else {
iv->i++;
}
return Qnil;
}
static VALUE
@ -295,20 +307,21 @@ enum_index(obj, val)
iv.i = 0;
iv.v = val;
iv.found = 0;
rb_iterate(rb_each, obj, index_i, &iv);
rb_iterate(rb_each, obj, index_i, (VALUE)&iv);
if (iv.found) return INT2FIX(iv.i);
return Qnil; /* not found */
}
static void
static VALUE
member_i(item, iv)
VALUE item;
struct i_v_pair *iv;
{
if (rb_equal(item, iv->v)) {
iv->i = 1;
rb_break();
rb_iter_break();
}
return Qnil;
}
static VALUE
@ -319,17 +332,18 @@ enum_member(obj, val)
iv.i = 0;
iv.v = val;
rb_iterate(rb_each, obj, member_i, &iv);
rb_iterate(rb_each, obj, member_i, (VALUE)&iv);
if (iv.i) return TRUE;
return FALSE;
}
static void
static VALUE
length_i(i, length)
VALUE i;
int *length;
{
(*length)++;
return Qnil;
}
VALUE
@ -338,7 +352,7 @@ enum_length(obj)
{
int length = 0;
rb_iterate(rb_each, obj, length_i, &length);
rb_iterate(rb_each, obj, length_i, (VALUE)&length);
return INT2FIX(length);
}

6
env.h
View file

@ -15,7 +15,7 @@ extern struct FRAME {
int argc;
VALUE *argv;
ID last_func;
struct RClass *last_class;
VALUE last_class;
VALUE cbase;
struct FRAME *prev;
char *file;
@ -23,6 +23,8 @@ extern struct FRAME {
int iter;
} *the_frame;
void gc_mark_frame _((struct FRAME *));
extern struct SCOPE {
struct RBasic super;
ID *local_tbl;
@ -36,7 +38,7 @@ extern struct SCOPE {
extern int rb_in_eval;
extern struct RClass *the_class;
extern VALUE the_class;
struct RVarmap {
struct RBasic super;

25
error.c
View file

@ -102,7 +102,7 @@ Warning(fmt, va_alist)
char buf[BUFSIZ];
va_list args;
if (!verbose) return;
if (!RTEST(verbose)) return;
sprintf(buf, "warning: %s", fmt);
@ -225,11 +225,10 @@ exc_new2(etype, s)
VALUE
exc_new3(etype, str)
VALUE etype;
struct RString *str;
VALUE etype, str;
{
Check_Type(str, T_STRING);
return exc_new(etype, str->ptr, str->len);
return exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len);
}
static VALUE
@ -251,14 +250,20 @@ static VALUE
exc_inspect(exc)
VALUE exc;
{
struct RString *classpath = RSTRING(rb_class_path(CLASS_OF(exc)));
VALUE str = str_new(classpath->ptr, classpath->len);
VALUE str, klass;
str_cat(str, ":", 1);
klass = CLASS_OF(exc);
if (RSTRING(exc)->len == 0) {
str_cat(str, "\"\"", 2);
return rb_class_path(klass);
}
str = str_new2("#<");
klass = rb_class_path(klass);
str_cat(str, RSTRING(klass)->ptr, RSTRING(klass)->len);
str_cat(str, ":", 1);
str_cat(str, RSTRING(exc)->ptr, RSTRING(exc)->len);
str_cat(str, ">", 1);
return str;
}
@ -285,7 +290,7 @@ exception(argc, argv)
}
}
for (i=0; i<argc; i++) {
v = rb_define_class(rb_id2name(rb_to_id(argv[i])), eException);
v = rb_define_class_under(the_class, rb_id2name(rb_to_id(argv[i])), eException);
}
return v;
}
@ -327,7 +332,7 @@ Init_Exception()
eNameError = rb_define_class("NameError", eException);
eIndexError = rb_define_class("IndexError", eException);
eNotImpError = rb_define_class("NotImplementError", eException);
eLoadError = rb_define_class("LoadError", eException);
eLoadError = rb_define_class("LoadError", eException);
eRuntimeError = rb_define_class("RuntimeError", eException);
eSecurityError = rb_define_class("SecurityError", eException);

1578
eval.c

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,7 @@
#etc
#fcntl
#kconv
#marshal
#md5
#socket
#tkutil
#tcltklib

View file

@ -32,7 +32,8 @@ struct windata {
WINDOW *window;
};
#define NUM2CHAR(x) (char)NUM2INT(x)
#define NUM2CHAR(x) ((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\
RSTRING(x)->ptr[0]:(char)NUM2INT(x)
#define CHAR2FIX(x) INT2FIX((int)x)
static void
@ -46,13 +47,7 @@ no_window()
if (winp->window == 0) no_window();\
}
static void
curses_err()
{
Fail("curses error");
}
#define CHECK(c) if ((c)==ERR) {curses_err();}
#define CHECK(c) c
static void
free_window(winp)
@ -99,7 +94,7 @@ curses_init_screen()
static VALUE
curses_stdscr()
{
if (!rb_stdscr) curses_init_screen();
if (rb_stdscr == 0) curses_init_screen();
return rb_stdscr;
}
@ -107,7 +102,7 @@ curses_stdscr()
static VALUE
curses_close_screen()
{
CHECK(endwin());
endwin();
return Qnil;
}
@ -139,7 +134,7 @@ static VALUE
curses_refresh(obj)
VALUE obj;
{
CHECK(refresh());
refresh();
return Qnil;
}
@ -148,7 +143,7 @@ static VALUE
curses_doupdate(obj)
VALUE obj;
{
CHECK(doupdate());
doupdate();
return Qnil;
}
@ -157,7 +152,7 @@ static VALUE
curses_echo(obj)
VALUE obj;
{
CHECK(echo());
echo();
return Qnil;
}
@ -166,7 +161,7 @@ static VALUE
curses_noecho(obj)
VALUE obj;
{
CHECK(noecho());
noecho();
return Qnil;
}
@ -175,7 +170,7 @@ static VALUE
curses_raw(obj)
VALUE obj;
{
CHECK(raw());
raw();
return Qnil;
}
@ -184,7 +179,7 @@ static VALUE
curses_noraw(obj)
VALUE obj;
{
CHECK(noraw());
noraw();
return Qnil;
}
@ -193,7 +188,7 @@ static VALUE
curses_cbreak(obj)
VALUE obj;
{
CHECK(cbreak());
cbreak();
return Qnil;
}
@ -202,7 +197,7 @@ static VALUE
curses_nocbreak(obj)
VALUE obj;
{
CHECK(nocbreak());
nocbreak();
return Qnil;
}
@ -211,7 +206,7 @@ static VALUE
curses_nl(obj)
VALUE obj;
{
CHECK(nl());
nl();
return Qnil;
}
@ -220,7 +215,7 @@ static VALUE
curses_nonl(obj)
VALUE obj;
{
CHECK(nonl());
nonl();
return Qnil;
}
@ -251,7 +246,7 @@ curses_ungetch(obj, ch)
VALUE ch;
{
#ifdef HAVE_UNGETCH
CHECK(ungetch(NUM2INT(ch)));
ungetch(NUM2INT(ch));
#else
rb_notimplement();
#endif
@ -265,7 +260,7 @@ curses_setpos(obj, y, x)
VALUE y;
VALUE x;
{
CHECK(move(NUM2INT(y), NUM2INT(x)));
move(NUM2INT(y), NUM2INT(x));
return Qnil;
}
@ -301,7 +296,7 @@ curses_addch(obj, ch)
VALUE obj;
VALUE ch;
{
CHECK(addch(NUM2CHAR(ch)));
addch(NUM2CHAR(ch));
return Qnil;
}
@ -311,7 +306,7 @@ curses_insch(obj, ch)
VALUE obj;
VALUE ch;
{
CHECK(insch(NUM2CHAR(ch)));
insch(NUM2CHAR(ch));
return Qnil;
}
@ -339,7 +334,7 @@ curses_getstr(obj)
VALUE obj;
{
char rtn[1024]; /* This should be big enough.. I hope */
CHECK(getstr(rtn));
getstr(rtn);
return str_taint(str_new2(rtn));
}
@ -348,7 +343,7 @@ static VALUE
curses_delch(obj)
VALUE obj;
{
CHECK(delch());
delch();
return Qnil;
}
@ -357,7 +352,7 @@ static VALUE
curses_deleteln(obj)
VALUE obj;
{
CHECK(deleteln());
deleteln();
return Qnil;
}
@ -443,7 +438,7 @@ window_refresh(obj)
struct windata *winp;
GetWINDOW(obj, winp);
CHECK(wrefresh(winp->window));
wrefresh(winp->window);
return Qnil;
}
@ -474,7 +469,7 @@ window_move(obj, y, x)
struct windata *winp;
GetWINDOW(obj, winp);
CHECK(mvwin(winp->window, NUM2INT(y), NUM2INT(x)));
mvwin(winp->window, NUM2INT(y), NUM2INT(x));
return Qnil;
}
@ -489,7 +484,7 @@ window_setpos(obj, y, x)
struct windata *winp;
GetWINDOW(obj, winp);
CHECK(wmove(winp->window, NUM2INT(y), NUM2INT(x)));
wmove(winp->window, NUM2INT(y), NUM2INT(x));
return Qnil;
}
@ -639,7 +634,7 @@ window_addch(obj, ch)
struct windata *winp;
GetWINDOW(obj, winp);
CHECK(waddch(winp->window, NUM2CHAR(ch)));
waddch(winp->window, NUM2CHAR(ch));
return Qnil;
}
@ -653,7 +648,7 @@ window_insch(obj, ch)
struct windata *winp;
GetWINDOW(obj, winp);
CHECK(winsch(winp->window, NUM2CHAR(ch)));
winsch(winp->window, NUM2CHAR(ch));
return Qnil;
}
@ -667,7 +662,7 @@ window_addstr(obj, str)
struct windata *winp;
GetWINDOW(obj, winp);
CHECK(waddstr(winp->window, RSTRING(str)->ptr));
waddstr(winp->window, RSTRING(str)->ptr);
return Qnil;
}
@ -702,7 +697,7 @@ window_getstr(obj)
char rtn[1024]; /* This should be big enough.. I hope */
GetWINDOW(obj, winp);
CHECK(wgetstr(winp->window, rtn));
wgetstr(winp->window, rtn);
return str_taint(str_new2(rtn));
}
@ -714,7 +709,7 @@ window_delch(obj)
struct windata *winp;
GetWINDOW(obj, winp);
CHECK(wdelch(winp->window));
wdelch(winp->window);
return Qnil;
}
@ -726,7 +721,7 @@ window_deleteln(obj)
struct windata *winp;
GetWINDOW(obj, winp);
CHECK(wdeleteln(winp->window));
wdeleteln(winp->window);
return Qnil;
}

View file

@ -122,17 +122,15 @@ fdbm_fetch(obj, keystr)
}
static VALUE
fdbm_indexes(obj, args)
VALUE obj;
struct RArray *args;
fdbm_indexes(obj, ag)
VALUE obj, ag;
{
VALUE *p, *pend;
VALUE new;
int i = 0;
struct RArray *args = RARRAY(rb_Array(ag));
args = (struct RArray*)rb_to_a(args);
new = ary_new2(args->len);
p = args->ptr; pend = p + args->len;
while (p < pend) {
ary_push(new, fdbm_fetch(obj, *p++));

View file

@ -1 +1 @@
dbm.o: dbm.c ../../ruby.h ../../config.h ../../defines.h
dbm.o: dbm.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h

View file

@ -1 +1 @@
etc.o : etc.c ../../ruby.h ../../config.h ../../defines.h
etc.o : etc.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h

View file

@ -1,5 +1,7 @@
#! /usr/local/bin/ruby
$".push 'mkmf.rb'
if ARGV[0] == 'static'
$force_static = TRUE
ARGV.shift
@ -21,16 +23,17 @@ $topdir = "@top_srcdir@"
if $topdir !~ "^/"
# get absolute path
save = Dir.pwd
Dir.chdir ".."
Dir.chdir $topdir
$topdir = Dir.pwd
Dir.chdir save
end
$dots = if "@INSTALL@" =~ /^\// then "" else "#{$topdir}/ext/" end
if File.exist?("config.cache") then
f = open("config.cache", "r")
while f.gets
case $_
when /^lib: ([\w_]+) (yes|no)/
when /^lib: (.+) (yes|no)/
$lib_cache[$1] = $2
when /^func: ([\w_]+) (yes|no)/
$func_cache[$1] = $2
@ -215,6 +218,8 @@ SHELL = /bin/sh
srcdir = #{$srcdir}
VPATH = #{$srcdir}
hdrdir = #{$topdir}
CC = @CC@
CFLAGS = %s -I#{$topdir} %s #$CFLAGS %s
@ -233,20 +238,22 @@ libdir = @libdir@/$(RUBY_INSTALL_NAME)/@arch@
@SET_MAKE@
#### End of system configuration section. ####
"
mfile.printf "LOCAL_LIBS = %s\n", $local_libs if $local_libs
mfile.printf "LIBS = %s\n", $libs
mfile.printf "OBJS = "
if !$objs then
$objs = Dir["#{$topdir}/ext/#{target}/*.c"]
for f in $objs
f.sub!(/\.c$/, ".o")
$objs = []
for f in Dir["#{$topdir}/ext/#{target}/*.{c,cc}"]
f = File.basename(f)
f.sub!(/\.(c|cc)$/, ".o")
$objs.push f
end
end
mfile.printf $objs.join(" ")
mfile.printf "\n"
dots = if "@INSTALL@" =~ /^\// then "" else "#{$topdir}/ext/" end
mfile.printf "\
TARGET = %s.%s
@ -262,28 +269,29 @@ clean:; @rm -f *.o *.so *.sl
realclean: clean
", target,
if $static then "o" else "@DLEXT@" end, dots
if $static then "o" else "@DLEXT@" end, $dots
if !$static
mfile.printf "\
mfile.printf "\
install:
"
if !$static
mfile.printf "
@test -d $(libdir) || mkdir $(libdir)
$(INSTALL) $(TARGET) $(libdir)/$(TARGET)
"
else
mfile.printf "\
install:;
"
end
for rb in Dir["lib/*.rb"]
mfile.printf "\t$(INSTALL) %s @libdir@/$(RUBY_INSTALL_NAME)\n", rb
end
mfile.printf "\n"
if !$static && "@DLEXT@" != "o"
mfile.printf "\
$(TARGET): $(OBJS)
$(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LOCAL_LIBS) $(LIBS)
"
elsif not File.exist?(target + ".c")
elsif not File.exist?(target + ".c") and not File.exist?(target + ".cc")
if PLATFORM == "m68k-human"
mfile.printf "\
$(TARGET): $(OBJS)
@ -316,9 +324,6 @@ $(TARGET): $(OBJS)
dfile.close
end
mfile.close
if $static
$extlist.push [$static,target]
end
end
def extmake(target)
@ -343,16 +348,19 @@ def extmake(target)
!File.exist?("./Makefile") ||
older("./Makefile", "#{$topdir}/ext/@setup@") ||
older("./Makefile", "../extmk.rb") ||
older("./Makefile", "./extconf.rb")
older("./Makefile", "#{$topdir}/ext/#{target}/extconf.rb")
then
$defs = []
if File.exist?("extconf.rb")
load "extconf.rb"
if File.exist?("#{$topdir}/ext/#{target}/extconf.rb")
load "#{$topdir}/ext/#{target}/extconf.rb"
else
create_makefile(target);
end
end
if File.exist?("./Makefile")
if $static
$extlist.push [$static,target]
end
if $install
system "make install"
elsif $clean
@ -373,19 +381,22 @@ end
# get static-link modules
$static_ext = {}
if File.file? "#{$topdir}/ext/@setup@"
f = open("#{$topdir}/ext/@setup@")
while f.gets()
$_.chop!
sub!(/#.*$/, '')
next if /^\s*$/
if /^option +nodynamic/
$nodynamic = TRUE
next
for setup in ["@setup@", "#{$topdir}/ext/@setup@"]
if File.file? setup
f = open(setup)
while f.gets()
$_.chop!
sub!(/#.*$/, '')
next if /^\s*$/
if /^option +nodynamic/
$nodynamic = TRUE
next
end
$static_ext[$_.split[0]] = TRUE
end
$static_ext[$_.split[0]] = TRUE
f.close
break
end
f.close
end
for d in Dir["#{$topdir}/ext/*"]
@ -418,6 +429,7 @@ if $cache_mod
end
exit if $install or $clean
$extinit += ""
if $extlist.size > 0
for s,t in $extlist
f = format("%s/%s.o", s, t)

View file

@ -18,7 +18,8 @@ $lib_cache = {}
$func_cache = {}
$hdr_cache = {}
$dllopt = '-MD'
#$dllopt = '-MD'
$dllopt = ''
if File.exist?("config.cache") then
f = open("config.cache", "r")
@ -48,11 +49,15 @@ def older(file1, file2)
return FALSE
end
LINK = "cl -o conftest -I../.. -Zi -O -I. %s %s conftest.c %s > nul"
CPP = "cl -E -I../.. -I../../missing -I. -Zi -O %s conftest.c > nul"
#LINK = "cl -o conftest.exe -I../.. -Zi -O -I. %s conftest.c %s > nul"
LINK = "cl -o conftest.exe -Zi -O %s conftest.c %s > nul"
CPP = "cl -E -I../.. -I../../missing -I../../win32 -I. -Zi -O %s conftest.c > nul"
def try_link(libs)
system(format(LINK, $CFLAGS, $LDFLAGS, libs))
#print(format("try #{LINK}", $CFLAGS, $LDFLAGS, libs))
#system(format(LINK, $CFLAGS, $LDFLAGS, libs))
print(format("try #{LINK}\n", $CFLAGS, libs))
system(format(LINK, $CFLAGS, libs))
end
def try_cpp
@ -60,12 +65,13 @@ def try_cpp
end
def have_library(lib, func)
#print format("have_library(%s, %s)\n", lib, func)
if $lib_cache[lib]
if $lib_cache[lib] == "yes"
if $libs
$libs = "-l" + lib + " " + $libs
if $libs#
$libs = lib + ".lib " + $libs
else
$libs = "-l" + lib
$libs = lib + ".lib "
end
return TRUE
else
@ -75,6 +81,8 @@ def have_library(lib, func)
cfile = open("conftest.c", "w")
cfile.printf "\
#include <windows.h>
#include <winsock.h>
int main() { return 0; }
int t() { %s(); return 0; }
", func
@ -86,7 +94,9 @@ int t() { %s(); return 0; }
else
libs = lib + ".lib"
end
#print "libs=#{libs}\n"
unless try_link(libs)
#print "fail : #{libs}\n"
$lib_cache[lib] = 'no'
$cache_mod = TRUE
return FALSE
@ -113,7 +123,9 @@ def have_func(func)
cfile = open("conftest.c", "w")
cfile.printf "\
char %s();
#include <windows.h>
#include <winsock.h>
//char %s();
int main() { return 0; }
int t() { %s(); return 0; }
", func, func
@ -123,6 +135,7 @@ int t() { %s(); return 0; }
libs = "" if libs == nil
begin
#print "libs=#{libs}\n"
unless try_link(libs)
$func_cache[func] = 'no'
$cache_mod = TRUE
@ -186,7 +199,7 @@ def create_makefile(target)
if $libs and "obj" == "obj"
libs = $libs.split
for lib in libs
lib.sub!(/(.*)/, '"lib\1.lib"')
lib.sub!(/(.*)/, '"\1.lib"') if /.lib$/ !~ lib
end
$defs.push(format("-DEXTLIB='%s'", libs.join(",")))
end
@ -203,7 +216,7 @@ VPATH = .
CC = cl
CFLAGS = %s -I../.. -I../../missing -I. -O -DNT %s #$CFLAGS %s
CFLAGS = %s -I../.. -I../../missing -I../../win32 -I. -O -DNT %s #$CFLAGS %s
RUBYLIB = ../../ruby.lib
DLDFLAGS = /DLL
@ -211,9 +224,9 @@ LDSHARED =
", if $static then "" else "-fpic" end, $dllopt, $defs.join(" ")
if $force_static
print "static\n"
print "static\n"
else
print "non static\n"
print "non static\n"
end
mfile.printf "\
@ -245,7 +258,7 @@ DEFFILE = %s.def
all: $(TARGET)
clean:; @rm -f *.obj *.lib *.exp *.pdb *.bak
clean:; @rm -f *.obj *.lib *.exp vc*.pdb *.bak *.def
@rm -f Makefile extconf.h conftest.*
realclean: clean
@ -274,7 +287,7 @@ $(TARGET): $(OBJS)
lib /OUT:$(TARGET) $(OBJS)
"
else
mfile.printf "\
mfile.printf "\
$(DEFFILE):
echo $(DEFFILE)
@ -293,11 +306,28 @@ $(TARGET): $(OBJS) $(DEFFILE)
end
mfile.close
if $static
printf format("push %s,%s\n", $static, target); ##debug print##
#printf format("push %s,%s\n", $static, target); ##debug print##
$extlist.push [$static,target]
end
end
#template of .def file.
def create_def(basename)
defname = sprintf("%s.def", basename)
f = open(defname, "w")
f.printf "\
LIBRARY %s.dll
CODE LOADONCALL
DATA LOADONCALL
DESCRIPTION 'win32 %s.dll'
EXPORTS
Init_%s
", basename, basename, basename
f.close
end
def extmake(target)
if $force_static or $static_ext[target]
$static = target
@ -328,6 +358,11 @@ def extmake(target)
create_makefile(target);
end
end
if !File.exist?("#{target}.def")
create_def(target)
end
if File.exist?("./Makefile")
if $install
system "nmake install"
@ -339,10 +374,12 @@ def extmake(target)
elsif $clean
system "nmake clean"
else
#print "!!!make!!!\n"
system "nmake all"
end
end
if $static
#$extlibs = " "
$extlibs += " " + $LDFLAGS if $LDFLAGS
$extlibs += " " + $local_libs if $local_libs
$extlibs += " " + $libs if $libs
@ -360,7 +397,8 @@ if File.file? "./Setup"
$_.chop!
sub!(/#.*$/, '')
next if /^\s*$/
print $_, "\n"
#print $_, "\n"
if /^option +nodynamic/
$nodynamic = TRUE
next
@ -401,20 +439,19 @@ end
exit if $install or $clean
if $extlist.size > 0
#for s,t in $extlist
for s,t in $static_ext
for s,t in $extlist
#for s,t in $static_ext
#f = format("%s/%s.obj", s, t)
#f = format("%s/%s.obj", s, s)
l = format("%s/%s.lib", s, s)
#print format("%s/%s.obj\n", s, s) ##debug print##
if File.exist?(l)
$extinit += format("\
\tInit_%s();\n\
\trb_provide(\"%s.o\");\n\
", s, s)
$extobjs += "ext/"
#$extobjs += f # *.obj
$extobjs += l # *.lib
#$extobjs += f # *.obj
$extobjs += l # *.lib
$extobjs += " "
else
FALSE
@ -441,7 +478,12 @@ if $extlist.size > 0
end
$extobjs = "ext/extinit.obj " + $extobjs
$extlibs = ""
#$extlibs = ""
#print "EXTLIBS=#{$extlibs}\n"
$extlibs.gsub!("-L/usr/local/lib", "") if $extlibs
$extlibs.gsub!(" +", " ") if $extlibs
#print "EXTLIBS=#{$extlibs}\n"
system format('nmake ruby.exe EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
else
Dir.chdir ".."
@ -450,31 +492,6 @@ else
`cp miniruby.exe ruby.exe`
end
end
#template of .def file.
#LIBRARY kconv.dll
#CODE LOADONCALL
#DATA LOADONCALL
#DESCRIPTION 'win32 kconv.dll'
#EXPORTS
#
# Init_kconv
def makedef(basename)
defname = sprintf("%s.def", basename)
f = open(defname, "w")
f.printf "\
LIBRARY %s.dll
CODE LOADONCALL
DATA LOADONCALL
DESCRIPTION 'win32 %s.dll'
EXPORTS
Init_%s
", basename, basename
f.close
end
#Local variables:
# mode: ruby
#end:

View file

@ -1 +1 @@
fcntl.o: fcntl.c ../../ruby.h ../../config.h ../../defines.h
fcntl.o: fcntl.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h

View file

@ -1 +1 @@
kconv.o: kconv.c ../../ruby.h ../../config.h ../../defines.h
kconv.o: kconv.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h

View file

@ -88,6 +88,9 @@ static char *Patchlevel =
#define _JIS 1
#define _EUC 2
#define _SJIS 3
#define _BINARY 4
#define _NOCONV 4
#define _UNKNOWN _AUTO
#if (defined(__TURBOC__) || defined(LSI_C)) && !defined(MSDOS)
#define MSDOS
@ -596,7 +599,7 @@ do_kconv(i, o, siz, out_code, in_code)
outptr = o; /* output buffer */
outsiz = siz; /* output buffer size */
outlen = 0; /* current length of output string */
x0201_f = FALSE; /* don't assume JISX0201 kana */
x0201_f = TRUE; /* don't assume JISX0201 kana */
rot_f = FALSE; /* rot14/43 mode */
input_f = FALSE; /* non fixed input code */
alpha_f = FALSE; /* convert JISX0208 alphbet to ASCII */
@ -1774,7 +1777,7 @@ kconv_kconv(argc, argv)
int argc;
VALUE *argv;
{
struct RString *src, *dst;
VALUE src, dst;
VALUE in, out;
int in_code, out_code;
@ -1786,63 +1789,134 @@ kconv_kconv(argc, argv)
}
else {
out_code = NUM2INT(out);
if (out_code == _NOCONV) return (VALUE)src;
}
if (NIL_P(in)) {
in_code = _AUTO;
}
else {
in_code = NUM2INT(in);
if (in_code == _NOCONV) return (VALUE)src;
}
dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
dst->len = do_kconv(src->ptr, dst->ptr, dst->len, out_code, in_code);
dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, out_code, in_code);
return (VALUE)dst;
return dst;
}
static VALUE
kconv_tojis(obj, src)
VALUE obj;
struct RString *src;
VALUE obj, src;
{
struct RString *dst;
VALUE dst;
Check_Type(src, T_STRING);
dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _JIS, _AUTO);
dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _JIS, _AUTO);
return (VALUE)dst;
return dst;
}
static VALUE
kconv_toeuc(obj, src)
VALUE obj;
struct RString* src;
VALUE obj, src;
{
struct RString *dst;
VALUE dst;
Check_Type(src, T_STRING);
dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _EUC, _AUTO);
dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _EUC, _AUTO);
return (VALUE)dst;
}
static VALUE
kconv_tosjis(obj, src)
VALUE obj;
struct RString* src;
VALUE obj, src;
{
struct RString *dst;
VALUE dst;
Check_Type(src, T_STRING);
dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _SJIS, _AUTO);
dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _SJIS, _AUTO);
return (VALUE)dst;
return dst;
}
/*
* Character code detection - Algorithm described in:
* Ken Lunde. `Understanding Japanese Information Processing'
* Sebastopol, CA: O'Reilly & Associates.
*/
static VALUE
kconv_guess(obj, src)
VALUE obj, src;
{
unsigned char *p = RSTRING(src)->ptr;
unsigned char *pend = p + RSTRING(src)->len;
#define INCR {p++;if (p==pend) return INT2FIX(_UNKNOWN);}
while (p<pend) {
if (*p == '\033') {
return INT2FIX(_JIS);
}
if ('\000' < *p && *p < '\006'
|| *p == 0x7f
|| *p == 0xdf) {
return INT2FIX(_BINARY);
}
if (0x81 <= *p && *p <= 0x8d) {
return INT2FIX(_SJIS);
}
if (*p == 0x8e) {
INCR;
if ((0x40 <= *p && *p <= 0x7e) ||
(0x80 <= *p && *p <= 0xa0) ||
(0xe0 <= *p && *p <= 0xfc))
return INT2FIX(_SJIS);
}
if (0xa1 <= *p && *p <= 0xdf) {
INCR;
if (0xf0 <= *p && *p <= 0xfe)
return INT2FIX(_EUC);
if (0xe0 <= *p && *p <= 0xef) {
while (*p >= 0x40) {
if (*p >= 0x81) {
if (0x8d <= *p || (0x8f <= *p && *p <= 0x9f)) {
return INT2FIX(_SJIS);
}
else if (0xfd <= *p && *p <= 0xfe) {
return INT2FIX(_EUC);
}
}
}
}
if (*p <= 0x9f) {
return INT2FIX(_SJIS);
}
}
if (0xf0 <= *p && *p <= 0xfe) {
return INT2FIX(_EUC);
}
if (0xe0 <= *p && *p <= 0xef) {
INCR;
if ((0x40 <= *p && *p <= 0x7e) ||
(0x80 <= *p && *p <= 0xa0)) {
return INT2FIX(_SJIS);
}
if (0xfd <= *p && *p <= 0xfe) {
return INT2FIX(_EUC);
}
}
p++;
}
return INT2FIX(_UNKNOWN);
}
void
@ -1854,11 +1928,15 @@ Init_kconv()
rb_define_module_function(mKconv, "tojis", kconv_tojis, 1);
rb_define_module_function(mKconv, "toeuc", kconv_toeuc, 1);
rb_define_module_function(mKconv, "tosjis", kconv_tosjis, 1);
rb_define_module_function(mKconv, "guess", kconv_guess, 1);
rb_define_const(mKconv, "AUTO", INT2FIX(_AUTO));
rb_define_const(mKconv, "JIS", INT2FIX(_JIS));
rb_define_const(mKconv, "EUC", INT2FIX(_EUC));
rb_define_const(mKconv, "SJIS", INT2FIX(_SJIS));
rb_define_const(mKconv, "BINARY", INT2FIX(_BINARY));
rb_define_const(mKconv, "NOCONV", INT2FIX(_NOCONV));
rb_define_const(mKconv, "UNKNOWN", INT2FIX(_UNKNOWN));
}
/**

View file

@ -1,2 +1,2 @@
md5c.o: md5c.c md5.h
md5init.o: md5init.c ../../ruby.h ../../config.h ../../defines.h md5.h
md5init.o: md5init.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h md5.h

View file

@ -1 +1 @@
socket.o : socket.c ../../ruby.h ../../config.h ../../defines.h ../../io.h ../../sig.h
socket.o : socket.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h $(hdrdir)/io.h $(hdrdir)/sig.h

View file

@ -1,9 +1,18 @@
$LDFLAGS = "-L/usr/local/lib"
have_library("wsock32", "cygwin32_socket") or have_library("socket", "socket")
have_library("inet", "gethostbyname")
have_library("nsl", "gethostbyname")
case PLATFORM
when /mswin32/
test_func = "WSACleanup"
have_library("wsock32", "WSACleanup")
when /cygwin32/
test_func = "cygwin32_socket"
else
test_func = "socket"
have_library("socket", "socket")
have_library("inet", "gethostbyname")
have_library("nsl", "gethostbyname")
end
have_header("sys/un.h")
if have_func("socket") or have_func("cygwin32_socket")
if have_func(test_func)
have_func("hsterror")
unless have_func("gethostname")
have_func("uname")

View file

@ -12,9 +12,11 @@
#include "io.h"
#include <stdio.h>
#include <sys/types.h>
#ifndef NT
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#include <errno.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
@ -36,8 +38,10 @@ extern VALUE cIO;
extern VALUE cInteger;
VALUE cBasicSocket;
VALUE cIPsocket;
VALUE cTCPsocket;
VALUE cTCPserver;
VALUE cUDPsocket;
#ifdef AF_UNIX
VALUE cUNIXsocket;
VALUE cUNIXserver;
@ -85,8 +89,6 @@ sock_new(class, fd)
fp->f = rb_fdopen(fd, "r");
#ifdef NT
fp->finalize = sock_finalize;
#else
setbuf(fp->f, NULL);
#endif
fp->f2 = rb_fdopen(fd, "w");
fp->mode = FMODE_READWRITE;
@ -254,24 +256,29 @@ bsock_send(argc, argv, sock)
return INT2FIX(n);
}
static VALUE tcpaddr _((struct sockaddr_in*));
static VALUE ipaddr _((struct sockaddr_in*));
#ifdef HAVE_SYS_UN_H
static VALUE unixaddr _((struct sockaddr_un*));
#endif
enum sock_recv_type {
RECV_RECV, /* BasicSocket#recv(no from) */
RECV_TCP, /* TCPsocket#recvfrom */
RECV_UDP, /* UDPsocket#recvfrom */
RECV_UNIX, /* UNIXsocket#recvfrom */
RECV_SOCKET, /* Socket#recvfrom */
};
static VALUE
s_recv(sock, argc, argv, from)
VALUE sock;
int argc;
VALUE *argv;
int from; /* 0 - recv,
1 - TCPsocket#recvfrom,
2 - UNIXsocket#recvfrom,
3 - Socket#recvfrom */
enum sock_recv_type from;
{
OpenFile *fptr;
FILE f;
struct RString *str;
VALUE str;
char buf[1024];
int fd, alen = sizeof buf;
VALUE len, flg;
@ -282,7 +289,7 @@ s_recv(sock, argc, argv, from)
if (flg == Qnil) flags = 0;
else flags = NUM2INT(flg);
str = (struct RString*)str_new(0, NUM2INT(len));
str = str_new(0, NUM2INT(len));
GetOpenFile(sock, fptr);
fd = fileno(fptr->f);
@ -291,11 +298,11 @@ s_recv(sock, argc, argv, from)
#endif
TRAP_BEG;
retry:
str->len = recvfrom(fd, str->ptr, str->len, flags,
(struct sockaddr*)buf, &alen);
RSTRING(str)->len = recvfrom(fd, RSTRING(str)->ptr, RSTRING(str)->len, flags,
(struct sockaddr*)buf, &alen);
TRAP_END;
if (str->len < 0) {
if (RSTRING(str)->len < 0) {
switch (errno) {
case EINTR:
case EWOULDBLOCK:
@ -311,21 +318,28 @@ s_recv(sock, argc, argv, from)
}
str_taint(str);
switch (from) {
case 0:
case RECV_RECV:
return (VALUE)str;
case 1:
case RECV_TCP:
if (alen != sizeof(struct sockaddr_in)) {
TypeError("sockaddr size differs - should not happen");
}
return assoc_new(str, tcpaddr((struct sockaddr_in *)buf));
return assoc_new(str, ipaddr((struct sockaddr_in *)buf));
case RECV_UDP:
{
VALUE addr = ipaddr((struct sockaddr_in *)buf);
return assoc_new(str, assoc_new(RARRAY(addr)->ptr[2],
RARRAY(addr)->ptr[1]));
}
#ifdef HAVE_SYS_UN_H
case 2:
case RECV_UNIX:
if (alen != sizeof(struct sockaddr_un)) {
TypeError("sockaddr size differs - should not happen");
}
return assoc_new(str, unixaddr((struct sockaddr_un *)buf));
#endif
case 3:
case RECV_SOCKET:
return assoc_new(str, str_new(buf, alen));
}
}
@ -336,7 +350,7 @@ bsock_recv(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
return s_recv(sock, argc, argv, 0);
return s_recv(sock, argc, argv, RECV_RECV);
}
#if defined(THREAD) && defined(HAVE_FCNTL)
@ -470,7 +484,7 @@ open_inet(class, h, serv, type)
Raise(eSocket, "no such proto %s", servent->s_proto);
}
fd = socket(PF_INET, SOCK_STREAM, protoent->p_proto);
fd = socket(AF_INET, SOCK_STREAM, protoent->p_proto);
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
@ -515,9 +529,7 @@ open_inet(class, h, serv, type)
if (type == INET_SERVER) listen(fd, 5);
/* create new instance */
sock = sock_new(class, fd);
return sock;
return sock_new(class, fd);
}
static VALUE
@ -606,6 +618,15 @@ tcp_accept(sock)
(struct sockaddr*)&from, &fromlen);
}
static VALUE
tcp_recvfrom(argc, argv, sock)
int argc;
VALUE *argv;
VALUE sock;
{
return s_recv(sock, argc, argv, RECV_TCP);
}
#ifdef HAVE_SYS_UN_H
static VALUE
open_unix(class, path, server)
@ -619,7 +640,7 @@ open_unix(class, path, server)
OpenFile *fptr;
Check_SafeStr(path);
fd = socket(PF_UNIX, SOCK_STREAM, 0);
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) rb_sys_fail("socket(2)");
memset(&sockaddr, 0, sizeof(sockaddr));
@ -700,7 +721,7 @@ mkipaddr(x)
}
static VALUE
tcpaddr(sockaddr)
ipaddr(sockaddr)
struct sockaddr_in *sockaddr;
{
VALUE family, port, addr1, addr2;
@ -725,7 +746,7 @@ tcpaddr(sockaddr)
}
static VALUE
tcp_addr(sock)
ip_addr(sock)
VALUE sock;
{
OpenFile *fptr;
@ -736,11 +757,11 @@ tcp_addr(sock)
if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
rb_sys_fail("getsockname(2)");
return tcpaddr(&addr);
return ipaddr(&addr);
}
static VALUE
tcp_peeraddr(sock)
ip_peeraddr(sock)
VALUE sock;
{
OpenFile *fptr;
@ -751,24 +772,14 @@ tcp_peeraddr(sock)
if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
rb_sys_fail("getpeername(2)");
return tcpaddr(&addr);
return ipaddr(&addr);
}
static VALUE
tcp_recvfrom(argc, argv, sock)
int argc;
VALUE *argv;
VALUE sock;
{
return s_recv(sock, argc, argv, 1);
}
static VALUE
tcp_s_getaddress(obj, host)
ip_s_getaddress(obj, host)
VALUE obj, host;
{
struct sockaddr_in addr;
struct hostent *h;
if (obj_is_kind_of(host, cInteger)) {
int i = NUM2INT(host);
@ -782,6 +793,148 @@ tcp_s_getaddress(obj, host)
return mkipaddr(addr.sin_addr.s_addr);
}
static VALUE
udp_s_open(class)
VALUE class;
{
return sock_new(class, socket(AF_INET, SOCK_DGRAM, 0));
}
static void
udp_addrsetup(host, port, addr)
VALUE host, port;
struct sockaddr_in *addr;
{
struct hostent *hostent;
memset(addr, 0, sizeof(struct sockaddr_in));
addr->sin_family = AF_INET;
if (NIL_P(host)) {
addr->sin_addr.s_addr = INADDR_ANY;
}
else if (obj_is_kind_of(host, cInteger)) {
int i = NUM2INT(host);
addr->sin_addr.s_addr = htonl(i);
}
else {
Check_Type(host, T_STRING);
setipaddr(RSTRING(host)->ptr, addr);
}
if (FIXNUM_P(port)) {
addr->sin_port = FIX2INT(port);
}
else {
struct servent *servent;
Check_Type(port, T_STRING);
servent = getservbyname(RSTRING(port)->ptr, "udp");
if (servent) {
addr->sin_port = servent->s_port;
}
else {
int port = strtoul(RSTRING(port)->ptr, 0, 0);
if (port == -1) {
Raise(eSocket, "no such servce %s", RSTRING(port)->ptr);
}
addr->sin_port = htons(port);
}
}
}
static VALUE
udp_connect(sock, host, port)
VALUE sock, host, port;
{
struct sockaddr_in addr;
OpenFile *fptr;
udp_addrsetup(host, port, &addr);
GetOpenFile(sock, fptr);
retry:
if (connect(fileno(fptr->f), (struct sockaddr*)&addr, sizeof(addr))<0) {
switch (errno) {
case EINTR:
case EWOULDBLOCK:
#if EAGAIN != EWOULDBLOCK
case EAGAIN:
#endif
#ifdef THREAD
thread_schedule();
#endif
goto retry;
}
rb_sys_fail("connect(2)");
}
return INT2FIX(0);
}
static VALUE
udp_bind(sock, host, port)
VALUE sock, host, port;
{
struct sockaddr_in addr;
OpenFile *fptr;
udp_addrsetup(host, port, &addr);
GetOpenFile(sock, fptr);
if (bind(fileno(fptr->f), (struct sockaddr*)&addr, sizeof(addr))<0) {
rb_sys_fail("bind(2)");
}
return INT2FIX(0);
}
static VALUE
udp_send(argc, argv, sock)
int argc;
VALUE *argv;
VALUE sock;
{
VALUE mesg, flags, host, port;
struct sockaddr_in addr;
OpenFile *fptr;
FILE *f;
int n;
if (argc == 2) {
return bsock_send(argc, argv, sock);
}
rb_scan_args(argc, argv, "4", &mesg, &flags, &host, &port);
Check_Type(mesg, T_STRING);
udp_addrsetup(host, port, &addr);
GetOpenFile(sock, fptr);
f = fptr->f2?fptr->f2:fptr->f;
retry:
n = sendto(fileno(f), RSTRING(mesg)->ptr, RSTRING(mesg)->len,
NUM2INT(flags), (struct sockaddr*)&addr, sizeof(addr));
if (n < 0) {
switch (errno) {
case EINTR:
case EWOULDBLOCK:
#if EAGAIN != EWOULDBLOCK
case EAGAIN:
#endif
#ifdef THREAD
thread_schedule();
#endif
goto retry;
}
rb_sys_fail("sendto(2)");
}
return INT2FIX(n);
}
static VALUE
udp_recvfrom(argc, argv, sock)
int argc;
VALUE *argv;
VALUE sock;
{
return s_recv(sock, argc, argv, RECV_UDP);
}
#ifdef HAVE_SYS_UN_H
static VALUE
unix_s_sock_open(sock, path)
@ -820,7 +973,7 @@ unix_recvfrom(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
return s_recv(sock, argc, argv, 2);
return s_recv(sock, argc, argv, RECV_UNIX);
}
static VALUE
@ -884,7 +1037,25 @@ setup_domain_and_type(domain, dv, type, tv)
if (TYPE(domain) == T_STRING) {
ptr = RSTRING(domain)->ptr;
if (strcmp(ptr, "PF_INET") == 0)
if (strcmp(ptr, "AF_INET") == 0)
*dv = AF_INET;
#ifdef AF_UNIX
else if (strcmp(ptr, "AF_UNIX") == 0)
*dv = AF_UNIX;
#endif
#ifdef AF_ISO
else if (strcmp(ptr, "AF_ISO") == 0)
*dv = AF_ISO;
#endif
#ifdef AF_NS
else if (strcmp(ptr, "AF_NS") == 0)
*dv = AF_NS;
#endif
#ifdef AF_IMPLINK
else if (strcmp(ptr, "AF_IMPLINK") == 0)
*dv = AF_IMPLINK;
#endif
else if (strcmp(ptr, "PF_INET") == 0)
*dv = PF_INET;
#ifdef PF_UNIX
else if (strcmp(ptr, "PF_UNIX") == 0)
@ -893,6 +1064,8 @@ setup_domain_and_type(domain, dv, type, tv)
#ifdef PF_IMPLINK
else if (strcmp(ptr, "PF_IMPLINK") == 0)
*dv = PF_IMPLINK;
else if (strcmp(ptr, "AF_IMPLINK") == 0)
*dv = AF_IMPLINK;
#endif
#ifdef PF_AX25
else if (strcmp(ptr, "PF_AX25") == 0)
@ -978,8 +1151,7 @@ sock_s_socketpair(class, domain, type, protocol)
static VALUE
sock_connect(sock, addr)
VALUE sock;
struct RString *addr;
VALUE sock, addr;
{
OpenFile *fptr;
@ -988,7 +1160,7 @@ sock_connect(sock, addr)
GetOpenFile(sock, fptr);
retry:
if (connect(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0) {
if (connect(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len) < 0) {
switch (errno) {
case EINTR:
case EWOULDBLOCK:
@ -1008,8 +1180,7 @@ sock_connect(sock, addr)
static VALUE
sock_bind(sock, addr)
VALUE sock;
struct RString *addr;
VALUE sock, addr;
{
OpenFile *fptr;
@ -1017,7 +1188,7 @@ sock_bind(sock, addr)
str_modify(addr);
GetOpenFile(sock, fptr);
if (bind(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0)
if (bind(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len) < 0)
rb_sys_fail("bind(2)");
return INT2FIX(0);
@ -1042,7 +1213,7 @@ sock_recvfrom(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
return s_recv(sock, argc, argv, 3);
return s_recv(sock, argc, argv, RECV_SOCKET);
}
static VALUE
@ -1185,7 +1356,7 @@ sock_s_getservbyaname(argc, argv)
VALUE *argv;
{
VALUE service, protocol;
char *name, *proto;
char *proto;
struct servent *sp;
int port;
@ -1203,12 +1374,24 @@ sock_s_getservbyaname(argc, argv)
return INT2FIX(port);
}
static VALUE mConst;
static void
sock_define_const(name, value)
char *name;
INT value;
{
rb_define_const(cSocket, name, INT2FIX(value));
rb_define_const(mConst, name, INT2FIX(value));
}
Init_socket()
{
eSocket = rb_define_class("SocketError", eException);
cBasicSocket = rb_define_class("BasicSocket", cIO);
rb_undef_method(CLASS_OF(cBasicSocket), "new");
rb_undef_method(CLASS_OF(cBasicSocket), "open");
rb_define_method(cBasicSocket, "shutdown", bsock_shutdown, -1);
rb_define_method(cBasicSocket, "setsockopt", bsock_setsockopt, 3);
rb_define_method(cBasicSocket, "getsockopt", bsock_getsockopt, 2);
@ -1217,12 +1400,14 @@ Init_socket()
rb_define_method(cBasicSocket, "send", bsock_send, -1);
rb_define_method(cBasicSocket, "recv", bsock_recv, -1);
cTCPsocket = rb_define_class("TCPsocket", cBasicSocket);
cIPsocket = rb_define_class("IPsocket", cBasicSocket);
rb_define_method(cIPsocket, "addr", ip_addr, 0);
rb_define_method(cIPsocket, "peeraddr", ip_peeraddr, 0);
rb_define_singleton_method(cIPsocket, "getaddress", ip_s_getaddress, 1);
cTCPsocket = rb_define_class("TCPsocket", cIPsocket);
rb_define_singleton_method(cTCPsocket, "open", tcp_s_open, 2);
rb_define_singleton_method(cTCPsocket, "new", tcp_s_open, 2);
rb_define_method(cTCPsocket, "addr", tcp_addr, 0);
rb_define_method(cTCPsocket, "peeraddr", tcp_peeraddr, 0);
rb_define_singleton_method(cTCPsocket, "getaddress", tcp_s_getaddress, 1);
rb_define_method(cTCPsocket, "recvfrom", tcp_recvfrom, -1);
#ifdef SOCKS
@ -1236,6 +1421,14 @@ Init_socket()
rb_define_singleton_method(cTCPserver, "new", tcp_svr_s_open, -1);
rb_define_method(cTCPserver, "accept", tcp_accept, 0);
cUDPsocket = rb_define_class("UDPsocket", cIPsocket);
rb_define_singleton_method(cUDPsocket, "open", udp_s_open, 0);
rb_define_singleton_method(cUDPsocket, "new", udp_s_open, 0);
rb_define_method(cUDPsocket, "connect", udp_connect, 2);
rb_define_method(cUDPsocket, "bind", udp_bind, 2);
rb_define_method(cUDPsocket, "send", udp_send, -1);
rb_define_method(cUDPsocket, "recvfrom", udp_recvfrom, -1);
#ifdef HAVE_SYS_UN_H
cUNIXsocket = rb_define_class("UNIXsocket", cBasicSocket);
rb_define_singleton_method(cUNIXsocket, "open", unix_s_sock_open, 1);
@ -1271,137 +1464,138 @@ Init_socket()
rb_define_singleton_method(cSocket, "getservbyname", sock_s_getservbyaname, -1);
/* constants */
rb_define_const(cSocket, "SOCK_STREAM", INT2FIX(SOCK_STREAM));
rb_define_const(cSocket, "SOCK_DGRAM", INT2FIX(SOCK_DGRAM));
rb_define_const(cSocket, "SOCK_RAW", INT2FIX(SOCK_RAW));
mConst = rb_define_module_under(cSocket, "Constants");
sock_define_const("SOCK_STREAM", SOCK_STREAM);
sock_define_const("SOCK_DGRAM", SOCK_DGRAM);
sock_define_const("SOCK_RAW", SOCK_RAW);
#ifdef SOCK_RDM
rb_define_const(cSocket, "SOCK_RDM", INT2FIX(SOCK_RDM));
sock_define_const("SOCK_RDM", SOCK_RDM);
#endif
#ifdef SOCK_SEQPACKET
rb_define_const(cSocket, "SOCK_SEQPACKET", INT2FIX(SOCK_SEQPACKET));
sock_define_const("SOCK_SEQPACKET", SOCK_SEQPACKET);
#endif
#ifdef SOCK_PACKET
rb_define_const(cSocket, "SOCK_PACKET", INT2FIX(SOCK_PACKET));
sock_define_const("SOCK_PACKET", SOCK_PACKET);
#endif
rb_define_const(cSocket, "AF_INET", INT2FIX(AF_INET));
rb_define_const(cSocket, "PF_INET", INT2FIX(PF_INET));
sock_define_const("AF_INET", AF_INET);
sock_define_const("PF_INET", PF_INET);
#ifdef AF_UNIX
rb_define_const(cSocket, "AF_UNIX", INT2FIX(AF_UNIX));
rb_define_const(cSocket, "PF_UNIX", INT2FIX(PF_UNIX));
sock_define_const("AF_UNIX", AF_UNIX);
sock_define_const("PF_UNIX", PF_UNIX);
#endif
#ifdef AF_AX25
rb_define_const(cSocket, "AF_AX25", INT2FIX(AF_AX25));
rb_define_const(cSocket, "PF_AX25", INT2FIX(PF_AX25));
sock_define_const("AF_AX25", AF_AX25);
sock_define_const("PF_AX25", PF_AX25);
#endif
#ifdef AF_IPX
rb_define_const(cSocket, "AF_IPX", INT2FIX(AF_IPX));
rb_define_const(cSocket, "PF_IPX", INT2FIX(PF_IPX));
sock_define_const("AF_IPX", AF_IPX);
sock_define_const("PF_IPX", PF_IPX);
#endif
#ifdef AF_APPLETALK
rb_define_const(cSocket, "AF_APPLETALK", INT2FIX(AF_APPLETALK));
rb_define_const(cSocket, "PF_APPLETALK", INT2FIX(PF_APPLETALK));
sock_define_const("AF_APPLETALK", AF_APPLETALK);
sock_define_const("PF_APPLETALK", PF_APPLETALK);
#endif
rb_define_const(cSocket, "MSG_OOB", INT2FIX(MSG_OOB));
rb_define_const(cSocket, "MSG_PEEK", INT2FIX(MSG_PEEK));
rb_define_const(cSocket, "MSG_DONTROUTE", INT2FIX(MSG_DONTROUTE));
sock_define_const("MSG_OOB", MSG_OOB);
sock_define_const("MSG_PEEK", MSG_PEEK);
sock_define_const("MSG_DONTROUTE", MSG_DONTROUTE);
rb_define_const(cSocket, "SOL_SOCKET", INT2FIX(SOL_SOCKET));
sock_define_const("SOL_SOCKET", SOL_SOCKET);
#ifdef SOL_IP
rb_define_const(cSocket, "SOL_IP", INT2FIX(SOL_IP));
sock_define_const("SOL_IP", SOL_IP);
#endif
#ifdef SOL_IPX
rb_define_const(cSocket, "SOL_IPX", INT2FIX(SOL_IPX));
sock_define_const("SOL_IPX", SOL_IPX);
#endif
#ifdef SOL_AX25
rb_define_const(cSocket, "SOL_AX25", INT2FIX(SOL_AX25));
sock_define_const("SOL_AX25", SOL_AX25);
#endif
#ifdef SOL_ATALK
rb_define_const(cSocket, "SOL_ATALK", INT2FIX(SOL_ATALK));
sock_define_const("SOL_ATALK", SOL_ATALK);
#endif
#ifdef SOL_TCP
rb_define_const(cSocket, "SOL_TCP", INT2FIX(SOL_TCP));
sock_define_const("SOL_TCP", SOL_TCP);
#endif
#ifdef SOL_UDP
rb_define_const(cSocket, "SOL_UDP", INT2FIX(SOL_UDP));
sock_define_const("SOL_UDP", SOL_UDP);
#endif
#ifdef SO_DEBUG
rb_define_const(cSocket, "SO_DEBUG", INT2FIX(SO_DEBUG));
sock_define_const("SO_DEBUG", SO_DEBUG);
#endif
rb_define_const(cSocket, "SO_REUSEADDR", INT2FIX(SO_REUSEADDR));
sock_define_const("SO_REUSEADDR", SO_REUSEADDR);
#ifdef SO_TYPE
rb_define_const(cSocket, "SO_TYPE", INT2FIX(SO_TYPE));
sock_define_const("SO_TYPE", SO_TYPE);
#endif
#ifdef SO_ERROR
rb_define_const(cSocket, "SO_ERROR", INT2FIX(SO_ERROR));
sock_define_const("SO_ERROR", SO_ERROR);
#endif
#ifdef SO_DONTROUTE
rb_define_const(cSocket, "SO_DONTROUTE", INT2FIX(SO_DONTROUTE));
sock_define_const("SO_DONTROUTE", SO_DONTROUTE);
#endif
#ifdef SO_BROADCAST
rb_define_const(cSocket, "SO_BROADCAST", INT2FIX(SO_BROADCAST));
sock_define_const("SO_BROADCAST", SO_BROADCAST);
#endif
#ifdef SO_SNDBUF
rb_define_const(cSocket, "SO_SNDBUF", INT2FIX(SO_SNDBUF));
sock_define_const("SO_SNDBUF", SO_SNDBUF);
#endif
#ifdef SO_RCVBUF
rb_define_const(cSocket, "SO_RCVBUF", INT2FIX(SO_RCVBUF));
sock_define_const("SO_RCVBUF", SO_RCVBUF);
#endif
rb_define_const(cSocket, "SO_KEEPALIVE", INT2FIX(SO_KEEPALIVE));
sock_define_const("SO_KEEPALIVE", SO_KEEPALIVE);
#ifdef SO_OOBINLINE
rb_define_const(cSocket, "SO_OOBINLINE", INT2FIX(SO_OOBINLINE));
sock_define_const("SO_OOBINLINE", SO_OOBINLINE);
#endif
#ifdef SO_NO_CHECK
rb_define_const(cSocket, "SO_NO_CHECK", INT2FIX(SO_NO_CHECK));
sock_define_const("SO_NO_CHECK", SO_NO_CHECK);
#endif
#ifdef SO_PRIORITY
rb_define_const(cSocket, "SO_PRIORITY", INT2FIX(SO_PRIORITY));
sock_define_const("SO_PRIORITY", SO_PRIORITY);
#endif
rb_define_const(cSocket, "SO_LINGER", INT2FIX(SO_LINGER));
sock_define_const("SO_LINGER", SO_LINGER);
#ifdef SOPRI_INTERACTIVE
rb_define_const(cSocket, "SOPRI_INTERACTIVE", INT2FIX(SOPRI_INTERACTIVE));
sock_define_const("SOPRI_INTERACTIVE", SOPRI_INTERACTIVE);
#endif
#ifdef SOPRI_NORMAL
rb_define_const(cSocket, "SOPRI_NORMAL", INT2FIX(SOPRI_NORMAL));
sock_define_const("SOPRI_NORMAL", SOPRI_NORMAL);
#endif
#ifdef SOPRI_BACKGROUND
rb_define_const(cSocket, "SOPRI_BACKGROUND", INT2FIX(SOPRI_BACKGROUND));
sock_define_const("SOPRI_BACKGROUND", SOPRI_BACKGROUND);
#endif
#ifdef IP_MULTICAST_IF
rb_define_const(cSocket, "IP_MULTICAST_IF", INT2FIX(IP_MULTICAST_IF));
sock_define_const("IP_MULTICAST_IF", IP_MULTICAST_IF);
#endif
#ifdef IP_MULTICAST_TTL
rb_define_const(cSocket, "IP_MULTICAST_TTL", INT2FIX(IP_MULTICAST_TTL));
sock_define_const("IP_MULTICAST_TTL", IP_MULTICAST_TTL);
#endif
#ifdef IP_MULTICAST_LOOP
rb_define_const(cSocket, "IP_MULTICAST_LOOP", INT2FIX(IP_MULTICAST_LOOP));
sock_define_const("IP_MULTICAST_LOOP", IP_MULTICAST_LOOP);
#endif
#ifdef IP_ADD_MEMBERSHIP
rb_define_const(cSocket, "IP_ADD_MEMBERSHIP", INT2FIX(IP_ADD_MEMBERSHIP));
sock_define_const("IP_ADD_MEMBERSHIP", IP_ADD_MEMBERSHIP);
#endif
#ifdef IP_DEFAULT_MULTICAST_TTL
rb_define_const(cSocket, "IP_DEFAULT_MULTICAST_TTL", INT2FIX(IP_DEFAULT_MULTICAST_TTL));
sock_define_const("IP_DEFAULT_MULTICAST_TTL", IP_DEFAULT_MULTICAST_TTL);
#endif
#ifdef IP_DEFAULT_MULTICAST_LOOP
rb_define_const(cSocket, "IP_DEFAULT_MULTICAST_LOOP", INT2FIX(IP_DEFAULT_MULTICAST_LOOP));
sock_define_const("IP_DEFAULT_MULTICAST_LOOP", IP_DEFAULT_MULTICAST_LOOP);
#endif
#ifdef IP_MAX_MEMBERSHIPS
rb_define_const(cSocket, "IP_MAX_MEMBERSHIPS", INT2FIX(IP_MAX_MEMBERSHIPS));
sock_define_const("IP_MAX_MEMBERSHIPS", IP_MAX_MEMBERSHIPS);
#endif
#ifdef IPX_TYPE
rb_define_const(cSocket, "IPX_TYPE", INT2FIX(IPX_TYPE));
sock_define_const("IPX_TYPE", IPX_TYPE);
#endif
#ifdef TCP_NODELAY
rb_define_const(cSocket, "TCP_NODELAY", INT2FIX(TCP_NODELAY));
sock_define_const("TCP_NODELAY", TCP_NODELAY);
#endif
#ifdef TCP_MAXSEG
rb_define_const(cSocket, "TCP_MAXSEG", INT2FIX(TCP_MAXSEG));
sock_define_const("TCP_MAXSEG", TCP_MAXSEG);
#endif
}

View file

@ -1 +1 @@
tkutil.o: tkutil.c ../../ruby.h ../../config.h ../../defines.h
tkutil.o: tkutil.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h

277
file.c
View file

@ -42,15 +42,11 @@ struct timeval {
#include <pwd.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
#ifndef HAVE_STRING_H
char *strrchr();
#endif
#ifdef NT
#include <sys/stat.h>
#endif
#ifndef NT
char *strdup();
@ -101,6 +97,10 @@ file_s_open(argc, argv, class)
file = file_open(RSTRING(fname)->ptr, mode);
RBASIC(file)->class = class;
if (iterator_p()) {
rb_ensure(rb_yield, file, io_close, file);
}
return file;
}
@ -136,7 +136,8 @@ file_reopen(argc, argv, file)
if (!fptr->f) {
fptr->f = rb_fopen(RSTRING(fname)->ptr, mode);
if (fptr->f2) {
fclose(fptr->f2);
if (fileno(fptr->f2) < 3) /* need to keep stdio */
fclose(fptr->f2);
fptr->f2 = NULL;
}
return file;
@ -155,13 +156,14 @@ file_reopen(argc, argv, file)
}
static int
apply2files(func, args, arg)
apply2files(func, vargs, arg)
int (*func)();
struct RArray *args;
VALUE vargs;
void *arg;
{
int i;
VALUE path;
struct RArray *args = RARRAY(vargs);
for (i=0; i<args->len; i++) {
Check_SafeStr(args->ptr[i]);
@ -269,7 +271,6 @@ file_isatty(obj)
#else
#include "missing/file.h"
#endif
#include <sys/stat.h>
static VALUE
stat_new(st)
@ -306,14 +307,13 @@ stat_new(st)
static VALUE
file_s_stat(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) == -1) {
rb_sys_fail(fname->ptr);
if (stat(RSTRING(fname)->ptr, &st) == -1) {
rb_sys_fail(RSTRING(fname)->ptr);
}
return stat_new(&st);
}
@ -334,15 +334,14 @@ file_stat(obj)
static VALUE
file_s_lstat(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#if !defined(MSDOS) && !defined(NT)
struct stat st;
Check_SafeStr(fname);
if (lstat(fname->ptr, &st) == -1) {
rb_sys_fail(fname->ptr);
if (lstat(RSTRING(fname)->ptr, &st) == -1) {
rb_sys_fail(RSTRING(fname)->ptr);
}
return stat_new(&st);
#else
@ -424,19 +423,6 @@ eaccess(path, mode)
return 0;
}
#if defined(DJGPP)
{
int stat_mode = 0;
if (mode & X_OK)
stat_mode |= S_IXOTH;
if (mode & W_OK)
stat_mode |= S_IWOTH;
if (mode & R_OK)
stat_mode |= S_IROTH;
mode = stat_mode;
}
#endif
if (st.st_uid == euid) /* owner */
mode <<= 6;
else if (group_member (st.st_gid))
@ -452,8 +438,7 @@ eaccess(path, mode)
static VALUE
test_d(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifndef S_ISDIR
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
@ -462,15 +447,14 @@ test_d(obj, fname)
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISDIR(st.st_mode)) return TRUE;
return FALSE;
}
static VALUE
test_p(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifdef S_IFIFO
# ifndef S_ISFIFO
@ -480,7 +464,7 @@ test_p(obj, fname)
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISFIFO(st.st_mode)) return TRUE;
#endif
@ -489,8 +473,7 @@ test_p(obj, fname)
static VALUE
test_l(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifndef S_ISLNK
# ifdef _S_ISLNK
@ -510,7 +493,7 @@ test_l(obj, fname)
struct stat st;
Check_SafeStr(fname);
if (lstat(fname->ptr, &st) < 0) return FALSE;
if (lstat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISLNK(st.st_mode)) return TRUE;
#endif
@ -519,8 +502,7 @@ test_l(obj, fname)
static VALUE
test_S(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifndef S_ISSOCK
# ifdef _S_ISSOCK
@ -540,7 +522,7 @@ test_S(obj, fname)
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISSOCK(st.st_mode)) return TRUE;
#endif
@ -549,8 +531,7 @@ test_S(obj, fname)
static VALUE
test_b(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifndef S_ISBLK
# ifdef S_IFBLK
@ -564,7 +545,7 @@ test_b(obj, fname)
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISBLK(st.st_mode)) return TRUE;
#endif
@ -573,8 +554,7 @@ test_b(obj, fname)
static VALUE
test_c(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifndef S_ISCHR
# define S_ISCHR(m) ((m & S_IFMT) == S_IFCHR)
@ -583,7 +563,7 @@ test_c(obj, fname)
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISBLK(st.st_mode)) return TRUE;
return FALSE;
@ -591,73 +571,66 @@ test_c(obj, fname)
static VALUE
test_e(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
return TRUE;
}
static VALUE
test_r(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
Check_SafeStr(fname);
if (eaccess(fname->ptr, R_OK) < 0) return FALSE;
if (eaccess(RSTRING(fname)->ptr, R_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_R(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
Check_SafeStr(fname);
if (access(fname->ptr, R_OK) < 0) return FALSE;
if (access(RSTRING(fname)->ptr, R_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_w(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
Check_SafeStr(fname);
if (eaccess(fname->ptr, W_OK) < 0) return FALSE;
if (eaccess(RSTRING(fname)->ptr, W_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_W(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
Check_SafeStr(fname);
if (access(fname->ptr, W_OK) < 0) return FALSE;
if (access(RSTRING(fname)->ptr, W_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_x(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
Check_SafeStr(fname);
if (eaccess(fname->ptr, X_OK) < 0) return FALSE;
if (eaccess(RSTRING(fname)->ptr, X_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_X(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
Check_SafeStr(fname);
if (access(fname->ptr, X_OK) < 0) return FALSE;
if (access(RSTRING(fname)->ptr, X_OK) < 0) return FALSE;
return TRUE;
}
@ -667,79 +640,73 @@ test_X(obj, fname)
static VALUE
test_f(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISREG(st.st_mode)) return TRUE;
return FALSE;
}
static VALUE
test_z(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_size == 0) return TRUE;
return FALSE;
}
static VALUE
test_s(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_size == 0) return FALSE;
return int2inum(st.st_size);
}
static VALUE
test_owned(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_uid == geteuid()) return TRUE;
return FALSE;
}
static VALUE
test_rowned(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_uid == getuid()) return TRUE;
return FALSE;
}
static VALUE
test_grpowned(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifndef NT
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) return FALSE;
if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_gid == getegid()) return TRUE;
#endif
return FALSE;
@ -761,12 +728,11 @@ check3rdbyte(file, mode)
static VALUE
test_suid(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifdef S_ISUID
Check_SafeStr(fname);
return check3rdbyte(fname->ptr, S_ISUID);
return check3rdbyte(RSTRING(fname)->ptr, S_ISUID);
#else
return FALSE;
#endif
@ -774,12 +740,11 @@ test_suid(obj, fname)
static VALUE
test_sgid(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
#ifndef NT
Check_SafeStr(fname);
return check3rdbyte(fname->ptr, S_ISGID);
return check3rdbyte(RSTRING(fname)->ptr, S_ISGID);
#else
return FALSE;
#endif
@ -787,12 +752,11 @@ test_sgid(obj, fname)
static VALUE
test_sticky(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
Check_Type(fname, T_STRING);
#ifdef S_ISVTX
return check3rdbyte(fname->ptr, S_ISVTX);
return check3rdbyte(RSTRING(fname)->ptr, S_ISVTX);
#else
return FALSE;
#endif
@ -800,26 +764,26 @@ test_sticky(obj, fname)
static VALUE
file_s_size(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
if (stat(RSTRING(fname)->ptr, &st) < 0)
rb_sys_fail(RSTRING(fname)->ptr);
return int2inum(st.st_size);
}
static VALUE
file_s_ftype(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
char *t;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
if (stat(RSTRING(fname)->ptr, &st) < 0)
rb_sys_fail(RSTRING(fname)->ptr);
if (S_ISREG(st.st_mode)) {
t = "file";
@ -857,13 +821,13 @@ file_s_ftype(obj, fname)
static VALUE
file_s_atime(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
if (stat(RSTRING(fname)->ptr, &st) < 0)
rb_sys_fail(RSTRING(fname)->ptr);
return time_new(st.st_atime, 0);
}
@ -883,13 +847,13 @@ file_atime(obj)
static VALUE
file_s_mtime(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
if (stat(RSTRING(fname)->ptr, &st) < 0)
rb_sys_fail(RSTRING(fname)->ptr);
return time_new(st.st_mtime, 0);
}
@ -909,13 +873,13 @@ file_mtime(obj)
static VALUE
file_s_ctime(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
if (stat(RSTRING(fname)->ptr, &st) < 0)
rb_sys_fail(RSTRING(fname)->ptr);
return time_new(st.st_ctime, 0);
}
@ -1118,32 +1082,26 @@ file_s_utime(argc, argv)
static VALUE
file_s_link(obj, from, to)
VALUE obj;
struct RString *from, *to;
VALUE obj, from, to;
{
#ifndef __human68k__
Check_SafeStr(from);
Check_SafeStr(to);
if (link(from->ptr, to->ptr) < 0)
rb_sys_fail(from->ptr);
if (link(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
rb_sys_fail(RSTRING(from)->ptr);
return INT2FIX(0);
#else
rb_notimplement();
#endif
}
static VALUE
file_s_symlink(obj, from, to)
VALUE obj;
struct RString *from, *to;
VALUE obj, from, to;
{
#if !defined(MSDOS) && !defined(NT)
Check_SafeStr(from);
Check_SafeStr(to);
if (symlink(from->ptr, to->ptr) < 0)
rb_sys_fail(from->ptr);
if (symlink(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
rb_sys_fail(RSTRING(from)->ptr);
return TRUE;
#else
rb_notimplement();
@ -1152,8 +1110,7 @@ file_s_symlink(obj, from, to)
static VALUE
file_s_readlink(obj, path)
VALUE obj;
struct RString *path;
VALUE obj, path;
{
#if !defined(MSDOS) && !defined(NT)
char buf[MAXPATHLEN];
@ -1161,8 +1118,8 @@ file_s_readlink(obj, path)
Check_SafeStr(path);
if ((cc = readlink(path->ptr, buf, MAXPATHLEN)) < 0)
rb_sys_fail(path->ptr);
if ((cc = readlink(RSTRING(path)->ptr, buf, MAXPATHLEN)) < 0)
rb_sys_fail(RSTRING(path)->ptr);
return str_new(buf, cc);
#else
@ -1180,8 +1137,7 @@ unlink_internal(path)
static VALUE
file_s_unlink(obj, args)
VALUE obj;
struct RArray *args;
VALUE obj, args;
{
int n;
@ -1191,14 +1147,13 @@ file_s_unlink(obj, args)
static VALUE
file_s_rename(obj, from, to)
VALUE obj;
struct RString *from, *to;
VALUE obj, from, to;
{
Check_SafeStr(from);
Check_SafeStr(to);
if (rename(from->ptr, to->ptr) == -1)
rb_sys_fail(from->ptr);
if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
rb_sys_fail(RSTRING(from)->ptr);
return INT2FIX(0);
}
@ -1225,14 +1180,13 @@ file_s_umask(argc, argv)
VALUE
file_s_expand_path(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
char *s, *p;
char buf[MAXPATHLEN];
Check_Type(fname, T_STRING);
s = fname->ptr;
s = RSTRING(fname)->ptr;
p = buf;
if (s[0] == '~') {
@ -1326,6 +1280,11 @@ rmext(p, e)
if (!e) return 0;
l2 = strlen(e);
if (l2 == 2 && e[1] == '*') {
e = strrchr(p, *e);
if (!e) return 0;
return e - p;
}
if (l1 < l2) return l1;
if (strcmp(p+l1-l2, e) == 0) {
@ -1339,25 +1298,24 @@ file_s_basename(argc, argv)
int argc;
VALUE *argv;
{
struct RString *fname;
struct RString *ext;
VALUE fname, ext;
char *p;
int f;
rb_scan_args(argc, argv, "11", &fname, &ext);
Check_Type(fname, T_STRING);
if (!NIL_P(ext)) Check_Type(ext, T_STRING);
p = strrchr(fname->ptr, '/');
p = strrchr(RSTRING(fname)->ptr, '/');
if (!p) {
if (!NIL_P(ext)) {
f = rmext(fname->ptr, ext->ptr);
if (f) return str_new(fname->ptr, f);
f = rmext(RSTRING(fname)->ptr, RSTRING(ext)->ptr);
if (f) return str_new(RSTRING(fname)->ptr, f);
}
return (VALUE)fname;
}
p++; /* skip last `/' */
if (!NIL_P(ext)) {
f = rmext(p, ext->ptr);
f = rmext(p, RSTRING(ext)->ptr);
if (f) return str_new(p, f);
}
return str_taint(str_new2(p));
@ -1365,19 +1323,18 @@ file_s_basename(argc, argv)
static VALUE
file_s_dirname(obj, fname)
VALUE obj;
struct RString *fname;
VALUE obj, fname;
{
UCHAR *p;
Check_Type(fname, T_STRING);
p = strrchr(fname->ptr, '/');
p = strrchr(RSTRING(fname)->ptr, '/');
if (!p) {
return str_new2(".");
}
if (p == fname->ptr)
if (p == RSTRING(fname)->ptr)
p++;
return str_taint(str_new(fname->ptr, p - fname->ptr));
return str_taint(str_new(RSTRING(fname)->ptr, p - RSTRING(fname)->ptr));
}
static VALUE
@ -1398,31 +1355,30 @@ file_s_join(obj, args)
static VALUE
file_s_truncate(obj, path, len)
VALUE obj, len;
struct RString *path;
VALUE obj, path, len;
{
Check_SafeStr(path);
#ifdef HAVE_TRUNCATE
if (truncate(path->ptr, NUM2INT(len)) < 0)
rb_sys_fail(path->ptr);
if (truncate(RSTRING(path)->ptr, NUM2INT(len)) < 0)
rb_sys_fail(RSTRING(path)->ptr);
#else
# ifdef HAVE_CHSIZE
{
int tmpfd;
# if defined(NT)
if ((tmpfd = open(path->ptr, O_RDWR)) < 0) {
rb_sys_fail(path->ptr);
if ((tmpfd = open(RSTRING(path)->ptr, O_RDWR)) < 0) {
rb_sys_fail(RSTRING(path)->ptr);
}
# else
if ((tmpfd = open(path->ptr, 0)) < 0) {
rb_sys_fail(path->ptr);
if ((tmpfd = open(RSTRING(path)->ptr, 0)) < 0) {
rb_sys_fail(RSTRING(path)->ptr);
}
# endif
if (chsize(tmpfd, NUM2INT(len)) < 0) {
close(tmpfd);
rb_sys_fail(path->ptr);
rb_sys_fail(RSTRING(path)->ptr);
}
close(tmpfd);
}
@ -1635,6 +1591,8 @@ extern VALUE mKernel;
void
Init_File()
{
VALUE mConst;
mFileTest = rb_define_module("FileTest");
rb_define_module_function(mFileTest, "directory?", test_d, 1);
@ -1649,6 +1607,7 @@ Init_File()
rb_define_module_function(mFileTest, "file?", test_f, 1);
rb_define_module_function(mFileTest, "zero?", test_z, 1);
rb_define_module_function(mFileTest, "size?", test_s, 1);
rb_define_module_function(mFileTest, "size", test_s, 1);
rb_define_module_function(mFileTest, "owned?", test_owned, 1);
rb_define_module_function(mFileTest, "grpowned?", test_grpowned, 1);
@ -1740,11 +1699,17 @@ Init_File()
# define LOCK_UN 8
# endif
mConst = rb_define_module_under(cFile, "Constants");
rb_define_const(cFile, "LOCK_SH", INT2FIX(LOCK_SH));
rb_define_const(cFile, "LOCK_EX", INT2FIX(LOCK_EX));
rb_define_const(cFile, "LOCK_UN", INT2FIX(LOCK_UN));
rb_define_const(cFile, "LOCK_NB", INT2FIX(LOCK_NB));
rb_define_const(mConst, "LOCK_SH", INT2FIX(LOCK_SH));
rb_define_const(mConst, "LOCK_EX", INT2FIX(LOCK_EX));
rb_define_const(mConst, "LOCK_UN", INT2FIX(LOCK_UN));
rb_define_const(mConst, "LOCK_NB", INT2FIX(LOCK_NB));
rb_define_method(cFile, "path", file_path, 0);
rb_define_global_function("test", f_test, -1);

168
gc.c
View file

@ -34,8 +34,6 @@
void *alloca();
#endif
void gc();
void gc_mark();
static void run_final();
#ifndef GC_MALLOC_LIMIT
@ -57,11 +55,11 @@ xmalloc(size)
if (size == 0) size = 1;
malloc_memories += size;
if (malloc_memories > GC_MALLOC_LIMIT) {
gc();
gc_gc();
}
mem = malloc(size);
if (!mem) {
gc();
gc_gc();
mem = malloc(size);
if (!mem)
Fatal("failed to allocate memory");
@ -92,7 +90,7 @@ xrealloc(ptr, size)
if (!ptr) return xmalloc(size);
mem = realloc(ptr, size);
if (!mem) {
gc();
gc_gc();
mem = realloc(ptr, size);
if (!mem)
Fatal("failed to allocate memory(realloc)");
@ -235,19 +233,21 @@ add_heap()
p++;
}
}
#define RANY(o) ((RVALUE*)(o))
struct RBasic *
VALUE
rb_newobj()
{
struct RBasic *obj;
VALUE obj;
if (freelist) {
retry:
obj = (struct RBasic*)freelist;
obj = (VALUE)freelist;
freelist = freelist->as.free.next;
return obj;
}
if (dont_gc) add_heap();
else gc();
else gc_gc();
goto retry;
}
@ -259,8 +259,7 @@ data_object_alloc(class, datap, dmark, dfree)
void (*dfree)();
void (*dmark)();
{
struct RData *data = (struct RData*)rb_newobj();
NEWOBJ(data, struct RData);
OBJSETUP(data, class, T_DATA);
data->data = datap;
data->dfree = dfree;
@ -273,9 +272,10 @@ extern st_table *rb_class_tbl;
VALUE *gc_stack_start;
static int
looks_pointerp(p)
register RVALUE *p;
looks_pointerp(ptr)
void *ptr;
{
register RVALUE *p = RANY(ptr);
register RVALUE *heap_org;
register long i;
@ -365,9 +365,11 @@ gc_mark_maybe(obj)
}
void
gc_mark(obj)
register RVALUE *obj;
gc_mark(ptr)
void *ptr;
{
register RVALUE *obj = RANY(ptr);
Top:
if (FIXNUM_P(obj)) return; /* fixnum not marked */
if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */
@ -403,16 +405,18 @@ gc_mark(obj)
case NODE_SUPER: /* 3 */
case NODE_FCALL:
case NODE_NEWLINE:
obj = (RVALUE*)obj->as.node.u3.node;
obj = RANY(obj->as.node.u3.node);
goto Top;
case NODE_WHILE: /* 1,2 */
case NODE_UNTIL:
case NODE_MATCH2:
case NODE_MATCH3:
gc_mark(obj->as.node.u1.node);
/* fall through */
case NODE_METHOD: /* 2 */
case NODE_NOT:
obj = (RVALUE*)obj->as.node.u2.node;
obj = RANY(obj->as.node.u2.node);
goto Top;
case NODE_HASH: /* 1 */
@ -420,12 +424,13 @@ gc_mark(obj)
case NODE_STR:
case NODE_XSTR:
case NODE_DEFINED:
obj = (RVALUE*)obj->as.node.u1.node;
case NODE_MATCH:
obj = RANY(obj->as.node.u1.node);
goto Top;
case NODE_SCOPE: /* 2,3 */
gc_mark(obj->as.node.u3.node);
obj = (RVALUE*)obj->as.node.u2.node;
obj = RANY(obj->as.node.u2.node);
goto Top;
case NODE_ZARRAY: /* - */
@ -443,6 +448,7 @@ gc_mark(obj)
case NODE_UNDEF:
case NODE_SELF:
case NODE_NIL:
case NODE_POSTEXE:
break;
default:
@ -453,7 +459,7 @@ gc_mark(obj)
gc_mark(obj->as.node.u2.node);
}
if (looks_pointerp(obj->as.node.u3.node)) {
obj = (RVALUE*)obj->as.node.u3.node;
obj = RANY(obj->as.node.u3.node);
goto Top;
}
}
@ -491,7 +497,7 @@ gc_mark(obj)
case T_STRING:
if (obj->as.string.orig) {
obj = (RVALUE*)obj->as.string.orig;
obj = RANY(obj->as.string.orig);
goto Top;
}
break;
@ -512,14 +518,14 @@ gc_mark(obj)
case T_MATCH:
if (obj->as.match.str) {
obj = (RVALUE*)obj->as.match.str;
obj = RANY(obj->as.match.str);
goto Top;
}
break;
case T_VARMAP:
gc_mark(obj->as.varmap.val);
obj = (RVALUE*)obj->as.varmap.next;
obj = RANY(obj->as.varmap.next);
goto Top;
break;
@ -604,20 +610,20 @@ gc_sweep()
void
gc_force_recycle(p)
RVALUE *p;
VALUE p;
{
p->as.free.flag = 0;
p->as.free.next = freelist;
freelist = p;
RANY(p)->as.free.flag = 0;
RANY(p)->as.free.next = freelist;
freelist = RANY(p);
}
static int need_call_final = 0;
static void
obj_free(obj)
RVALUE *obj;
VALUE obj;
{
switch (obj->as.basic.flags & T_MASK) {
switch (RANY(obj)->as.basic.flags & T_MASK) {
case T_NIL:
case T_FIXNUM:
case T_TRUE:
@ -629,40 +635,44 @@ obj_free(obj)
if (need_call_final) {
run_final(obj);
}
switch (obj->as.basic.flags & T_MASK) {
switch (RANY(obj)->as.basic.flags & T_MASK) {
case T_OBJECT:
if (obj->as.object.iv_tbl) st_free_table(obj->as.object.iv_tbl);
if (RANY(obj)->as.object.iv_tbl) {
st_free_table(RANY(obj)->as.object.iv_tbl);
}
break;
case T_MODULE:
case T_CLASS:
rb_clear_cache();
st_free_table(obj->as.class.m_tbl);
if (obj->as.object.iv_tbl) st_free_table(obj->as.object.iv_tbl);
st_free_table(RANY(obj)->as.class.m_tbl);
if (RANY(obj)->as.object.iv_tbl) {
st_free_table(RANY(obj)->as.object.iv_tbl);
}
break;
case T_STRING:
if (!obj->as.string.orig) free(obj->as.string.ptr);
if (!RANY(obj)->as.string.orig) free(RANY(obj)->as.string.ptr);
break;
case T_ARRAY:
if (obj->as.array.ptr) free(obj->as.array.ptr);
if (RANY(obj)->as.array.ptr) free(RANY(obj)->as.array.ptr);
break;
case T_HASH:
st_free_table(obj->as.hash.tbl);
st_free_table(RANY(obj)->as.hash.tbl);
break;
case T_REGEXP:
reg_free(obj->as.regexp.ptr);
free(obj->as.regexp.str);
reg_free(RANY(obj)->as.regexp.ptr);
free(RANY(obj)->as.regexp.str);
break;
case T_DATA:
if (obj->as.data.dfree && DATA_PTR(obj))
(*obj->as.data.dfree)(DATA_PTR(obj));
if (RANY(obj)->as.data.dfree && DATA_PTR(obj))
(*RANY(obj)->as.data.dfree)(DATA_PTR(obj));
break;
case T_MATCH:
re_free_registers(obj->as.match.regs);
free(obj->as.match.regs);
re_free_registers(RANY(obj)->as.match.regs);
free(RANY(obj)->as.match.regs);
break;
case T_FILE:
io_fptr_finalize(obj->as.file.fptr);
free(obj->as.file.fptr);
io_fptr_finalize(RANY(obj)->as.file.fptr);
free(RANY(obj)->as.file.fptr);
break;
case T_ICLASS:
/* iClass shares table with the module */
@ -673,30 +683,30 @@ obj_free(obj)
break;
case T_BIGNUM:
if (obj->as.bignum.digits) free(obj->as.bignum.digits);
if (RANY(obj)->as.bignum.digits) free(RANY(obj)->as.bignum.digits);
break;
case T_NODE:
if (nd_type(obj) == NODE_SCOPE && obj->as.node.u1.tbl) {
free(obj->as.node.u1.tbl);
if (nd_type(obj) == NODE_SCOPE && RANY(obj)->as.node.u1.tbl) {
free(RANY(obj)->as.node.u1.tbl);
}
return; /* no need to free iv_tbl */
case T_SCOPE:
if (obj->as.scope.local_vars) {
VALUE *vars = obj->as.scope.local_vars-1;
if (RANY(obj)->as.scope.local_vars) {
VALUE *vars = RANY(obj)->as.scope.local_vars-1;
if (vars[0] == 0)
free(obj->as.scope.local_tbl);
if (obj->as.scope.flag&SCOPE_MALLOC)
free(RANY(obj)->as.scope.local_tbl);
if (RANY(obj)->as.scope.flag&SCOPE_MALLOC)
free(vars);
}
break;
case T_STRUCT:
free(obj->as.rstruct.ptr);
free(RANY(obj)->as.rstruct.ptr);
break;
default:
Bug("gc_sweep(): unknown data type %d", obj->as.basic.flags & T_MASK);
Bug("gc_sweep(): unknown data type %d", RANY(obj)->as.basic.flags & T_MASK);
}
}
@ -750,7 +760,7 @@ int rb_setjmp (rb_jmp_buf);
#endif /* __GNUC__ */
void
gc()
gc_gc()
{
struct gc_list *list;
struct FRAME *frame;
@ -806,7 +816,7 @@ gc()
static VALUE
gc_method()
{
gc();
gc_gc();
return Qnil;
}
@ -851,7 +861,7 @@ os_live_obj()
case T_CLASS:
if (FL_TEST(p, FL_SINGLETON)) continue;
default:
rb_yield(p);
rb_yield((VALUE)p);
n++;
}
}
@ -883,8 +893,8 @@ os_obj_of(of)
case T_CLASS:
if (FL_TEST(p, FL_SINGLETON)) continue;
default:
if (obj_is_kind_of(p, of)) {
rb_yield(p);
if (obj_is_kind_of((VALUE)p, of)) {
rb_yield((VALUE)p);
n++;
}
}
@ -957,12 +967,47 @@ run_final(obj)
if (!FL_TEST(obj, FL_FINALIZE)) return;
obj |= FIXNUM_FLAG; /* make obj into id */
obj = INT2NUM((int)obj); /* make obj into id */
for (i=0; i<RARRAY(finalizers)->len; i++) {
rb_eval_cmd(RARRAY(finalizers)->ptr[i], obj);
rb_eval_cmd(RARRAY(finalizers)->ptr[i], ary_new3(1,obj));
}
}
void
gc_call_finalizer_at_exit()
{
RVALUE *p, *pend;
int i;
for (i = 0; i < heaps_used; i++) {
p = heaps[i]; pend = p + HEAP_SLOTS;
while (p < pend) {
run_final(p);
if (BUILTIN_TYPE(p) == T_DATA &&
DATA_PTR(p) &&
RANY(p)->as.data.dfree)
(*RANY(p)->as.data.dfree)(DATA_PTR(p));
p++;
}
}
}
static VALUE
id2ref(obj, id)
VALUE obj, id;
{
INT ptr = NUM2INT(id);
if (FIXNUM_P(ptr)) return (VALUE)ptr;
if (!looks_pointerp(ptr)) {
IndexError("0x%x is not the id value", ptr);
}
if (RANY(ptr)->as.free.flag == 0) {
IndexError("0x%x is recycled object", ptr);
}
return (VALUE)ptr;
}
extern VALUE cModule;
void
@ -978,11 +1023,12 @@ Init_GC()
mObSpace = rb_define_module("ObjectSpace");
rb_define_module_function(mObSpace, "each_object", os_each_obj, -1);
rb_define_module_function(mObSpace, "garbage_collect", gc, 0);
rb_define_module_function(mObSpace, "garbage_collect", gc_method, 0);
rb_define_module_function(mObSpace, "add_finalizer", add_final, 1);
rb_define_module_function(mObSpace, "remove_finalizer", rm_final, 1);
rb_define_module_function(mObSpace, "finalizers", finals, 0);
rb_define_module_function(mObSpace, "call_finalizer", call_final, 1);
rb_define_module_function(mObSpace, "id2ref", id2ref, 1);
rb_global_variable(&finalizers);
finalizers = ary_new();

360
hash.c
View file

@ -14,15 +14,44 @@
#include "st.h"
#include "sig.h"
#ifdef HAVE_STRING_H
# include <string.h>
#else
#include <sys/stat.h>
#ifndef HAVE_STRING_H
char *strchr();
#endif
#define HASH_DELETED 0x1
#define HASH_REHASHED 0x2
#define HASH_FREEZE FL_USER1
static void
hash_modify(hash)
VALUE hash;
{
rb_secure(5);
if (FL_TEST(hash, HASH_FREEZE)) {
TypeError("can't modify frozen hash");
}
}
VALUE
hash_freeze(hash)
VALUE hash;
{
FL_SET(hash, HASH_FREEZE);
return hash;
}
static VALUE
hash_frozen_p(hash)
VALUE hash;
{
if (FL_TEST(hash, HASH_FREEZE))
return TRUE;
return FALSE;
}
#ifndef NT
char *getenv();
#endif
@ -90,7 +119,7 @@ static struct st_hash_type objhash = {
};
struct hash_foreach_arg {
struct RHash *hash;
VALUE hash;
enum st_retval (*func)();
char *arg;
};
@ -104,7 +133,7 @@ hash_foreach_iter(key, value, arg)
if (key == Qnil) return ST_CONTINUE;
status = (*arg->func)(key, value, arg->arg);
if (arg->hash->status & HASH_REHASHED) return ST_STOP;
if (RHASH(arg->hash)->status & HASH_REHASHED) return ST_STOP;
return status;
}
@ -112,7 +141,7 @@ static VALUE
hash_foreach_call(arg)
struct hash_foreach_arg *arg;
{
st_foreach(arg->hash->tbl, hash_foreach_iter, arg);
st_foreach(RHASH(arg->hash)->tbl, hash_foreach_iter, arg);
return Qnil;
}
@ -126,31 +155,31 @@ hash_delete_nil(key, value)
static void
hash_foreach_ensure(hash)
struct RHash *hash;
VALUE hash;
{
hash->iter_lev--;
RHASH(hash)->iter_lev--;
if (hash->iter_lev == 0) {
if (hash->status & HASH_DELETED) {
st_foreach(hash->tbl, hash_delete_nil, 0);
if (RHASH(hash)->iter_lev == 0) {
if (RHASH(hash)->status & HASH_DELETED) {
st_foreach(RHASH(hash)->tbl, hash_delete_nil, 0);
}
hash->status = 0;
RHASH(hash)->status = 0;
}
}
static int
hash_foreach(hash, func, farg)
struct RHash *hash;
VALUE hash;
enum st_retval (*func)();
char *farg;
{
struct hash_foreach_arg arg;
hash->iter_lev++;
RHASH(hash)->iter_lev++;
arg.hash = hash;
arg.func = func;
arg.arg = farg;
return rb_ensure(hash_foreach_call, &arg, hash_foreach_ensure, hash);
return rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, (VALUE)hash);
}
static VALUE
@ -177,7 +206,7 @@ hash_s_new(argc, argv, class)
return (VALUE)hash;
}
VALUE
static VALUE
hash_new2(class)
VALUE class;
{
@ -196,7 +225,7 @@ hash_s_create(argc, argv, class)
VALUE *argv;
VALUE class;
{
struct RHash *hash;
VALUE hash;
int i;
if (argc == 1 && TYPE(argv[0]) == T_HASH) {
@ -216,18 +245,18 @@ hash_s_create(argc, argv, class)
if (argc % 2 != 0) {
ArgError("odd number args for Hash");
}
hash = (struct RHash*)hash_new2(class);
hash = hash_new2(class);
for (i=0; i<argc; i+=2) {
st_insert(hash->tbl, argv[i], argv[i+1]);
st_insert(RHASH(hash)->tbl, argv[i], argv[i+1]);
}
return (VALUE)hash;
return hash;
}
static VALUE
hash_clone(hash)
struct RHash *hash;
VALUE hash;
{
NEWOBJ(hash2, struct RHash);
CLONESETUP(hash2, hash);
@ -235,7 +264,22 @@ hash_clone(hash)
hash2->iter_lev = 0;
hash2->status = 0;
hash2->tbl = 0; /* avoid GC crashing */
hash2->tbl = (st_table*)st_copy(hash->tbl);
hash2->tbl = (st_table*)st_copy(RHASH(hash)->tbl);
return (VALUE)hash2;
}
static VALUE
hash_dup(hash)
VALUE hash;
{
NEWOBJ(hash2, struct RHash);
OBJSETUP(hash2, CLASS_OF(hash), T_HASH);
hash2->iter_lev = 0;
hash2->status = 0;
hash2->tbl = 0; /* avoid GC crashing */
hash2->tbl = (st_table*)st_copy(RHASH(hash)->tbl);
return (VALUE)hash2;
}
@ -253,26 +297,26 @@ hash_rehash_i(key, value, tbl)
static VALUE
hash_rehash(hash)
struct RHash *hash;
VALUE hash;
{
st_table *tbl = st_init_table_with_size(&objhash, hash->tbl->num_entries);
st_table *tbl;
st_foreach(hash->tbl, hash_rehash_i, tbl);
st_free_table(hash->tbl);
hash->tbl = tbl;
if (hash->iter_lev > 0) hash->status |= HASH_REHASHED;
tbl = st_init_table_with_size(&objhash, RHASH(hash)->tbl->num_entries);
st_foreach(RHASH(hash)->tbl, hash_rehash_i, tbl);
st_free_table(RHASH(hash)->tbl);
RHASH(hash)->tbl = tbl;
if (RHASH(hash)->iter_lev > 0) RHASH(hash)->status |= HASH_REHASHED;
return (VALUE)hash;
}
VALUE
hash_aref(hash, key)
struct RHash *hash;
VALUE key;
VALUE hash, key;
{
VALUE val;
if (!st_lookup(hash->tbl, key, &val)) {
if (!st_lookup(RHASH(hash)->tbl, key, &val)) {
return Qnil;
}
return val;
@ -282,30 +326,30 @@ static VALUE
hash_indexes(argc, argv, hash)
int argc;
VALUE *argv;
struct RHash *hash;
VALUE hash;
{
struct RArray *indexes;
VALUE indexes;
int i;
indexes = (struct RArray*)ary_new2(argc);
indexes = ary_new2(argc);
for (i=0; i<argc; i++) {
indexes->ptr[i] = hash_aref(hash, argv[i]);
RARRAY(indexes)->ptr[i] = hash_aref(hash, argv[i]);
}
indexes->len = i;
return (VALUE)indexes;
RARRAY(indexes)->len = i;
return indexes;
}
static VALUE
hash_delete(hash, key)
struct RHash *hash;
VALUE key;
VALUE hash, key;
{
VALUE val;
rb_secure(5);
if (hash->iter_lev > 0 && st_delete_safe(hash->tbl, &key, &val, Qnil))
hash_modify(hash);
if (RHASH(hash)->iter_lev > 0
&& st_delete_safe(RHASH(hash)->tbl, &key, &val, Qnil))
return val;
else if (st_delete(hash->tbl, &key, &val))
else if (st_delete(RHASH(hash)->tbl, &key, &val))
return val;
if (iterator_p()) rb_yield(key);
return Qnil;
@ -332,13 +376,13 @@ shift_i(key, value, var)
static VALUE
hash_shift(hash)
struct RHash *hash;
VALUE hash;
{
struct shift_var var;
rb_secure(5);
hash_modify(hash);
var.stop = 0;
st_foreach(hash->tbl, shift_i, &var);
st_foreach(RHASH(hash)->tbl, shift_i, &var);
if (var.stop == 0) return Qnil;
return assoc_new(var.key, var.val);
@ -356,9 +400,9 @@ delete_if_i(key, value)
static VALUE
hash_delete_if(hash)
struct RHash *hash;
VALUE hash;
{
rb_secure(5);
hash_modify(hash);
hash_foreach(hash, delete_if_i, 0);
return (VALUE)hash;
@ -373,20 +417,19 @@ clear_i(key, value)
static VALUE
hash_clear(hash)
struct RHash *hash;
VALUE hash;
{
rb_secure(5);
st_foreach(hash->tbl, clear_i);
hash_modify(hash);
st_foreach(RHASH(hash)->tbl, clear_i);
return (VALUE)hash;
}
VALUE
hash_aset(hash, key, val)
struct RHash *hash;
VALUE key, val;
VALUE hash, key, val;
{
rb_secure(5);
hash_modify(hash);
if (NIL_P(val)) {
hash_delete(hash, key);
return Qnil;
@ -394,22 +437,22 @@ hash_aset(hash, key, val)
if (TYPE(key) == T_STRING) {
key = str_dup_freezed(key);
}
st_insert(hash->tbl, key, val);
st_insert(RHASH(hash)->tbl, key, val);
return val;
}
static VALUE
hash_length(hash)
struct RHash *hash;
VALUE hash;
{
return INT2FIX(hash->tbl->num_entries);
return INT2FIX(RHASH(hash)->tbl->num_entries);
}
VALUE
static VALUE
hash_empty_p(hash)
struct RHash *hash;
VALUE hash;
{
if (hash->tbl->num_entries == 0)
if (RHASH(hash)->tbl->num_entries == 0)
return TRUE;
return FALSE;
}
@ -425,7 +468,7 @@ each_value_i(key, value)
static VALUE
hash_each_value(hash)
struct RHash *hash;
VALUE hash;
{
hash_foreach(hash, each_value_i);
return (VALUE)hash;
@ -442,7 +485,7 @@ each_key_i(key, value)
static VALUE
hash_each_key(hash)
struct RHash *hash;
VALUE hash;
{
hash_foreach(hash, each_key_i);
return (VALUE)hash;
@ -459,7 +502,7 @@ each_pair_i(key, value)
static VALUE
hash_each_pair(hash)
struct RHash *hash;
VALUE hash;
{
hash_foreach(hash, each_pair_i);
return (VALUE)hash;
@ -476,25 +519,24 @@ to_a_i(key, value, ary)
static VALUE
hash_to_a(hash)
struct RHash *hash;
VALUE hash;
{
VALUE ary;
ary = ary_new();
st_foreach(hash->tbl, to_a_i, ary);
st_foreach(RHASH(hash)->tbl, to_a_i, ary);
return ary;
}
static int
inspect_i(key, value, str)
VALUE key, value;
struct RString *str;
VALUE key, value, str;
{
VALUE str2;
if (key == Qnil) return ST_CONTINUE;
if (str->len > 1) {
if (RSTRING(str)->len > 1) {
str_cat(str, ", ", 2);
}
str2 = rb_inspect(key);
@ -508,12 +550,12 @@ inspect_i(key, value, str)
static VALUE
hash_inspect(hash)
struct RHash *hash;
VALUE hash;
{
VALUE str;
str = str_new2("{");
st_foreach(hash->tbl, inspect_i, str);
st_foreach(RHASH(hash)->tbl, inspect_i, str);
str_cat(str, "}", 1);
return str;
@ -537,12 +579,12 @@ keys_i(key, value, ary)
static VALUE
hash_keys(hash)
struct RHash *hash;
VALUE hash;
{
VALUE ary;
ary = ary_new();
st_foreach(hash->tbl, keys_i, ary);
st_foreach(RHASH(hash)->tbl, keys_i, ary);
return ary;
}
@ -558,22 +600,22 @@ values_i(key, value, ary)
static VALUE
hash_values(hash)
struct RHash *hash;
VALUE hash;
{
VALUE ary;
ary = ary_new();
st_foreach(hash->tbl, values_i, ary);
st_foreach(RHASH(hash)->tbl, values_i, ary);
return ary;
}
static VALUE
hash_has_key(hash, key)
struct RHash *hash;
VALUE hash;
VALUE key;
{
if (st_lookup(hash->tbl, key, 0)) {
if (st_lookup(RHASH(hash)->tbl, key, 0)) {
return TRUE;
}
return FALSE;
@ -593,14 +635,14 @@ hash_search_value(key, value, data)
static VALUE
hash_has_value(hash, val)
struct RHash *hash;
VALUE hash;
VALUE val;
{
VALUE data[2];
data[0] = FALSE;
data[1] = val;
st_foreach(hash->tbl, hash_search_value, data);
st_foreach(RHASH(hash)->tbl, hash_search_value, data);
return data[0];
}
@ -630,17 +672,17 @@ equal_i(key, val1, data)
static VALUE
hash_equal(hash1, hash2)
struct RHash *hash1, *hash2;
VALUE hash1, hash2;
{
struct equal_data data;
if (TYPE(hash2) != T_HASH) return FALSE;
if (hash1->tbl->num_entries != hash2->tbl->num_entries)
if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries)
return FALSE;
data.tbl = hash2->tbl;
data.tbl = RHASH(hash2)->tbl;
data.result = TRUE;
st_foreach(hash1->tbl, equal_i, &data);
st_foreach(RHASH(hash1)->tbl, equal_i, &data);
return data.result;
}
@ -648,7 +690,7 @@ hash_equal(hash1, hash2)
static int
hash_invert_i(key, value, hash)
VALUE key, value;
struct RHash *hash;
VALUE hash;
{
if (key == Qnil) return ST_CONTINUE;
hash_aset(hash, value, key);
@ -657,15 +699,36 @@ hash_invert_i(key, value, hash)
static VALUE
hash_invert(hash)
struct RHash *hash;
VALUE hash;
{
VALUE h = hash_new();
st_foreach(hash->tbl, hash_invert_i, h);
st_foreach(RHASH(hash)->tbl, hash_invert_i, h);
return h;
}
int env_path_tainted = 0;
static int
hash_update_i(key, value, hash)
VALUE key, value;
VALUE hash;
{
if (key == Qnil) return ST_CONTINUE;
hash_aset(hash, key, value);
return ST_CONTINUE;
}
static VALUE
hash_update(hash1, hash2)
VALUE hash1, hash2;
{
Check_Type(hash2, T_HASH);
st_foreach(RHASH(hash2)->tbl, hash_update_i, hash1);
return hash1;
}
int env_path_tainted();
static int path_tainted = -1;
#ifndef NT
extern char **environ;
@ -673,17 +736,16 @@ extern char **environ;
static VALUE
env_delete(obj, name)
VALUE obj;
struct RString *name;
VALUE obj, name;
{
int i, len;
char *nam, *val = 0;
rb_secure(4);
Check_Type(name, T_STRING);
nam = name->ptr;
nam = RSTRING(name)->ptr;
len = strlen(nam);
if (strcmp(nam, "PATH") == 0) env_path_tainted = 0;
if (strcmp(nam, "PATH") == 0) path_tainted = 0;
for(i=0; environ[i]; i++) {
if (strncmp(environ[i], nam, len) == 0 && environ[i][len] == '=') {
val = environ[i]+len+1;
@ -700,31 +762,98 @@ env_delete(obj, name)
return Qnil;
}
static VALUE
env_delete_method(obj, name)
VALUE obj, name;
{
VALUE val = env_delete(obj, name);
if (iterator_p()) rb_yield(name);
return val;
}
static VALUE
f_getenv(obj, name)
VALUE obj;
struct RString *name;
VALUE obj, name;
{
char *env;
Check_Type(name, T_STRING);
if (strlen(name->ptr) != name->len)
if (strlen(RSTRING(name)->ptr) != RSTRING(name)->len)
ArgError("Bad environment name");
env = getenv(name->ptr);
env = getenv(RSTRING(name)->ptr);
if (env) {
if (strcmp(name->ptr, "PATH") == 0 && !env_path_tainted)
if (strcmp(RSTRING(name)->ptr, "PATH") == 0 && !env_path_tainted())
return str_new2(env);
return str_taint(str_new2(env));
}
return Qnil;
}
static int
path_check_1(path)
char *path;
{
struct stat st;
char *p = 0;
char *s;
for (;;) {
if (stat(path, &st) == 0 && (st.st_mode & 2)) {
return 0;
}
s = strrchr(path, '/');
if (p) *p = '/';
if (!s || s == path) return 1;
p = s;
*p = '\0';
}
}
static void
path_check(path)
char *path;
{
char *p = path;
char *pend = strchr(path, ':');
if (!path) {
path_tainted = 0;
}
p = path;
pend = strchr(path, ':');
for (;;) {
int safe;
if (pend) *pend = '\0';
safe = path_check_1(p);
if (!pend) break;
*pend = ':';
if (!safe) {
path_tainted = 1;
return;
}
p = pend + 1;
pend = strchr(p, ':');
}
path_tainted = 0;
}
int
env_path_tainted()
{
if (path_tainted < 0) {
path_check(getenv("PATH"));
}
return path_tainted;
}
static VALUE
f_setenv(obj, name, value)
VALUE obj;
struct RString *name, *value;
VALUE obj, name, value;
{
if (rb_safe_level() >= 4) {
extern VALUE eSecurityError;
@ -738,13 +867,23 @@ f_setenv(obj, name, value)
}
Check_SafeStr(value);
if (strlen(name->ptr) != name->len)
if (strlen(RSTRING(name)->ptr) != RSTRING(name)->len)
ArgError("Bad environment name");
if (strlen(value->ptr) != value->len)
if (strlen(RSTRING(value)->ptr) != RSTRING(value)->len)
ArgError("Bad environment value");
setenv(name->ptr, value->ptr, 1);
if (strcmp(name->ptr, "PATH") == 0) env_path_tainted = 0;
setenv(RSTRING(name)->ptr, RSTRING(value)->ptr, 1);
if (strcmp(RSTRING(name)->ptr, "PATH") == 0) {
char *p, pend;
if (str_tainted(value)) {
/* already tainted, no check */
path_tainted = 1;
return TRUE;
}
path_check(RSTRING(name)->ptr);
}
return TRUE;
}
@ -941,15 +1080,19 @@ Init_Hash()
rb_define_singleton_method(cHash, "new", hash_s_new, -1);
rb_define_singleton_method(cHash, "[]", hash_s_create, -1);
rb_define_method(cHash,"clone", hash_clone, 0);
rb_define_method(cHash,"rehash", hash_rehash, 0);
rb_define_method(cHash,"clone", hash_clone, 0);
rb_define_method(cHash,"dup", hash_dup, 0);
rb_define_method(cHash,"rehash", hash_rehash, 0);
rb_define_method(cHash,"to_a", hash_to_a, 0);
rb_define_method(cHash,"to_s", hash_to_s, 0);
rb_define_method(cHash,"inspect", hash_inspect, 0);
rb_define_method(cHash,"freeze", hash_freeze, 0);
rb_define_method(cHash,"frozen?",hash_frozen_p, 0);
rb_define_method(cHash,"==", hash_equal, 1);
rb_define_method(cHash,"[]", hash_aref, 1);
rb_define_method(cHash,"to_a", hash_to_a, 0);
rb_define_method(cHash,"to_s", hash_to_s, 0);
rb_define_method(cHash,"inspect", hash_inspect, 0);
rb_define_method(cHash,"==", hash_equal, 1);
rb_define_method(cHash,"[]", hash_aref, 1);
rb_define_method(cHash,"[]=", hash_aset, 2);
rb_define_method(cHash,"indexes", hash_indexes, -1);
rb_define_method(cHash,"length", hash_length, 0);
@ -969,6 +1112,7 @@ Init_Hash()
rb_define_method(cHash,"delete_if", hash_delete_if, 0);
rb_define_method(cHash,"clear", hash_clear, 0);
rb_define_method(cHash,"invert", hash_invert, 0);
rb_define_method(cHash,"update", hash_update, 1);
rb_define_method(cHash,"include?", hash_has_key, 1);
rb_define_method(cHash,"has_key?", hash_has_key, 1);
@ -985,7 +1129,7 @@ Init_Hash()
rb_define_singleton_method(envtbl,"each_pair", env_each, 0);
rb_define_singleton_method(envtbl,"each_key", env_each_key, 0);
rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
rb_define_singleton_method(envtbl,"delete", env_delete, 1);
rb_define_singleton_method(envtbl,"delete", env_delete_method, 1);
rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
rb_define_singleton_method(envtbl,"rehash", env_none, 0);

36
inits.c
View file

@ -12,20 +12,51 @@
#include "ruby.h"
void Init_Array _((void));
void Init_Bignum _((void));
void Init_Comparable _((void));
void Init_Dir _((void));
void Init_Enumerable _((void));
void Init_Exception _((void));
void Init_eval _((void));
void Init_load _((void));
void Init_Proc _((void));
void Init_Thread _((void));
void Init_File _((void));
void Init_GC _((void));
void Init_Hash _((void));
void Init_IO _((void));
void Init_Math _((void));
void Init_marshal _((void));
void Init_Numeric _((void));
void Init_Object _((void));
void Init_pack _((void));
void Init_sym _((void));
void Init_process _((void));
void Init_Random _((void));
void Init_Range _((void));
void Init_Regexp _((void));
void Init_signal _((void));
void Init_String _((void));
void Init_Struct _((void));
void Init_Time _((void));
void Init_var_tables _((void));
void Init_version _((void));
void
rb_call_inits()
{
Init_sym();
Init_var_tables();
Init_Object();
Init_Exception();
#ifdef THREAD
Init_Thread();
#endif
Init_eval();
Init_Comparable();
Init_Enumerable();
Init_eval();
Init_String();
Init_Exception();
Init_Numeric();
Init_Bignum();
Init_Array();
@ -44,5 +75,6 @@ rb_call_inits()
Init_Proc();
Init_Math();
Init_GC();
Init_marshal();
Init_version();
}

301
io.c
View file

@ -49,6 +49,10 @@ struct timeval {
# define NOFILE 64
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
VALUE rb_ad_string();
VALUE cIO;
@ -130,16 +134,15 @@ closed()
/* writing functions */
VALUE
io_write(io, str)
VALUE io;
struct RString *str;
VALUE io, str;
{
OpenFile *fptr;
FILE *f;
int n;
if (TYPE(str) != T_STRING)
str = (struct RString*)obj_as_string(str);
if (str->len == 0) return INT2FIX(0);
str = obj_as_string(str);
if (RSTRING(str)->len == 0) return INT2FIX(0);
if (BUILTIN_TYPE(io) != T_FILE) {
return rb_funcall(io, id_write, 1, str);
@ -164,7 +167,7 @@ io_write(io, str)
if (ferror(f))
rb_sys_fail(fptr->path);
#else
n = fwrite(str->ptr, 1, str->len, f);
n = fwrite(RSTRING(str)->ptr, 1, RSTRING(str)->len, f);
if (n == 0 || ferror(f)) {
rb_sys_fail(fptr->path);
}
@ -177,7 +180,7 @@ io_write(io, str)
}
static VALUE
io_puts(io, str)
io_addstr(io, str)
VALUE io, str;
{
io_write(io, str);
@ -265,29 +268,53 @@ io_fileno(io)
}
/* reading functions */
#ifndef S_ISREG
# define S_ISREG(m) ((m & S_IFMT) == S_IFREG)
#endif
#define SMALLBUF 100
static VALUE
read_all(port)
VALUE port;
{
OpenFile *fptr;
VALUE str = Qnil;
char buf[BUFSIZ];
char *buf;
struct stat st;
int siz = BUFSIZ;
int bytes = 0;
int n;
GetOpenFile(port, fptr);
io_readable(fptr);
if (fptr->f == NULL) closed();
if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode)) {
if (st.st_size == 0) return Qnil;
else {
int pos = ftell(fptr->f);
if (st.st_size > pos && pos >= 0) {
siz = st.st_size - pos + 1;
}
}
}
str = str_new(0, siz);
for (;;) {
READ_CHECK(fptr->f);
TRAP_BEG;
n = fread(buf, 1, BUFSIZ, fptr->f);
n = fread(RSTRING(str)->ptr+bytes, 1, siz-bytes, fptr->f);
TRAP_END;
if (n == 0) break;
if (n < 0) rb_sys_fail(0);
if (NIL_P(str)) str = str_new(buf, n);
else str_cat(str, buf, n);
if (n < 0) rb_sys_fail(fptr->path);
bytes += n;
if (bytes < siz) break;
siz += BUFSIZ;
str_resize(str, siz);
}
if (bytes == 0) return Qnil;
if (bytes != siz) str_resize(str, bytes);
return str_taint(str);
}
@ -298,26 +325,26 @@ io_read(argc, argv, io)
VALUE io;
{
OpenFile *fptr;
int n, lgt;
VALUE len, str;
int n, len;
VALUE length, str;
if (rb_scan_args(argc, argv, "01", &len) == 0) {
if (rb_scan_args(argc, argv, "01", &length) == 0) {
return read_all(io);
}
lgt = NUM2INT(len);
len = NUM2INT(length);
GetOpenFile(io, fptr);
io_readable(fptr);
if (fptr->f == NULL) closed();
str = str_new(0, lgt);
str = str_new(0, len);
READ_CHECK(fptr->f);
TRAP_BEG;
n = fread(RSTRING(str)->ptr, 1, RSTRING(str)->len, fptr->f);
n = fread(RSTRING(str)->ptr, 1, len, fptr->f);
TRAP_END;
if (n == 0) {
if (feof(fptr->f)) return Qnil;
if (n == 0) return Qnil;
if (n < 0) {
rb_sys_fail(fptr->path);
}
@ -332,12 +359,12 @@ static VALUE lineno;
VALUE
io_gets_method(argc, argv, io)
int argc;
VALUE argv;
VALUE *argv;
VALUE io;
{
OpenFile *fptr;
FILE *f;
struct RString *str;
VALUE str = Qnil;
int c, newline;
char *rsptr;
int rslen, rspara = 0;
@ -415,7 +442,7 @@ io_gets_method(argc, argv, io)
if (c == EOF) {
if (!append && cnt == 0) {
str = RSTRING(Qnil);
str = Qnil;
goto return_gets;
}
}
@ -423,12 +450,12 @@ io_gets_method(argc, argv, io)
if (append)
str_cat(str, buf, cnt);
else
str = (struct RString*)str_new(buf, cnt);
str = str_new(buf, cnt);
if (c != EOF &&
(!rslen ||
str->len < rslen ||
memcmp(str->ptr+str->len-rslen, rsptr, rslen))) {
RSTRING(str)->len < rslen ||
memcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen, rsptr, rslen))) {
append = 1;
goto again;
}
@ -448,13 +475,14 @@ io_gets_method(argc, argv, io)
}
}
if (str) {
if (!NIL_P(str)) {
fptr->lineno++;
lineno = INT2FIX(fptr->lineno);
str_taint(str);
}
lastline_set(str);
return str_taint(str);
return str;
}
VALUE
@ -467,7 +495,7 @@ io_gets(io)
static VALUE
io_readline(argc, argv, io)
int argc;
VALUE argv;
VALUE *argv;
VALUE io;
{
VALUE line = io_gets_method(argc, argv, io);
@ -481,7 +509,7 @@ io_readline(argc, argv, io)
static VALUE
io_readlines(argc, argv, io)
int argc;
VALUE argv;
VALUE *argv;
VALUE io;
{
VALUE line, ary;
@ -496,7 +524,7 @@ io_readlines(argc, argv, io)
static VALUE
io_each_line(argc, argv, io)
int argc;
VALUE argv;
VALUE *argv;
VALUE io;
{
VALUE str;
@ -582,6 +610,7 @@ io_ungetc(io, c)
if (ungetc(FIX2INT(c), fptr->f) == EOF)
rb_sys_fail(fptr->path);
return Qnil;
}
static VALUE
@ -777,7 +806,7 @@ rb_fopen(fname, mode)
f = fopen(fname, mode);
if (f == NULL) {
if (errno == EMFILE || errno == ENFILE) {
gc();
gc_gc();
f = fopen(fname, mode);
}
if (f == NULL) {
@ -945,16 +974,9 @@ pipe_open(pname, mode)
}
if (doexec) {
VALUE serr = io_fileno(rb_stderr);
int fd = FIX2INT(serr);
extern char *sourcefile;
extern int sourceline;
if (fd != 2) {
close(2);
dup2(fd, 2);
close(fd);
}
int fd;
for (fd = 3; fd < NOFILE; fd++)
close(fd);
@ -1043,13 +1065,13 @@ io_open(fname, mode)
}
static VALUE
f_open(argc, argv, self)
f_open(argc, argv)
int argc;
VALUE *argv;
VALUE self;
{
char *mode;
VALUE pname, pmode;
VALUE port;
rb_scan_args(argc, argv, "11", &pname, &pmode);
Check_SafeStr(pname);
@ -1062,13 +1084,35 @@ f_open(argc, argv, self)
ArgError("illegal access mode");
mode = RSTRING(pmode)->ptr;
}
return io_open(RSTRING(pname)->ptr, mode);
port = io_open(RSTRING(pname)->ptr, mode);
if (iterator_p()) {
rb_ensure(rb_yield, port, io_close, port);
}
return port;
}
#ifndef NT
extern char *strdup();
#endif
static char*
io_mode_string(fptr)
OpenFile *fptr;
{
switch (fptr->mode & FMODE_READWRITE) {
case FMODE_READABLE:
default:
return "r";
case FMODE_WRITABLE:
return "w";
case FMODE_READWRITE:
return "r+";
}
return "r";
}
VALUE
io_reopen(io, nfile)
VALUE io, nfile;
@ -1097,25 +1141,17 @@ io_reopen(io, nfile)
else fptr->path = 0;
fptr->finalize = orig->finalize;
switch (fptr->mode & FMODE_READWRITE) {
case FMODE_READABLE:
default:
mode = "r"; break;
case FMODE_WRITABLE:
mode = "w"; break;
case FMODE_READWRITE:
if (orig->f2) mode = "r";
else mode = "r+";
break;
}
mode = io_mode_string(fptr);
fd = fileno(fptr->f);
fclose(fptr->f);
if (fileno(fptr->f) < 3) /* need to keep stdio */
fclose(fptr->f);
dup2(fileno(orig->f), fd);
fptr->f = rb_fdopen(fd, mode);
if (fptr->f2) {
fd = fileno(fptr->f2);
fclose(fptr->f2);
if (fileno(fptr->f2) < 3)
fclose(fptr->f2);
if (orig->f2) {
dup2(fileno(orig->f2), fd);
fptr->f = rb_fdopen(fd, "w");
@ -1179,7 +1215,7 @@ io_clone(io)
fptr->f = rb_fdopen(fd, "w");
}
if (fptr->mode & FMODE_BINMODE) {
io_binmode(obj);
io_binmode((VALUE)obj);
}
return (VALUE)obj;
@ -1226,7 +1262,7 @@ io_print(argc, argv, out)
VALUE *argv;
VALUE out;
{
int i;
int i, j;
VALUE line;
/* if no argument given, print `$_' */
@ -1244,7 +1280,12 @@ io_print(argc, argv, out)
io_write(out, str_new2("nil"));
break;
case T_ARRAY:
ary_print_on(argv[i], out);
for (j=0; j<RARRAY(argv[i])->len; j++) {
if (!NIL_P(OFS) && j>0) {
io_write(out, OFS);
}
io_write(out, RARRAY(argv[i])->ptr[j]);
}
break;
default:
io_write(out, argv[i]);
@ -1267,6 +1308,53 @@ f_print(argc, argv)
return Qnil;
}
static VALUE
io_puts(argc, argv, out)
int argc;
VALUE *argv;
VALUE out;
{
int i, j;
VALUE line;
/* if no argument given, print newline. */
if (argc == 0) {
io_write(out, str_new2("\n"));
return Qnil;
}
for (i=0; i<argc; i++) {
switch (TYPE(argv[i])) {
case T_NIL:
line = str_new2("nil");
break;
case T_ARRAY:
for (j=0; j<RARRAY(argv[i])->len; j++) {
io_puts(1, &RARRAY(argv[i])->ptr[j], out);
}
continue;
default:
line = argv[i];
break;
}
line = obj_as_string(line);
io_write(out, line);
if (RSTRING(line)->ptr[RSTRING(line)->len-1] != '\n') {
io_write(out, str_new2("\n"));
}
}
return Qnil;
}
static VALUE
f_puts(argc, argv)
int argc;
VALUE *argv;
{
io_puts(argc, argv, rb_defout);
return Qnil;
}
static VALUE
f_p(obj, val)
VALUE obj, val;
@ -1279,6 +1367,13 @@ f_p(obj, val)
return Qnil;
}
void
rb_p(obj) /* for debug print within C code */
VALUE obj;
{
f_p(Qnil, obj);
}
static void
io_defset(val, id)
VALUE val;
@ -1294,6 +1389,41 @@ io_defset(val, id)
rb_defout = val;
}
static void
io_errset(val, id)
VALUE val;
ID id;
{
OpenFile *fptr;
int fd;
if (TYPE(val) != T_FILE) {
TypeError("$stderr must be IO Object");
}
GetOpenFile(val, fptr);
io_writable(fptr);
rb_stderr = val;
fd = fileno(fptr->f2?fptr->f2:fptr->f);
if (fd != 2) {
FILE *f;
fflush(stderr);
dup2(fd, 2);
f = rb_fdopen(2, io_mode_string(fptr));
if (fptr->f2) {
if (fileno(fptr->f2) < 3) /* need to keep stdio */
fclose(fptr->f2);
fptr->f2 = f;
}
else {
if (fileno(fptr->f) < 3)
fclose(fptr->f);
fptr->f = f;
}
}
}
static VALUE
prep_stdio(f, mode)
FILE *f;
@ -1336,11 +1466,11 @@ static int init_p = 0, next_p = 0;
static int
next_argv()
{
extern VALUE Argv;
extern VALUE rb_argv;
char *fn;
if (init_p == 0) {
if (RARRAY(Argv)->len > 0) {
if (RARRAY(rb_argv)->len > 0) {
next_p = 1;
}
else {
@ -1354,8 +1484,8 @@ next_argv()
retry:
if (next_p == 1) {
next_p = 0;
if (RARRAY(Argv)->len > 0) {
filename = ary_shift(Argv);
if (RARRAY(rb_argv)->len > 0) {
filename = ary_shift(rb_argv);
fn = RSTRING(filename)->ptr;
if (RSTRING(filename)->len == 1 && fn[0] == '-') {
file = rb_stdin;
@ -1371,7 +1501,7 @@ next_argv()
VALUE str;
FILE *fw;
if (rb_defout != rb_stdout) {
if (TYPE(rb_defout) == T_FILE && rb_defout != rb_stdout) {
io_close(rb_defout);
}
fstat(fileno(fr), &st);
@ -1539,13 +1669,12 @@ rb_str_setter(val, id, var)
static VALUE
f_backquote(obj, str)
VALUE obj;
struct RString *str;
VALUE obj, str;
{
VALUE port, result;
Check_SafeStr(str);
port = pipe_open(str->ptr, "r");
port = pipe_open(RSTRING(str)->ptr, "r");
result = read_all(port);
io_close(port);
@ -1719,8 +1848,7 @@ f_select(argc, argv, obj)
static VALUE
io_ctl(io, req, arg, io_p)
VALUE io, req;
struct RString *arg;
VALUE io, req, arg;
int io_p;
{
#if !defined(MSDOS) && !defined(__human68k__)
@ -1757,12 +1885,14 @@ io_ctl(io, req, arg, io_p)
#endif
str_modify(arg);
if (len < arg->len) {
len = arg->len;
if (len <= RSTRING(arg)->len) {
len = RSTRING(arg)->len;
}
str_resize(arg, len+1);
arg->ptr[len] = 17; /* a little sanity check here */
narg = (long)arg->ptr;
if (RSTRING(arg)->len < len) {
str_resize(arg, len+1);
}
RSTRING(arg)->ptr[len] = 17; /* a little sanity check here */
narg = (long)RSTRING(arg)->ptr;
}
fd = fileno(fptr->f);
#ifdef HAVE_FCNTL
@ -1774,7 +1904,7 @@ io_ctl(io, req, arg, io_p)
retval = ioctl(fd, cmd, narg);
#endif
if (retval < 0) rb_sys_fail(fptr->path);
if (TYPE(arg) == T_STRING && arg->ptr[len] != 17) {
if (TYPE(arg) == T_STRING && RSTRING(arg)->ptr[len] != 17) {
ArgError("return value overflowed string");
}
return INT2NUM(retval);
@ -1957,14 +2087,14 @@ io_s_foreach(argc, argv, io)
VALUE *argv;
VALUE io;
{
struct RString *fname;
VALUE fname;
struct foreach_arg arg;
rb_scan_args(argc, argv, "11", &fname, &arg.sep);
Check_SafeStr(fname);
arg.argc = argc - 1;
arg.io = io_open(fname->ptr, "r");
arg.io = io_open(RSTRING(fname)->ptr, "r");
return rb_ensure(io_foreach_line, &arg, io_close, arg.io);
}
@ -1988,14 +2118,14 @@ io_s_readlines(argc, argv, io)
VALUE *argv;
VALUE io;
{
struct RString *fname;
VALUE fname;
struct foreach_arg arg;
rb_scan_args(argc, argv, "11", &fname, &arg.sep);
Check_SafeStr(fname);
arg.argc = argc - 1;
arg.io = io_open(fname->ptr, "r");
arg.io = io_open(RSTRING(fname)->ptr, "r");
return rb_ensure(io_readline_line, &arg, io_close, arg.io);
}
@ -2139,22 +2269,20 @@ opt_i_get()
static void
opt_i_set(val)
struct RString *val;
VALUE val;
{
if (NIL_P(val)) {
inplace = 0;
return;
}
Check_Type(val, T_STRING);
inplace = val->ptr;
inplace = RSTRING(val)->ptr;
}
extern VALUE mEnumerable;
void
Init_IO()
{
extern VALUE mKernel;
extern VALUE mEnumerable;
extern VALUE eException;
eEOFError = rb_define_class("EOFError", eException);
@ -2166,6 +2294,7 @@ Init_IO()
rb_define_global_function("open", f_open, -1);
rb_define_global_function("printf", f_printf, -1);
rb_define_global_function("print", f_print, -1);
rb_define_global_function("puts", f_puts, -1);
rb_define_global_function("gets", f_gets_method, -1);
rb_define_global_function("readline", f_readline, -1);
rb_define_global_function("eof", f_eof, 0);
@ -2209,6 +2338,7 @@ Init_IO()
rb_define_method(cIO, "reopen", io_reopen, 1);
rb_define_method(cIO, "print", io_print, -1);
rb_define_method(cIO, "puts", io_puts, -1);
rb_define_method(cIO, "printf", io_printf, -1);
rb_define_method(cIO, "each", io_each_line, -1);
@ -2233,8 +2363,7 @@ Init_IO()
rb_define_method(cIO, "getc", io_getc, 0);
rb_define_method(cIO, "readchar", io_readchar, 0);
rb_define_method(cIO, "ungetc",io_ungetc, 1);
rb_define_method(cIO, "puts", io_puts, 1);
rb_define_method(cIO, "<<", io_puts, 1);
rb_define_method(cIO, "<<", io_addstr, 1);
rb_define_method(cIO, "flush", io_flush, 0);
rb_define_method(cIO, "eof", io_eof, 0);
rb_define_method(cIO, "eof?", io_eof, 0);
@ -2254,7 +2383,7 @@ Init_IO()
rb_stdout = prep_stdio(stdout, FMODE_WRITABLE);
rb_define_readonly_variable("$stdout", &rb_stdout);
rb_stderr = prep_stdio(stderr, FMODE_WRITABLE);
rb_define_readonly_variable("$stderr", &rb_stderr);
rb_define_hooked_variable("$stderr", &rb_stderr, 0, io_errset);
rb_defout = rb_stdout;
rb_define_hooked_variable("$>", &rb_defout, 0, io_defset);

7
io.h
View file

@ -48,6 +48,11 @@ typedef struct OpenFile {
#define GetWriteFile(fptr) (((fptr)->f2) ? (fptr)->f2 : (fptr)->f)
FILE *rb_fopen();
FILE *rb_fopen _((char *, char *));
FILE *rb_fdopen _((int, char *));
void io_writable _((OpenFile *));
void io_readable _((OpenFile *));
void io_fptr_finalize _((OpenFile *));
void io_unbuffered _((OpenFile *));
#endif

View file

@ -9,29 +9,59 @@
# foo.keys <== array of fields
# foo.inputs <== hash of { <field> => <value> }
# if running on Windows(IIS or PWS) then change cwd.
if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/ then
Dir.chdir ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, '')
end
require "shellwords.rb"
class CGI
include Shellwords
attr("inputs")
# original is CGI.pm
def read_from_cmdline
words = shellwords(if not ARGV.empty? then
ARGV.join(' ')
else
print "(offline mode: enter name=value pairs on standard input)\n"
readlines.join(' ').gsub(/\n/, '')
end.gsub(/\\=/, '%3D').gsub(/\\&/, '%26'))
if words.find{|x| x =~ /=/} then words.join('&') else words.join('+') end
end
# escape url encode
def escape(str)
str.gsub!(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
str
end
# unescape url encoded
def unescape(str)
str.gsub! /\+/, ' '
str.gsub!(/%([0-9a-fA-F]{2})/){ [$1.hex].pack("c") }
str
end
module_function :escape, :unescape
def initialize
str = if ENV['REQUEST_METHOD'] == "GET"
ENV['QUERY_STRING']
elsif ENV['REQUEST_METHOD'] == "POST"
$stdin.read ENV['CONTENT_LENGTH'].to_i
else
""
end
arr = str.split(/&/)
# exception messages should be printed to stdout.
STDERR.reopen(STDOUT)
@inputs = {}
arr.each do |x|
x.gsub!(/\+/, ' ')
key, val = x.split(/=/, 2)
val = "" unless val
key.gsub!(/%(..)/) { [$1.hex].pack("c") }
val.gsub!(/%(..)/) { [$1.hex].pack("c") }
@inputs[key] += "\0" if @inputs[key]
@inputs[key] += val
case ENV['REQUEST_METHOD']
when "GET"
ENV['QUERY_STRING'] or ""
when "POST"
$stdin.read ENV['CONTENT_LENGTH'].to_i
else
read_from_cmdline
end.split(/&/).each do |x|
key, val = x.split(/=/,2).collect{|x|unescape(x)}
@inputs[key] += ("\0" if @inputs[key]) + (val or "")
end
end
@ -53,4 +83,15 @@ class CGI
TRUE
end
def CGI.error
m = $!.dup
m.gsub!(/&/, '&amp;')
m.gsub!(/</, '&lt;')
m.gsub!(/>/, '&gt;')
msgs = ["<pre>ERROR: <strong>#{m}</strong>"]
msgs << $@
msgs << "</pre>"
CGI.message(msgs.join("\n"), "ERROR")
exit
end
end

View file

@ -1,9 +1,9 @@
#
# finalize.rb -
# $Release Version: $
# $Revision: 1.2 $
# $Date: 1997/07/25 02:43:00 $
# by Keiju ISHITSUKA(SHL Japan Inc.)
# finalizer.rb -
# $Release Version: 0.2$
# $Revision: 1.3 $
# $Date: 1998/01/09 08:09:49 $
# by Keiju ISHITSUKA
#
# --
#
@ -44,14 +44,14 @@
#
module Finalizer
RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/finalize.rb,v 1.2 1997/07/25 02:43:00 keiju Exp keiju $-'
RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/finalize.rb,v 1.3 1998/01/09 08:09:49 keiju Exp keiju $-'
# @dependency: {id => [[dependant, method, *opt], ...], ...}
# 依存関係 R_method(obj, dependant) の追加
def add_dependency(obj, dependant, method = :finalize, *opt)
ObjectSpace.call_finalizer(obj)
method = method.id unless method.kind_of?(Fixnum)
method = method.intern unless method.kind_of?(Integer)
assoc = [dependant, method].concat(opt)
if dep = @dependency[obj.id]
dep.push assoc
@ -63,8 +63,8 @@ module Finalizer
# 依存関係 R_method(obj, dependant) の削除
def delete_dependency(id, dependant, method = :finalize)
id = id.id unless id.kind_of?(Fixnum)
method = method.id unless method.kind_of?(Fixnum)
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|
@ -77,8 +77,8 @@ module Finalizer
# 依存関係 R_*(obj, dependant) の削除
def delete_all_dependency(id, dependant)
id = id.id unless id.kind_of?(Fixnum)
method = method.id unless method.kind_of?(Fixnum)
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|
@ -90,8 +90,8 @@ module Finalizer
# 依存関係 R_method(*, dependant) の削除
def delete_by_dependant(dependant, method = :finalize)
method = method.id unless method.kind_of?(Fixnum)
for id in @dependency.keys
method = method.intern unless method.kind_of?(Integer)
for id in Dependency.keys
delete(id, dependant, method)
end
end
@ -106,8 +106,8 @@ module Finalizer
# 依存関連 R_method(obj, dependtant) で結ばれるdependantをfinalizeす
# る.
def finalize_dependency(id, dependant, method = :finalize)
id = id.id unless id.kind_of?(Fixnum)
method = method.id unless method.kind_of?(Fixnum)
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|
@ -121,8 +121,8 @@ module Finalizer
# 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする.
def finalize_all_dependency(id, dependant)
id = id.id unless id.kind_of?(Fixnum)
method = method.id unless method.kind_of?(Fixnum)
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|
@ -134,7 +134,7 @@ module Finalizer
# 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする.
def finalize_by_dependant(dependant, method = :finalize)
method = method.id unless method.kind_of?(Fixnum)
method = method.intern unless method.kind_of?(Integer)
for id in @dependency.keys
finalize(id, dependant, method)
end

View file

@ -1,36 +1,35 @@
class Mail
def Mail.new(f)
unless f.kind_of?(IO)
f = open(f, "r")
me = super(f)
f.close
else
me = super
end
return me
end
def initialize(f)
@header = {}
@body = []
while f.gets()
$_.chop!
next if /^From / # skip From-line
break if /^$/ # end of header
if /^(\S+):\s*(.*)/
@header[attr = $1.capitalize!] = $2
elsif attr
sub!(/^\s*/, '')
@header[attr] += "\n" + $_
end
unless f.kind_of?(IO)
f = open(f, "r")
opened = true
end
return unless $_
@header = {}
@body = []
begin
while f.gets()
$_.chop!
next if /^From / # skip From-line
break if /^$/ # end of header
while f.gets()
break if /^From /
@body.push($_)
if /^(\S+):\s*(.*)/
@header[attr = $1.capitalize!] = $2
elsif attr
sub!(/^\s*/, '')
@header[attr] += "\n" + $_
end
end
return unless $_
while f.gets()
break if /^From /
@body.push($_)
end
ensure
f.close if opened
end
end

View file

@ -1,13 +1,19 @@
#
# sync.rb - カウント付2-フェーズロッククラス
# $Release Version: 0.1$
# $Release Version: 0.2$
# $Revision$
# $Date$
# by Keiju ISHITSUKA
#
# --
# Sync_m, Synchronizer_m
# Usage:
# Sync_m, Synchronizer_m
# obj.extend(Sync_m)
# or
# class Foo
# Sync_m.include_to self
# :
# end
#
# Sync_m#sync_mode
# Sync_m#sync_locked?, locked?
@ -19,8 +25,9 @@
#
# Sync, Synchronicer:
# include Sync_m
#
# Usage:
# sync = Sync.new
#
# Sync#mode
# Sync#locked?
# Sync#shared?
@ -36,15 +43,17 @@ unless defined? Thread
fail "Thread not available for this ruby interpreter"
end
require "finalize.rb"
require "finalize"
module Sync_m
RCS_ID='-$Header$-'
# lock mode
UN = :UN
SH = :SH
EX = :EX
# 例外定義
class Err < Exception
def Err.Fail(*opt)
fail self, sprintf(self::Message, *opt)
@ -68,21 +77,53 @@ module Sync_m
end
end
def Sync_m.extend_object(obj)
# include and extend initialize methods.
def Sync_m.extendable_module(obj)
if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj
raise TypeError, "Sync_m can't extend to this class(#{obj.type})"
else
begin
eval "class << obj
@sync_locked
end"
obj.extend(For_primitive_object)
obj.instance_eval "@sync_locked"
For_general_object
rescue TypeError
obj.extend(For_general_object)
For_primitive_object
end
end
end
def Sync_m.includable_module(cl)
begin
dummy = cl.new
Sync_m.extendable_module(dummy)
rescue NameError
# newが定義されていない時は, DATAとみなす.
For_primitive_object
end
end
def Sync_m.extend_class(cl)
return super if cl.instance_of?(Module)
# モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定
# とaliasを行う.
real = includable_module(cl)
cl.module_eval %q{
include real
alias locked? sync_locked?
alias shared? sync_shared?
alias exclusive? sync_exclusive?
alias lock sync_lock
alias unlock sync_unlock
alias try_lock sync_try_lock
alias synchronize sync_synchronize
}
end
def Sync_m.extend_object(obj)
obj.extend(Sync_m.extendable_module(obj))
end
def sync_extended
unless (defined? locked? and
defined? shared? and
@ -94,7 +135,7 @@ module Sync_m
eval "class << self
alias locked? sync_locked?
alias shared? sync_shared?
alias excluive? sync_exclusive?
alias exclusive? sync_exclusive?
alias lock sync_lock
alias unlock sync_unlock
alias try_lock sync_try_lock
@ -103,6 +144,7 @@ module Sync_m
end
end
# accessing
def sync_locked?
sync_mode != UN
end
@ -115,6 +157,7 @@ module Sync_m
sync_mode == EX
end
# locking methods.
def sync_try_lock(mode = EX)
return unlock if sync_mode == UN
@ -238,7 +281,6 @@ module Sync_m
self.sync_ex_locker = Thread.current
self.sync_ex_count = 1
ret = TRUE
elsif sync_mode == EX && sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1
ret = TRUE
@ -262,6 +304,7 @@ module Sync_m
end
end
# internal class
module For_primitive_object
include Sync_m
@ -281,12 +324,18 @@ module Sync_m
Finalizer.add(obj, For_primitive_object, :sync_finalize)
end
def sync_extended
def initialize
super
Sync_Locked[id] = LockState.new(UN, [], [], Hash.new, nil, 0 )
self
end
def sync_finalize
def sync_extended
super
initialize
end
def For_primitive_object.sync_finalize(id)
wait = Sync_Locked.delete(id)
# waiting == [] ときだけ GCされるので, 待ち行列の解放は意味がない.
end
@ -343,7 +392,7 @@ module Sync_m
obj.sync_extended
end
def sync_extended
def initialize
super
@sync_mode = UN
@sync_waiting = []
@ -351,6 +400,12 @@ module Sync_m
@sync_sh_locker = Hash.new
@sync_ex_locker = nil
@sync_ex_count = 0
self
end
def sync_extended
super
initialize
end
attr :sync_mode, TRUE
@ -366,10 +421,11 @@ end
Synchronizer_m = Sync_m
class Sync
include Sync_m::For_general_object
Sync_m.extend_class self
#include Sync_m
def initialize
sync_extended
super
end
end

573
lib/tk.rb
View file

@ -1,12 +1,483 @@
#
# tk.rb - Tk interface for ruby
# tk.rb - Tk interface modue using tcltklib
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp>
# by Yukihiro Matsumoto <matz@netlab.co.jp>
if defined? Thread and $tk_thread_safe
require "tkthcore"
else
require "tkcore"
# use Shigehiro's tcltklib
require "tcltklib"
require "tkutil"
module TkComm
None = Object.new
def None.to_s
'None'
end
Tk_CMDTBL = {}
Tk_WINDOWS = {}
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
private :error_at
def tk_tcl2ruby(val)
case val
when /^-?\d+$/
val.to_i
when /^\./
Tk_WINDOWS[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 hash_kv(keys)
conf = []
if keys and keys != None
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 :hash_kv
def bool(val)
case val
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_WINDOWS[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
Tk_IDs = [0] # [0]-cmdid, [1]-winid
def _curr_cmd_id
id = format("c%.4d", Tk_IDs[0])
end
def _next_cmd_id
id = _curr_cmd_id
Tk_IDs[0] += 1
end
def install_cmd(cmd)
return '' if cmd == ''
id = _next_cmd_id
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
def install_win(ppath)
id = format("w%.4d", Tk_IDs[0])
Tk_IDs[0] += 1
if !ppath or ppath == "."
@path = format(".%s", id);
else
@path = format("%s.%s", ppath, id)
end
Tk_WINDOWS[@path] = self
end
def uninstall_win()
Tk_WINDOWS[@path] = nil
end
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
uninstall_cmd(id)
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
def after(ms, cmd=Proc.new)
myid = _curr_cmd_id
tk_call 'after', ms,
install_cmd(proc{
TkUtil.eval_cmd cmd
uninstall_cmd myid
})
end
end
module TkCore
include TkComm
extend TkComm
INTERP = TclTkIp.new
INTERP._eval("proc rb_out {args} { ruby [format \"TkCore.callback %%Q!%s!\" $args] }")
def TkCore.callback(arg)
arg = Array(tk_split_list(arg))
TkUtil.eval_cmd Tk_CMDTBL[arg.shift], *arg
end
def mainloop
TclTkLib.mainloop
end
def _get_eval_string(*args)
argstr = ""
args.each{|arg|
next if arg == None
if arg.kind_of?(Hash)
str = hash_kv(arg).join(" ")
elsif arg == nil
str = ""
elsif arg == false
str = "0"
elsif arg == true
str = "1"
elsif (arg.respond_to?(:to_eval))
str = arg.to_eval()
else
str = arg.to_s()
end
argstr += " " if argstr != ""
argstr += '"' + str.gsub(/[][$"]/, '\\\\\&') + '"'
}
return argstr
end
def tk_call(*args)
argstr = _get_eval_string(*args)
res = INTERP._eval(argstr)
if INTERP._return_value() != 0
fail RuntimeError, res, error_at
end
return res
end
end
module Tk
include TkCore
extend Tk
def root
TkRoot.new
end
def bell
tk_call 'bell'
end
def mainloop
TclTkLib.mainloop
end
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
class TkVariable
include Tk
Tk_VARIABLE_ID = ["v00000"]
def initialize(val="")
@id = Tk_VARIABLE_ID[0]
Tk_VARIABLE_ID[0] = Tk_VARIABLE_ID[0].succ
INTERP._eval(format('global %s; set %s %s', @id, @id, _get_eval_string(val)))
end
def id
@id
end
def value
INTERP._eval(format('global %s; set %s', @id, @id))
end
def value=(val)
INTERP._eval(format('global %s; set %s %s', @id, @id, _get_eval_string(val)))
end
def to_i
Integer(number(value))
end
def to_f
Float(number(value))
end
def to_s
String(string(value))
end
def inspect
format "<TkVariable: %s>", @id
end
def ==(other)
case other
when TkVariable
self.equal(self)
when String
self.to_s == other
when Integer
self.to_i == other
when Float
self.to_f == other
when Array
self.to_a == other
else
false
end
end
def to_a
list(value)
end
def to_eval
@id
end
end
module TkSelection
@ -290,7 +761,7 @@ module TkPack
end
def propagate(master, bool=None)
bool(tk_call('pack', 'propagate', mastaer.epath, bool))
bool(tk_call('pack', 'propagate', master.epath, bool))
end
module_function :configure, :forget, :propagate
end
@ -324,6 +795,10 @@ class TkObject<TkKernel
return @path
end
def to_eval
@path
end
def tk_send(cmd, *rest)
tk_call path, cmd, *rest
end
@ -372,60 +847,10 @@ class TkObject<TkKernel
end
end
class TkVariable
include Tk
$tk_variable_id = "v00000"
def initialize(val="")
@id = $tk_variable_id
$tk_variable_id = $tk_variable_id.succ
tk_call(format('global %s; set %s', @id, @id), val)
end
def id
@id
end
def value
tk_call(format('global %s; set', @id), @id)
end
def value=(val)
tk_call(format('global %s; set %s', @id, @id), val)
end
def to_i
Integer(number(value))
end
def to_f
Float(number(value))
end
def to_s
String(string(value))
end
def inspect
format "<TkVariable: %s>", @id
end
def to_a
list(value)
end
end
class TkWindow<TkObject
$tk_window_id = "w00000"
def initialize(parent=nil, keys=nil)
id = $tk_window_id
$tk_window_id = $tk_window_id.succ
if !parent or parent == Tk.root
@path = format(".%s", id);
else
@path = format("%s.%s", parent.path, id)
end
$tk_window_list[@path] = self
install_win(if parent then parent.path end)
create_self
if keys
tk_call @path, 'configure', *hash_kv(keys)
@ -527,30 +952,32 @@ class TkWindow<TkObject
uninstall_cmd id
end
end
$tk_window_list[path] = nil
super
uninstall_win
end
end
class TkRoot<TkWindow
include Wm
ROOT = []
def TkRoot.new
return $tk_root if $tk_root
super
return ROOT[0] if ROOT[0]
new = super
ROOT[0] = new
end
def create_self
@path = '.'
end
def path
"."
end
$tk_root = TkRoot.new
$tk_window_list['.'] = $tk_root
end
class TkToplevel<TkWindow
include Wm
def initialize(parent=nil, screen=nil, classname=nil)
def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
@screen = screen if screen
@classname = classname if classname
super
super(parent, keys)
end
def create_self
@ -661,7 +1088,7 @@ class TkScrollbar<TkWindow
ary1 = tk_send('get', path).split
ary2 = []
for i in ary1
push number(i)
ary2.push number(i)
end
ary2
end
@ -671,7 +1098,6 @@ class TkScrollbar<TkWindow
end
end
# abstract class for Text and Listbox
class TkTextWin<TkWindow
def bbox(index)
tk_send 'bbox', index
@ -682,9 +1108,6 @@ class TkTextWin<TkWindow
def get(*index)
tk_send 'get', *index
end
def insert(index, *rest)
tk_send 'insert', index, *rest
end
def index(index)
tk_send 'index', index
end
@ -793,8 +1216,10 @@ module TkComposite
private :initialize_composite
def delegate(option, *wins)
@delegates = {} if not @delegates
@delegates['DEFAULT'] = @frame
unless @delegates
@delegates = {}
@delegates['DEFAULT'] = @frame
end
if option.kind_of?(String)
@delegates[option] = wins
else

View file

@ -131,7 +131,7 @@ class TkTextMark<TkObject
@t = parent
@path = @id = $tk_text_mark
$tk_text_mark = $tk_text_mark.succ
tk_call @t.path, 'set', @id, index
tk_call @t.path, 'mark', 'set', @id, index
@t._addtag id, self
end
def id
@ -139,7 +139,7 @@ class TkTextMark<TkObject
end
def set(where)
tk_call @t.path, 'mark', 'unset', @id, where
tk_call @t.path, 'mark', 'set', @id, where
end
def unset

52
math.c
View file

@ -14,16 +14,8 @@
#include <math.h>
VALUE mMath;
VALUE float_new();
VALUE f_float();
#define Need_Float(x) \
if (FIXNUM_P(x)) {\
(x) = (struct RFloat*)float_new((double)FIX2INT(x));\
} else {\
(x) = (struct RFloat*)f_float(x, x);\
}
#define Need_Float(x) (x) = rb_Float(x)
#define Need_Float2(x,y) {\
Need_Float(x);\
Need_Float(y);\
@ -31,79 +23,71 @@ if (FIXNUM_P(x)) {\
static VALUE
math_atan2(obj, x, y)
VALUE obj;
struct RFloat *x, *y;
VALUE obj, x, y;
{
Need_Float2(x, y);
return float_new(atan2(x->value, y->value));
return float_new(atan2(RFLOAT(x)->value, RFLOAT(y)->value));
}
static VALUE
math_cos(obj, x)
VALUE obj;
struct RFloat *x;
VALUE obj, x;
{
Need_Float(x);
return float_new(cos(x->value));
return float_new(cos(RFLOAT(x)->value));
}
static VALUE
math_sin(obj, x)
VALUE obj;
struct RFloat *x;
VALUE obj, x;
{
Need_Float(x);
return float_new(sin(x->value));
return float_new(sin(RFLOAT(x)->value));
}
static VALUE
math_tan(obj, x)
VALUE obj;
struct RFloat *x;
VALUE obj, x;
{
Need_Float(x);
return float_new(tan(x->value));
return float_new(tan(RFLOAT(x)->value));
}
static VALUE
math_exp(obj, x)
VALUE obj;
struct RFloat *x;
VALUE obj, x;
{
Need_Float(x);
return float_new(exp(x->value));
return float_new(exp(RFLOAT(x)->value));
}
static VALUE
math_log(obj, x)
VALUE obj;
struct RFloat *x;
VALUE obj, x;
{
Need_Float(x);
return float_new(log(x->value));
return float_new(log(RFLOAT(x)->value));
}
static VALUE
math_log10(obj, x)
VALUE obj;
struct RFloat *x;
VALUE obj, x;
{
Need_Float(x);
return float_new(log10(x->value));
return float_new(log10(RFLOAT(x)->value));
}
static VALUE
math_sqrt(obj, x)
VALUE obj;
struct RFloat *x;
VALUE obj, x;
{
Need_Float(x);
if (x->value < 0.0) ArgError("square root for negative number");
return float_new(sqrt(x->value));
if (RFLOAT(x)->value < 0.0) ArgError("square root for negative number");
return float_new(sqrt(RFLOAT(x)->value));
}
void

View file

@ -183,66 +183,3 @@ 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 $
*
* (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 $
* Revision 4.0.1.1 91/06/07 11:22:10 lwall
* patch4: new copyright notice
*
* Revision 4.0 91/03/20 01:34:20 lwall
* 4.0 baseline.
*
* Revision 3.0.1.1 90/03/27 16:07:08 lwall
* patch16: MSDOS support
*
* Revision 1.1 90/03/18 20:32:29 dds
* Initial revision
*
*
*/
/*
* defines the type returned by the directory(3) functions
*/
#ifndef __DIR_INCLUDED
#define __DIR_INCLUDED
/*Directory entry size */
#ifdef DIRSIZ
#undef DIRSIZ
#endif
#define DIRSIZ(rp) (sizeof(struct direct))
/*
* Structure of a directory entry
*/
struct direct {
ino_t d_ino; /* inode number (not used by MS-DOS) */
int d_namlen; /* Name length */
char d_name[256]; /* file name */
};
struct _dir_struc { /* Structure used by dir operations */
char *start; /* Starting position */
char *curr; /* Current position */
long size; /* Size of string table */
long nfiles; /* number if filenames in table */
struct direct dirstr; /* Directory structure to return */
};
typedef struct _dir_struc DIR; /* Type returned by dir operations */
DIR *cdecl opendir(char *filename);
struct direct *readdir(DIR *dirp);
long telldir(DIR *dirp);
void seekdir(DIR *dirp,long loc);
void rewinddir(DIR *dirp);
void closedir(DIR *dirp);
#endif /* __DIR_INCLUDED */

View file

@ -149,8 +149,8 @@ flock(int fd, int oper)
#undef LK_LEN
#undef const
FILE *fdopen(int, const char *);
//#undef const
//FILE *fdopen(int, const char *);
#if 0
void
@ -185,7 +185,7 @@ NtInitialize(int *argc, char ***argv) {
tzset();
// Initialize Winsock
// StartSockets();
StartSockets();
}
@ -501,7 +501,6 @@ mypopen (char *cmd, char *mode)
return fp;
}
fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
if (!fRet)
Fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));
@ -1572,7 +1571,7 @@ valid_filename(char *s)
//
FILE *
fdopen (int fd, const char *mode)
myfdopen (int fd, const char *mode)
{
FILE *fp;
char sockbuf[80];
@ -1580,6 +1579,8 @@ fdopen (int fd, const char *mode)
int retval;
extern int errno;
//fprintf(stderr, "myfdopen()\n");
retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
if (retval == SOCKET_ERROR) {
int iRet;
@ -1951,8 +1952,10 @@ mysocket (int af, int type, int protocol)
if (!NtSocketsInitialized++) {
StartSockets();
}
if ((s = socket (af, type, protocol)) == INVALID_SOCKET)
if ((s = socket (af, type, protocol)) == INVALID_SOCKET) {
errno = WSAGetLastError();
//fprintf(stderr, "socket fail (%d)", WSAGetLastError());
}
return s;
}

View file

@ -147,6 +147,29 @@ extern char *NtGetLib(void);
extern char *NtGetBin(void);
extern FILE *mypopen(char *, char *);
extern int flock(int fd, int oper);
extern FILE * myfdopen(int, char*);
extern SOCKET myaccept(SOCKET, struct sockaddr *, int *);
extern int mybind(SOCKET, struct sockaddr *, int);
extern int myconnect(SOCKET, struct sockaddr *, int);
extern int mygetpeername(SOCKET, struct sockaddr *, int *);
extern int mygetsockname(SOCKET, struct sockaddr *, int *);
extern int mygetsockopt(SOCKET, int, int, char *, int *);
extern int myioctlsocket(SOCKET, long, u_long *);
extern int mylisten(SOCKET, int);
extern int myrecv(SOCKET, char *, int, int);
extern int myrecvfrom(SOCKET, char *, int, int, struct sockaddr *, int *);
extern int mysend(SOCKET, char *, int, int);
extern int mysendto(SOCKET, char *, int, int, struct sockaddr *, int);
extern int mysetsockopt(SOCKET, int, int, char *, int);
extern int myshutdown(SOCKET, int);
extern SOCKET mysocket(int, int, int);
extern struct hostent * mygethostbyaddr(char *, int, int);
extern struct hostent * mygethostbyname(char *);
extern int mygethostname(char *, int);
extern struct protoent * mygetprotobyname(char *);
extern struct protoent * mygetprotobynumber(int);
extern struct servent * mygetservbyname(char *, char *);
extern struct servent * mygetservbyport(int, char *);
//
// define this so we can do inplace editing
@ -222,4 +245,118 @@ extern char *mystrerror(int);
#undef va_start
#undef va_end
#ifdef fdopen
#undef fdopen
#endif
#define fdopen myfdopen
#ifdef accept
#undef accept
#endif
#define accept myaccept
#ifdef bind
#undef bind
#endif
#define bind mybind
#ifdef connect
#undef connect
#endif
#define connect myconnect
#ifdef getpeername
#undef getpeername
#endif
#define getpeername mygetpeername
#ifdef getsockname
#undef getsockname
#endif
#define getsockname mygetsockname
#ifdef getsockopt
#undef getsockopt
#endif
#define getsockopt mygetsockopt
#ifdef ioctlsocket
#undef ioctlsocket
#endif
#define ioctlsocket myioctlsocket
#ifdef listen
#undef listen
#endif
#define listen mylisten
#ifdef recv
#undef recv
#endif
#define recv myrecv
#ifdef recvfrom
#undef recvfrom
#endif
#define recvfrom myrecvfrom
#ifdef send
#undef send
#endif
#define send mysend
#ifdef sendto
#undef sendto
#endif
#define sendto mysendto
#ifdef setsockopt
#undef setsockopt
#endif
#define setsockopt mysetsockopt
#ifdef shutdown
#undef shutdown
#endif
#define shutdown myshutdown
#ifdef socket
#undef socket
#endif
#define socket mysocket
#ifdef gethostbyaddr
#undef gethostbyaddr
#endif
#define gethostbyaddr mygethostbyaddr
#ifdef gethostbyname
#undef gethostbyname
#endif
#define gethostbyname mygethostbyname
#ifdef gethostname
#undef gethostname
#endif
#define gethostname mygethostname
#ifdef getprotobyname
#undef getprotobyname
#endif
#define getprotobyname mygetprotobyname
#ifdef getprotobynumber
#undef getprotobynumber
#endif
#define getprotobynumber mygetprotobynumber
#ifdef getservbyname
#undef getservbyname
#endif
#define getservbyname mygetservbyname
#ifdef getservbyport
#undef getservbyport
#endif
#define getservbyport mygetservbyport
#endif

View file

@ -16,6 +16,10 @@ extern char **origenviron;
char *strdup();
#endif
#ifdef USE_WIN32_RTL_ENV
#include <stdlib.h>
#endif
static int
envix(nam)
char *nam;
@ -29,9 +33,11 @@ char *nam;
return i;
}
#ifndef WIN32
void
setenv(nam,val)
setenv(nam,val, n)
char *nam, *val;
int n;
{
register int i=envix(nam); /* where does it go? */
@ -75,3 +81,69 @@ char *nam, *val;
(void)sprintf(environ[i] + strlen(nam),"=%s",val);
#endif /* MSDOS */
}
#else /* if WIN32 */
void
setenv(nam,val, n)
char *nam, *val;
int n;
{
#ifdef USE_WIN32_RTL_ENV
register char *envstr;
STRLEN namlen = strlen(nam);
STRLEN vallen;
char *oldstr = environ[envix(nam)];
/* putenv() has totally broken semantics in both the Borland
* and Microsoft CRTLs. They either store the passed pointer in
* the environment without making a copy, or make a copy and don't
* free it. And on top of that, they dont free() old entries that
* are being replaced/deleted. This means the caller must
* free any old entries somehow, or we end up with a memory
* leak every time setenv() is called. One might think
* one could directly manipulate environ[], like the UNIX code
* above, but direct changes to environ are not allowed when
* calling putenv(), since the RTLs maintain an internal
* *copy* of environ[]. Bad, bad, *bad* stink.
* GSAR 97-06-07
*/
if (!val) {
if (!oldstr)
return;
val = "";
vallen = 0;
}
else
vallen = strlen(val);
envstr = ALLOC_N(char, namelen + vallen + 3);
(void)sprintf(envstr,"%s=%s",nam,val);
(void)putenv(envstr);
if (oldstr)
free(oldstr);
#ifdef _MSC_VER
free(envstr); /* MSVCRT leaks without this */
#endif
#else /* !USE_WIN32_RTL_ENV */
/* The sane way to deal with the environment.
* Has these advantages over putenv() & co.:
* * enables us to store a truly empty value in the
* environment (like in UNIX).
* * we don't have to deal with RTL globals, bugs and leaks.
* * Much faster.
* Why you may want to enable USE_WIN32_RTL_ENV:
* * environ[] and RTL functions will not reflect changes,
* which might be an issue if extensions want to access
* the env. via RTL. This cuts both ways, since RTL will
* not see changes made by extensions that call the Win32
* functions directly, either.
* GSAR 97-06-07
*/
SetEnvironmentVariable(nam,val);
#endif
}
#endif /* WIN32 */

43
node.h
View file

@ -13,8 +13,6 @@
#ifndef NODE_H
#define NODE_H
struct global_entry *rb_global_entry();
enum node_type {
NODE_METHOD,
NODE_FBODY,
@ -29,6 +27,10 @@ enum node_type {
NODE_UNTIL,
NODE_ITER,
NODE_FOR,
NODE_BREAK,
NODE_NEXT,
NODE_REDO,
NODE_RETRY,
NODE_BEGIN,
NODE_RESCUE,
NODE_RESBODY,
@ -64,6 +66,8 @@ enum node_type {
NODE_MATCH_REF,
NODE_LASTLINE,
NODE_MATCH,
NODE_MATCH2,
NODE_MATCH3,
NODE_LIT,
NODE_STR,
NODE_DSTR,
@ -91,14 +95,17 @@ enum node_type {
NODE_ATTRSET,
NODE_SELF,
NODE_NIL,
NODE_TRUE,
NODE_FALSE,
NODE_DEFINED,
NODE_TAG,
NODE_NEWLINE,
NODE_POSTEXE,
};
typedef struct RNode {
UINT flags;
char *file;
char *nd_file;
union {
struct RNode *node;
ID id;
@ -185,7 +192,7 @@ typedef struct RNode {
#define nd_argc u2.argc
#define nd_cname u1.id
#define nd_super u3.id
#define nd_super u3.node
#define nd_modl u1.id
#define nd_clss u1.value
@ -201,8 +208,6 @@ typedef struct RNode {
#define nd_tlev u3.cnt
#define nd_tval u2.value
#define nd_file file
#define NEW_METHOD(n,x) node_newnode(NODE_METHOD,x,n,0)
#define NEW_FBODY(n,i,o) node_newnode(NODE_FBODY,n,i,o)
#define NEW_DEFN(i,a,d,p) node_newnode(NODE_DEFN,p,i,NEW_RFUNC(a,d))
@ -220,6 +225,10 @@ typedef struct RNode {
#define NEW_UNTIL(c,b,n) node_newnode(NODE_UNTIL,c,b,n)
#define NEW_FOR(v,i,b) node_newnode(NODE_FOR,v,b,i)
#define NEW_ITER(v,i,b) node_newnode(NODE_ITER,v,b,i)
#define NEW_BREAK() node_newnode(NODE_BREAK,0,0,0)
#define NEW_NEXT() node_newnode(NODE_NEXT,0,0,0)
#define NEW_REDO() node_newnode(NODE_REDO,0,0,0)
#define NEW_RETRY() node_newnode(NODE_RETRY,0,0,0)
#define NEW_BEGIN(b) node_newnode(NODE_BEGIN,0,b,0)
#define NEW_RESCUE(b,res) node_newnode(NODE_RESCUE,b,res,0)
#define NEW_RESBODY(a,ex,n) node_newnode(NODE_RESBODY,n,ex,a)
@ -248,6 +257,8 @@ typedef struct RNode {
#define NEW_NTH_REF(n) node_newnode(NODE_NTH_REF,0,n,local_cnt('~'))
#define NEW_BACK_REF(n) node_newnode(NODE_BACK_REF,0,n,local_cnt('~'))
#define NEW_MATCH(c) node_newnode(NODE_MATCH,c,0,0)
#define NEW_MATCH2(n1,n2) node_newnode(NODE_MATCH2,n1,n2,0)
#define NEW_MATCH3(r,n2) node_newnode(NODE_MATCH3,r,n2,0)
#define NEW_LIT(l) node_newnode(NODE_LIT,l,0,0)
#define NEW_STR(s) node_newnode(NODE_STR,s,0,0)
#define NEW_DSTR(s) node_newnode(NODE_DSTR,s,0,0)
@ -275,8 +286,12 @@ typedef struct RNode {
#define NEW_ATTRSET(a) node_newnode(NODE_ATTRSET,a,0,0)
#define NEW_SELF() node_newnode(NODE_SELF,0,0,0)
#define NEW_NIL() node_newnode(NODE_NIL,0,0,0)
#define NEW_TRUE() node_newnode(NODE_TRUE,0,0,0)
#define NEW_FALSE() node_newnode(NODE_FALSE,0,0,0)
#define NEW_DEFINED(e) node_newnode(NODE_DEFINED,e,0,0)
#define NEW_NEWLINE(n) node_newnode(NODE_NEWLINE,0,0,n)
#define NEW_PREEXE(b) NEW_SCOPE(b)
#define NEW_POSTEXE() node_newnode(NODE_POSTEXE,0,0,0)
NODE *node_newnode();
VALUE rb_method_booundp();
@ -284,7 +299,19 @@ VALUE rb_method_booundp();
#define NOEX_PUBLIC 0
#define NOEX_PRIVATE 1
NODE *compile_string();
NODE *compile_file();
NODE *compile_string _((char *, char *, int));
NODE *compile_file _((char *, VALUE, int));
void rb_add_method _((VALUE, ID, NODE *, int));
void rb_remove_method _((VALUE, ID));
NODE *node_newnode();
enum node_type nodetype _((NODE *));
int nodeline _((NODE *));
struct global_entry *rb_global_entry _((ID));
VALUE rb_gvar_get _((struct global_entry *));
VALUE rb_gvar_set _((struct global_entry *, VALUE));
VALUE rb_gvar_defined _((struct global_entry *));
#endif

176
numeric.c
View file

@ -12,11 +12,6 @@
#include "ruby.h"
#include <math.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif
static ID coerce;
static ID to_i;
@ -42,7 +37,7 @@ static VALUE
num_coerce(x, y)
VALUE x, y;
{
return assoc_new(f_float(x,x),f_float(y,y));
return assoc_new(rb_Float(x),rb_Float(y));
}
VALUE
@ -116,7 +111,7 @@ num_chr(num)
VALUE num;
{
char c;
int i = NUM2INT(num);
INT i = NUM2INT(num);
if (i < 0 || 0xff < i)
Fail("%d out of char range", i);
@ -147,11 +142,11 @@ float_new(d)
static VALUE
flo_to_s(flt)
struct RFloat *flt;
VALUE flt;
{
char buf[32];
sprintf(buf, "%g", flt->value);
sprintf(buf, "%g", RFLOAT(flt)->value);
if (strchr(buf, '.') == 0) {
int len = strlen(buf);
char *ind = strchr(buf, 'e');
@ -172,27 +167,27 @@ static VALUE
flo_coerce(x, y)
VALUE x, y;
{
return assoc_new(f_float(x, y), x);
return assoc_new(rb_Float(y), x);
}
static VALUE
flo_uminus(flt)
struct RFloat *flt;
VALUE flt;
{
return float_new(-flt->value);
return float_new(-RFLOAT(flt)->value);
}
static VALUE
flo_plus(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
return float_new(x->value + (double)FIX2INT(y));
return float_new(RFLOAT(x)->value + (double)FIX2INT(y));
case T_BIGNUM:
return float_new(x->value + big2dbl(y));
return float_new(RFLOAT(x)->value + big2dbl(y));
case T_FLOAT:
return float_new(x->value + y->value);
return float_new(RFLOAT(x)->value + RFLOAT(y)->value);
case T_STRING:
return str_plus(obj_as_string(x), y);
default:
@ -202,15 +197,15 @@ flo_plus(x, y)
static VALUE
flo_minus(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
return float_new(x->value - (double)FIX2INT(y));
return float_new(RFLOAT(x)->value - (double)FIX2INT(y));
case T_BIGNUM:
return float_new(x->value - big2dbl(y));
return float_new(RFLOAT(x)->value - big2dbl(y));
case T_FLOAT:
return float_new(x->value - y->value);
return float_new(RFLOAT(x)->value - RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@ -218,17 +213,17 @@ flo_minus(x, y)
static VALUE
flo_mul(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
return float_new(x->value * (double)FIX2INT(y));
return float_new(RFLOAT(x)->value * (double)FIX2INT(y));
case T_BIGNUM:
return float_new(x->value * big2dbl(y));
return float_new(RFLOAT(x)->value * big2dbl(y));
case T_FLOAT:
return float_new(x->value * y->value);
return float_new(RFLOAT(x)->value * RFLOAT(y)->value);
case T_STRING:
return str_times(y, INT2FIX((int)x->value));
return str_times(y, INT2FIX((int)RFLOAT(x)->value));
default:
return num_coerce_bin(x, y);
}
@ -236,23 +231,23 @@ flo_mul(x, y)
static VALUE
flo_div(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
int f_y;
INT f_y;
double d;
switch (TYPE(y)) {
case T_FIXNUM:
f_y = FIX2INT(y);
if (f_y == 0) num_zerodiv();
return float_new(x->value / (double)f_y);
return float_new(RFLOAT(x)->value / (double)f_y);
case T_BIGNUM:
d = big2dbl(y);
if (d == 0.0) num_zerodiv();
return float_new(x->value / d);
return float_new(RFLOAT(x)->value / d);
case T_FLOAT:
if (y->value == 0.0) num_zerodiv();
return float_new(x->value / y->value);
if (RFLOAT(y)->value == 0.0) num_zerodiv();
return float_new(RFLOAT(x)->value / RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@ -260,7 +255,7 @@ flo_div(x, y)
static VALUE
flo_mod(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
double value;
@ -272,16 +267,16 @@ flo_mod(x, y)
value = big2dbl(y);
break;
case T_FLOAT:
value = y->value;
value = RFLOAT(y)->value;
break;
default:
return num_coerce_bin(x, y);
}
#ifdef HAVE_FMOD
value = fmod(x->value, value);
value = fmod(RFLOAT(x)->value, value);
#else
{
double value1 = x->value;
double value1 = RFLOAT(x)->value;
double value2;
modf(value1/value, &value2);
@ -294,15 +289,15 @@ flo_mod(x, y)
VALUE
flo_pow(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
return float_new(pow(x->value, (double)FIX2INT(y)));
return float_new(pow(RFLOAT(x)->value, (double)FIX2INT(y)));
case T_BIGNUM:
return float_new(pow(x->value, big2dbl(y)));
return float_new(pow(RFLOAT(x)->value, big2dbl(y)));
case T_FLOAT:
return float_new(pow(x->value, y->value));
return float_new(pow(RFLOAT(x)->value, RFLOAT(y)->value));
default:
return num_coerce_bin(x, y);
}
@ -327,16 +322,16 @@ num_equal(x, y)
static VALUE
flo_eq(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
if (x->value == FIX2INT(y)) return TRUE;
if (RFLOAT(x)->value == FIX2INT(y)) return TRUE;
return FALSE;
case T_BIGNUM:
return (x->value == big2dbl(y))?TRUE:FALSE;
return (RFLOAT(x)->value == big2dbl(y))?TRUE:FALSE;
case T_FLOAT:
return (x->value == y->value)?TRUE:FALSE;
return (RFLOAT(x)->value == RFLOAT(y)->value)?TRUE:FALSE;
default:
return num_equal(x, y);
}
@ -344,13 +339,13 @@ flo_eq(x, y)
static VALUE
flo_hash(num)
struct RFloat *num;
VALUE num;
{
double d;
char *c;
int i, hash;
d = num->value;
d = RFLOAT(num)->value;
c = (char*)&d;
for (hash=0, i=0; i<sizeof(double);i++) {
hash += c[i] * 971;
@ -361,11 +356,11 @@ flo_hash(num)
static VALUE
flo_cmp(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
double a, b;
a = x->value;
a = RFLOAT(x)->value;
switch (TYPE(y)) {
case T_FIXNUM:
b = (double)FIX2INT(y);
@ -376,7 +371,7 @@ flo_cmp(x, y)
break;
case T_FLOAT:
b = y->value;
b = RFLOAT(y)->value;
break;
default:
@ -389,19 +384,20 @@ flo_cmp(x, y)
static VALUE
flo_eql(x, y)
struct RFloat *x, *y;
VALUE x, y;
{
if (TYPE(y) == T_FLOAT) {
if (x->value == y->value) return TRUE;
if (RFLOAT(x)->value == RFLOAT(y)->value) return TRUE;
}
return FALSE;
}
static VALUE
flo_to_i(num)
struct RFloat *num;
VALUE num;
{
double f = num->value;
int val;
double f = RFLOAT(num)->value;
INT val;
if (!FIXABLE(f)) {
return dbl2big(f);
@ -419,9 +415,9 @@ flo_to_f(num)
static VALUE
flo_abs(flt)
struct RFloat *flt;
VALUE flt;
{
double val = fabs(flt->value);
double val = fabs(RFLOAT(flt)->value);
return float_new(val);
}
@ -472,7 +468,7 @@ VALUE
num2fix(val)
VALUE val;
{
int v;
INT v;
if (NIL_P(val)) return INT2FIX(0);
switch (TYPE(val)) {
@ -515,12 +511,12 @@ fix2str(x, base)
VALUE x;
int base;
{
char fmt[3], buf[12];
char fmt[4], buf[22];
fmt[0] = '%'; fmt[2] = '\0';
if (base == 10) fmt[1] = 'd';
else if (base == 16) fmt[1] = 'x';
else if (base == 8) fmt[1] = 'o';
fmt[0] = '%'; fmt[1] = 'l'; fmt[3] = '\0';
if (base == 10) fmt[2] = 'd';
else if (base == 16) fmt[2] = 'x';
else if (base == 8) fmt[2] = 'o';
else Fatal("fixnum cannot treat base %d", base);
sprintf(buf, fmt, FIX2INT(x));
@ -536,13 +532,12 @@ fix_to_s(in)
static VALUE
fix_plus(x, y)
VALUE x;
struct RFloat *y;
VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
{
int a, b, c;
INT a, b, c;
VALUE r;
a = FIX2INT(x);
@ -556,7 +551,7 @@ fix_plus(x, y)
return r;
}
case T_FLOAT:
return float_new((double)FIX2INT(x) + y->value);
return float_new((double)FIX2INT(x) + RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@ -564,13 +559,12 @@ fix_plus(x, y)
static VALUE
fix_minus(x, y)
VALUE x;
struct RFloat *y;
VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
{
int a, b, c;
INT a, b, c;
VALUE r;
a = FIX2INT(x);
@ -584,7 +578,7 @@ fix_minus(x, y)
return r;
}
case T_FLOAT:
return float_new((double)FIX2INT(x) - y->value);
return float_new((double)FIX2INT(x) - RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@ -592,13 +586,12 @@ fix_minus(x, y)
static VALUE
fix_mul(x, y)
VALUE x;
struct RFloat *y;
VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
{
int a, b, c;
INT a, b, c;
VALUE r;
a = FIX2INT(x);
@ -614,7 +607,7 @@ fix_mul(x, y)
return r;
}
case T_FLOAT:
return float_new((double)FIX2INT(x) * y->value);
return float_new((double)FIX2INT(x) * RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@ -622,10 +615,9 @@ fix_mul(x, y)
static VALUE
fix_div(x, y)
VALUE x;
struct RFloat *y;
VALUE x, y;
{
int i;
INT i;
if (TYPE(y) == T_FIXNUM) {
i = FIX2INT(y);
@ -640,7 +632,7 @@ static VALUE
fix_mod(x, y)
VALUE x, y;
{
int i;
INT i;
if (TYPE(y) == T_FIXNUM) {
i = FIX2INT(y);
@ -656,7 +648,7 @@ fix_pow(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
int a, b;
INT a, b;
b = FIX2INT(y);
if (b == 0) return INT2FIX(1);
@ -689,7 +681,7 @@ fix_cmp(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
int a = FIX2INT(x), b = FIX2INT(y);
INT a = FIX2INT(x), b = FIX2INT(y);
if (a == b) return INT2FIX(0);
if (a > b) return INT2FIX(1);
@ -705,7 +697,7 @@ fix_gt(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
int a = FIX2INT(x), b = FIX2INT(y);
INT a = FIX2INT(x), b = FIX2INT(y);
if (a > b) return TRUE;
return FALSE;
@ -720,7 +712,7 @@ fix_ge(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
int a = FIX2INT(x), b = FIX2INT(y);
INT a = FIX2INT(x), b = FIX2INT(y);
if (a >= b) return TRUE;
return FALSE;
@ -735,7 +727,7 @@ fix_lt(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
int a = FIX2INT(x), b = FIX2INT(y);
INT a = FIX2INT(x), b = FIX2INT(y);
if (a < b) return TRUE;
return FALSE;
@ -750,7 +742,7 @@ fix_le(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
int a = FIX2INT(x), b = FIX2INT(y);
INT a = FIX2INT(x), b = FIX2INT(y);
if (a <= b) return TRUE;
return FALSE;
@ -876,14 +868,14 @@ static VALUE
fix_type(fix)
VALUE fix;
{
return str_new2("Fixnum");
return cFixnum;
}
static VALUE
fix_abs(fix)
VALUE fix;
{
int i = FIX2INT(fix);
INT i = FIX2INT(fix);
if (i < 0) i = -i;
@ -903,7 +895,7 @@ static VALUE
fix_succ(fix)
VALUE fix;
{
int i = FIX2INT(fix) + 1;
INT i = FIX2INT(fix) + 1;
return int2inum(i);
}
@ -912,7 +904,7 @@ static VALUE
fix_size(fix)
VALUE fix;
{
return INT2FIX(sizeof(VALUE));
return INT2FIX(sizeof(INT));
}
VALUE
@ -951,7 +943,7 @@ num_step(from, to, step)
ID cmp;
if (step == INT2FIX(0)) {
IndexError("step cannot be 0");
ArgError("step cannot be 0");
}
if (RTEST(rb_funcall(step, '>', 1, INT2FIX(0)))) {
@ -986,7 +978,7 @@ VALUE
fix_upto(from, to)
VALUE from, to;
{
int i, end;
INT i, end;
if (!FIXNUM_P(to)) return num_upto(from, to);
end = FIX2INT(to);
@ -1001,7 +993,7 @@ static VALUE
fix_downto(from, to)
VALUE from, to;
{
int i, end;
INT i, end;
if (!FIXNUM_P(to)) return num_downto(from, to);
end = FIX2INT(to);
@ -1016,7 +1008,7 @@ static VALUE
fix_step(from, to, step)
VALUE from, to, step;
{
int i, end, diff;
INT i, end, diff;
if (!FIXNUM_P(to) || !FIXNUM_P(step))
return num_step(from, to, step);
@ -1044,7 +1036,7 @@ static VALUE
fix_dotimes(num)
VALUE num;
{
int i, end;
INT i, end;
end = FIX2INT(num);
for (i=0; i<end; i++) {

397
object.c
View file

@ -18,7 +18,7 @@ VALUE mKernel;
VALUE cObject;
VALUE cModule;
VALUE cClass;
VALUE cFixnum;
extern VALUE cFixnum;
VALUE cData;
static VALUE cNilClass;
@ -72,14 +72,19 @@ static VALUE
obj_id(obj)
VALUE obj;
{
return obj | FIXNUM_FLAG;
return INT2NUM((int)obj);
}
static VALUE
obj_type(obj)
struct RBasic *obj;
VALUE obj;
{
return rb_class_path(CLASS_OF(obj));
VALUE cl = CLASS_OF(obj);
if (FL_TEST(cl, FL_SINGLETON)) {
cl = RCLASS(cl)->super;
}
return cl;
}
static VALUE
@ -91,13 +96,13 @@ obj_clone(obj)
if (TYPE(obj) != T_OBJECT) {
TypeError("can't clone %s", rb_class2name(CLASS_OF(obj)));
}
clone = obj_alloc(RBASIC(obj)->class);
CLONESETUP(clone,obj);
if (ROBJECT(obj)->iv_tbl) {
ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl);
}
RBASIC(clone)->class = singleton_class_clone(RBASIC(obj)->class);
RBASIC(clone)->flags = RBASIC(obj)->flags;
}
return clone;
}
@ -130,15 +135,15 @@ static int
inspect_i(id, value, str)
ID id;
VALUE value;
struct RString *str;
VALUE str;
{
VALUE str2;
char *ivname;
/* need not to show internal data */
if (CLASS_OF(value) == 0) return ST_CONTINUE;
if (str->ptr[0] == '-') {
str->ptr[0] = '#';
if (RSTRING(str)->ptr[0] == '-') {
RSTRING(str)->ptr[0] = '#';
str_cat(str, ": ", 2);
}
else {
@ -160,17 +165,18 @@ inspect_i(id, value, str)
static VALUE
obj_inspect(obj)
struct RObject *obj;
VALUE obj;
{
if (TYPE(obj) == T_OBJECT
&& obj->iv_tbl && obj->iv_tbl->num_entries > 0) {
&& ROBJECT(obj)->iv_tbl
&& ROBJECT(obj)->iv_tbl->num_entries > 0) {
VALUE str;
char *b;
str = str_new2("-<");
b = rb_class2name(CLASS_OF(obj));
str_cat(str, b, strlen(b));
st_foreach(obj->iv_tbl, inspect_i, str);
st_foreach(ROBJECT(obj)->iv_tbl, inspect_i, str);
str_cat(str, ">", 1);
return str;
@ -182,7 +188,7 @@ VALUE
obj_is_instance_of(obj, c)
VALUE obj, c;
{
struct RClass *class = (struct RClass*)CLASS_OF(obj);
VALUE cl;
switch (TYPE(c)) {
case T_MODULE:
@ -205,10 +211,11 @@ obj_is_instance_of(obj, c)
TypeError("class or module required");
}
while (FL_TEST(class, FL_SINGLETON)) {
class = class->super;
cl = CLASS_OF(obj);
while (FL_TEST(cl, FL_SINGLETON)) {
cl = RCLASS(cl)->super;
}
if (c == (VALUE)class) return TRUE;
if (c == cl) return TRUE;
return FALSE;
}
@ -216,7 +223,7 @@ VALUE
obj_is_kind_of(obj, c)
VALUE obj, c;
{
struct RClass *class = (struct RClass*)CLASS_OF(obj);
VALUE cl = CLASS_OF(obj);
switch (TYPE(c)) {
case T_MODULE:
@ -239,28 +246,21 @@ obj_is_kind_of(obj, c)
TypeError("class or module required");
}
while (class) {
if ((VALUE)class == c || RCLASS(class)->m_tbl == RCLASS(c)->m_tbl)
while (cl) {
if (cl == c || RCLASS(cl)->m_tbl == RCLASS(c)->m_tbl)
return TRUE;
class = class->super;
cl = RCLASS(cl)->super;
}
return FALSE;
}
static VALUE
obj_initialize(obj)
obj_dummy(obj)
VALUE obj;
{
return Qnil;
}
static VALUE
obj_s_added(obj, id)
VALUE obj, id;
{
return Qnil;
}
static VALUE
nil_to_s(obj)
VALUE obj;
@ -268,6 +268,13 @@ nil_to_s(obj)
return str_new2("");
}
static VALUE
nil_to_a(obj)
VALUE obj;
{
return ary_new2(0);
}
static VALUE
nil_inspect(obj)
VALUE obj;
@ -279,7 +286,7 @@ static VALUE
nil_type(obj)
VALUE obj;
{
return str_new2("nil");
return cNilClass;
}
static VALUE
@ -311,28 +318,28 @@ static VALUE
true_to_s(obj)
VALUE obj;
{
return str_new2("TRUE");
return str_new2("true");
}
static VALUE
true_type(obj)
VALUE obj;
{
return str_new2("TRUE");
return cTrueClass;
}
static VALUE
false_to_s(obj)
VALUE obj;
{
return str_new2("FALSE");
return str_new2("false");
}
static VALUE
false_type(obj)
VALUE obj;
{
return str_new2("FALSE");
return cFalseClass;
}
static VALUE
@ -362,15 +369,15 @@ obj_alloc(class)
static VALUE
mod_clone(module)
struct RClass *module;
VALUE module;
{
NEWOBJ(clone, struct RClass);
OBJSETUP(clone, CLASS_OF(module), TYPE(module));
clone->super = module->super;
clone->super = RCLASS(module)->super;
clone->iv_tbl = 0;
clone->m_tbl = 0; /* avoid GC crashing */
clone->m_tbl = st_copy(module->m_tbl);
clone->m_tbl = st_copy(RCLASS(module)->m_tbl);
return (VALUE)clone;
}
@ -389,15 +396,89 @@ mod_eqq(mod, arg)
return obj_is_kind_of(arg, mod);
}
static VALUE
mod_le(mod, arg)
VALUE mod, arg;
{
switch (TYPE(arg)) {
case T_MODULE:
case T_CLASS:
break;
default:
TypeError("compared with non class/module");
}
while (mod) {
if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl)
return TRUE;
mod = RCLASS(mod)->super;
}
return FALSE;
}
static VALUE
mod_lt(mod, arg)
VALUE mod, arg;
{
if (mod == arg) return FALSE;
return mod_le(mod, arg);
}
static VALUE
mod_ge(mod, arg)
VALUE mod, arg;
{
switch (TYPE(arg)) {
case T_MODULE:
case T_CLASS:
break;
default:
TypeError("compared with non class/module");
}
return mod_lt(arg, mod);
}
static VALUE
mod_gt(mod, arg)
VALUE mod, arg;
{
if (mod == arg) return FALSE;
return mod_ge(mod, arg);
}
static VALUE
mod_cmp(mod, arg)
VALUE mod, arg;
{
if (mod == arg) return INT2FIX(0);
switch (TYPE(arg)) {
case T_MODULE:
case T_CLASS:
break;
default:
TypeError("<=> requires Class or Module (%s given)",
rb_class2name(CLASS_OF(arg)));
break;
}
if (mod_le(mod, arg)) {
return INT2FIX(-1);
}
return INT2FIX(1);
}
VALUE module_new();
VALUE class_new_instance();
static VALUE
class_s_new(argc, argv, class)
class_s_new(argc, argv)
int argc;
VALUE *argv;
{
VALUE super, cls;
VALUE super, klass;
rb_scan_args(argc, argv, "01", &super);
if (NIL_P(super)) super = cObject;
@ -405,26 +486,33 @@ class_s_new(argc, argv, class)
if (FL_TEST(super, FL_SINGLETON)) {
TypeError("can't make subclass of virtual class");
}
cls = class_new(super);
klass = class_new(super);
/* make metaclass */
RBASIC(cls)->class = singleton_class_new(RBASIC(super)->class);
RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class);
singleton_class_attached(RBASIC(klass)->class, klass);
return cls;
return klass;
}
VALUE mod_name();
VALUE mod_included_modules();
VALUE mod_ancestors();
VALUE class_instance_methods();
VALUE class_private_instance_methods();
static VALUE
class_superclass(class)
struct RClass *class;
class_superclass(cl)
VALUE cl;
{
struct RClass *super = class->super;
VALUE super = RCLASS(cl)->super;
while (TYPE(super) == T_ICLASS) {
super = super->super;
super = RCLASS(super)->super;
}
if (!super) {
return Qnil;
}
return (VALUE)super;
return super;
}
ID
@ -447,10 +535,101 @@ mod_attr(argc, argv, class)
VALUE name, pub;
rb_scan_args(argc, argv, "11", &name, &pub);
rb_define_attr(class, rb_to_id(name), RTEST(pub));
rb_define_attr(class, rb_to_id(name), 1, RTEST(pub));
return Qnil;
}
static VALUE
mod_attr_reader(argc, argv, class)
int argc;
VALUE *argv;
VALUE class;
{
int i;
for (i=0; i<argc; i++) {
rb_define_attr(class, rb_to_id(argv[i]), 1, 0);
}
return Qnil;
}
static VALUE
mod_attr_writer(argc, argv, class)
int argc;
VALUE *argv;
VALUE class;
{
int i;
for (i=0; i<argc; i++) {
rb_define_attr(class, rb_to_id(argv[i]), 0, 1);
}
return Qnil;
}
static VALUE
mod_attr_accessor(argc, argv, class)
int argc;
VALUE *argv;
VALUE class;
{
int i;
for (i=0; i<argc; i++) {
rb_define_attr(class, rb_to_id(argv[i]), 1, 1);
}
return Qnil;
}
VALUE mod_constants();
static VALUE
mod_const_get(mod, name)
VALUE mod, name;
{
return rb_const_get_at(mod, rb_to_id(name));
}
static VALUE
mod_const_set(mod, name, value)
VALUE mod, name, value;
{
rb_const_set(mod, rb_to_id(name), value);
return value;
}
static VALUE
mod_const_defined(mod, name)
VALUE mod, name;
{
return rb_const_defined_at(mod, rb_to_id(name));
}
static VALUE
obj_methods(obj)
VALUE obj;
{
VALUE argv[1];
argv[0] = TRUE;
return class_instance_methods(1, argv, CLASS_OF(obj));
}
VALUE obj_singleton_methods();
static VALUE
obj_private_methods(obj)
VALUE obj;
{
VALUE argv[1];
argv[0] = TRUE;
return class_private_instance_methods(1, argv, CLASS_OF(obj));
}
VALUE obj_instance_variables();
VALUE obj_remove_instance_variable();
static VALUE
f_integer(obj, arg)
VALUE obj, arg;
@ -478,6 +657,13 @@ f_integer(obj, arg)
return INT2NUM(i);
}
VALUE
rb_Integer(val)
VALUE val;
{
return f_integer(Qnil, val);
}
static VALUE
to_flo(val)
VALUE val;
@ -494,12 +680,14 @@ fail_to_flo(val)
double big2dbl();
VALUE
static VALUE
f_float(obj, arg)
VALUE obj, arg;
{
switch (TYPE(arg)) {
case T_FIXNUM:
return float_new((double)FIX2INT(arg));
case T_FLOAT:
return arg;
@ -511,6 +699,21 @@ f_float(obj, arg)
}
}
VALUE
rb_Float(val)
VALUE val;
{
return f_float(Qnil, val);
}
double
num2dbl(val)
VALUE val;
{
VALUE v = rb_Float(val);
return RFLOAT(v)->value;
}
static VALUE
f_string(obj, arg)
VALUE obj, arg;
@ -518,11 +721,37 @@ f_string(obj, arg)
return rb_funcall(arg, rb_intern("to_s"), 0);
}
VALUE
rb_String(val)
VALUE val;
{
return f_string(Qnil, val);
}
static VALUE
f_array(obj, arg)
VALUE obj, arg;
{
return rb_funcall(arg, rb_intern("to_a"), 0);
if (TYPE(arg) == T_ARRAY) return arg;
arg = rb_funcall(arg, rb_intern("to_a"), 0);
if (TYPE(arg) != T_ARRAY) {
TypeError("`to_a' did not return Array");
}
return arg;
}
VALUE
rb_Array(val)
VALUE val;
{
return f_array(Qnil, val);
}
VALUE
rb_to_a(val) /* backward compatibility */
VALUE val;
{
return f_array(Qnil, val);
}
static VALUE
@ -531,7 +760,7 @@ boot_defclass(name, super)
VALUE super;
{
extern st_table *rb_class_tbl;
struct RClass *obj = (struct RClass*)class_new(super);
VALUE obj = class_new(super);
ID id = rb_intern(name);
rb_name_class(obj, id);
@ -551,30 +780,6 @@ rb_class_of(obj)
return RBASIC(obj)->class;
}
int
rb_type(obj)
VALUE obj;
{
if (FIXNUM_P(obj)) return T_FIXNUM;
if (obj == Qnil) return T_NIL;
if (obj == FALSE) return T_FALSE;
if (obj == TRUE) return T_TRUE;
return BUILTIN_TYPE(obj);
}
int
rb_special_const_p(obj)
VALUE obj;
{
if (FIXNUM_P(obj)) return TRUE;
if (obj == Qnil) return TRUE;
if (obj == FALSE) return TRUE;
if (obj == TRUE) return TRUE;
return FALSE;
}
VALUE TopSelf;
void
@ -587,11 +792,15 @@ Init_Object()
cClass = boot_defclass("Class", cModule);
metaclass = RBASIC(cObject)->class = singleton_class_new(cClass);
singleton_class_attached(metaclass, cObject);
metaclass = RBASIC(cModule)->class = singleton_class_new(metaclass);
singleton_class_attached(metaclass, cModule);
metaclass = RBASIC(cClass)->class = singleton_class_new(metaclass);
singleton_class_attached(metaclass, cClass);
mKernel = rb_define_module("Kernel");
rb_include_module(cObject, mKernel);
rb_define_private_method(cClass, "inherited", obj_dummy, 1);
/*
* Ruby's Class Hierarchy Chart
@ -621,6 +830,7 @@ Init_Object()
rb_define_method(mKernel, "==", obj_equal, 1);
rb_define_alias(mKernel, "equal?", "==");
rb_define_alias(mKernel, "===", "==");
rb_define_method(mKernel, "=~", rb_false, 1);
rb_define_method(mKernel, "eql?", obj_equal, 1);
@ -634,6 +844,11 @@ Init_Object()
rb_define_method(mKernel, "to_a", any_to_a, 0);
rb_define_method(mKernel, "to_s", any_to_s, 0);
rb_define_method(mKernel, "inspect", obj_inspect, 0);
rb_define_method(mKernel, "methods", obj_methods, 0);
rb_define_method(mKernel, "singleton_methods", obj_singleton_methods, 0);
rb_define_method(mKernel, "private_methods", obj_private_methods, 0);
rb_define_method(mKernel, "instance_variables", obj_instance_variables, 0);
rb_define_method(mKernel, "remove_instance_variable", obj_remove_instance_variable, 0);
rb_define_method(mKernel, "instance_of?", obj_is_instance_of, 1);
rb_define_method(mKernel, "kind_of?", obj_is_kind_of, 1);
@ -651,27 +866,53 @@ Init_Object()
cNilClass = rb_define_class("NilClass", cObject);
rb_define_method(cNilClass, "type", nil_type, 0);
rb_define_method(cNilClass, "to_s", nil_to_s, 0);
rb_define_method(cNilClass, "to_a", nil_to_a, 0);
rb_define_method(cNilClass, "inspect", nil_inspect, 0);
rb_define_method(cNilClass, "=~", rb_equal, 1);
rb_define_method(cNilClass, "nil?", rb_true, 0);
rb_undef_method(CLASS_OF(cNilClass), "new");
rb_define_global_const("NIL", Qnil);
/* default addition */
rb_define_method(cNilClass, "+", nil_plus, 1);
rb_define_global_function("initialize", obj_initialize, -1);
rb_define_global_function("singleton_method_added", obj_s_added, 1);
rb_define_global_function("initialize", obj_dummy, -1);
rb_define_global_function("singleton_method_added", obj_dummy, 1);
rb_define_method(cModule, "===", mod_eqq, 1);
rb_define_method(cModule, "<=>", mod_cmp, 1);
rb_define_method(cModule, "<", mod_lt, 1);
rb_define_method(cModule, "<=", mod_le, 1);
rb_define_method(cModule, ">", mod_gt, 1);
rb_define_method(cModule, ">=", mod_ge, 1);
rb_define_method(cModule, "clone", mod_clone, 0);
rb_define_method(cModule, "to_s", mod_to_s, 0);
rb_define_method(cModule, "included_modules", mod_included_modules, 0);
rb_define_method(cModule, "name", mod_name, 0);
rb_define_method(cModule, "ancestors", mod_ancestors, 0);
rb_define_private_method(cModule, "attr", mod_attr, -1);
rb_define_private_method(cModule, "attr_reader", mod_attr_reader, -1);
rb_define_private_method(cModule, "attr_writer", mod_attr_writer, -1);
rb_define_private_method(cModule, "attr_accessor", mod_attr_accessor, -1);
rb_define_singleton_method(cModule, "new", module_new, 0);
rb_define_method(cModule, "instance_methods", class_instance_methods, -1);
rb_define_method(cModule, "private_instance_methods", class_private_instance_methods, -1);
rb_define_method(cModule, "constants", mod_constants, 0);
rb_define_method(cModule, "const_get", mod_const_get, 1);
rb_define_method(cModule, "const_set", mod_const_set, 2);
rb_define_method(cModule, "const_defined?", mod_const_defined, 1);
rb_define_private_method(cModule, "method_added", obj_dummy, 1);
rb_define_method(cClass, "new", class_new_instance, -1);
rb_define_method(cClass, "superclass", class_superclass, 0);
rb_define_singleton_method(cClass, "new", class_s_new, -1);
rb_undef_method(cClass, "extend_object");
rb_undef_method(cClass, "append_features");
rb_define_singleton_method(cClass, "new", class_s_new, -1);
cData = rb_define_class("Data", cObject);

133
pack.c
View file

@ -85,8 +85,7 @@ static void encodes();
static VALUE
pack_pack(ary, fmt)
struct RArray *ary;
struct RString *fmt;
VALUE ary, fmt;
{
static char *nul10 = "\0\0\0\0\0\0\0\0\0\0";
static char *spc10 = " ";
@ -99,14 +98,14 @@ pack_pack(ary, fmt)
Check_Type(fmt, T_STRING);
p = fmt->ptr;
pend = fmt->ptr + fmt->len;
p = RSTRING(fmt)->ptr;
pend = RSTRING(fmt)->ptr + RSTRING(fmt)->len;
res = str_new(0, 0);
items = ary->len;
items = RARRAY(ary)->len;
idx = 0;
#define NEXTFROM (items-- > 0 ? ary->ptr[idx++] : (ArgError(toofew),0))
#define NEXTFROM (items-- > 0 ? RARRAY(ary)->ptr[idx++] : (ArgError(toofew),0))
while (p < pend) {
type = *p++; /* get data type */
@ -285,7 +284,7 @@ pack_pack(ary, fmt)
else {
s = NUM2INT(from);
}
str_cat(res, &s, sizeof(short));
str_cat(res, (UCHAR*)&s, sizeof(short));
}
break;
@ -299,7 +298,7 @@ pack_pack(ary, fmt)
else {
i = NUM2INT(from);
}
str_cat(res, &i, sizeof(int));
str_cat(res, (UCHAR*)&i, sizeof(int));
}
break;
@ -313,7 +312,7 @@ pack_pack(ary, fmt)
else {
l = NUM2INT(from);
}
str_cat(res, &l, sizeof(long));
str_cat(res, (UCHAR*)&l, sizeof(long));
}
break;
@ -327,7 +326,7 @@ pack_pack(ary, fmt)
s = NUM2INT(from);
}
s = htons(s);
str_cat(res, &s, sizeof(short));
str_cat(res, (UCHAR*)&s, sizeof(short));
}
break;
@ -341,7 +340,7 @@ pack_pack(ary, fmt)
l = NUM2INT(from);
}
l = htonl(l);
str_cat(res, &l, sizeof(long));
str_cat(res, (UCHAR*)&l, sizeof(long));
}
break;
@ -355,7 +354,7 @@ pack_pack(ary, fmt)
s = NUM2INT(from);
}
s = htovs(s);
str_cat(res, &s, sizeof(short));
str_cat(res, (UCHAR*)&s, sizeof(short));
}
break;
@ -369,7 +368,7 @@ pack_pack(ary, fmt)
l = NUM2INT(from);
}
l = htovl(l);
str_cat(res, &l, sizeof(long));
str_cat(res, (UCHAR*)&l, sizeof(long));
}
break;
@ -389,7 +388,7 @@ pack_pack(ary, fmt)
f = (float)NUM2INT(from);
break;
}
str_cat(res, &f, sizeof(float));
str_cat(res, (UCHAR*)&f, sizeof(float));
}
break;
@ -409,7 +408,7 @@ pack_pack(ary, fmt)
d = (double)NUM2INT(from);
break;
}
str_cat(res, &d, sizeof(double));
str_cat(res, (UCHAR*)&d, sizeof(double));
}
break;
@ -442,6 +441,7 @@ pack_pack(ary, fmt)
break;
case 'u':
case 'm':
from = obj_as_string(NEXTFROM);
ptr = RSTRING(from)->ptr;
plen = RSTRING(from)->len;
@ -457,7 +457,7 @@ pack_pack(ary, fmt)
todo = len;
else
todo = plen;
encodes(res, ptr, todo);
encodes(res, ptr, todo, type);
plen -= todo;
ptr += todo;
}
@ -471,39 +471,55 @@ pack_pack(ary, fmt)
return res;
}
static char uu_table[] =
"`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
static char b64_table[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void
encodes(str, s, len)
struct RString *str;
encodes(str, s, len, type)
VALUE str;
UCHAR *s;
int len;
int type;
{
char hunk[4];
UCHAR *p, *pend;
char *trans = type == 'u' ? uu_table : b64_table;
int padding;
*hunk = len + ' ';
str_cat(str, hunk, 1);
if (type == 'u') {
*hunk = len + ' ';
str_cat(str, hunk, 1);
padding = '`';
}
else {
padding = '=';
}
while (len > 0) {
hunk[0] = ' ' + (077 & (*s >> 2));
hunk[1] = ' ' + (077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)));
hunk[2] = ' ' + (077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)));
hunk[3] = ' ' + (077 & (s[2] & 077));
hunk[0] = trans[077 & (*s >> 2)];
hunk[1] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
hunk[2] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
hunk[3] = trans[077 & s[2]];
str_cat(str, hunk, 4);
s += 3;
len -= 3;
}
p = str->ptr;
pend = str->ptr + str->len;
while (p < pend) {
if (*p == ' ')
*p = '`';
p++;
p = RSTRING(str)->ptr;
pend = RSTRING(str)->ptr + RSTRING(str)->len;
if (len == -1) {
pend[-1] = padding;
}
else if (len == -2) {
pend[-2] = padding;
pend[-1] = padding;
}
str_cat(str, "\n", 1);
}
static VALUE
pack_unpack(str, fmt)
struct RString *str, *fmt;
VALUE str, fmt;
{
static char *hexdigits = "0123456789abcdef0123456789ABCDEFx";
UCHAR *s, *send;
@ -514,10 +530,10 @@ pack_unpack(str, fmt)
Check_Type(fmt, T_STRING);
s = str->ptr;
send = s + str->len;
p = fmt->ptr;
pend = p + fmt->len;
s = RSTRING(str)->ptr;
send = s + RSTRING(str)->len;
p = RSTRING(fmt)->ptr;
pend = p + RSTRING(fmt)->len;
ary = ary_new();
while (p < pend) {
@ -851,12 +867,55 @@ pack_unpack(str, fmt)
}
break;
case 'm':
{
VALUE str = str_new(0, (send - s)*3/4);
UCHAR *ptr = RSTRING(str)->ptr;
int total = 0;
int a,b,c,d;
static int first = 1;
static int b64_xtable[256];
if (first) {
int i;
first = 0;
for (i = 0; i < 256; i++) {
b64_xtable[i] = -1;
}
for (i = 0; i < 64; i++) {
b64_xtable[b64_table[i]] = i;
}
}
for (;;) {
while (s[0] == '\r' || s[0] == '\n') { s++; }
if ((a = b64_xtable[s[0]]) == -1) break;
if ((b = b64_xtable[s[1]]) == -1) break;
if ((c = b64_xtable[s[2]]) == -1) break;
if ((d = b64_xtable[s[3]]) == -1) break;
*ptr++ = a << 2 | b >> 4;
*ptr++ = b << 4 | c >> 2;
*ptr++ = c << 6 | d;
s += 4;
}
if (a != -1 && b != -1 && s[2] == '=') {
*ptr++ = a << 2 | b >> 4;
}
if (a != -1 && b != -1 && c != -1 && s[3] == '=') {
*ptr++ = a << 2 | b >> 4;
*ptr++ = b << 4 | c >> 2;
}
RSTRING(str)->len = ptr - RSTRING(str)->ptr;
ary_push(ary, str);
}
break;
case '@':
s = str->ptr + len;
s = RSTRING(str)->ptr + len;
break;
case 'X':
if (len > s - str->ptr)
if (len > s - RSTRING(str)->ptr)
ArgError("X outside of string");
s -= len;
break;

840
parse.y

File diff suppressed because it is too large Load diff

132
process.c
View file

@ -108,9 +108,6 @@ rb_waitpid(pid, flags, st)
result = wait4(pid, st, flags, NULL);
if (result < 0) {
if (errno == EINTR) {
#ifdef THREAD
thread_schedule();
#endif
goto retry;
}
return -1;
@ -250,30 +247,36 @@ after_exec()
#endif
extern char *dln_find_exe();
int env_path_tainted();
static void
security(str)
char *str;
{
extern int env_path_tainted;
extern VALUE eSecurityError;
if (rb_safe_level() > 0 && env_path_tainted) {
Raise(eSecurityError, "Insecure PATH - %s", str);
if (rb_safe_level() > 0) {
if (env_path_tainted()) {
Raise(eSecurityError, "Insecure PATH - %s", str);
}
}
}
static int
proc_exec_v(argv)
proc_exec_v(argv, prog)
char **argv;
{
char *prog;
security(argv[0]);
prog = dln_find_exe(argv[0], 0);
if (!prog) {
errno = ENOENT;
return -1;
{
if (prog) {
security(prog);
}
else {
security(argv[0]);
prog = dln_find_exe(argv[0], 0);
if (!prog) {
errno = ENOENT;
return -1;
}
}
#if (defined(MSDOS) && !defined(DJGPP)) || defined(__human68k__)
{
@ -315,13 +318,19 @@ proc_exec_v(argv)
}
static int
proc_exec_n(argc, argv)
proc_exec_n(argc, argv, progv)
int argc;
VALUE *argv;
VALUE progv;
{
char *prog = 0;
char **args;
int i;
if (progv) {
Check_SafeStr(progv);
prog = RSTRING(progv)->ptr;
}
args = ALLOCA_N(char*, argc+1);
for (i=0; i<argc; i++) {
Check_SafeStr(argv[i]);
@ -329,7 +338,7 @@ proc_exec_n(argc, argv)
}
args[i] = 0;
if (args[0]) {
return proc_exec_v(args);
return proc_exec_v(args, prog);
}
return -1;
}
@ -382,7 +391,7 @@ rb_proc_exec(str)
*a = NULL;
}
if (argv[0]) {
return proc_exec_v(argv);
return proc_exec_v(argv, 0);
}
errno = ENOENT;
return -1;
@ -390,16 +399,22 @@ rb_proc_exec(str)
#if defined(__human68k__)
static int
proc_spawn_v(argv)
proc_spawn_v(argv, prog)
char **argv;
{
char *prog;
{
char *extension;
int state;
prog = dln_find_exe(argv[0], 0);
if (!prog)
return -1;
if (prog) {
security(prog);
}
else {
security(argv[0]);
prog = dln_find_exe(argv[0], 0);
if (!prog)
return -1;
}
if ((extension = strrchr(prog, '.')) != NULL && strcasecmp(extension, ".bat") == 0) {
char **new_argv;
@ -430,9 +445,10 @@ proc_spawn_v(argv)
}
static int
proc_spawn_n(argc, argv)
proc_spawn_n(argc, argv, prog)
int argc;
VALUE *argv;
VALUE prog;
{
char **args;
int i;
@ -442,9 +458,10 @@ proc_spawn_n(argc, argv)
Check_SafeStr(argv[i]);
args[i] = RSTRING(argv[i])->ptr;
}
Check_SafeStr(prog);
args[i] = (char *) 0;
if (args[0])
return proc_exec_v(args);
return proc_spawn_v(args, RSTRING(prog)->ptr);
return -1;
}
@ -473,7 +490,7 @@ proc_spawn(str)
*a++ = t;
*a = NULL;
}
return argv[0] ? proc_spawn_v(argv) : -1 ;
return argv[0] ? proc_spawn_v(argv, 0) : -1 ;
}
#endif /* __human68k__ */
@ -482,12 +499,29 @@ f_exec(argc, argv)
int argc;
VALUE *argv;
{
if (argc == 1) {
VALUE prog = 0;
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
ArgError("wrong first argument");
}
prog = RARRAY(argv[0])->ptr[0];
argv[0] = RARRAY(argv[0])->ptr[1];
}
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
ArgError("wrong first argument");
}
prog = RARRAY(argv[0])->ptr[0];
argv[0] = RARRAY(argv[0])->ptr[1];
}
if (argc == 1 && prog == 0) {
Check_SafeStr(argv[0]);
rb_proc_exec(RSTRING(argv[0])->ptr);
}
else {
proc_exec_n(argc, argv);
proc_exec_n(argc, argv, prog);
}
rb_sys_fail(RSTRING(argv[0])->ptr);
}
@ -574,6 +608,12 @@ f_system(argc, argv)
VALUE cmd;
int state;
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
ArgError("wrong first argument");
}
argv[0] = RARRAY(argv[0])->ptr[0];
}
cmd = ary_join(ary_new4(argc, argv), str_new2(" "));
Check_SafeStr(cmd);
@ -587,6 +627,12 @@ f_system(argc, argv)
VALUE cmd;
int state;
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
ArgError("wrong first argument");
}
argv[0] = RARRAY(argv[0])->ptr[0];
}
cmd = ary_join(ary_new4(argc, argv), str_new2(" "));
Check_SafeStr(cmd);
@ -597,6 +643,7 @@ f_system(argc, argv)
return FALSE;
#else
#if defined(__human68k__)
VALUE prog = 0;
int i;
int state;
@ -608,14 +655,25 @@ f_system(argc, argv)
return INT2FIX(0);
}
for (i = 0; i < argc; i++)
Check_SafeStr(argv[i]);
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
ArgError("wrong first argument");
}
prog = RARRAY(argv[0])->ptr[0];
argv[0] = RARRAY(argv[0])->ptr[1];
}
state = argc == 1 ? proc_spawn(RSTRING(argv[0])->ptr) : proc_spawn_n(argc, argv) ;
if (argc == 1 && prog == 0) {
state = proc_spawn(RSTRING(argv[0])->ptr);
}
else {
state = proc_spawn_n(argc, argv, prog);
}
last_status = state == -1 ? INT2FIX(127) : INT2FIX(state);
return state == 0 ? TRUE : FALSE ;
#else
VALUE prog = 0;
int i;
int pid;
@ -627,18 +685,22 @@ f_system(argc, argv)
return INT2FIX(0);
}
for (i=0; i<argc; i++) {
Check_SafeStr(argv[i]);
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
ArgError("wrong first argument");
}
prog = RARRAY(argv[0])->ptr[0];
argv[0] = RARRAY(argv[0])->ptr[1];
}
retry:
switch (pid = vfork()) {
case 0:
if (argc == 1) {
if (argc == 1 && prog == 0) {
rb_proc_exec(RSTRING(argv[0])->ptr);
}
else {
proc_exec_n(argc, argv);
proc_exec_n(argc, argv, prog);
}
_exit(127);
break; /* not reached */
@ -930,8 +992,6 @@ extern VALUE f_kill();
void
Init_process()
{
extern VALUE mKernel;
rb_define_virtual_variable("$$", get_pid, 0);
rb_define_readonly_variable("$?", &last_status);
rb_define_global_function("exec", f_exec, -1);

View file

@ -21,7 +21,8 @@ f_srand(argc, argv, obj)
VALUE *argv;
VALUE obj;
{
int seed, old;
VALUE seed;
int old;
static int saved_seed;
if (rb_scan_args(argc, argv, "01", &seed) == 0) {

View file

@ -12,7 +12,6 @@
#include "ruby.h"
VALUE mComparable;
static VALUE cRange;
extern VALUE cNumeric;
@ -170,6 +169,8 @@ range_inspect(range)
return str;
}
VALUE enum_length();
static VALUE
range_length(rng)
VALUE rng;

413
re.c
View file

@ -73,19 +73,19 @@ static char casetable[] = {
int
str_cicmp(str1, str2)
struct RString *str1, *str2;
VALUE str1, str2;
{
int len, i;
char *p1, *p2;
len = min(str1->len, str2->len);
p1 = str1->ptr; p2 = str2->ptr;
len = min(RSTRING(str1)->len, RSTRING(str2)->len);
p1 = RSTRING(str1)->ptr; p2 = RSTRING(str2)->ptr;
for (i = 0; i < len; i++, p1++, p2++) {
if (casetable[(unsigned)*p1] != casetable[(unsigned)*p2])
return casetable[(unsigned)*p1] - casetable[(unsigned)*p2];
}
return str1->len - str2->len;
return RSTRING(str1)->len - RSTRING(str2)->len;
}
#define REG_IGNORECASE FL_USER0
@ -109,7 +109,7 @@ static int reg_kcode =
static void
kcode_euc(reg)
struct RRegexp *reg;
VALUE reg;
{
FL_UNSET(reg, KCODE_MASK);
FL_SET(reg, KCODE_EUC);
@ -118,7 +118,7 @@ kcode_euc(reg)
static void
kcode_sjis(reg)
struct RRegexp *reg;
VALUE reg;
{
FL_UNSET(reg, KCODE_MASK);
FL_SET(reg, KCODE_SJIS);
@ -127,7 +127,7 @@ kcode_sjis(reg)
static void
kcode_none(reg)
struct RRegexp *reg;
VALUE reg;
{
FL_UNSET(reg, KCODE_MASK);
FL_SET(reg, KCODE_FIXED);
@ -135,7 +135,7 @@ kcode_none(reg)
static void
kcode_set_option(reg)
struct RRegexp *reg;
VALUE reg;
{
if (!FL_TEST(reg, KCODE_FIXED)) return;
@ -153,7 +153,7 @@ kcode_set_option(reg)
re_set_syntax(re_syntax_options);
}
static void
void
kcode_reset_option()
{
re_syntax_options &= ~RE_MBCTYPE_MASK;
@ -172,13 +172,12 @@ kcode_reset_option()
extern int rb_in_eval;
static VALUE
reg_desc(s, len, re)
static void
reg_expr_str(str, s, len)
VALUE str;
char *s;
int len;
VALUE re;
{
VALUE str = str_new2("/");
char *p, *pend;
int slash = 0;
@ -207,20 +206,52 @@ reg_desc(s, len, re)
p++;
}
}
}
static VALUE
reg_desc(s, len, re)
char *s;
int len;
VALUE re;
{
VALUE str = str_new2("/");
reg_expr_str(str, s, len);
str_cat(str, "/", 1);
if (re) {
if (FL_TEST(re, REG_IGNORECASE)) {
if (FL_TEST(re,REG_IGNORECASE))
str_cat(str, "i", 1);
if (FL_TEST(re,KCODE_FIXED)) {
switch ((RBASIC(re)->flags & KCODE_MASK)) {
case KCODE_NONE:
str_cat(str, "n", 1);
break;
case KCODE_EUC:
str_cat(str, "e", 1);
break;
case KCODE_SJIS:
str_cat(str, "s", 1);
break;
}
}
}
return str;
}
static VALUE
reg_inspect(re)
struct RRegexp *re;
reg_source(re)
VALUE re;
{
return reg_desc(re->str, re->len, re);
VALUE str = str_new(0,0);
reg_expr_str(str, RREGEXP(re)->str,RREGEXP(re)->len,re);
return str;
}
static VALUE
reg_inspect(re)
VALUE re;
{
return reg_desc(RREGEXP(re)->str, RREGEXP(re)->len, re);
}
static void
@ -238,6 +269,36 @@ reg_raise(s, len, err, re)
Error("%s: %s", err, RSTRING(desc)->ptr);
}
static VALUE
reg_casefold_p(re)
VALUE re;
{
if (FL_TEST(re, REG_IGNORECASE)) return TRUE;
return FALSE;
}
static VALUE
reg_kcode_method(re)
VALUE re;
{
char *kcode = "$KCODE";
if (FL_TEST(re, KCODE_FIXED)) {
switch (RBASIC(re)->flags & KCODE_MASK) {
case KCODE_NONE:
kcode = "none"; break;
case KCODE_EUC:
kcode = "euc"; break;
case KCODE_SJIS:
kcode = "sjis"; break;
default:
break;
}
}
return str_new2(kcode);
}
static Regexp*
make_regexp(s, len, flag)
char *s;
@ -286,50 +347,52 @@ match_alloc()
return (VALUE)match;
}
VALUE ignorecase;
static VALUE
match_clone(orig)
VALUE orig;
{
struct re_registers *rr;
int
reg_search(reg, str, start, regs)
struct RRegexp *reg;
struct RString *str;
int start;
struct re_registers *regs;
NEWOBJ(match, struct RMatch);
OBJSETUP(match, cMatch, T_MATCH);
match->str = RMATCH(orig)->str;
match->regs = ALLOC(struct re_registers);
match->regs->allocated = 0;
re_copy_registers(match->regs, RMATCH(orig)->regs);
return (VALUE)match;
}
VALUE ignorecase;
static VALUE matchcache;
void
reg_prepare_re(reg)
VALUE reg;
{
int result;
int casefold = RTEST(ignorecase);
VALUE match = 0;
struct re_registers *regs0 = 0;
int need_recompile = 0;
if (start > str->len) return -1;
/* case-flag set for the object */
if (FL_TEST(reg, REG_IGNORECASE)) {
casefold = TRUE;
}
if (casefold) {
if (reg->ptr->translate != casetable) {
reg->ptr->translate = casetable;
reg->ptr->fastmap_accurate = 0;
if (RREGEXP(reg)->ptr->translate != casetable) {
RREGEXP(reg)->ptr->translate = casetable;
RREGEXP(reg)->ptr->fastmap_accurate = 0;
need_recompile = 1;
}
}
else if (reg->ptr->translate) {
reg->ptr->translate = NULL;
reg->ptr->fastmap_accurate = 0;
else if (RREGEXP(reg)->ptr->translate) {
RREGEXP(reg)->ptr->translate = NULL;
RREGEXP(reg)->ptr->fastmap_accurate = 0;
need_recompile = 1;
}
if (regs == (struct re_registers*)-1) {
regs = 0;
}
else {
match = match_alloc();
regs0 = RMATCH(match)->regs;
}
if (regs && !match) regs0 = regs;
if (FL_TEST(reg, KCODE_FIXED)) {
kcode_set_option(reg);
}
@ -342,28 +405,61 @@ reg_search(reg, str, start, regs)
if (need_recompile) {
char *err;
err = re_compile_pattern(reg->str, reg->len, reg->ptr);
err = re_compile_pattern(RREGEXP(reg)->str, RREGEXP(reg)->len, RREGEXP(reg)->ptr);
if (err != NULL) {
kcode_reset_option();
reg_raise(reg->str, reg->len, err, reg);
reg_raise(RREGEXP(reg)->str, RREGEXP(reg)->len, err, reg);
}
}
}
result = re_search(reg->ptr, str->ptr, str->len,
start, str->len - start, regs0);
int
reg_search(reg, str, start, regs)
VALUE reg, str;
int start;
struct re_registers *regs;
{
int result;
int casefold = RTEST(ignorecase);
VALUE match = 0;
struct re_registers *regs0 = 0;
int need_recompile = 0;
if (start > RSTRING(str)->len) return -1;
reg_prepare_re(reg);
if (regs == (struct re_registers*)-1) {
regs = 0;
}
else {
if (matchcache) {
match = matchcache;
matchcache = 0;
}
else {
match = match_alloc();
}
regs0 = RMATCH(match)->regs;
}
result = re_search(RREGEXP(reg)->ptr,RSTRING(str)->ptr,RSTRING(str)->len,
start,RSTRING(str)->len-start,regs0);
kcode_reset_option();
if (start == -2) {
reg_raise(reg->str, reg->len, "Stack overfow in regexp matcher", reg);
reg_raise(RREGEXP(reg)->str, RREGEXP(reg)->len,
"Stack overfow in regexp matcher", reg);
}
if (result < 0) {
matchcache = match;
backref_set(Qnil);
}
else if (match) {
RMATCH(match)->str = str_new4(str);
backref_set(match);
}
if (regs && regs0 && regs0 != regs) re_copy_registers(regs, regs0);
if (regs && regs0) re_copy_registers(regs, regs0);
return result;
}
@ -371,70 +467,70 @@ reg_search(reg, str, start, regs)
VALUE
reg_nth_defined(nth, match)
int nth;
struct RMatch *match;
VALUE match;
{
if (NIL_P(match)) return Qnil;
if (nth >= match->regs->num_regs) {
if (nth >= RMATCH(match)->regs->num_regs) {
return FALSE;
}
if (match->BEG(nth) == -1) return FALSE;
if (RMATCH(match)->BEG(nth) == -1) return FALSE;
return TRUE;
}
VALUE
reg_nth_match(nth, match)
int nth;
struct RMatch *match;
VALUE match;
{
int start, end, len;
if (NIL_P(match)) return Qnil;
if (nth >= match->regs->num_regs) {
if (nth >= RMATCH(match)->regs->num_regs) {
return Qnil;
}
start = match->BEG(nth);
start = RMATCH(match)->BEG(nth);
if (start == -1) return Qnil;
end = match->END(nth);
end = RMATCH(match)->END(nth);
len = end - start;
return str_new(RSTRING(match->str)->ptr + start, len);
return str_new(RSTRING(RMATCH(match)->str)->ptr + start, len);
}
VALUE
reg_last_match(match)
struct RMatch *match;
VALUE match;
{
return reg_nth_match(0, match);
}
VALUE
reg_match_pre(match)
struct RMatch *match;
VALUE match;
{
if (NIL_P(match)) return Qnil;
if (match->BEG(0) == -1) return Qnil;
return str_new(RSTRING(match->str)->ptr, match->BEG(0));
if (RMATCH(match)->BEG(0) == -1) return Qnil;
return str_new(RSTRING(RMATCH(match)->str)->ptr, RMATCH(match)->BEG(0));
}
VALUE
reg_match_post(match)
struct RMatch *match;
VALUE match;
{
if (NIL_P(match)) return Qnil;
if (match->BEG(0) == -1) return Qnil;
return str_new(RSTRING(match->str)->ptr+match->END(0),
RSTRING(match->str)->len-match->END(0));
if (RMATCH(match)->BEG(0) == -1) return Qnil;
return str_new(RSTRING(RMATCH(match)->str)->ptr+RMATCH(match)->END(0),
RSTRING(RMATCH(match)->str)->len-RMATCH(match)->END(0));
}
VALUE
reg_match_last(match)
struct RMatch *match;
VALUE match;
{
int i;
if (NIL_P(match)) return Qnil;
if (match->BEG(0) == -1) return Qnil;
if (RMATCH(match)->BEG(0) == -1) return Qnil;
for (i=match->regs->num_regs-1; match->BEG(i) == -1 && i > 0; i--)
for (i=RMATCH(match)->regs->num_regs-1; RMATCH(match)->BEG(i) == -1 && i > 0; i--)
;
if (i == 0) return Qnil;
return reg_nth_match(i, match);
@ -466,11 +562,11 @@ last_paren_match_getter()
static VALUE
match_to_a(match)
struct RMatch *match;
VALUE match;
{
struct re_registers *regs = match->regs;
VALUE ary = ary_new(regs->num_regs);
char *ptr = RSTRING(match->str)->ptr;
struct re_registers *regs = RMATCH(match)->regs;
VALUE ary = ary_new2(regs->num_regs);
char *ptr = RSTRING(RMATCH(match)->str)->ptr;
int i;
for (i=0; i<regs->num_regs; i++) {
@ -481,9 +577,35 @@ match_to_a(match)
return ary;
}
static VALUE
match_aref(argc, argv, match)
int argc;
VALUE *argv;
VALUE match;
{
VALUE idx, rest;
struct re_registers *regs;
char *ptr;
int i;
rb_scan_args(argc, argv, "11", &idx, &rest);
if (!NIL_P(rest) || !FIXNUM_P(idx) || FIX2INT(idx) < 0) {
return ary_aref(argc, argv, match_to_a(match));
}
regs = RMATCH(match)->regs;
i = FIX2INT(idx);
if (i>=regs->num_regs) return Qnil;
ptr = RSTRING(RMATCH(match)->str)->ptr;
return str_new(ptr+regs->beg[i], regs->end[i]-regs->beg[i]);
}
static VALUE
match_to_s(match)
struct RMatch *match;
VALUE match;
{
VALUE str = reg_last_match(match);
@ -557,23 +679,51 @@ static VALUE reg_cache;
VALUE
reg_regcomp(str)
struct RString *str;
VALUE str;
{
int ignc = RTEST(ignorecase);
if (reg_cache && RREGEXP(reg_cache)->len == str->len
if (reg_cache && RREGEXP(reg_cache)->len == RSTRING(str)->len
&& ign_cache == ignc
&& memcmp(RREGEXP(reg_cache)->str, str->ptr, str->len) == 0)
&& memcmp(RREGEXP(reg_cache)->str, RSTRING(str)->ptr, RSTRING(str)->len) == 0)
return reg_cache;
ign_cache = ignc;
return reg_cache = reg_new(str->ptr, str->len, ignc);
return reg_cache = reg_new(RSTRING(str)->ptr, RSTRING(str)->len, ignc);
}
static int
reg_cur_kcode(re)
VALUE re;
{
if (FL_TEST(re, KCODE_FIXED)) {
return RBASIC(re)->flags & KCODE_MASK;
}
return 0;
}
static VALUE
reg_equal(re1, re2)
VALUE re1, re2;
{
int min;
if (re1 == re2) return TRUE;
if (TYPE(re2) != T_REGEXP) return FALSE;
if (RREGEXP(re1)->len != RREGEXP(re2)->len) return FALSE;
min = RREGEXP(re1)->len;
if (min > RREGEXP(re2)->len) min = RREGEXP(re2)->len;
if (memcmp(RREGEXP(re1)->str, RREGEXP(re2)->str, min) == 0 &&
reg_cur_kcode(re1) == reg_cur_kcode(re2) &&
!(FL_TEST(re1,REG_IGNORECASE) ^ FL_TEST(re2,REG_IGNORECASE))) {
return TRUE;
}
return FALSE;
}
VALUE
reg_match(re, str)
struct RRegexp *re;
struct RString *str;
VALUE re, str;
{
int start;
@ -587,7 +737,7 @@ reg_match(re, str)
VALUE
reg_match2(re)
struct RRegexp *re;
VALUE re;
{
int start;
VALUE line = lastline_get();
@ -653,17 +803,16 @@ reg_s_new(argc, argv, self)
static VALUE
reg_s_quote(re, str)
VALUE re;
struct RString *str;
VALUE re, str;
{
char *s, *send, *t;
char *tmp;
Check_Type(str, T_STRING);
tmp = ALLOCA_N(char, str->len*2);
tmp = ALLOCA_N(char, RSTRING(str)->len*2);
s = str->ptr; send = s + str->len;
s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
t = tmp;
for (; s != send; s++) {
@ -682,30 +831,41 @@ reg_s_quote(re, str)
return str_new(tmp, t - tmp);
}
static int
reg_get_kcode(re)
VALUE re;
{
int kcode = 0;
switch (RBASIC(re)->flags & KCODE_MASK) {
case KCODE_NONE:
kcode |= 2; break;
case KCODE_EUC:
kcode |= 4; break;
case KCODE_SJIS:
kcode |= 6; break;
default:
break;
}
return kcode;
}
static VALUE
reg_clone(re)
struct RRegexp *re;
VALUE re;
{
int flag = FL_TEST(re, REG_IGNORECASE);
int flag = FL_TEST(re, REG_IGNORECASE)?1:0;
if (FL_TEST(re, KCODE_FIXED)) {
switch (RBASIC(re)->flags & KCODE_MASK) {
case KCODE_NONE:
flag |= 2; break;
case KCODE_EUC:
flag |= 4; break;
case KCODE_SJIS:
flag |= 6; break;
default:
break;
}
flag |= reg_get_kcode(re);
}
return reg_new_1(CLASS_OF(re), re->str, re->len, flag);
return reg_new_1(CLASS_OF(re), RREGEXP(re)->str, RREGEXP(re)->len, flag);
}
VALUE
reg_regsub(str, src, regs)
struct RString *str;
struct RString *src;
VALUE str, src;
struct re_registers *regs;
{
VALUE val = 0;
@ -713,8 +873,8 @@ reg_regsub(str, src, regs)
char *p, *s, *e, c;
int no;
p = s = str->ptr;
e = s + str->len;
p = s = RSTRING(str)->ptr;
e = s + RSTRING(str)->len;
while (s < e) {
char *ss = s;
@ -737,11 +897,11 @@ reg_regsub(str, src, regs)
break;
case '`':
str_cat(val, src->ptr, BEG(0));
str_cat(val, RSTRING(src)->ptr, BEG(0));
continue;
case '\'':
str_cat(val, src->ptr+END(0), src->len-END(0));
str_cat(val, RSTRING(src)->ptr+END(0), RSTRING(src)->len-END(0));
continue;
case '+':
@ -761,7 +921,7 @@ reg_regsub(str, src, regs)
if (no >= 0) {
if (BEG(no) == -1) continue;
str_cat(val, src->ptr+BEG(no), END(no)-BEG(no));
str_cat(val, RSTRING(src)->ptr+BEG(no), END(no)-BEG(no));
}
}
@ -774,6 +934,41 @@ reg_regsub(str, src, regs)
return val;
}
#define IS_KCODE_FIXED(re) (FL_TEST((re), KCODE_FIXED)?1:0)
static int
reg_prepare_operation(re1, re2)
VALUE re1, re2;
{
int flag = 0;
Check_Type(re2, T_REGEXP);
flag = IS_KCODE_FIXED(re1)+IS_KCODE_FIXED(re2)*2;
switch (IS_KCODE_FIXED(re1)+IS_KCODE_FIXED(re2)*2) {
case 3: /* both have fixed kcode (must match) */
if (((RBASIC(re1)->flags^RBASIC(re2)->flags)&KCODE_MASK) != 0) {
Raise(eRegxpError, "kanji code mismatch");
}
/* fall through */
case 2: /* re2 has fixed kcode */
flag = reg_get_kcode(re2);
break;
case 1: /* re1 has fixed kcode */
flag = reg_get_kcode(re1);
break;
case 0: /* neither has fixed kcode */
flag = 0;
break;
}
if (FL_TEST(re1, REG_IGNORECASE) ^ FL_TEST(re2, REG_IGNORECASE)) {
Raise(eRegxpError, "casefold mismatch");
}
if (FL_TEST(re1, REG_IGNORECASE)) flag |= 0x1;
return flag;
}
static VALUE
kcode_getter()
{
@ -854,7 +1049,7 @@ Init_Regexp()
#ifdef DEFAULT_MBCTYPE
| DEFAULT_MBCTYPE
#endif
);
);
rb_define_virtual_variable("$~", match_getter, match_setter);
rb_define_virtual_variable("$&", last_match_getter, 0);
@ -872,15 +1067,21 @@ Init_Regexp()
rb_define_singleton_method(cRegexp, "quote", reg_s_quote, 1);
rb_define_method(cRegexp, "clone", reg_clone, 0);
rb_define_method(cRegexp, "==", reg_equal, 1);
rb_define_method(cRegexp, "=~", reg_match, 1);
rb_define_method(cRegexp, "===", reg_match, 1);
rb_define_method(cRegexp, "~", reg_match2, 0);
rb_define_method(cRegexp, "inspect", reg_inspect, 0);
rb_define_method(cRegexp, "source", reg_source, 0);
rb_define_method(cRegexp, "casefold?", reg_casefold_p, 0);
rb_define_method(cRegexp, "kcode", reg_kcode_method, 0);
rb_global_variable(&reg_cache);
rb_global_variable(&matchcache);
cMatch = rb_define_class("MatchingData", cData);
rb_define_method(cMatch, "to_a", match_to_a, 0);
rb_define_method(cMatch, "[]", match_aref, -1);
rb_define_method(cMatch, "to_s", match_to_s, 0);
rb_define_method(cMatch, "inspect", any_to_s, 0);
}

7
re.h
View file

@ -29,6 +29,9 @@ struct RMatch {
#define RMATCH(obj) (R_CAST(RMatch)(obj))
VALUE re_regcomp();
VALUE re_regsub();
int str_cicmp _((VALUE, VALUE));
VALUE reg_regcomp _((VALUE));
int reg_search _((VALUE, VALUE, int, struct re_registers *));
VALUE reg_regsub _((VALUE, VALUE, struct re_registers *));
void reg_free _((Regexp *));
#endif

1473
regex.c

File diff suppressed because it is too large Load diff

View file

@ -30,6 +30,7 @@
#define BYTEWIDTH 8
#define RE_REG_MAX ((1<<BYTEWIDTH)-1)
/* Maximum number of duplicates an interval can allow. */
#ifndef RE_DUP_MAX
@ -55,11 +56,6 @@ extern long re_syntax_options;
If not set, \| serves as the `or'-operator, and | is a literal. */
#define RE_NO_BK_VBAR (1L << 1)
/* If this bit is not set, plain + or ? serves as an operator, and \+, \? are
literals.
If set, \+, \? are operators and plain +, ? are literals. */
#define RE_BK_PLUS_QM (1L << 2)
/* If this bit is set, | binds tighter than ^ or $.
If not set, the contrary. */
#define RE_TIGHT_VBAR (1L << 3)
@ -207,7 +203,8 @@ struct re_pattern_buffer
comparing, or zero for no translation.
The translation is applied to a pattern when it is
compiled and to data when it is matched. */
char *must; /* Pointer to exact pattern which strings should have
to be matched. */
long re_nsub; /* Number of subexpressions found by the compiler. */
char fastmap_accurate;

137
ruby.c
View file

@ -10,6 +10,9 @@
************************************************/
#ifdef _WIN32
#include <windows.h>
#endif
#include "ruby.h"
#include "re.h"
#include "dln.h"
@ -18,9 +21,10 @@
#include <sys/types.h>
#include <fcntl.h>
#ifdef HAVE_STRING_H
# include <string.h>
#else
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifndef HAVE_STRING_H
char *strchr();
char *strrchr();
char *strstr();
@ -30,8 +34,8 @@ char *getenv();
static int version, copyright;
int debug = FALSE;
int verbose = FALSE;
VALUE debug = FALSE;
VALUE verbose = FALSE;
int tainting = FALSE;
static int sflag = FALSE;
@ -49,12 +53,18 @@ static void load_stdin();
static void load_file _((char *, int));
static void forbid_setid _((char *));
static int do_loop = FALSE, do_print = FALSE;
static int do_check = FALSE, do_line = FALSE;
static int do_split = FALSE;
static VALUE do_loop = FALSE, do_print = FALSE;
static VALUE do_check = FALSE, do_line = FALSE;
static VALUE do_split = FALSE;
static char *script;
static int origargc;
static char **origargv;
extern int sourceline;
extern char *sourcefile;
#ifndef RUBY_LIB
#define RUBY_LIB "/usr/local/lib/ruby"
#endif
@ -118,18 +128,14 @@ rb_require_modules()
{
struct req_list *list = req_list;
struct req_list *tmp;
extern void *eval_tree; /* hack to save syntax tree */
void *save;
req_list = 0;
save = eval_tree;
while (list) {
f_require(Qnil, str_new2(list->name));
tmp = list->next;
free(list);
list = tmp;
}
eval_tree = save;
}
static void
@ -331,6 +337,11 @@ proc_options(argcp, argvp)
}
break;
case '*':
case ' ':
if (s[1] == '-') s+=2;
break;
default:
Fatal("Unrecognized switch: -%s",s);
@ -366,11 +377,12 @@ proc_options(argcp, argvp)
if (do_search) {
char *path = getenv("RUBYPATH");
script = 0;
if (path) {
script = dln_find_file(script, path);
script = dln_find_file(argv[0], path);
}
if (!script) {
script = dln_find_file(script, getenv("PATH"));
script = dln_find_file(argv[0], getenv("PATH"));
}
if (!script) script = argv[0];
}
@ -457,14 +469,45 @@ load_file(fname, script)
char *p;
if ((p = strstr(RSTRING(line)->ptr, "ruby")) == 0) {
/* not ruby script, kick the program */
char **argv;
char *path;
char *pend = RSTRING(line)->ptr + RSTRING(line)->len;
p = RSTRING(line)->ptr + 2; /* skip `#!' */
if (pend[-1] == '\n') pend--; /* chomp line */
if (pend[-1] == '\r') pend--;
*pend = '\0';
while (p < pend && isspace(*p))
p++;
path = p; /* interpreter path */
while (p < pend && !isspace(*p))
p++;
*p++ = '\0';
if (p < pend) {
argv = ALLOCA_N(char*, origargc+3);
argv[1] = p;
MEMCPY(argv+2, origargv+1, char*, origargc);
}
else {
argv = origargv;
}
argv[0] = path;
execv(path, argv);
sourcefile = fname;
sourceline = 1;
Fatal("Can't exec %s", path);
}
start_read:
if (p = strstr(RSTRING(line)->ptr, "ruby -")) {
int argc; char *argv[2]; char **argvp = argv;
UCHAR *s;
s = RSTRING(line)->ptr;
while (isspace(*s++))
;
while (isspace(*s))
s++;
*s = '\0';
RSTRING(line)->ptr[RSTRING(line)->len-1] = '\0';
if (RSTRING(line)->ptr[RSTRING(line)->len-2] == '\r')
@ -497,11 +540,9 @@ load_stdin()
load_file("-", 1);
}
VALUE Progname;
VALUE Argv;
static int origargc;
static char **origargv;
VALUE rb_progname;
VALUE rb_argv;
VALUE rb_argv0;
static void
set_arg0(val, id)
@ -537,7 +578,7 @@ set_arg0(val, id)
while (++i < len)
*s++ = ' ';
}
Progname = str_taint(str_new2(origargv[0]));
rb_progname = str_taint(str_new2(origargv[0]));
}
void
@ -545,7 +586,7 @@ ruby_script(name)
char *name;
{
if (name) {
Progname = str_taint(str_new2(name));
rb_progname = str_taint(str_new2(name));
sourcefile = name;
}
}
@ -578,6 +619,40 @@ forbid_setid(s)
Fatal("No %s allowed while running setgid", s);
}
#if defined(_WIN32) || defined(DJGPP)
static char *
ruby_libpath()
{
static char libpath[FILENAME_MAX+1];
char *p;
#if defined(_WIN32)
GetModuleFileName(NULL, libpath, sizeof libpath);
#elif defined(DJGPP)
extern char *__dos_argv0;
strcpy(libpath, __dos_argv0);
#endif
p = strrchr(libpath, '\\');
if (p)
*p = 0;
if (!strcasecmp(p-4, "\\bin"))
p -= 4;
strcpy(p, "\\lib");
#if defined(__CYGWIN32__)
p = (char *)malloc(strlen(libpath)+10);
if (!p)
return 0;
cygwin32_conv_to_posix_path(libpath, p);
strcpy(libpath, p);
free(p);
#else
for (p = libpath; *p; p++)
if (*p == '\\')
*p = '/';
#endif
return libpath;
}
#endif
void
ruby_prog_init()
{
@ -591,6 +666,10 @@ ruby_prog_init()
rb_define_readonly_variable("$-p", &do_print);
rb_define_readonly_variable("$-l", &do_line);
#if defined(_WIN32) || defined(DJGPP)
addpath(ruby_libpath());
#endif
if (rb_safe_level() == 0) {
addpath(getenv("RUBYLIB"));
}
@ -607,12 +686,13 @@ ruby_prog_init()
addpath(".");
}
rb_define_hooked_variable("$0", &Progname, 0, set_arg0);
rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
Argv = ary_new();
rb_define_readonly_variable("$*", &Argv);
rb_define_global_const("ARGV", Argv);
rb_argv = ary_new();
rb_define_readonly_variable("$*", &rb_argv);
rb_define_global_const("ARGV", rb_argv);
rb_define_readonly_variable("$-a", &do_split);
rb_global_variable(&rb_argv0);
#ifdef MSDOS
/*
@ -636,7 +716,7 @@ ruby_set_argv(argc, argv)
else dln_argv0 = argv[0];
#endif
for (i=0; i < argc; i++) {
ary_push(Argv, str_taint(str_new2(argv[i])));
ary_push(rb_argv, str_taint(str_new2(argv[i])));
}
}
@ -650,6 +730,7 @@ ruby_process_options(argc, argv)
origargc = argc; origargv = argv;
ruby_script(argv[0]); /* for the time being */
rb_argv0 = str_taint(str_new2(argv[0]));
#if defined(USE_DLN_A_OUT)
dln_argv0 = argv[0];
#endif

152
ruby.h
View file

@ -21,6 +21,12 @@
# include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
#ifndef __STDC__
# define volatile
# ifdef __GNUC__
@ -41,11 +47,19 @@
#pragma alloca
#endif
typedef unsigned int UINT;
typedef UINT VALUE;
typedef UINT ID;
typedef unsigned short USHORT;
typedef unsigned long UINT;
#if SIZEOF_INT == SIZEOF_VOIDP
typedef int INT;
#elif SIZEOF_LONG == SIZEOF_VOIDP
typedef long INT;
#else
---->> ruby requires sizeof(void*) == sizeof(int/long) to be compiled. <<----
#endif
typedef UINT VALUE;
typedef unsigned int ID;
typedef unsigned char UCHAR;
#ifdef __STDC__
@ -71,11 +85,11 @@ typedef unsigned char UCHAR;
#endif
#define FIXNUM_MAX (LONG_MAX>>1)
#define FIXNUM_MIN RSHIFT((long)LONG_MIN,1)
#define FIXNUM_MIN RSHIFT((INT)LONG_MIN,1)
#define FIXNUM_FLAG 0x01
#define INT2FIX(i) (VALUE)(((int)(i))<<1 | FIXNUM_FLAG)
VALUE int2inum _((int));
#define INT2FIX(i) (VALUE)(((INT)(i))<<1 | FIXNUM_FLAG)
VALUE int2inum _((INT));
#define INT2NUM(v) int2inum(v)
#if (-1==(((-1)<<1)&FIXNUM_FLAG)>>1)
@ -83,22 +97,24 @@ VALUE int2inum _((int));
#else
# define RSHIFT(x,y) (((x)<0) ? ~((~(x))>>y) : (x)>>y)
#endif
#define FIX2INT(x) RSHIFT((int)x,1)
#define FIX2INT(x) RSHIFT((INT)x,1)
#define FIX2UINT(f) ((UINT)(f)>>1)
#define FIXNUM_P(f) (((int)(f))&FIXNUM_FLAG)
#define FIX2UINT(f) (((UINT)(f))>>1)
#define FIXNUM_P(f) (((long)(f))&FIXNUM_FLAG)
#define POSFIXABLE(f) ((f) <= FIXNUM_MAX)
#define NEGFIXABLE(f) ((f) >= FIXNUM_MIN)
#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
/* special contants - i.e. non-zero and non-fixnum constants */
#undef FALSE
#define FALSE 0
#undef TRUE
#define TRUE 2
#define Qnil 4
#define FALSE 0
#define TRUE 2
#define NIL 4
#define Qfalse 0
#define Qtrue 2
#define Qnil 4
int rb_test_false_or_nil _((VALUE));
# define RTEST(v) rb_test_false_or_nil((VALUE)(v))
#define NIL_P(v) ((VALUE)(v) == Qnil)
@ -135,7 +151,6 @@ VALUE rb_class_of _((VALUE));
#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
int rb_type _((VALUE));
#define TYPE(x) rb_type((VALUE)(x))
void rb_check_type _((VALUE,int));
@ -144,17 +159,22 @@ void rb_check_safe_str _((VALUE));
#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))
void rb_secure _((int));
#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):num2int(x))
VALUE num2fix _((VALUE));
int num2int _((VALUE));
#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):num2int(x))
double num2dbl _((VALUE));
#define NUM2DBL(x) num2dbl((VALUE)(x))
VALUE rb_newobj _((void));
#define NEWOBJ(obj,type) type *obj = (type*)rb_newobj()
#define OBJSETUP(obj,c,t) {\
RBASIC(obj)->class = (c);\
RBASIC(obj)->flags = (t);\
}
#define CLONESETUP(obj1,obj2) \
OBJSETUP(obj1,RBASIC(obj2)->class,RBASIC(obj2)->flags);
#define CLONESETUP(clone,obj) {\
OBJSETUP(clone,singleton_class_clone(RBASIC(obj)->class),RBASIC(obj)->flags);\
singleton_class_attached(RBASIC(clone)->class, (VALUE)clone);\
}
struct RBasic {
UINT flags;
@ -170,7 +190,7 @@ struct RClass {
struct RBasic basic;
struct st_table *iv_tbl;
struct st_table *m_tbl;
struct RClass *super;
VALUE super;
};
struct RFloat {
@ -182,7 +202,7 @@ struct RString {
struct RBasic basic;
UINT len;
UCHAR *ptr;
struct RString *orig;
VALUE orig;
};
struct RArray {
@ -278,13 +298,44 @@ struct RBignum {
#define FL_UMASK (0x7f<<FL_USHIFT)
int rb_special_const_p _((VALUE));
#define FL_ABLE(x) (!(FIXNUM_P(x)||rb_special_const_p((VALUE)(x))))
#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)
#define FL_SET(x,f) if (FL_ABLE(x)) {RBASIC(x)->flags |= (f);}
#define FL_UNSET(x,f) if(FL_ABLE(x)){RBASIC(x)->flags &= ~(f);}
#define FL_REVERSE(x,f) if(FL_ABLE(x)){RBASIC(x)->flags ^= f;}
#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(RUBY_NO_INLINE)
extern __inline__ int
rb_type(VALUE obj)
{
if (FIXNUM_P(obj)) return T_FIXNUM;
if (obj == Qnil) return T_NIL;
if (obj == FALSE) return T_FALSE;
if (obj == TRUE) return T_TRUE;
return BUILTIN_TYPE(obj);
}
extern __inline__ int
rb_special_const_p(VALUE obj)
{
return (FIXNUM_P(obj)||obj == Qnil||obj == FALSE||obj == TRUE)?TRUE:FALSE;
}
extern __inline__ int
rb_test_false_or_nil(VALUE v)
{
return (v != Qnil) && (v != FALSE);
}
#else
int rb_type _((VALUE));
int rb_special_const_p _((VALUE));
int rb_test_false_or_nil _((VALUE));
#endif
void *xmalloc _((unsigned long));
void *xcalloc _((unsigned long,unsigned long));
void *xrealloc _((void*,unsigned long));
#define ALLOC_N(type,n) (type*)xmalloc(sizeof(type)*(n))
#define ALLOC(type) (type*)xmalloc(sizeof(type))
#define REALLOC_N(var,type,n) (var)=(type*)xrealloc((char*)(var),sizeof(type)*(n))
@ -295,51 +346,53 @@ int rb_special_const_p _((VALUE));
#define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))
#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))
void *xmalloc _((unsigned long));
void *xcalloc _((unsigned long,unsigned long));
void *xrealloc _((void*,unsigned long));
VALUE rb_define_class _((char*,VALUE));
VALUE rb_define_module _((char*));
VALUE rb_define_class_under _((VALUE, char *, VALUE));
VALUE rb_define_module_under _((VALUE, char *));
void rb_include_module _((VALUE,VALUE));
void rb_extend_object _((VALUE,VALUE));
void rb_define_variable _((char*,VALUE*));
void rb_define_virtual_variable _((char*,VALUE(*)(),void(*)()));
void rb_define_hooked_variable _((char*,VALUE*,VALUE(*)(),void(*)()));
void rb_define_readonly_variable _((char*,VALUE*));
void rb_define_const _((VALUE,char*,VALUE));
void rb_define_global_const _((char*,VALUE));
void rb_define_method _((VALUE,char*,VALUE(*)(),int));
void rb_define_singleton_method _((VALUE,char*,VALUE(*)(),int));
void rb_define_function _((VALUE,char*,VALUE(*)(),int));
void rb_define_module_function _((VALUE,char*,VALUE(*)(),int));
void rb_define_global_function _((char *, VALUE (*)(), int));
void rb_undef_method _((VALUE,char*));
void rb_define_alias _((VALUE,char*,char*));
void rb_define_attr _((VALUE,ID,int));
void rb_define_attr _((VALUE,ID,int,int));
ID rb_intern _((char*));
char *rb_id2name _((ID));
ID rb_to_id _((VALUE));
char *rb_class2name _((VALUE));
int rb_method_boundp _((VALUE,ID,int));
void rb_p _((VALUE));
VALUE rb_eval_string _((char*));
VALUE rb_funcall();
int rb_scan_args();
VALUE rb_iv_get();
VALUE rb_iv_set();
void rb_const_set();
VALUE rb_const_get();
VALUE rb_yield();
int iterator_p();
VALUE rb_iv_get _((VALUE, char *));
VALUE rb_iv_set _((VALUE, char *, VALUE));
VALUE rb_const_get _((VALUE, ID));
VALUE rb_const_get_at _((VALUE, ID));
void rb_const_set _((VALUE, ID, VALUE));
VALUE rb_equal _((VALUE,VALUE));
extern int verbose, debug;
extern VALUE verbose, debug;
int rb_safe_level();
int rb_safe_level _((void));
void rb_set_safe_level _((int));
#ifdef __GNUC__
@ -350,7 +403,7 @@ volatile voidfn Fatal;
volatile voidfn Bug;
volatile voidfn WrongType;
volatile voidfn rb_sys_fail;
volatile voidfn rb_break;
volatile voidfn rb_iter_break;
volatile voidfn rb_exit;
volatile voidfn rb_fatal;
volatile voidfn rb_raise;
@ -361,17 +414,26 @@ void Fail();
void Fatal();
void Bug();
void WrongType();
void rb_sys_fail();
void rb_break();
void rb_exit();
void rb_fatal();
void rb_raise();
void rb_notimplement();
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));
#endif
void Error();
void Warning();
VALUE rb_each _((VALUE));
VALUE rb_yield _((VALUE));
int iterator_p _((void));
VALUE rb_iterate();
VALUE rb_rescue();
VALUE rb_ensure();
#include "intern.h"
#if defined(EXTLIB) && defined(USE_DLN_A_OUT)
/* hook for external modules */
static char *libs_to_be_linked[] = { EXTLIB, 0 };

View file

@ -9,7 +9,7 @@ while gets()
send = $_.rindex("\n%%") + 1
$_ = $_[sbeg, send-sbeg]
sub!(/.*\n/, "")
gsub!(/'{'/, "'\001'")
gsub!(/'\{'/, "'\001'")
gsub!(/'}'/, "'\002'")
gsub!('\*/', "\003\003")
gsub!("/\\*[^\003]*\003\003", '')

View file

@ -1,8 +1,10 @@
def fact(n)
if n == 0
1
else
n * fact(n-1)
return 1 if n == 0
f = 1
while n>0
f *= n
n -= 1
end
return f
end
print fact(ARGV[0].to_i), "\n"

View file

@ -1,6 +1,6 @@
$/ = nil
while gets()
if /^((void|VALUE|int|char *\*|ID|struct [\w_]+ *\*|st_table *\*) *)?\n([\w\d_]+)\(.*\)\n\s*((.+;\n)*){/
if /^((void|VALUE|int|char *\*|ID|struct [\w_]+ *\*|st_table *\*) *)?\n([\w\d_]+)\(.*\)\n\s*((.+;\n)*)\{/
$_ = $'
printf "%s %s(", $2, $3
args = []

View file

@ -131,7 +131,7 @@ The variable ruby-indent-level controls the amount of indentation.
(make-variable-buffer-local 'comment-column)
(setq comment-column 32)
(make-variable-buffer-local 'comment-start-skip)
(setq comment-start-skip "#+ *")
(setq comment-start-skip "\\(^\\|\\s-\\);?#+ *")
(make-local-variable 'parse-sexp-ignore-comments)
(setq parse-sexp-ignore-comments t)
(run-hooks 'ruby-mode-hook))
@ -385,6 +385,8 @@ The variable ruby-indent-level controls the amount of indentation.
))
((and (nth 2 state)(> (nth 2 state) 0)) ; in nest
(if (null (cdr (nth 1 state)))
(error "invalid nest"))
(goto-char (cdr (nth 1 state)))
(forward-word -1) ; skip back a keyword
(cond
@ -440,7 +442,10 @@ The variable ruby-indent-level controls the amount of indentation.
(and
(or (and (looking-at ruby-symbol-chars)
(skip-chars-backward ruby-symbol-chars)
(looking-at ruby-block-op-re))
(looking-at ruby-block-op-re)
(save-excursion
(goto-char (match-end 0))
(not (looking-at "[a-z_]"))))
(and (looking-at ruby-operator-chars)
(or (not (or (eq ?/ (char-after (point)))))
(null (nth 0 (ruby-parse-region parse-start (point)))))
@ -627,7 +632,7 @@ 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
'("\\bdef[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*[?!=]?\\|\\[\\]=?\\)"
'("^\\s *def[ \t]+.*$"
0 font-lock-function-name-face))
"*Additional expressions to highlight in ruby mode.")
(if (and (>= (string-to-int emacs-version) 20)

View file

@ -28,59 +28,59 @@ check "condition"
$x = '0';
$x == $x && ok(TRUE)
$x != $x && ok(FALSE)
$x == $x || ok(FALSE)
$x != $x || ok(TRUE)
$x == $x && ok(true)
$x != $x && ok(false)
$x == $x || ok(false)
$x != $x || ok(true)
# first test to see if we can run the tests.
check "if/unless";
$x = 'test';
ok(if $x == $x then TRUE else FALSE end)
$bad = FALSE
ok(if $x == $x then true else false end)
$bad = false
unless $x == $x
$bad = TRUE
$bad = true
end
ok(!$bad)
ok(unless $x != $x then TRUE else FALSE end)
ok(unless $x != $x then true else false end)
check "case"
case 5
when 1, 2, 3, 4, 6, 7, 8
ok(FALSE)
ok(false)
when 5
ok(TRUE)
ok(true)
end
case 5
when 5
ok(TRUE)
ok(true)
when 1..10
ok(FALSE)
ok(false)
end
case 5
when 1..10
ok(TRUE)
ok(true)
else
ok(FALSE)
ok(false)
end
case 5
when 5
ok(TRUE)
ok(true)
else
ok(FALSE)
ok(false)
end
case "foobar"
when /^f.*r$/
ok(TRUE)
ok(true)
else
ok(FALSE)
ok(false)
end
check "while/until";
@ -106,7 +106,7 @@ ok(!tmp.eof? && /vt100/)
tmp.close
# test next
$bad = FALSE
$bad = false
tmp = open("while_tmp", "r")
while tmp.gets()
next if /vt100/;
@ -116,7 +116,7 @@ ok(!(!tmp.eof? || /vt100/ || $bad))
tmp.close
# test redo
$bad = FALSE
$bad = false
tmp = open("while_tmp", "r")
while tmp.gets()
if gsub!('vt100', 'VT100')
@ -140,12 +140,12 @@ end
ok(sum == 220)
# test interval
$bad = FALSE
$bad = false
tmp = open("while_tmp", "r")
while tmp.gets()
break unless 1..2
if /vt100/ || /Amiga/ || /paper/
$bad = TRUE
$bad = true
break
end
end
@ -166,22 +166,22 @@ check "exception";
begin
fail "this must be handled"
ok(FALSE)
ok(false)
rescue
ok(TRUE)
ok(true)
end
$bad = TRUE
$bad = true
begin
fail "this must be handled no.2"
rescue
if $bad
$bad = FALSE
$bad = false
retry
ok(FALSE)
ok(false)
end
end
ok(TRUE)
ok(true)
# exception in rescue clause
$string = "this must be handled no.3"
@ -191,9 +191,9 @@ begin
rescue
fail $string
end
ok(FALSE)
ok(false)
rescue
ok(TRUE) if $! == $string
ok(true) if $! == $string
end
# exception in ensure clause
@ -203,39 +203,39 @@ begin
ensure
fail "exception in ensure clause"
end
ok(FALSE)
ok(false)
rescue
ok(TRUE)
ok(true)
end
$bad = TRUE
$bad = true
begin
begin
fail "this must be handled no.5"
ensure
$bad = FALSE
$bad = false
end
rescue
end
ok(!$bad)
$bad = TRUE
$bad = true
begin
begin
fail "this must be handled no.6"
ensure
$bad = FALSE
$bad = false
end
rescue
end
ok(!$bad)
$bad = TRUE
while TRUE
$bad = true
while true
begin
break
ensure
$bad = FALSE
$bad = false
end
end
ok(!$bad)
@ -292,6 +292,11 @@ ok("1 byte string".split(//).reverse.join(":") == "g:n:i:r:t:s: :e:t:y:b: :1")
$x = "a b c d"
ok($x.split == ['a', 'b', 'c', 'd'])
ok($x.split(' ') == ['a', 'b', 'c', 'd'])
ok(defined? "a".chomp)
ok("abc".scan(/./) == ["a", "b", "c"])
ok("1a2b3c".scan(/(\d.)/) == [["1a"], ["2b"], ["3c"]])
# non-greedy match
ok("a=12;b=22".scan(/(.*?)=(\d*?);?/) == [["a", "12"], ["b", "22"]])
$x = [1]
ok(($x * 5).join(":") == '1:1:1:1:1')
@ -312,16 +317,16 @@ ok(begin
for k,v in $y
fail if k*2 != v
end
TRUE
true
rescue
FALSE
false
end)
ok($x.length == 3)
ok($x.has_key?(1))
ok($x.has_value?(4))
ok($x.indexes(2,3) == [4,6])
ok($x == (1=>2, 2=>4, 3=>6))
ok($x == {1=>2, 2=>4, 3=>6})
$z = $y.keys.join(":")
ok($z == "1:2:3")
@ -371,39 +376,39 @@ ok(i == 5)
# iterator break/redo/next/retry
unless defined? loop
def loop
while TRUE
while true
yield
end
end
ok(FALSE)
ok(false)
else
ok(TRUE)
ok(true)
end
done = TRUE
done = true
loop{
break
done = FALSE
done = false
}
ok(done)
done = FALSE
$bad = FALSE
done = false
$bad = false
loop {
break if done
done = TRUE
done = true
next
$bad = TRUE
$bad = true
}
ok(!$bad)
done = FALSE
$bad = FALSE
done = false
$bad = false
loop {
break if done
done = TRUE
done = true
redo
$bad = TRUE
$bad = true
}
ok(!$bad)
@ -414,11 +419,11 @@ end
ok($x.size == 7)
ok($x == [1, 2, 3, 4, 5, 6, 7])
$done = FALSE
$done = false
$x = []
for i in 1 .. 7 # see how retry works in iterator loop
if i == 4 and not $done
$done = TRUE
$done = true
retry
end
$x.push(i)
@ -451,33 +456,33 @@ ok($x == -815915283247897734345611269596115894272000000000)
ok(2-(2**32) == -(2**32-2))
ok(2**32 - 5 == (2**32-3)-2)
$good = TRUE;
for i in 1000..1024
$good = FALSE if ((1<<i) != (2**i))
$good = true;
for i in 1000..1014
$good = false if ((1<<i) != (2**i))
end
ok($good)
$good = TRUE;
$good = true;
n1=1<<1000
for i in 1000..1024
$good = FALSE if ((1<<i) != n1)
for i in 1000..1014
$good = false if ((1<<i) != n1)
n1 *= 2
end
ok($good)
$good = TRUE;
$good = true;
n2=n1
for i in 1..10
n1 = n1 / 2
n2 = n2 >> 1
$good = FALSE if (n1 != n2)
$good = false if (n1 != n2)
end
ok($good)
$good = TRUE;
for i in 4000..4192
$good = true;
for i in 4000..4096
n1 = 1 << i;
$good = FALSE if ((n1**2-1) / (n1+1) != (n1-1))
$good = false if ((n1**2-1) / (n1+1) != (n1-1))
end
ok($good)
@ -486,13 +491,21 @@ check "string & char"
ok("abcd" == "abcd")
ok("abcd" =~ "abcd")
ok("abcd" === "abcd")
ok(("abc" =~ /^$/) == FALSE)
ok(("abc\n" =~ /^$/) == FALSE)
ok(("abc" =~ /^d*$/) == FALSE)
ok(("abc" =~ /^$/) == false)
ok(("abc\n" =~ /^$/) == false)
ok(("abc" =~ /^d*$/) == false)
ok(("abc" =~ /d*$/) == 3)
ok("" =~ /^$/)
ok("\n" =~ /^$/)
ok("a\n\n" =~ /^$/)
"abcabc" =~ /.*a/
ok($& == "abca")
"abcabc" =~ /.*c/
ok($& == "abcabc")
"abcabc" =~ /.*?a/
ok($& == "a")
"abcabc" =~ /.*?c/
ok($& == "abc")
$foo = "abc"
ok("#$foo = abc" == "abc = abc")
@ -523,13 +536,18 @@ ok(?a == ?a)
ok(?\C-a == 1)
ok(?\M-a == 225)
ok(?\M-\C-a == 129)
ok("a".upcase![0] == ?A)
ok("A".downcase![0] == ?a)
ok("abc".tr!("a-z", "A-Z") == "ABC")
ok("abcc".squeeze!("a-z") == "abc")
ok("abcd".delete!("bc") == "ad")
$x = "abcdef"
$y = [ ?a, ?b, ?c, ?d, ?e, ?f ]
$bad = FALSE
$bad = false
$x.each_byte {|i|
if i != $y.shift
$bad = TRUE
$bad = true
break
end
}
@ -556,6 +574,9 @@ ok(a == 1 && b == [2, 3])
*a = 1, 2, 3
ok(a == [1, 2, 3])
*a = 1..3
ok(a == [1, 2, 3])
check "call"
def aaa(a, b=100, *rest)
res = [a, b]
@ -566,38 +587,20 @@ end
# not enough argument
begin
aaa() # need at least 1 arg
ok(FALSE)
ok(false)
rescue
ok(TRUE)
ok(true)
end
begin
aaa # no arg given (exception raised)
ok(FALSE)
ok(false)
rescue
ok(TRUE)
end
begin
if aaa(1) == [1, 100]
ok(TRUE)
else
fail
end
rescue
ok(FALSE)
end
begin
if aaa(1, 2) == [1, 2]
ok(TRUE)
else
fail
end
rescue
ok(FALSE)
ok(true)
end
ok(aaa(1) == [1, 100])
ok(aaa(1, 2) == [1, 2])
ok(aaa(1, 2, 3, 4) == [1, 2, 3, 4])
ok(aaa(1, *[2, 3, 4]) == [1, 2, 3, 4])
@ -639,7 +642,7 @@ if defined? Process.kill
trap "SIGINT", proc{fail "Interrupt"}
x = FALSE
x = false
begin
Process.kill "SIGINT", $$
sleep 0.1
@ -648,26 +651,31 @@ if defined? Process.kill
end
ok(x && x =~ /Interrupt/)
else
ok(FALSE)
ok(false)
end
check "eval"
ok(eval("") == nil)
$bad=FALSE
eval 'while FALSE; $bad = TRUE; print "foo\n" end'
$bad=false
eval 'while false; $bad = true; print "foo\n" end'
ok(!$bad)
ok(eval('TRUE'))
ok(eval('true'))
ok(!eval('NIL'))
ok(!eval('nil'))
ok(!eval('FALSE'))
ok(!eval('false'))
$foo = 'ok(TRUE)'
$foo = 'ok(true)'
begin
eval $foo
rescue
ok(FALSE)
ok(false)
end
ok(eval("$foo") == 'ok(TRUE)')
ok(eval("TRUE") == TRUE)
ok(eval("$foo") == 'ok(true)')
ok(eval("true") == true)
i = 5
ok(eval("i == 5"))
ok(eval("i") == 5)
@ -685,11 +693,11 @@ end
$x = test_ev
ok(eval("local1", $x) == "local1") # static local var
ok(eval("local2", $x) == "local2") # dynamic local var
$bad = TRUE
$bad = true
begin
p eval("local1")
rescue NameError # must raise error
$bad = FALSE
$bad = false
end
ok(!$bad)
@ -700,11 +708,11 @@ module EvTest
end
ok(eval("EVTEST1", $x) == 25) # constant in module
ok(eval("evtest2", $x) == 125) # local var in module
$bad = TRUE
$bad = true
begin
eval("EVTEST1")
rescue NameError # must raise error
$bad = FALSE
$bad = false
end
ok(!$bad)
@ -716,7 +724,7 @@ tmp = open("script_tmp", "w")
tmp.print "print $zzz\n";
tmp.close
ok(`./ruby -s script_tmp -zzz` == 'TRUE')
ok(`./ruby -s script_tmp -zzz` == 'true')
ok(`./ruby -s script_tmp -zzz=555` == '555')
tmp = open("script_tmp", "w")
@ -744,11 +752,11 @@ end
tmp.close
`./ruby -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp`
done = TRUE
done = true
tmp = open("script_tmp", "r")
while tmp.gets
if $_.to_i % 5 != 0
done = FALSE
done = false
break
end
end
@ -796,9 +804,9 @@ ok(foo.test == "test")
begin
foo.test2
ok FALSE
ok false
rescue
ok TRUE
ok true
end
check "pack"
@ -843,9 +851,9 @@ ok($$.instance_of?(Fixnum))
# read-only variable
begin
$$ = 5
ok FALSE
ok false
rescue
ok TRUE
ok true
end
foobar = "foobar"
@ -931,9 +939,9 @@ begin
tmp = [0,1,2,3,4,5,6,7,8,9]
}
tmp = nil
ok TRUE
ok true
rescue
ok FALSE
ok false
end
if $failed > 0

View file

@ -1,13 +1,10 @@
require "tk"
TkButton.new {
text 'hello'
command proc{print "hello\n"}
pack('fill'=>'x')
}
TkButton.new {
text 'quit'
command 'exit'
pack('fill'=>'x')
}
TkButton.new(nil,
'text' => 'hello',
'command' => proc{print "hello\n"}).pack('fill'=>'x')
TkButton.new(nil,
'text' => 'quit',
'command' => 'exit').pack('fill'=>'x')
Tk.mainloop

View file

@ -1,37 +1,43 @@
#!/usr/local/bin/ruby
if ARGV[0] == "-c"
out_stdout = 1;
out_stdout = 1
ARGV.shift
end
$sawbegin = 0
$sawend = 0
while gets()
if /^begin\s*(\d*)\s*(\S*)/
$mode, $file = $1, $2
$sawbegin+=1
break
if out_stdout
out = STDOUT
else
out = open($file, "w") if $file != ""
end
out.binmode
next
end
end
fail "missing begin" if ! $sawbegin;
if out_stdout
out = STDOUT
else
out = open($file, "w") if $file != "";
end
raise "missing begin" unless $sawbegin
out.binmode
while gets()
if /^end/
$sawend+=1
break
out.close unless out_stdout
File.chmod $mode.oct, $file unless out_stdout
next
end
sub(/[a-z]+$/, ""); # handle stupid trailing lowercase letters
sub(/[a-z]+$/, "") # handle stupid trailing lowercase letters
next if /[a-z]/
next if !(((($_[0] - 32) & 077) + 2) / 3 == $_.length / 4)
out << $_.unpack("u");
out << $_.unpack("u") if $sawbegin > $sawend
end
fail "missing end" if !$sawend;
File.chmod $mode.oct, $file if ! out_stdout
exit 0;
raise "missing end" if $sawbegin > $sawend
raise "missing begin" if ! $sawbegin
exit 0

View file

@ -109,7 +109,7 @@ f_sprintf(argc, argv)
int argc;
VALUE *argv;
{
struct RString *fmt;
VALUE fmt;
char *buf, *p, *end;
int blen, bsiz;
VALUE result;
@ -122,7 +122,7 @@ f_sprintf(argc, argv)
#define FWIDTH 16
#define FPREC 32
int width, prec, flags = FNONE;
int width = 0, prec = 0, flags = FNONE;
VALUE str;
@ -142,15 +142,15 @@ f_sprintf(argc, argv)
#define GETARG() \
((argc == 0)?(ArgError("too few argument."),0):(argc--,((argv++)[0])))
fmt = (struct RString*)GETARG();
fmt = GETARG();
Check_Type(fmt, T_STRING);
blen = 0;
bsiz = 120;
buf = ALLOC_N(char, bsiz);
end = fmt->ptr + fmt->len;
end = RSTRING(fmt)->ptr + RSTRING(fmt)->len;
for (p = fmt->ptr; p < end; p++) {
for (p = RSTRING(fmt)->ptr; p < end; p++) {
char *t;
for (t = p; t < end && *t != '%'; t++) ;
@ -597,7 +597,7 @@ f_sprintf(argc, argv)
}
sprint_exit:
if (verbose && argc > 1) {
if (RTEST(verbose) && argc > 1) {
ArgError("too many argument for format string");
}
result = str_new(buf, blen);

792
string.c

File diff suppressed because it is too large Load diff

127
struct.c
View file

@ -44,7 +44,7 @@ struct_members(obj)
VALUE
struct_getmember(obj, id)
struct RStruct *obj;
VALUE obj;
ID id;
{
VALUE nstr, member, slot;
@ -58,7 +58,7 @@ struct_getmember(obj, id)
slot = INT2FIX(id);
for (i=0; i<RARRAY(member)->len; i++) {
if (RARRAY(member)->ptr[i] == slot) {
return obj->ptr[i];
return RSTRUCT(obj)->ptr[i];
}
}
NameError("%s is not struct member", rb_id2name(id));
@ -72,16 +72,16 @@ struct_ref(obj)
return struct_getmember(obj, rb_frame_last_func());
}
static VALUE struct_ref0(obj) struct RStruct *obj; {return obj->ptr[0];}
static VALUE struct_ref1(obj) struct RStruct *obj; {return obj->ptr[1];}
static VALUE struct_ref2(obj) struct RStruct *obj; {return obj->ptr[2];}
static VALUE struct_ref3(obj) struct RStruct *obj; {return obj->ptr[3];}
static VALUE struct_ref4(obj) struct RStruct *obj; {return obj->ptr[4];}
static VALUE struct_ref5(obj) struct RStruct *obj; {return obj->ptr[5];}
static VALUE struct_ref6(obj) struct RStruct *obj; {return obj->ptr[6];}
static VALUE struct_ref7(obj) struct RStruct *obj; {return obj->ptr[7];}
static VALUE struct_ref8(obj) struct RStruct *obj; {return obj->ptr[8];}
static VALUE struct_ref9(obj) struct RStruct *obj; {return obj->ptr[9];}
static VALUE struct_ref0(obj) VALUE obj; {return RSTRUCT(obj)->ptr[0];}
static VALUE struct_ref1(obj) VALUE obj; {return RSTRUCT(obj)->ptr[1];}
static VALUE struct_ref2(obj) VALUE obj; {return RSTRUCT(obj)->ptr[2];}
static VALUE struct_ref3(obj) VALUE obj; {return RSTRUCT(obj)->ptr[3];}
static VALUE struct_ref4(obj) VALUE obj; {return RSTRUCT(obj)->ptr[4];}
static VALUE struct_ref5(obj) VALUE obj; {return RSTRUCT(obj)->ptr[5];}
static VALUE struct_ref6(obj) VALUE obj; {return RSTRUCT(obj)->ptr[6];}
static VALUE struct_ref7(obj) VALUE obj; {return RSTRUCT(obj)->ptr[7];}
static VALUE struct_ref8(obj) VALUE obj; {return RSTRUCT(obj)->ptr[8];}
static VALUE struct_ref9(obj) VALUE obj; {return RSTRUCT(obj)->ptr[9];}
VALUE (*ref_func[10])() = {
struct_ref0,
@ -98,8 +98,7 @@ VALUE (*ref_func[10])() = {
static VALUE
struct_set(obj, val)
struct RStruct *obj;
VALUE val;
VALUE obj, val;
{
VALUE nstr, member, slot;
int i;
@ -112,7 +111,7 @@ struct_set(obj, val)
for (i=0; i<RARRAY(member)->len; i++) {
slot = RARRAY(member)->ptr[i];
if (id_attrset(FIX2INT(slot)) == rb_frame_last_func()) {
return obj->ptr[i] = val;
return RSTRUCT(obj)->ptr[i] = val;
}
}
NameError("not struct member");
@ -123,26 +122,25 @@ VALUE struct_alloc();
static VALUE
make_struct(name, member)
struct RString *name;
struct RArray *member;
VALUE name, member;
{
VALUE nstr;
ID id;
int i;
id = rb_intern(name->ptr);
id = rb_intern(RSTRING(name)->ptr);
if (!rb_is_const_id(id)) {
NameError("identifier %s needs to be constant", name->ptr);
NameError("identifier %s needs to be constant", RSTRING(name)->ptr);
}
nstr = rb_define_class_under(cStruct, name->ptr, cStruct);
rb_iv_set(nstr, "__size__", INT2FIX(member->len));
nstr = rb_define_class_under(cStruct, RSTRING(name)->ptr, cStruct);
rb_iv_set(nstr, "__size__", INT2FIX(RARRAY(member)->len));
rb_iv_set(nstr, "__member__", member);
rb_define_singleton_method(nstr, "new", struct_alloc, -2);
rb_define_singleton_method(nstr, "[]", struct_alloc, -2);
rb_define_singleton_method(nstr, "members", struct_s_members, 0);
for (i=0; i< member->len; i++) {
ID id = FIX2INT(member->ptr[i]);
for (i=0; i< RARRAY(member)->len; i++) {
ID id = FIX2INT(RARRAY(member)->ptr[i]);
if (i<10) {
rb_define_method_id(nstr, id, ref_func[i], 0);
}
@ -199,15 +197,14 @@ struct_s_def(argc, argv)
VALUE
struct_alloc(class, values)
VALUE class;
struct RArray *values;
VALUE class, values;
{
VALUE size;
int n;
size = rb_iv_get(class, "__size__");
n = FIX2INT(size);
if (n < values->len) {
if (n < RARRAY(values)->len) {
ArgError("struct size differs");
}
else {
@ -216,8 +213,8 @@ struct_alloc(class, values)
st->len = n;
st->ptr = 0; /* avoid GC crashing */
st->ptr = ALLOC_N(VALUE, n);
MEMCPY(st->ptr, values->ptr, VALUE, values->len);
memclear(st->ptr+values->len, n - values->len);
MEMCPY(st->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len);
memclear(st->ptr+RARRAY(values)->len, n - RARRAY(values)->len);
return (VALUE)st;
}
@ -248,12 +245,12 @@ struct_new(class, va_alist)
static VALUE
struct_each(s)
struct RStruct *s;
VALUE s;
{
int i;
for (i=0; i<s->len; i++) {
rb_yield(s->ptr[i]);
for (i=0; i<RSTRUCT(s)->len; i++) {
rb_yield(RSTRUCT(s)->ptr[i]);
}
return Qnil;
}
@ -262,7 +259,7 @@ char *rb_class2name();
static VALUE
struct_to_s(s)
struct RStruct *s;
VALUE s;
{
char *name, *buf;
@ -274,7 +271,7 @@ struct_to_s(s)
static VALUE
struct_inspect(s)
struct RStruct *s;
VALUE s;
{
char *name = rb_class2name(CLASS_OF(s));
VALUE str, member;
@ -288,7 +285,7 @@ struct_inspect(s)
sprintf(buf, "#<%s ", name);
str = str_new2(buf);
for (i=0; i<s->len; i++) {
for (i=0; i<RSTRUCT(s)->len; i++) {
VALUE str2, slot;
char *p;
@ -299,7 +296,7 @@ struct_inspect(s)
p = rb_id2name(FIX2INT(slot));
str_cat(str, p, strlen(p));
str_cat(str, "=", 1);
str2 = rb_inspect(s->ptr[i]);
str2 = rb_inspect(RSTRUCT(s)->ptr[i]);
str2 = obj_as_string(str2);
str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
}
@ -310,102 +307,100 @@ struct_inspect(s)
static VALUE
struct_to_a(s)
struct RStruct *s;
VALUE s;
{
return ary_new4(s->len, s->ptr);
return ary_new4(RSTRUCT(s)->len, RSTRUCT(s)->ptr);
}
static VALUE
struct_clone(s)
struct RStruct *s;
VALUE s;
{
NEWOBJ(st, struct RStruct);
CLONESETUP(st, s);
st->len = s->len;
st->len = RSTRUCT(s)->len;
st->ptr = 0; /* avoid GC crashing */
st->ptr = ALLOC_N(VALUE, s->len);
MEMCPY(st->ptr, s->ptr, VALUE, st->len);
st->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len);
MEMCPY(st->ptr, RSTRUCT(s)->ptr, VALUE, st->len);
return (VALUE)st;
}
VALUE
struct_aref(s, idx)
struct RStruct *s;
VALUE idx;
VALUE s, idx;
{
int i;
i = NUM2INT(idx);
if (i < 0) i = s->len - i;
if (i < 0) i = RSTRUCT(s)->len - i;
if (i < 0)
IndexError("offset %d too small for struct(size:%d)", i, s->len);
if (s->len <= i)
IndexError("offset %d too large for struct(size:%d)", i, s->len);
return s->ptr[i];
IndexError("offset %d too small for struct(size:%d)", i, RSTRUCT(s)->len);
if (RSTRUCT(s)->len <= i)
IndexError("offset %d too large for struct(size:%d)", i, RSTRUCT(s)->len);
return RSTRUCT(s)->ptr[i];
}
VALUE
struct_aset(s, idx, val)
struct RStruct *s;
VALUE idx, val;
VALUE s, idx, val;
{
int i;
i = NUM2INT(idx);
if (i < 0) i = s->len - i;
if (i < 0) i = RSTRUCT(s)->len - i;
if (i < 0)
IndexError("offset %d too small for struct(size:%d)", i, s->len);
if (s->len <= i)
IndexError("offset %d too large for struct(size:%d)", i, s->len);
return s->ptr[i] = val;
IndexError("offset %d too small for struct(size:%d)", i, RSTRUCT(s)->len);
if (RSTRUCT(s)->len <= i)
IndexError("offset %d too large for struct(size:%d)", i, RSTRUCT(s)->len);
return RSTRUCT(s)->ptr[i] = val;
}
static VALUE
struct_equal(s, s2)
struct RStruct *s, *s2;
VALUE s, s2;
{
int i;
if (TYPE(s2) != T_STRUCT) return FALSE;
if (CLASS_OF(s) != CLASS_OF(s2)) return FALSE;
if (s->len != s2->len) {
if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {
Bug("inconsistent struct"); /* should never happen */
}
for (i=0; i<s->len; i++) {
if (!rb_equal(s->ptr[i], s2->ptr[i])) return FALSE;
for (i=0; i<RSTRUCT(s)->len; i++) {
if (!rb_equal(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return FALSE;
}
return TRUE;
}
static VALUE
struct_eql(s, s2)
struct RStruct *s, *s2;
VALUE s, s2;
{
int i;
if (TYPE(s2) != T_STRUCT) return FALSE;
if (CLASS_OF(s) != CLASS_OF(s2)) return FALSE;
if (s->len != s2->len) {
if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {
Bug("inconsistent struct"); /* should never happen */
}
for (i=0; i<s->len; i++) {
if (!rb_eql(s->ptr[i], s2->ptr[i])) return FALSE;
for (i=0; i<RSTRUCT(s)->len; i++) {
if (!rb_eql(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return FALSE;
}
return TRUE;
}
static VALUE
struct_hash(s)
struct RStruct *s;
VALUE s;
{
int i, h;
h = CLASS_OF(s);
for (i=0; i<s->len; i++) {
h ^= rb_hash(s->ptr[i]);
for (i=0; i<RSTRUCT(s)->len; i++) {
h ^= rb_hash(RSTRUCT(s)->ptr[i]);
}
return INT2FIX(h);
}

65
time.c
View file

@ -13,10 +13,6 @@
#include "ruby.h"
#include <sys/types.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include <time.h>
#ifndef NT
#ifdef HAVE_SYS_TIME_H
@ -437,20 +433,6 @@ time_asctime(time)
return str_new(buf, len);
}
static VALUE
time_coerce(time1, time2)
VALUE time1, time2;
{
if (TYPE(time2) == T_FLOAT) {
double d = RFLOAT(time2)->value;
unsigned int i = (unsigned int) d;
return assoc_new(time_new(i, (int)((d - (double)i)*1e6)),time1);
}
return assoc_new(time_new(NUM2INT(time2), 0), time1);
}
static VALUE
time_plus(time1, time2)
VALUE time1, time2;
@ -673,13 +655,40 @@ time_to_a(time)
return ary;
}
#define SMALLBUF 100
static int
rb_strftime(buf, format, time)
char ** volatile buf;
char * volatile format;
struct tm * volatile time;
{
volatile int i;
int len;
len = strftime(*buf, SMALLBUF, format, time);
if (len != 0) return len;
for (i=1024; i<8192; i+=1024) {
*buf = xmalloc(i);
len = strftime(*buf, i-1, format, time);
if (len == 0) {
free(*buf);
continue;
}
return len;
}
ArgError("bad strftime format or result too long");
}
static VALUE
time_strftime(time, format)
VALUE time, format;
{
struct time_object *tobj;
char buf[100];
char buffer[SMALLBUF];
char *buf = buffer;
int len;
VALUE str;
Check_Type(format, T_STRING);
GetTimeval(time, tobj);
@ -687,22 +696,23 @@ time_strftime(time, format)
time_localtime(time);
}
if (strlen(RSTRING(format)->ptr) < RSTRING(format)->len) {
/* Ruby string contains \0. */
VALUE str;
/* Ruby string may contain \0's. */
int l;
char *p = RSTRING(format)->ptr, *pe = p + RSTRING(format)->len;
str = str_new(0, 0);
while (p < pe) {
len = strftime(buf, 100, p, &(tobj->tm));
len = rb_strftime(&buf, p, &(tobj->tm));
str_cat(str, buf, len);
l = strlen(p);
p += l + 1;
p += strlen(p) + 1;
if (len > SMALLBUF) free(buf);
}
return str;
}
len = strftime(buf, 100, RSTRING(format)->ptr, &(tobj->tm));
return str_new(buf, len);
len = rb_strftime(&buf, RSTRING(format)->ptr, &(tobj->tm));
str = str_new(buf, len);
if (len > SMALLBUF) free(buf);
return str;
}
static VALUE
@ -767,7 +777,6 @@ Init_Time()
rb_define_method(cTime, "to_s", time_asctime, 0);
rb_define_method(cTime, "inspect", time_asctime, 0);
rb_define_method(cTime, "to_a", time_to_a, 0);
rb_define_method(cTime, "coerce", time_coerce, 1);
rb_define_method(cTime, "+", time_plus, 1);
rb_define_method(cTime, "-", time_minus, 1);
@ -776,7 +785,9 @@ Init_Time()
rb_define_method(cTime, "min", time_min, 0);
rb_define_method(cTime, "hour", time_hour, 0);
rb_define_method(cTime, "mday", time_mday, 0);
rb_define_method(cTime, "day", time_mday, 0);
rb_define_method(cTime, "mon", time_mon, 0);
rb_define_method(cTime, "month", time_mon, 0);
rb_define_method(cTime, "year", time_year, 0);
rb_define_method(cTime, "wday", time_wday, 0);
rb_define_method(cTime, "yday", time_yday, 0);

View file

@ -1,6 +1,6 @@
/^SHELL/s,/bin/sh,$(COMPSEC),
/^VPATH/s/:/;/g
s/@srcdir@/./g
s/@top_srcdir@/../
s/@CC@/gcc/
s/@CPP@/gcc -E/
s/@CPPFLAGS@//
@ -11,7 +11,7 @@ s/@INSTALL@/ginstall -c/
s/@INSTALL_PROGRAM@/${INSTALL}/
s/@INSTALL_DATA@/${INSTALL} -m 644/
s/@SET_MAKE@//
s/@CFLAGS@/-g -O -I./
s/@CFLAGS@/-g -O2 -I./
s/@STATIC@//
s/@LDFLAGS@//
s/@LIBS@//
@ -40,7 +40,7 @@ s/y\.tab\.c/y_tab.c/
#/`rm -f ruby`/s//`rm -f ruby.exe`/
#/`cp miniruby ruby`/s//`cp miniruby.exe ruby.exe`/
/^all:.*miniruby/ {
n;N;N;N;c\
n;c\
cd ext\
../miniruby ./extmk.rb\
cd ..

54
util.c
View file

@ -10,11 +10,42 @@
************************************************/
#define RUBY_NO_INLINE
#include "ruby.h"
int
rb_type(obj)
VALUE obj;
{
if (FIXNUM_P(obj)) return T_FIXNUM;
if (obj == Qnil) return T_NIL;
if (obj == FALSE) return T_FALSE;
if (obj == TRUE) return T_TRUE;
return BUILTIN_TYPE(obj);
}
int
rb_special_const_p(obj)
VALUE obj;
{
if (FIXNUM_P(obj)) return TRUE;
if (obj == Qnil) return TRUE;
if (obj == FALSE) return TRUE;
if (obj == TRUE) return TRUE;
return FALSE;
}
int
rb_test_false_or_nil(v)
VALUE v;
{
return (v != Qnil) && (v != FALSE);
}
#include "util.h"
#ifdef HAVE_STRING_H
# include <string.h>
#else
#ifndef HAVE_STRING_H
char *strchr();
#endif
@ -136,7 +167,7 @@ static char suffix2[] = ".~~~";
#define strEQ(s1,s2) (strcmp(s1,s2) == 0)
void
add_suffix(struct RString *str, char *suffix)
add_suffix(VALUE str, char *suffix)
{
int baselen;
int extlen = strlen(suffix);
@ -144,25 +175,25 @@ add_suffix(struct RString *str, char *suffix)
int slen;
char buf[1024];
if (str->len > 1000)
Fatal("Cannot do inplace edit on long filename (%d characters)", str->len);
if (RSTRING(str)->len > 1000)
Fatal("Cannot do inplace edit on long filename (%d characters)", RSTRING(str)->len);
#if defined(DJGPP) || defined(__CYGWIN32__) || defined(NT)
/* Style 0 */
slen = str->len;
slen = RSTRING(str)->len;
str_cat(str, suffix, extlen);
#if defined(DJGPP)
if (_USE_LFN) return;
#else
if (valid_filename(str->ptr)) return;
if (valid_filename(RSTRING(str)->ptr)) return;
#endif
/* Fooey, style 0 failed. Fix str before continuing. */
str->ptr[str->len = slen] = '\0';
RSTRING(str)->ptr[RSTRING(str)->len = slen] = '\0';
#endif
slen = extlen;
t = buf; baselen = 0; s = str->ptr;
t = buf; baselen = 0; s = RSTRING(str)->ptr;
while ( (*t = *s) && *s != '.') {
baselen++;
if (*s == '\\' || *s == '/') baselen = 0;
@ -194,7 +225,7 @@ fallback:
(void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5);
}
str_resize(str, strlen(buf));
memcpy(str->ptr, buf, str->len);
memcpy(RSTRING(str)->ptr, buf, RSTRING(str)->len);
}
#if defined(__CYGWIN32__) || defined(NT)
@ -232,7 +263,6 @@ valid_filename(char *s)
#include <stdio.h> /* For FILENAME_MAX */
#include <errno.h> /* For errno */
#include <ctype.h> /* For tolower */
#include <string.h> /* For strlen() */
#include <fcntl.h> /* For LFN stuff */
#include <go32.h>
#include <dpmi.h> /* For dpmisim */

View file

@ -13,10 +13,6 @@
#include "node.h"
#include "st.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif
static st_table *rb_global_tbl;
st_table *rb_class_tbl;
#define global_tbl rb_global_tbl
@ -39,7 +35,7 @@ Init_var_tables()
struct fc_result {
ID name;
VALUE class;
VALUE klass;
VALUE path;
VALUE track;
struct fc_result *prev;
@ -67,7 +63,7 @@ fc_i(key, value, res)
else {
path = str_new2(name);
}
if (value == res->class) {
if (value == res->klass) {
res->name = key;
res->path = path;
return ST_STOP;
@ -87,7 +83,7 @@ fc_i(key, value, res)
arg.name = 0;
arg.path = path;
arg.class = res->class;
arg.klass = res->klass;
arg.track = value;
arg.prev = res;
st_foreach(RCLASS(value)->iv_tbl, fc_i, &arg);
@ -101,15 +97,14 @@ fc_i(key, value, res)
}
static VALUE
find_class_path(class)
VALUE class;
find_class_path(cls)
VALUE cls;
{
VALUE c;
struct fc_result arg;
arg.name = 0;
arg.path = 0;
arg.class = class;
arg.klass = cls;
arg.track = cObject;
arg.prev = 0;
if (RCLASS(cObject)->iv_tbl) {
@ -119,30 +114,30 @@ find_class_path(class)
st_foreach(class_tbl, fc_i, &arg);
}
if (arg.name) {
rb_iv_set(class, "__classpath__", arg.path);
rb_iv_set(cls, "__classpath__", arg.path);
return arg.path;
}
return Qnil;
}
static VALUE
classname(class)
VALUE class;
classname(cls)
VALUE cls;
{
VALUE path;
while (TYPE(class) == T_ICLASS || FL_TEST(class, FL_SINGLETON)) {
class = (VALUE)RCLASS(class)->super;
while (TYPE(cls) == T_ICLASS || FL_TEST(cls, FL_SINGLETON)) {
cls = (VALUE)RCLASS(cls)->super;
}
path = rb_iv_get(class, "__classpath__");
path = rb_iv_get(cls, "__classpath__");
if (NIL_P(path)) {
path = rb_iv_get(class, "__classid__");
path = rb_iv_get(cls, "__classid__");
if (!NIL_P(path)) {
path = str_new2(rb_id2name(FIX2INT(path)));
}
}
if (NIL_P(path)) {
path = find_class_path(class);
path = find_class_path(cls);
if (NIL_P(path)) {
return 0;
}
@ -153,29 +148,38 @@ classname(class)
}
VALUE
rb_class_path(class)
VALUE class;
mod_name(mod)
VALUE mod;
{
VALUE path = classname(class);
VALUE path = classname(mod);
if (path) return path;
return str_new(0,0);
}
VALUE
rb_class_path(cls)
VALUE cls;
{
VALUE path = classname(cls);
if (path) return path;
else {
char buf[256];
char *s = "Class";
if (TYPE(class) == T_MODULE) s = "Module";
sprintf(buf, "#<%s 0x%x>", s, class);
if (TYPE(cls) == T_MODULE) s = "Module";
sprintf(buf, "#<%s 0x%x>", s, cls);
return str_new2(buf);
}
}
void
rb_set_class_path(class, under, name)
VALUE class, under;
rb_set_class_path(cls, under, name)
VALUE cls, under;
char *name;
{
VALUE str;
char *s;
if (under == cObject) {
str = str_new2(name);
@ -185,7 +189,7 @@ rb_set_class_path(class, under, name)
str_cat(str, "::", 2);
str_cat(str, name, strlen(name));
}
rb_iv_set(class, "__classpath__", str);
rb_iv_set(cls, "__classpath__", str);
}
VALUE
@ -199,17 +203,17 @@ rb_path2class(path)
}
void
rb_name_class(class, id)
VALUE class;
rb_name_class(cls, id)
VALUE cls;
ID id;
{
extern VALUE cString;
if (cString) {
rb_iv_set(class, "__classpath__", str_new2(rb_id2name(id)));
rb_iv_set(cls, "__classpath__", str_new2(rb_id2name(id)));
}
else {
rb_iv_set(class, "__classid__", INT2FIX(id));
rb_iv_set(cls, "__classid__", INT2FIX(id));
}
}
@ -231,39 +235,37 @@ rb_autoload_id(id, filename)
}
void
rb_autoload(class, filename)
char *class, *filename;
rb_autoload(cls, filename)
char *cls, *filename;
{
rb_autoload_id(rb_intern(class), filename);
rb_autoload_id(rb_intern(cls), filename);
}
VALUE
f_autoload(obj, class, file)
VALUE obj, class;
struct RString *file;
f_autoload(obj, cls, file)
VALUE obj, cls, file;
{
ID id = rb_to_id(class);
ID id = rb_to_id(cls);
Check_Type(file, T_STRING);
rb_autoload_id(id, file->ptr);
rb_autoload_id(id, RSTRING(file)->ptr);
return Qnil;
}
char *
rb_class2name(class)
VALUE class;
rb_class2name(cls)
VALUE cls;
{
return RSTRING(rb_class_path(class))->ptr;
return RSTRING(rb_class_path(cls))->ptr;
}
struct trace_var {
int removed;
void (*func)();
void *data;
struct trace_var *next;
};
VALUE f_untrace_var();
struct global_entry {
ID id;
void *data;
@ -496,7 +498,7 @@ f_trace_var(argc, argv)
cmd = f_lambda();
}
if (NIL_P(cmd)) {
return f_untrace_var(argc, argv, Qnil);
return f_untrace_var(argc, argv);
}
id = rb_to_id(var);
if (!st_lookup(global_tbl, id, &entry)) {
@ -506,11 +508,33 @@ f_trace_var(argc, argv)
trace->next = entry->trace;
trace->func = rb_trace_eval;
trace->data = (void*)cmd;
trace->removed = 0;
entry->trace = trace;
return Qnil;
}
static void
remove_trace(entry)
struct global_entry *entry;
{
struct trace_var *trace = entry->trace;
struct trace_var t;
struct trace_var *next;
t.next = trace;
trace = &t;
while (trace->next) {
next = trace->next;
if (next->removed) {
trace->next = next->next;
free(next);
}
trace = next;
}
entry->trace = t.next;
}
VALUE
f_untrace_var(argc, argv)
int argc;
@ -532,34 +556,27 @@ f_untrace_var(argc, argv)
trace = entry->trace;
while (trace) {
struct trace_var *next = trace->next;
ary_push(ary, trace->data);
free(trace);
ary_push(ary, (VALUE)trace->data);
trace->removed = 1;
trace = next;
}
entry->trace = 0;
if (!entry->block_trace) remove_trace(entry);
return ary;
}
else {
struct trace_var t;
struct trace_var *next;
t.next = entry->trace;
trace = &t;
while (trace->next) {
next = trace->next;
if (next->data == (void*)cmd) {
trace->next = next->next;
free(next);
entry->trace = t.next;
while (trace) {
if (trace->data == (void*)cmd) {
trace->removed = 1;
if (!entry->block_trace) remove_trace(entry);
return ary_new3(1, cmd);
}
trace = next;
trace = trace->next;
}
}
return Qnil;
}
VALUE
rb_gvar_get(entry)
struct global_entry *entry;
@ -589,6 +606,7 @@ trace_en(entry)
struct global_entry *entry;
{
entry->block_trace = 0;
remove_trace(entry);
}
VALUE
@ -604,7 +622,7 @@ rb_gvar_set(entry, val)
}
(*entry->setter)(val, entry->id, entry->data, entry);
if (!entry->block_trace) {
if (entry->trace && !entry->block_trace) {
entry->block_trace = 1;
trace.trace = entry->trace;
trace.val = val;
@ -632,6 +650,31 @@ rb_gvar_defined(entry)
return TRUE;
}
static int
gvar_i(key, entry, ary)
ID key;
struct global_entry *entry;
VALUE ary;
{
ary_push(ary, str_new2(rb_id2name(entry->id)));
return ST_CONTINUE;
}
VALUE
f_global_variables()
{
VALUE ary = ary_new();
char buf[3];
char *s = "^&`'+123456789";
st_foreach(global_tbl, gvar_i, ary);
while (*s) {
sprintf(buf, "$%c", *s++);
ary_push(ary, str_new2(buf));
}
return ary;
}
void
rb_alias_variable(name1, name2)
ID name1;
@ -650,7 +693,7 @@ rb_alias_variable(name1, name2)
VALUE
rb_ivar_get(obj, id)
struct RObject *obj;
VALUE obj;
ID id;
{
VALUE val;
@ -659,7 +702,7 @@ rb_ivar_get(obj, id)
case T_OBJECT:
case T_CLASS:
case T_MODULE:
if (obj->iv_tbl && st_lookup(obj->iv_tbl, id, &val))
if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, &val))
return val;
return Qnil;
default:
@ -673,7 +716,7 @@ rb_ivar_get(obj, id)
VALUE
rb_ivar_set(obj, id, val)
struct RObject *obj;
VALUE obj;
ID id;
VALUE val;
{
@ -685,8 +728,8 @@ rb_ivar_set(obj, id, val)
case T_OBJECT:
case T_CLASS:
case T_MODULE:
if (!obj->iv_tbl) obj->iv_tbl = new_idhash();
st_insert(obj->iv_tbl, id, val);
if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = new_idhash();
st_insert(ROBJECT(obj)->iv_tbl, id, val);
break;
default:
TypeError("class %s can not have instance variables",
@ -698,55 +741,117 @@ rb_ivar_set(obj, id, val)
VALUE
rb_ivar_defined(obj, id)
struct RObject *obj;
VALUE obj;
ID id;
{
if (!rb_is_instance_id(id)) return FALSE;
switch (TYPE(obj)) {
case T_OBJECT:
case T_CLASS:
case T_MODULE:
if (obj->iv_tbl && st_lookup(obj->iv_tbl, id, 0))
if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, 0))
return TRUE;
break;
}
return FALSE;
}
static int
ivar_i(key, value, hash)
ID key;
VALUE value;
VALUE hash;
{
if (rb_is_instance_id(key)) {
hash_aset(hash, str_new2(rb_id2name(key)), value);
}
return ST_CONTINUE;
}
VALUE
rb_const_get_at(class, id)
struct RClass *class;
obj_instance_variables(obj)
VALUE obj;
{
VALUE hash = hash_new();
switch (TYPE(obj)) {
case T_OBJECT:
case T_CLASS:
case T_MODULE:
if (ROBJECT(obj)->iv_tbl) {
st_foreach(ROBJECT(obj)->iv_tbl, ivar_i, hash);
}
break;
default:
break;
}
return hash;
}
VALUE
obj_remove_instance_variable(obj, name)
VALUE obj, name;
{
VALUE val;
ID id = rb_to_id(name);
if (rb_ivar_defined(obj, id)) {
NameError("`%s' is not an instance variable", rb_id2name(id));
}
switch (TYPE(obj)) {
case T_OBJECT:
case T_CLASS:
case T_MODULE:
if (ROBJECT(obj)->iv_tbl) {
st_delete(ROBJECT(obj)->iv_tbl, &id, &val);
}
break;
default:
TypeError("object %s can not have instance variables",
rb_class2name(CLASS_OF(obj)));
break;
}
return obj;
}
VALUE
rb_const_get_at(cls, id)
VALUE cls;
ID id;
{
VALUE value;
if (class->iv_tbl && st_lookup(class->iv_tbl, id, &value)) {
if (RCLASS(cls)->iv_tbl && st_lookup(RCLASS(cls)->iv_tbl, id, &value)) {
return value;
}
if ((VALUE)class == cObject) {
return rb_const_get(class, id);
if (cls == cObject) {
return rb_const_get(cls, id);
}
NameError("Uninitialized constant %s::%s",
RSTRING(rb_class_path(class))->ptr,
RSTRING(rb_class_path(cls))->ptr,
rb_id2name(id));
/* not reached */
}
VALUE
rb_const_get(class, id)
struct RClass *class;
rb_const_get(cls, id)
VALUE cls;
ID id;
{
VALUE value;
struct RClass *tmp;
VALUE tmp;
tmp = class;
tmp = cls;
while (tmp) {
if (tmp->iv_tbl && st_lookup(tmp->iv_tbl, id, &value)) {
if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
return value;
}
tmp = tmp->super;
tmp = RCLASS(tmp)->super;
}
if (BUILTIN_TYPE(class) == T_MODULE) {
if (BUILTIN_TYPE(cls) == T_MODULE) {
return rb_const_get(cObject, id);
}
@ -762,13 +867,13 @@ rb_const_get(class, id)
module = str_new2(modname);
free(modname);
f_require(0, module);
return rb_const_get(class, id);
return rb_const_get(cls, id);
}
/* Uninitialized constant */
if (class && (VALUE)class != cObject)
if (cls && cls != cObject)
NameError("Uninitialized constant %s::%s",
RSTRING(rb_class_path(class))->ptr,
RSTRING(rb_class_path(cls))->ptr,
rb_id2name(id));
else {
NameError("Uninitialized constant %s",rb_id2name(id));
@ -776,61 +881,81 @@ rb_const_get(class, id)
/* not reached */
}
int
const_i(key, value, hash)
static int
const_i(key, value, ary)
ID key;
VALUE value;
VALUE hash;
VALUE ary;
{
if (rb_is_const_id(key)) {
hash_aset(hash, str_new2(rb_id2name(key)), value);
VALUE kval = str_new2(rb_id2name(key));
if (!ary_includes(ary, kval)) {
ary_push(ary, kval);
}
}
return ST_CONTINUE;
}
static int
autoload_i(key, name, ary)
ID key;
char *name;
VALUE ary;
{
VALUE kval = str_new2(rb_id2name(key));
if (!ary_includes(ary, kval)) {
ary_push(ary, kval);
}
return ST_CONTINUE;
}
VALUE
mod_constants(argc, argv, mod)
int argc;
VALUE *argv;
struct RClass *mod;
mod_const_at(mod, ary)
VALUE mod, ary;
{
VALUE option;
VALUE hash;
rb_scan_args(argc, argv, "01", &option);
hash = hash_new();
st_foreach(mod->iv_tbl, const_i, hash);
if (!FL_TEST(mod, FL_SINGLETON)) {
mod = mod->super;
if (!mod) {
Bug("no superclass for singleton class");
}
st_foreach(mod->iv_tbl, const_i, hash);
if (RCLASS(mod)->iv_tbl) {
st_foreach(RCLASS(mod)->iv_tbl, const_i, ary);
}
if (RTEST(option)) {
for (;;) {
mod = mod->super;
if (!mod) break;
st_foreach(mod->iv_tbl, const_i, hash);
}
st_foreach(class_tbl, const_i, hash);
if ((VALUE)mod == cObject) {
st_foreach(class_tbl, const_i, ary);
if (autoload_tbl) {
st_foreach(autoload_tbl, const_i, hash);
st_foreach(autoload_tbl, autoload_i, ary);
}
}
return hash;
return ary;
}
VALUE
mod_constants(mod)
VALUE mod;
{
return mod_const_at(mod, ary_new());
}
VALUE
mod_const_of(mod, ary)
VALUE mod;
VALUE ary;
{
mod_const_at(mod, ary);
for (;;) {
mod = RCLASS(mod)->super;
if (!mod) break;
mod_const_at(mod, ary);
}
return ary;
}
int
rb_const_defined_at(class, id)
struct RClass *class;
rb_const_defined_at(cls, id)
VALUE cls;
ID id;
{
if (class->iv_tbl && st_lookup(class->iv_tbl, id, 0)) {
if (RCLASS(cls)->iv_tbl && st_lookup(RCLASS(cls)->iv_tbl, id, 0)) {
return TRUE;
}
if ((VALUE)class == cObject) {
return rb_const_defined(class, id);
if (cls == cObject) {
return rb_const_defined(cls, id);
}
return FALSE;
}
@ -845,15 +970,15 @@ rb_autoload_defined(id)
}
int
rb_const_defined(class, id)
struct RClass *class;
rb_const_defined(cls, id)
VALUE cls;
ID id;
{
while (class) {
if (class->iv_tbl && st_lookup(class->iv_tbl, id, 0)) {
while (cls) {
if (RCLASS(cls)->iv_tbl && st_lookup(RCLASS(cls)->iv_tbl, id, 0)) {
return TRUE;
}
class = class->super;
cls = RCLASS(cls)->super;
}
if (st_lookup(class_tbl, id, 0))
return TRUE;
@ -861,24 +986,24 @@ rb_const_defined(class, id)
}
void
rb_const_set(class, id, val)
struct RClass *class;
rb_const_set(cls, id, val)
VALUE cls;
ID id;
VALUE val;
{
if (!class->iv_tbl) {
class->iv_tbl = new_idhash();
if (!RCLASS(cls)->iv_tbl) {
RCLASS(cls)->iv_tbl = new_idhash();
}
else if (st_lookup(class->iv_tbl, id, 0)) {
else if (st_lookup(RCLASS(cls)->iv_tbl, id, 0)) {
NameError("already initialized constant %s", rb_id2name(id));
}
st_insert(class->iv_tbl, id, val);
st_insert(RCLASS(cls)->iv_tbl, id, val);
}
void
rb_define_const(class, name, val)
VALUE class;
rb_define_const(cls, name, val)
VALUE cls;
char *name;
VALUE val;
{
@ -886,17 +1011,15 @@ rb_define_const(class, name, val)
if (!rb_is_const_id(id)) {
NameError("wrong constant name %s", name);
}
rb_const_set(class, id, val);
rb_const_set(cls, id, val);
}
extern VALUE mKernel;
void
rb_define_global_const(name, val)
char *name;
VALUE val;
{
rb_define_const(mKernel, name, val);
rb_define_const(cObject, name, val);
}
VALUE

View file

@ -25,7 +25,7 @@ Init_version()
void
show_version()
{
fprintf(stderr, "ruby - version %s (%s)\n", RUBY_VERSION, RUBY_PLATFORM);
fprintf(stderr, "ruby %s(%s) [%s]\n", RUBY_VERSION, VERSION_DATE, RUBY_PLATFORM);
}
void

View file

@ -1,2 +1,2 @@
#define RUBY_VERSION "1.0-971225"
#define VERSION_DATE "97/12/25"
#define RUBY_VERSION "1.1b5"
#define VERSION_DATE "98/01/16"

View file

@ -15,10 +15,10 @@ INSTALL_DATA = $(INSTALL) -m 644
PURIFY =
#CFLAGS = -nologo -DNT=1 -Ox
#LDFLAGS = $(CFLAGS) -Fm
CFLAGS = -nologo -DNT=1 -Zi -MD
LDFLAGS = $(CFLAGS) -Fm -MD
CFLAGS = -nologo -DNT=1 -Ox
LDFLAGS = $(CFLAGS) -Fm
#CFLAGS = -nologo -DNT=1 -Zi -MD
#LDFLAGS = $(CFLAGS) -Fm -MD
LIBS = $(EXTLIBS) advapi32.lib wsock32.lib
MISSING = crypt.obj setenv.obj alloca.obj nt.obj
@ -29,6 +29,8 @@ bindir =
libdir =
STACK = 0x200000
ORGLIBPATH = $(LIB)
#MISCLIBS = win32\sdbm.lib
#### End of system configuration section. ####
@ -56,6 +58,7 @@ OBJS = array.obj \
inits.obj \
io.obj \
math.obj \
marshal.obj \
numeric.obj \
object.obj \
pack.obj \
@ -77,31 +80,29 @@ OBJS = array.obj \
version.obj \
$(MISSING)
all: miniruby.exe ext/Setup
all: miniruby.exe ext/Setup $(MISCLIBS)
cd ext
set LIB=..\..\win32;$(ORGLIBPATH)
..\miniruby .\extmk.rb static
# ..\miniruby .\extmk.rb
cd ..
miniruby.exe: $(OBJS) $(MAINOBJ) $(EXTOBJS)
@echo $(EXTOBJS)
@echo $(LIBS)
@rm -f miniruby.exe
# $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(LIBS) -o miniruby.exe
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(LIBS) -o miniruby.exe -link /NOD:LIBC
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(LIBS) -o miniruby.exe
ruby.exe: $(LIBRUBY) $(MAINOBJ) $(EXTOBJS) ruby.dll
@echo $(EXTOBJS)
@echo $(LIBS)
ruby.exe: $(LIBRUBY) $(MAINOBJ) $(EXTOBJS) rubymw.dll
@rm -f ruby.exe
# $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY) $(LIBS) -o ruby.exe
# $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY) $(LIBS) -o ruby.exe -link /DEF:rubyexe.def /NOD:LIBC
$(CC) $(LDFLAGS) $(MAINOBJ) -o ruby.exe ruby.lib -link /NOD:LIBC /STACK:$(STACK)
$(CC) $(LDFLAGS) $(MAINOBJ) -o ruby.exe rubymw.lib -link /STACK:$(STACK)
ruby.dll: $(LIBRUBY) $(EXTOBJS)
@echo $(EXTOBJS)
@echo $(LIBS)
@rm -f ruby.dll
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY) $(LIBS) -o ruby.dll -link /DLL /DEF:ruby.def /NOD:LIBC
rubymw.dll: $(LIBRUBY) $(EXTOBJS)
set LIB=.\win32;$(ORGLIBPATH)
@rm -f rubymw.dll
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY) $(LIBS) -o rubymw.dll -link /DLL /DEF:ruby.def
@mv rubymw.map rubydll.map
$(LIBRUBY): $(OBJS)
lib /OUT:$(LIBRUBY) $(OBJS)
@ -188,6 +189,13 @@ parse.c: parse.y
sed -e "s!^extern char \*getenv();!/* & */!" y.tab.c > parse.c
@rm y.tab.c
win32\sdbm.lib : win32\sdbm.c win32\sdbm.h
cd win32
$(CC) $(CFLAGS) $(CPPFLAGS) -DMSDOS -c sdbm.c
lib /OUT:sdbm.lib sdbm.obj
copy sdbm.h ndbm.h
cd ..
# Prevent GNU make v3 from overflowing arg limit on SysV.
.NOEXPORT:
###

View file

@ -1,55 +1,424 @@
LIBRARY ruby.dll
LIBRARY rubymw.dll
CODE LOADONCALL
DATA LOADONCALL
DESCRIPTION 'win32 ruby.dll'
DESCRIPTION 'win32 rubymw.dll'
EXPORTS
;global objects
;array.c:
cArray
;bignum.c:
cBignum
;eval.c:
cProc
;file.c:
cFile
;hash.c:
cHash
;io.c:
cIO
;numeric.c:
cNumeric
cFloat
cInteger
cFixnum
;object.c
cObject
cModule
cClass
cFixnum
cData
;re.c:
cRegexp
;string.c:
cString
cStruct
; procedures/methods
;missing/nt.c
NtInitialize
myfdopen
myaccept
mybind
myconnect
mygetpeername
mygetsockname
mygetsockopt
myioctlsocket
mylisten
myrecv
myrecvfrom
mysend
mysendto
mysetsockopt
myshutdown
mysocket
mygethostbyaddr
mygethostbyname
mygethostname
mygetprotobyname
mygetprotobynumber
mygetservbyname
mygetservbyport
;array.c
memclear
ary_freeze
ary_new2
ary_new
ary_new3
ary_new4
assoc_new
ary_store
ary_push
ary_pop
ary_shift
ary_unshift
ary_entry
ary_each
ary_join
ary_to_s
ary_reverse
ary_sort_bang
ary_sort
ary_delete
ary_delete_at
ary_plus
ary_concat
ary_assoc
ary_rassoc
ary_includes
;bignum.c
big_clone
big_2comp
big_norm
uint2big
int2big
uint2inum
int2inum
str2inum
big2str
big2int
big_to_i
dbl2big
big2dbl
big_to_f
big_plus
big_minus
big_mul
big_pow
big_and
big_or
big_xor
big_lshift
big_rand
;class.c
class_new
singleton_class_new
singleton_class_clone
rb_define_class_id
rb_define_class
rb_define_class_under
module_new
rb_define_module_id
rb_define_module
rb_define_module_under
rb_include_module
rb_define_method_id
rb_define_method
rb_undef_method
rb_define_private_method
rb_singleton_class
rb_define_singleton_method
rb_define_module_function
rb_define_global_function
rb_define_alias
rb_define_attr
rb_scan_args
; dln.c
dln_load
dln_find_exe
dln_find_file
; enum.c
rb_each
enum_length
; error.c
Error
Error_Append
Warning
Bug
rb_check_type
exc_new
exc_new2
exc_new3
Raise
TypeError
ArgError
NameError
IndexError
Fail
rb_notimplement
LoadError
Fatal
rb_sys_fail
;eval.c
rb_clear_cache
rb_add_method
rb_alias
rb_method_boundp
dyna_var_defined
dyna_var_ref
dyna_var_asgn
rb_safe_level
rb_set_safe_level
rb_check_safe_str
rb_secure
ruby_init
ruby_options
ruby_run
;class.c
;;rb_define_module_function
;;rb_define_const
;;rb_define_singleton_method
;;rb_define_alias
rb_define_alias
rb_define_attr
rb_define_class
rb_define_class_id
rb_define_class_under
rb_define_global_function
rb_define_method
rb_define_method_id
rb_define_module
rb_define_module_function
rb_define_module_id
rb_define_module_under
rb_define_private_method
rb_define_singleton_method
rb_scan_args
;variable.c
rb_define_const
rb_define_hooked_variable
rb_define_global_const
rb_define_readonly_variable
rb_define_variable
rb_define_virtual_variable
;string.c
rb_eval_string
rb_eval_cmd
rb_trap_eval
rb_test_false_or_nil
rb_respond_to
rb_exit
rb_raise
rb_fatal
rb_interrupt
iterator_p
rb_yield_0
rb_yield
rb_iterate
rb_rescue
rb_ensure
rb_apply
rb_funcall
rb_funcall2
rb_backtrace
rb_frame_last_func
f_load
rb_provide
f_require
class_new_instance
rb_extend_object
f_lambda
gc_mark_threads
thread_schedule
thread_wait_fd
thread_fd_writable
thread_wait_for
thread_alone
thread_select
thread_sleep
thread_sleep_forever
thread_create
thread_interrupt
; file.c
file_open
eaccess
file_s_expand_path
; gc.c
xmalloc
xcalloc
xrealloc
gc_s_enable
gc_s_disable
rb_global_variable
rb_newobj
data_object_alloc
gc_mark_locations
gc_mark_maybe
gc_mark
gc_force_recycle
gc_mark_frame
gc_gc
; hash.c
rb_hash
hash_new
hash_aref
hash_aset
; inits.c
rb_call_inits
; io.c
eof_error
io_writable
io_readable
io_write
io_gets_method
io_gets
io_getc
io_ungetc
io_fptr_finalize
io_close
io_binmode
io_mode_flags
rb_fopen
rb_fdopen
io_unbuffered
io_reopen
f_gets
rb_str_setter
; numeric.c
num_zerodiv
num_coerce_bin
float_new
flo_pow
num2int
num2fix
fix2str
fix_to_s
num_upto
fix_upto
; object.c
rb_equal
rb_eql
obj_equal
any_to_s
rb_inspect
obj_is_instance_of
obj_is_kind_of
obj_alloc
rb_to_id
rb_class_of
rb_type
rb_special_const_p
rb_Integer
rb_Float
rb_String
rb_Array
; parse.c
;;compile_string
;;compile_file
;;node_newnode
nodetype
nodeline
id_attrset
rb_intern
rb_id2name
rb_is_const_id
rb_is_instance_id
local_var_append
backref_get
backref_set
lastline_get
lastline_set
; process.c
rb_proc_exec
rb_syswait
; range.c
range_new
range_beg_end
; re.c
str_cicmp
reg_search
reg_nth_defined
reg_nth_match
reg_last_match
reg_match_pre
reg_match_post
reg_match_last
reg_free
reg_new
reg_regcomp
reg_match
reg_match2
reg_regsub
rb_set_kcode
; ruby.c
rb_require_modules
rb_load_file
ruby_script
ruby_prog_init
ruby_set_argv
ruby_process_options
; signal.c
gc_mark_trap_list
rb_trap_exit
rb_trap_exec
; st.c
st_init_table_with_size
st_init_table
st_init_numtable
st_init_strtable
st_free_table
st_lookup
st_insert
st_add_direct
st_find_or_add
st_copy
st_delete
st_delete_safe
st_foreach
; string.c
str_new
str_new2
str_new3
str_new4
;numeric.c
num2int
obj_as_string
str_dup
str_plus
str_times
str_substr
str_modify
str_freeze
str_dup_freezed
str_taint
str_tainted
str_resize
str_cat
str_hash
str_cmp
str_upto
str_inspect
str_split
; struct.c
struct_getmember
struct_define
struct_alloc
struct_new
struct_aref
struct_aset
; time.c
time_new
time_timeval
; util.c
scan_oct
scan_hex
add_suffix
;variable.c
new_idhash
rb_class_path
rb_set_class_path
rb_path2class
rb_name_class
rb_autoload
f_autoload
rb_class2name
rb_global_entry
gc_mark_global_tbl
rb_define_hooked_variable
rb_define_variable
rb_define_readonly_variable
rb_define_virtual_variable
rb_gvar_get
rb_gvar_set
rb_gvar_set2
rb_gvar_defined
rb_alias_variable
rb_ivar_get
rb_ivar_set
rb_ivar_defined
rb_const_get_at
rb_const_get
mod_constants
rb_const_defined_at
rb_autoload_defined
rb_const_defined
rb_const_set
rb_define_const
rb_define_global_const
rb_iv_get
rb_iv_set
; version.c
show_version
show_copyright
;error.c
rb_check_type
Fatal
;gc.c
xmalloc
xcalloc