1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@394 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1999-02-09 06:08:24 +00:00
parent 9b64dfe3b8
commit 115eb4595c
37 changed files with 704 additions and 398 deletions

View file

@ -1,3 +1,39 @@
Tue Feb 9 01:22:49 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (yylex): do not ignore newlines in mbchars.
* io.c (rb_file_s_open): mode can be specified by flags like
open(2), e.g. File::open(path, File::CREAT|File::WRONLY).
* io.c (rb_f_open): bit-wise mode flags for pipes
* io.c (Init_IO): bit flags for open.
Sat Feb 6 22:56:21 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* string.c (rb_str_sub_bang): should not overwrite match data by
regexp match within the block.
* string.c (rb_str_gsub_bang): ditto.
Sat Feb 6 03:06:17 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* re.c (match_getter): accessng $~ without matching caused SEGV.
Fri Feb 5 22:11:08 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
* parse.y (yylex): binary literal support, like 0b01001.
* parse.y (yylex): octal numbers can contain `_'s.
* parse.y (yylex): warns if non-octal number follows immediately
after octal literal.
* parse.y (yylex): now need at least one digit after prefix such
as 0x, or 0b.
* bignum.c (rb_str2inum): recognize binary numbers like 0b0101.
Fri Feb 5 03:26:56 1999 Yasuhiro Fukuma <yasuf@big.or.jp> Fri Feb 5 03:26:56 1999 Yasuhiro Fukuma <yasuf@big.or.jp>
* ruby.c (proc_options): -e without program prints error. * ruby.c (proc_options): -e without program prints error.

View file

@ -109,25 +109,21 @@ bugs.
1.4 Convert C data into VALUE 1.4 Convert C data into VALUE
VALUEの実際の構造は To convert C data to the values of Ruby:
* FIXNUMの場合 * FIXNUM
1bit右シフトしてLSBを立てる right shift 1 bit, and turn on LSB.
* その他のポインタの場合 * Other pointer values
そのままVALUEにキャストする cast to VALUE.
となっていますよってLSBをチェックすればVALUEがFIXNUMかど You can determine whether VALUE is pointer or not, by checking LSB.
うかわかるわけです(ポインタのLSBが立っていないことを仮定して
いる)
ですからFIXNUM以外のRubyのオブジェクトの構造体は単にVALUE Notice Ruby does not allow arbitrary pointer value to be VALUE. They
にキャストするだけでVALUEに変換出来ますただし任意の構造 should be pointers to the structures which Ruby knows. The known
体がVALUEにキャスト出来るわけではありませんキャストするの structures are defined in <ruby.h>.
はRubyの知っている構造体(ruby.hで定義されているstruct RXxxx
のもの)だけにしておいてください.
To convert C numbers to Ruby value, use these macros. To convert C numbers to Ruby value, use these macros.
@ -356,9 +352,8 @@ Ruby nil in C scope.
3.2 Global variables shared between C and Ruby 3.2 Global variables shared between C and Ruby
CとRubyで大域変数を使って情報を共有できます共有できる大域 Information can be shared between two worlds, using shared global
変数にはいくつかの種類があります.そのなかでもっとも良く使わ variables. To define them, you can use functions listed below:
れると思われるのはrb_define_variable()です.
void rb_define_variable(char *name, VALUE *var) void rb_define_variable(char *name, VALUE *var)
@ -371,28 +366,21 @@ function below.
void rb_define_readonly_variable(char *name, VALUE *var) void rb_define_readonly_variable(char *name, VALUE *var)
これら変数の他にhookをつけた大域変数を定義できますhook付き You can defined hooked variables. The accessor functions (getter and
の大域変数は以下の関数を用いて定義しますhook付き大域変数の setter) are called on access to the hooked variables.
値の参照や設定はhookで行う必要があります
void rb_define_hooked_variable(char *name, VALUE *var, void rb_define_hooked_variable(char *name, VALUE *var,
VALUE (*getter)(), VALUE (*setter)()) VALUE (*getter)(), VALUE (*setter)())
この関数はCの関数によってhookのつけられた大域変数を定義しま If you need to supply either setter or getter, just supply 0 for the
変数が参照された時には関数getterが変数に値がセットされ hook you don't need. If both hooks are 0, rb_define_hooked_variable()
た時には関数setterが呼ばれるhookを指定しない場合はgetterや works just like rb_define_variable().
setterに0を指定します
# getterもsetterも0ならばrb_define_variable()と同じになる.
それからCの関数によって実現されるRubyの大域変数を定義する
関数があります.
void rb_define_virtual_variable(char *name, void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)()) VALUE (*getter)(), VALUE (*setter)())
この関数によって定義されたRubyの大域変数が参照された時には This function defines the Ruby global variable without corresponding C
getterが変数に値がセットされた時にはsetterが呼ばれます variable. The value of the variable will be set/get only by hooks.
The prototypes of the getter and setter functions are as following: The prototypes of the getter and setter functions are as following:
@ -401,34 +389,25 @@ The prototypes of the getter and setter functions are as following:
3.3 Encapsulate C data into Ruby object 3.3 Encapsulate C data into Ruby object
Cの世界で定義されたデータ(構造体)をRubyのオブジェクトとして To wrapping and objectify the C pointer as Ruby object (so called
取り扱いたい場合がありえますこのような場合にはDataという DATA), use Data_Wrap_Struct().
RubyオブジェクトにCの構造体(へのポインタ)をくるむことでRuby
オブジェクトとして取り扱えるようになります.
To wrapping and objectify the C pointer, use Data_Wrap_Struct().
Data_Wrap_Struct(class,mark,free,ptr) Data_Wrap_Struct(class,mark,free,ptr)
Data_Wrap_Struct() returns a created Data object. Data_Wrap_Struct() returns a created DATA object. The class argument
is the class for the DATA object. The mark argument is the function
to mark Ruby objects pointed by this data. The free argument is the
function to free the pointer allocation. The functions, mark and
free, will be called from garbage collector.
classはこのDataオブジェクトのクラスですptrはカプセル化する You can allocate and wrap the structure in one step.
Cの構造体へのポインタですmarkはこの構造体がRubyのオブジェ
クトへの参照がある時に使う関数です.そのような参照を含まない
時には0を指定します
# そのような参照は勧められません.
freeはこの構造体がもう不要になった時に呼ばれる関数ですこの
関数がガーベージコレクタから呼ばれます.
Cの構造体の割当とDataオブジェクトの生成を同時に行うマクロと
して以下のものが提供されています.
Data_Make_Struct(class, type, mark, free, sval) Data_Make_Struct(class, type, mark, free, sval)
This macro returns an allocated Data object, wrapping the pointer to This macro returns an allocated Data object, wrapping the pointer to
the structure, which is also allocated. the structure, which is also allocated. This macro works like:
(sval = ALLOC(type), Data_Wrap_Struct(class, mark, free, sval))
Arguments, class, mark, free, works like thier counterpart of Arguments, class, mark, free, works like thier counterpart of
Data_Wrap_Struct(). The pointer to allocated structure will be Data_Wrap_Struct(). The pointer to allocated structure will be
@ -445,9 +424,9 @@ See example below for detail.
4¡¥Example - Create dbm module 4¡¥Example - Create dbm module
ここまでの説明でとりあえず拡張ライブラリは作れるはずです. OK, here's the example to make extension library. This is the
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に extension to access dbm. The full source is included in ext/
して段階的に説明します. directory in the Ruby's source tree.
(1) make the directory (1) make the directory

View file

@ -191,6 +191,10 @@ rb_str2inum(str, base)
str++; str++;
base = 16; base = 16;
} }
else if (*str == 'b' || *str == 'B') {
str++;
base = 2;
}
else { else {
base = 8; base = 8;
} }
@ -204,10 +208,13 @@ rb_str2inum(str, base)
while (str[0] == '0') str++; while (str[0] == '0') str++;
len = 3*strlen(str)*sizeof(char); len = 3*strlen(str)*sizeof(char);
} }
else { /* base == 10 or 16 */ else { /* base == 10, 2 or 16 */
if (base == 16 && str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) { if (base == 16 && str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
str += 2; str += 2;
} }
if (base == 2 && str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
str += 2;
}
while (str[0] == '0') str++; while (str[0] == '0') str++;
len = 4*strlen(str)*sizeof(char); len = 4*strlen(str)*sizeof(char);
} }

94
configure vendored
View file

@ -3798,10 +3798,21 @@ echo "configure:3765: checking whether OS depend dynamic link works" >&5
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
linux*) LDSHARED="gcc -shared" linux*) LDSHARED="gcc -shared"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
freebsd*) LDSHARED="gcc -shared" freebsd*) LDSHARED="gcc -shared"
test -x /usr/bin/objformat && LDFLAGS="-rdynamic" if test -x /usr/bin/objformat -a \
`/usr/bin/objformat` = "elf" ; then
LDFLAGS="-rdynamic"
DLDFLAGS='-Wl,-soname,$(.TARGET)'
rb_cv_freebsd_elf=yes
fi
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
netbsd*) LDSHARED="ld -Bshareable" netbsd*) LDSHARED="ld -Bshareable"
case "$host_cpu" in
alpha|mips)
LDFLAGS="-export-dynamic" ;;
*)
;;
esac
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
openbsd*) LDSHARED="ld -Bforcearchive -Bshareable" openbsd*) LDSHARED="ld -Bforcearchive -Bshareable"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
@ -3843,12 +3854,12 @@ if test "$ac_cv_header_a_out_h" = yes; then
if test "$with_dln_a_out" = yes || test "$rb_cv_dlopen" = unknown; then if test "$with_dln_a_out" = yes || test "$rb_cv_dlopen" = unknown; then
cat confdefs.h > config.h cat confdefs.h > config.h
echo $ac_n "checking whether matz's dln works""... $ac_c" 1>&6 echo $ac_n "checking whether matz's dln works""... $ac_c" 1>&6
echo "configure:3847: checking whether matz's dln works" >&5 echo "configure:3858: checking whether matz's dln works" >&5
if eval "test \"`echo '$''{'rb_cv_dln_a_out'+set}'`\" = set"; then if eval "test \"`echo '$''{'rb_cv_dln_a_out'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3852 "configure" #line 3863 "configure"
#include "confdefs.h" #include "confdefs.h"
#define USE_DLN_A_OUT #define USE_DLN_A_OUT
@ -3858,7 +3869,7 @@ int main() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3862: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3873: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
rb_cv_dln_a_out=yes rb_cv_dln_a_out=yes
else else
@ -3960,7 +3971,7 @@ fi
case "$host_os" in case "$host_os" in
human*) human*)
echo $ac_n "checking for _harderr in -lsignal""... $ac_c" 1>&6 echo $ac_n "checking for _harderr in -lsignal""... $ac_c" 1>&6
echo "configure:3964: checking for _harderr in -lsignal" >&5 echo "configure:3975: checking for _harderr in -lsignal" >&5
ac_lib_var=`echo signal'_'_harderr | sed 'y%./+-%__p_%'` ac_lib_var=`echo signal'_'_harderr | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@ -3968,7 +3979,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lsignal $LIBS" LIBS="-lsignal $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3972 "configure" #line 3983 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
@ -3979,7 +3990,7 @@ int main() {
_harderr() _harderr()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3994: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
@ -4007,7 +4018,7 @@ else
fi fi
echo $ac_n "checking for hmemset in -lhmem""... $ac_c" 1>&6 echo $ac_n "checking for hmemset in -lhmem""... $ac_c" 1>&6
echo "configure:4011: checking for hmemset in -lhmem" >&5 echo "configure:4022: checking for hmemset in -lhmem" >&5
ac_lib_var=`echo hmem'_'hmemset | sed 'y%./+-%__p_%'` ac_lib_var=`echo hmem'_'hmemset | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@ -4015,7 +4026,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lhmem $LIBS" LIBS="-lhmem $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4019 "configure" #line 4030 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
@ -4026,7 +4037,7 @@ int main() {
hmemset() hmemset()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4030: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4041: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
@ -4056,12 +4067,12 @@ fi
for ac_func in select for ac_func in select
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:4060: checking for $ac_func" >&5 echo "configure:4071: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4065 "configure" #line 4076 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
@ -4084,7 +4095,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:4088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:4099: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
@ -4109,7 +4120,7 @@ fi
done done
echo $ac_n "checking whether PD libc _dtos18 fail to convert big number""... $ac_c" 1>&6 echo $ac_n "checking whether PD libc _dtos18 fail to convert big number""... $ac_c" 1>&6
echo "configure:4113: checking whether PD libc _dtos18 fail to convert big number" >&5 echo "configure:4124: checking whether PD libc _dtos18 fail to convert big number" >&5
if eval "test \"`echo '$''{'rb_cv_missing__dtos18'+set}'`\" = set"; then if eval "test \"`echo '$''{'rb_cv_missing__dtos18'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -4117,7 +4128,7 @@ else
rb_cv_missing__dtos18=no rb_cv_missing__dtos18=no
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4121 "configure" #line 4132 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <stdio.h> #include <stdio.h>
@ -4129,7 +4140,7 @@ main ()
} }
EOF EOF
if { (eval echo configure:4133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null if { (eval echo configure:4144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then then
rb_cv_missing__dtos18=yes rb_cv_missing__dtos18=yes
else else
@ -4151,7 +4162,7 @@ EOF
fi fi
echo $ac_n "checking whether PD libc fconvert fail to round""... $ac_c" 1>&6 echo $ac_n "checking whether PD libc fconvert fail to round""... $ac_c" 1>&6
echo "configure:4155: checking whether PD libc fconvert fail to round" >&5 echo "configure:4166: checking whether PD libc fconvert fail to round" >&5
if eval "test \"`echo '$''{'rb_cv_missing_fconvert'+set}'`\" = set"; then if eval "test \"`echo '$''{'rb_cv_missing_fconvert'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -4159,7 +4170,7 @@ else
rb_cv_missing_fconvert=no rb_cv_missing_fconvert=no
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 4163 "configure" #line 4174 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <stdio.h> #include <stdio.h>
@ -4172,7 +4183,7 @@ main ()
} }
EOF EOF
if { (eval echo configure:4176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null if { (eval echo configure:4187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then then
rb_cv_missing_fconvert=yes rb_cv_missing_fconvert=yes
else else
@ -4249,9 +4260,16 @@ if test "$enable_shared" = 'yes'; then
LIBRUBYARG='-L./ -l$(RUBY_INSTALL_NAME)' LIBRUBYARG='-L./ -l$(RUBY_INSTALL_NAME)'
CFLAGS="$CFLAGS $CCDLFLAGS" CFLAGS="$CFLAGS $CCDLFLAGS"
case "$host_os" in case "$host_os" in
freebsd2*|sunos4*|linux*) sunos4*|linux*)
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so'
;; ;;
freebsd*)
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR)$(MINOR)'
if test "$rb_cv_freebsd_elf" != "yes" ; then
LIBRUBY_SO="$LIBRUBY_SO.\$(TEENY)"
LIBRUBY_ALIASES=''
fi
;;
hpux*) hpux*)
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR).$(TEENY)' LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR).$(TEENY)'
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).sl' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).sl'
@ -4293,12 +4311,13 @@ test "$program_suffix" != NONE &&
LIBSUFFIX=$ri_suffix LIBSUFFIX=$ri_suffix
RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}" RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}"
RUBY_LIB_PATH="${prefix}/lib/${RUBY_INSTALL_NAME}/${MAJOR}.${MINOR}"
cat >> confdefs.h <<EOF cat >> confdefs.h <<EOF
#define RUBY_LIB "${prefix}/lib/${RUBY_INSTALL_NAME}" #define RUBY_LIB "${RUBY_LIB_PATH}"
EOF EOF
cat >> confdefs.h <<EOF cat >> confdefs.h <<EOF
#define RUBY_SITE_LIB "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby" #define RUBY_SITE_LIB "${RUBY_LIB_PATH}/site_ruby"
EOF EOF
@ -4306,42 +4325,29 @@ if test "$fat_binary" = yes ; then
arch="fat-${host_os}" arch="fat-${host_os}"
cat >> confdefs.h <<EOF cat >> confdefs.h <<EOF
#define RUBY_THIN_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}" #define RUBY_THIN_ARCHLIB "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}"
EOF EOF
cat >> confdefs.h <<EOF cat >> confdefs.h <<EOF
#define RUBY_SITE_THIN_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}" #define RUBY_SITE_THIN_ARCHLIB "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}"
EOF
cat >> confdefs.h <<EOF
#define RUBY_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}"
EOF
cat >> confdefs.h <<EOF
#define RUBY_SITE_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}"
EOF
cat >> confdefs.h <<EOF
#define RUBY_PLATFORM __ARCHITECTURE__ "-${host_os}"
EOF EOF
else else
arch="${host_cpu}-${host_os}" arch="${host_cpu}-${host_os}"
cat >> confdefs.h <<EOF fi
#define RUBY_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}" cat >> confdefs.h <<EOF
#define RUBY_ARCHLIB "${RUBY_LIB_PATH}/${arch}"
EOF EOF
cat >> confdefs.h <<EOF cat >> confdefs.h <<EOF
#define RUBY_SITE_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}" #define RUBY_SITE_ARCHLIB "${RUBY_LIB_PATH}/site_ruby/${arch}"
EOF EOF
cat >> confdefs.h <<EOF cat >> confdefs.h <<EOF
#define RUBY_PLATFORM "${arch}" #define RUBY_PLATFORM "${arch}"
EOF EOF
fi
echo "creating config.h" echo "creating config.h"
cat confdefs.h > config.h cat confdefs.h > config.h

View file

@ -413,10 +413,21 @@ if test "$with_dln_a_out" != yes; then
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
linux*) LDSHARED="gcc -shared" linux*) LDSHARED="gcc -shared"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
freebsd*) LDSHARED="gcc -shared" freebsd*) LDSHARED="gcc -shared"
test -x /usr/bin/objformat && LDFLAGS="-rdynamic" if test -x /usr/bin/objformat -a \
`/usr/bin/objformat` = "elf" ; then
LDFLAGS="-rdynamic"
DLDFLAGS='-Wl,-soname,$(.TARGET)'
rb_cv_freebsd_elf=yes
fi
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
netbsd*) LDSHARED="ld -Bshareable" netbsd*) LDSHARED="ld -Bshareable"
case "$host_cpu" in
alpha|mips)
LDFLAGS="-export-dynamic" ;;
*)
;;
esac
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
openbsd*) LDSHARED="ld -Bforcearchive -Bshareable" openbsd*) LDSHARED="ld -Bforcearchive -Bshareable"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
@ -624,9 +635,16 @@ if test "$enable_shared" = 'yes'; then
LIBRUBYARG='-L./ -l$(RUBY_INSTALL_NAME)' LIBRUBYARG='-L./ -l$(RUBY_INSTALL_NAME)'
CFLAGS="$CFLAGS $CCDLFLAGS" CFLAGS="$CFLAGS $CCDLFLAGS"
case "$host_os" in case "$host_os" in
freebsd2*|sunos4*|linux*) sunos4*|linux*)
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so'
;; ;;
freebsd*)
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR)$(MINOR)'
if test "$rb_cv_freebsd_elf" != "yes" ; then
LIBRUBY_SO="$LIBRUBY_SO.\$(TEENY)"
LIBRUBY_ALIASES=''
fi
;;
hpux*) hpux*)
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR).$(TEENY)' LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR).$(TEENY)'
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).sl' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).sl'
@ -666,30 +684,26 @@ ri_suffix=
test "$program_suffix" != NONE && test "$program_suffix" != NONE &&
ri_suffix=$program_suffix ri_suffix=$program_suffix
LIBSUFFIX=$ri_suffix
RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}" RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}"
AC_DEFINE_UNQUOTED(RUBY_LIB, "${prefix}/lib/${RUBY_INSTALL_NAME}") RUBY_LIB_PATH="${prefix}/lib/${RUBY_INSTALL_NAME}/${MAJOR}.${MINOR}"
AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby") AC_DEFINE_UNQUOTED(RUBY_LIB, "${RUBY_LIB_PATH}")
AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${RUBY_LIB_PATH}/site_ruby")
AC_SUBST(arch)dnl AC_SUBST(arch)dnl
if test "$fat_binary" = yes ; then if test "$fat_binary" = yes ; then
arch="fat-${host_os}" arch="fat-${host_os}"
AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB, AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB,
"${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}" ) "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}" )
AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB, AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB,
"${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}" ) "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}" )
AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}")
AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${host_os}" )
else else
arch="${host_cpu}-${host_os}" arch="${host_cpu}-${host_os}"
AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}")
AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}")
fi fi
AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${RUBY_LIB_PATH}/${arch}")
AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${RUBY_LIB_PATH}/site_ruby/${arch}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}")
echo "creating config.h" echo "creating config.h"
cat confdefs.h > config.h cat confdefs.h > config.h

2
dln.c
View file

@ -79,7 +79,7 @@ int eaccess();
#endif #endif
#ifndef FUNCNAME_PATTERN #ifndef FUNCNAME_PATTERN
# if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(NeXT) || defined(__WATCOMC__) # if defined(__hp9000s300) || (defined(__NetBSD__) && (!defined(__alpha__) && !defined(__mips__))) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(NeXT) || defined(__WATCOMC__)
# define FUNCNAME_PATTERN "_Init_%.200s" # define FUNCNAME_PATTERN "_Init_%.200s"
# else # else
# define FUNCNAME_PATTERN "Init_%.200s" # define FUNCNAME_PATTERN "Init_%.200s"

View file

@ -337,7 +337,10 @@ static VALUE
exc_backtrace(exc) exc_backtrace(exc)
VALUE exc; VALUE exc;
{ {
return rb_iv_get(exc, "bt"); ID bt = rb_intern("bt");
if (!rb_ivar_defined(exc, bt)) return Qnil;
return rb_ivar_get(exc, bt);
} }
static VALUE static VALUE

14
eval.c
View file

@ -2537,7 +2537,7 @@ rb_eval(self, node)
body = search_method(ruby_class, node->nd_mid, &origin); body = search_method(ruby_class, node->nd_mid, &origin);
if (body) { if (body) {
if (origin == ruby_class) { if (origin == ruby_class) {
if (safe_level >= 3) { if (safe_level >= 4) {
rb_raise(rb_eSecurityError, "re-defining method prohibited"); rb_raise(rb_eSecurityError, "re-defining method prohibited");
} }
if (RTEST(ruby_verbose)) { if (RTEST(ruby_verbose)) {
@ -2604,7 +2604,7 @@ rb_eval(self, node)
} }
klass = rb_singleton_class(recv); klass = rb_singleton_class(recv);
if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) { if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) {
if (safe_level >= 3) { if (safe_level >= 4) {
rb_raise(rb_eSecurityError, "re-defining method prohibited"); rb_raise(rb_eSecurityError, "re-defining method prohibited");
} }
if (RTEST(ruby_verbose)) { if (RTEST(ruby_verbose)) {
@ -2709,7 +2709,7 @@ rb_eval(self, node)
rb_id2name(node->nd_cname)); rb_id2name(node->nd_cname));
} }
} }
if (safe_level >= 3) { if (safe_level >= 4) {
rb_raise(rb_eSecurityError, "extending class prohibited"); rb_raise(rb_eSecurityError, "extending class prohibited");
} }
rb_clear_cache(); rb_clear_cache();
@ -2751,7 +2751,7 @@ rb_eval(self, node)
rb_raise(rb_eTypeError, "%s is not a module", rb_raise(rb_eTypeError, "%s is not a module",
rb_id2name(node->nd_cname)); rb_id2name(node->nd_cname));
} }
if (safe_level >= 3) { if (safe_level >= 4) {
rb_raise(rb_eSecurityError, "extending module prohibited"); rb_raise(rb_eSecurityError, "extending module prohibited");
} }
} }
@ -5852,6 +5852,7 @@ thread_mark(th)
rb_gc_mark(th->errinfo); rb_gc_mark(th->errinfo);
rb_gc_mark(th->last_line); rb_gc_mark(th->last_line);
rb_gc_mark(th->last_match); rb_gc_mark(th->last_match);
rb_mark_tbl(th->locals);
/* mark data in copied stack */ /* mark data in copied stack */
if (th->status == THREAD_KILLED) return; if (th->status == THREAD_KILLED) return;
@ -5878,7 +5879,6 @@ thread_mark(th)
} }
block = block->prev; block = block->prev;
} }
rb_mark_tbl(th->locals);
} }
void void
@ -7008,13 +7008,11 @@ rb_thread_local_aset(thread, id, val)
ID id; ID id;
VALUE val; VALUE val;
{ {
thread_t th; thread_t th = rb_thread_check(thread);
if (safe_level >= 4 && !FL_TEST(thread, FL_TAINT)) if (safe_level >= 4 && !FL_TEST(thread, FL_TAINT))
rb_raise(rb_eSecurityError, "Insecure: can't modify thread values"); rb_raise(rb_eSecurityError, "Insecure: can't modify thread values");
th = rb_thread_check(thread);
if (!th->locals) { if (!th->locals) {
th->locals = st_init_numtable(); th->locals = st_init_numtable();
} }

View file

@ -2,9 +2,11 @@
Win32API - Ruby Win32 API Import Facility Win32API - Ruby Win32 API Import Facility
*/ */
#ifndef _MSC_VER
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <stdio.h> #include <stdio.h>
#endif
#define _T_VOID 0 #define _T_VOID 0
#define _T_NUMBER 1 #define _T_NUMBER 1

126
file.c
View file

@ -65,101 +65,6 @@ VALUE rb_cFile;
VALUE rb_mFileTest; VALUE rb_mFileTest;
static VALUE sStat; static VALUE sStat;
VALUE
rb_file_open(fname, mode)
char *fname, *mode;
{
OpenFile *fptr;
NEWOBJ(port, struct RFile);
OBJSETUP(port, rb_cFile, T_FILE);
MakeOpenFile(port, fptr);
fptr->mode = rb_io_mode_flags(mode);
fptr->f = rb_fopen(fname, mode);
fptr->path = strdup(fname);
rb_obj_call_init((VALUE)port);
return (VALUE)port;
}
static VALUE
rb_file_s_open(argc, argv, klass)
int argc;
VALUE *argv;
VALUE klass;
{
VALUE fname, vmode, file;
char *mode;
rb_scan_args(argc, argv, "11", &fname, &vmode);
Check_SafeStr(fname);
if (!NIL_P(vmode)) {
mode = STR2CSTR(vmode);
}
else {
mode = "r";
}
file = rb_file_open(RSTRING(fname)->ptr, mode);
RBASIC(file)->klass = klass;
rb_obj_call_init(file);
if (rb_iterator_p()) {
return rb_ensure(rb_yield, file, rb_io_close, file);
}
return file;
}
static VALUE
rb_file_reopen(argc, argv, file)
int argc;
VALUE *argv;
VALUE file;
{
VALUE fname, nmode;
char *mode;
OpenFile *fptr;
rb_secure(4);
if (rb_scan_args(argc, argv, "11", &fname, &nmode) == 1) {
if (TYPE(fname) == T_FILE) { /* fname must be IO */
return rb_io_reopen(file, fname);
}
}
Check_SafeStr(fname);
if (!NIL_P(nmode)) {
mode = STR2CSTR(nmode);
}
else {
mode = "r";
}
GetOpenFile(file, fptr);
if (fptr->path) free(fptr->path);
fptr->path = strdup(RSTRING(fname)->ptr);
fptr->mode = rb_io_mode_flags(mode);
if (!fptr->f) {
fptr->f = rb_fopen(RSTRING(fname)->ptr, mode);
if (fptr->f2) {
fclose(fptr->f2);
fptr->f2 = NULL;
}
return file;
}
if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == NULL) {
rb_sys_fail(fptr->path);
}
if (fptr->f2) {
if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == NULL) {
rb_sys_fail(fptr->path);
}
}
return file;
}
static int static int
apply2files(func, vargs, arg) apply2files(func, vargs, arg)
int (*func)(); int (*func)();
@ -1601,11 +1506,20 @@ rb_f_test(argc, argv)
return Qnil; /* not reached */ return Qnil; /* not reached */
} }
static VALUE rb_mConst;
void
rb_file_const(name, value)
char *name;
VALUE value;
{
rb_define_const(rb_cFile, name, value);
rb_define_const(rb_mConst, name, value);
}
void void
Init_File() Init_File()
{ {
VALUE rb_mConst;
rb_mFileTest = rb_define_module("FileTest"); rb_mFileTest = rb_define_module("FileTest");
rb_define_module_function(rb_mFileTest, "directory?", test_d, 1); rb_define_module_function(rb_mFileTest, "directory?", test_d, 1);
@ -1638,9 +1552,6 @@ Init_File()
rb_cFile = rb_define_class("File", rb_cIO); rb_cFile = rb_define_class("File", rb_cIO);
rb_extend_object(rb_cFile, CLASS_OF(rb_mFileTest)); rb_extend_object(rb_cFile, CLASS_OF(rb_mFileTest));
rb_define_singleton_method(rb_cFile, "new", rb_file_s_open, -1);
rb_define_singleton_method(rb_cFile, "open", rb_file_s_open, -1);
rb_define_singleton_method(rb_cFile, "stat", rb_file_s_stat, 1); rb_define_singleton_method(rb_cFile, "stat", rb_file_s_stat, 1);
rb_define_singleton_method(rb_cFile, "lstat", rb_file_s_lstat, 1); rb_define_singleton_method(rb_cFile, "lstat", rb_file_s_lstat, 1);
rb_define_singleton_method(rb_cFile, "ftype", rb_file_s_ftype, 1); rb_define_singleton_method(rb_cFile, "ftype", rb_file_s_ftype, 1);
@ -1672,8 +1583,6 @@ Init_File()
rb_define_singleton_method(rb_cFile, "split", rb_file_s_split, 1); rb_define_singleton_method(rb_cFile, "split", rb_file_s_split, 1);
rb_define_singleton_method(rb_cFile, "join", rb_file_s_join, -2); rb_define_singleton_method(rb_cFile, "join", rb_file_s_join, -2);
rb_define_method(rb_cFile, "reopen", rb_file_reopen, -1);
rb_define_method(rb_cIO, "stat", rb_io_stat, 0); /* this is IO's method */ rb_define_method(rb_cIO, "stat", rb_io_stat, 0); /* this is IO's method */
rb_define_method(rb_cFile, "lstat", rb_file_lstat, 0); rb_define_method(rb_cFile, "lstat", rb_file_lstat, 0);
@ -1688,15 +1597,10 @@ Init_File()
rb_define_method(rb_cFile, "flock", rb_file_flock, 1); rb_define_method(rb_cFile, "flock", rb_file_flock, 1);
rb_mConst = rb_define_module_under(rb_cFile, "Constants"); rb_mConst = rb_define_module_under(rb_cFile, "Constants");
rb_define_const(rb_cFile, "LOCK_SH", INT2FIX(LOCK_SH)); rb_file_const("LOCK_SH", INT2FIX(LOCK_SH));
rb_define_const(rb_cFile, "LOCK_EX", INT2FIX(LOCK_EX)); rb_file_const("LOCK_EX", INT2FIX(LOCK_EX));
rb_define_const(rb_cFile, "LOCK_UN", INT2FIX(LOCK_UN)); rb_file_const("LOCK_UN", INT2FIX(LOCK_UN));
rb_define_const(rb_cFile, "LOCK_NB", INT2FIX(LOCK_NB)); rb_file_const("LOCK_NB", INT2FIX(LOCK_NB));
rb_define_const(rb_mConst, "LOCK_SH", INT2FIX(LOCK_SH));
rb_define_const(rb_mConst, "LOCK_EX", INT2FIX(LOCK_EX));
rb_define_const(rb_mConst, "LOCK_UN", INT2FIX(LOCK_UN));
rb_define_const(rb_mConst, "LOCK_NB", INT2FIX(LOCK_NB));
rb_define_method(rb_cFile, "path", rb_file_path, 0); rb_define_method(rb_cFile, "path", rb_file_path, 0);

4
gc.c
View file

@ -42,10 +42,10 @@ static void run_final();
#if defined(MSDOS) || defined(__human68k__) #if defined(MSDOS) || defined(__human68k__)
#define GC_MALLOC_LIMIT 100000 #define GC_MALLOC_LIMIT 100000
#else #else
#define GC_MALLOC_LIMIT 200000 #define GC_MALLOC_LIMIT 400000
#endif #endif
#endif #endif
#define GC_NEWOBJ_LIMIT 1000 #define GC_NEWOBJ_LIMIT 10000
static unsigned long malloc_memories = 0; static unsigned long malloc_memories = 0;
static unsigned long alloc_objects = 0; static unsigned long alloc_objects = 0;

2
hash.c
View file

@ -504,7 +504,7 @@ rb_hash_aset(hash, key, val)
st_insert(RHASH(hash)->tbl, key, val); st_insert(RHASH(hash)->tbl, key, val);
} }
else { else {
st_add_direct(RHASH(hash)->tbl, rb_str_dup_frozen(key), val); st_add_direct(RHASH(hash)->tbl, rb_str_new4(key), val);
} }
return val; return val;
} }

View file

@ -142,9 +142,9 @@ VALUE rb_thread_main _((void));
VALUE rb_thread_local_aref _((VALUE, ID)); VALUE rb_thread_local_aref _((VALUE, ID));
VALUE rb_thread_local_aset _((VALUE, ID, VALUE)); VALUE rb_thread_local_aset _((VALUE, ID, VALUE));
/* file.c */ /* file.c */
VALUE rb_file_open _((char*, char*));
int eaccess _((char*, int)); int eaccess _((char*, int));
VALUE rb_file_s_expand_path _((int, VALUE *)); VALUE rb_file_s_expand_path _((int, VALUE *));
void rb_file_const _((char*, VALUE));
/* gc.c */ /* gc.c */
void rb_global_variable _((VALUE*)); void rb_global_variable _((VALUE*));
void rb_gc_mark_locations _((VALUE*, VALUE*)); void rb_gc_mark_locations _((VALUE*, VALUE*));
@ -176,8 +176,7 @@ VALUE rb_io_ungetc _((VALUE, VALUE));
VALUE rb_io_close _((VALUE)); VALUE rb_io_close _((VALUE));
VALUE rb_io_eof _((VALUE)); VALUE rb_io_eof _((VALUE));
VALUE rb_io_binmode _((VALUE)); VALUE rb_io_binmode _((VALUE));
int rb_io_mode_flags _((char*)); VALUE rb_file_open _((char*, char*));
VALUE rb_io_reopen _((VALUE, VALUE));
VALUE rb_gets _((void)); VALUE rb_gets _((void));
void rb_str_setter _((VALUE, ID, VALUE*)); void rb_str_setter _((VALUE, ID, VALUE*));
/* numeric.c */ /* numeric.c */
@ -272,7 +271,6 @@ VALUE rb_str_times _((VALUE, VALUE));
VALUE rb_str_substr _((VALUE, int, int)); VALUE rb_str_substr _((VALUE, int, int));
void rb_str_modify _((VALUE)); void rb_str_modify _((VALUE));
VALUE rb_str_freeze _((VALUE)); VALUE rb_str_freeze _((VALUE));
VALUE rb_str_dup_frozen _((VALUE));
VALUE rb_str_resize _((VALUE, int)); VALUE rb_str_resize _((VALUE, int));
VALUE rb_str_cat _((VALUE, char*, int)); VALUE rb_str_cat _((VALUE, char*, int));
VALUE rb_str_concat _((VALUE, VALUE)); VALUE rb_str_concat _((VALUE, VALUE));

349
io.c
View file

@ -1026,7 +1026,7 @@ rb_io_binmode(io)
return io; return io;
} }
int static int
rb_io_mode_flags(mode) rb_io_mode_flags(mode)
char *mode; char *mode;
{ {
@ -1043,7 +1043,8 @@ rb_io_mode_flags(mode)
flags |= FMODE_WRITABLE; flags |= FMODE_WRITABLE;
break; break;
default: default:
rb_raise(rb_eArgError, "illegal access mode"); error:
rb_raise(rb_eArgError, "illegal access mode %s", mode);
} }
if (mode[1] == 'b') { if (mode[1] == 'b') {
@ -1053,29 +1054,79 @@ rb_io_mode_flags(mode)
if (mode[1] == '+') { if (mode[1] == '+') {
flags |= FMODE_READWRITE; flags |= FMODE_READWRITE;
if (mode[2] != 0) goto error;
} }
else if (mode[1] != 0) goto error;
return flags; return flags;
} }
static int
rb_io_mode_flags2(mode)
int mode;
{
int flags;
switch (mode & (O_RDONLY|O_WRONLY|O_RDWR)) {
case O_RDONLY:
flags = FMODE_READABLE;
break;
case O_WRONLY:
flags = FMODE_WRITABLE;
break;
case O_RDWR:
flags = FMODE_WRITABLE|FMODE_READABLE;
break;
}
#ifdef O_BINARY
if (mode & O_BINARY) {
flags |= FMODE_BINMODE;
}
#endif
return flags;
}
static int
rb_open(fname, flag, mode)
char *fname;
int flag;
mode_t mode;
{
int fd;
fd = open(fname, flag, mode);
if (fd < 0) {
if (errno == EMFILE || errno == ENFILE) {
rb_gc();
fd = open(fname, flag, mode);
}
if (fd < 0) {
rb_sys_fail(fname);
}
}
return fd;
}
FILE * FILE *
rb_fopen(fname, mode) rb_fopen(fname, mode)
char *fname; char *fname;
char *mode; char *mode;
{ {
FILE *f; FILE *file;
f = fopen(fname, mode); file = fopen(fname, mode);
if (f == NULL) { if (file == NULL) {
if (errno == EMFILE || errno == ENFILE) { if (errno == EMFILE || errno == ENFILE) {
rb_gc(); rb_gc();
f = fopen(fname, mode); file = fopen(fname, mode);
} }
if (f == NULL) { if (file == NULL) {
rb_sys_fail(fname); rb_sys_fail(fname);
} }
} }
return f; return file;
} }
FILE * FILE *
@ -1083,18 +1134,57 @@ rb_fdopen(fd, mode)
int fd; int fd;
char *mode; char *mode;
{ {
FILE *f; FILE *file;
f = fdopen(fd, mode); file = fdopen(fd, mode);
if (f == NULL) { if (file == NULL) {
if (errno == EMFILE) { if (errno == EMFILE || errno == ENFILE) {
f = fdopen(fd, mode); rb_gc();
file = fdopen(fd, mode);
} }
if (f == NULL) { if (file == NULL) {
rb_sys_fail(0); rb_sys_fail(0);
} }
} }
return f; return file;
}
VALUE
rb_file_open(fname, mode)
char *fname, *mode;
{
OpenFile *fptr;
NEWOBJ(port, struct RFile);
OBJSETUP(port, rb_cFile, T_FILE);
MakeOpenFile(port, fptr);
fptr->mode = rb_io_mode_flags(mode);
fptr->f = rb_fopen(fname, mode);
fptr->path = strdup(fname);
rb_obj_call_init((VALUE)port);
return (VALUE)port;
}
VALUE
rb_file_sysopen(fname, flags, mode)
char *fname;
int flags, mode;
{
OpenFile *fptr;
int fd;
char *m;
NEWOBJ(port, struct RFile);
OBJSETUP(port, rb_cFile, T_FILE);
MakeOpenFile(port, fptr);
fd = rb_open(fname, flags, mode);
fptr->mode = rb_io_mode_flags2(flags);
fptr->f = rb_fdopen(fd, m);
fptr->path = strdup(fname);
rb_obj_call_init((VALUE)port);
return (VALUE)port;
} }
#if defined (NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__) #if defined (NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__)
@ -1329,6 +1419,108 @@ rb_io_s_popen(argc, argv, self)
return pipe_open(RSTRING(pname)->ptr, mode); return pipe_open(RSTRING(pname)->ptr, mode);
} }
static VALUE
rb_file_s_open(argc, argv, klass)
int argc;
VALUE *argv;
VALUE klass;
{
VALUE fname, vmode, file, perm;
char *path, *mode;
rb_scan_args(argc, argv, "12", &fname, &vmode, &perm);
Check_SafeStr(fname);
path = RSTRING(fname)->ptr;
if (FIXNUM_P(vmode)) {
int flags = FIX2INT(vmode);
int fmode = NIL_P(perm) ? 0666 : FIX2INT(perm);
file = rb_file_sysopen(path, flags, fmode);
}
else {
if (!NIL_P(vmode)) {
mode = STR2CSTR(vmode);
}
else {
mode = "r";
}
file = rb_file_open(RSTRING(fname)->ptr, mode);
}
RBASIC(file)->klass = klass;
rb_obj_call_init(file);
if (rb_iterator_p()) {
return rb_ensure(rb_yield, file, rb_io_close, file);
}
return file;
}
static VALUE
rb_f_open(argc, argv)
int argc;
VALUE *argv;
{
char *mode;
VALUE pname, pmode, perm;
VALUE port;
rb_scan_args(argc, argv, "12", &pname, &pmode, &perm);
Check_SafeStr(pname);
if (RSTRING(pname)->ptr[0] != '|') /* open file */
return rb_file_s_open(argc, argv, rb_cFile);
/* open pipe */
if (NIL_P(pmode)) {
mode = "r";
}
else if (FIXNUM_P(pmode)) {
int flags = FIX2INT(pmode);
char *p;
mode = p = ALLOCA_N(char, 4);
switch (flags & (O_RDONLY|O_WRONLY|O_RDWR)) {
case O_RDONLY:
*p++ = 'r';
break;
case O_WRONLY:
*p++ = 'w';
break;
case O_RDWR:
*p++ = 'w';
*p++ = '+';
break;
}
*p++ = '\0';
#ifdef O_BINARY
if (flags & O_BINARY) {
if (mode[1] == '+') {
mode[1] = 'b'; mode[2] = '+'; mode[3] = '\0';
}
else {
mode[1] = 'b'; mode[2] = '\0';
}
}
#endif
}
else {
int len;
mode = STR2CSTR(pmode);
len = strlen(mode);
if (len == 0 || len > 3)
rb_raise(rb_eArgError, "illegal access mode %s", mode);
}
port = pipe_open(RSTRING(pname)->ptr, mode);
if (rb_iterator_p()) {
return rb_ensure(rb_yield, port, rb_io_close, port);
}
return port;
}
static VALUE static VALUE
rb_io_open(fname, mode) rb_io_open(fname, mode)
char *fname, *mode; char *fname, *mode;
@ -1341,37 +1533,6 @@ rb_io_open(fname, mode)
} }
} }
static VALUE
rb_f_open(argc, argv)
int argc;
VALUE *argv;
{
char *mode;
VALUE pname, pmode;
VALUE port;
rb_scan_args(argc, argv, "11", &pname, &pmode);
Check_SafeStr(pname);
if (NIL_P(pmode)) {
mode = "r";
}
else {
int len;
mode = STR2CSTR(pmode);
len = strlen(mode);
if (len == 0 || len > 3)
rb_raise(rb_eArgError, "illegal access mode");
}
port = rb_io_open(RSTRING(pname)->ptr, mode);
if (rb_iterator_p()) {
return rb_ensure(rb_yield, port, rb_io_close, port);
}
return port;
}
static VALUE static VALUE
rb_io_get_io(io) rb_io_get_io(io)
VALUE io; VALUE io;
@ -1394,7 +1555,7 @@ rb_io_mode_string(fptr)
} }
} }
VALUE static VALUE
rb_io_reopen(io, nfile) rb_io_reopen(io, nfile)
VALUE io, nfile; VALUE io, nfile;
{ {
@ -1458,6 +1619,56 @@ rb_io_reopen(io, nfile)
return io; return io;
} }
static VALUE
rb_file_reopen(argc, argv, file)
int argc;
VALUE *argv;
VALUE file;
{
VALUE fname, nmode;
char *mode;
OpenFile *fptr;
rb_secure(4);
if (rb_scan_args(argc, argv, "11", &fname, &nmode) == 1) {
if (TYPE(fname) == T_FILE) { /* fname must be IO */
return rb_io_reopen(file, fname);
}
}
Check_SafeStr(fname);
if (!NIL_P(nmode)) {
mode = STR2CSTR(nmode);
}
else {
mode = "r";
}
GetOpenFile(file, fptr);
if (fptr->path) free(fptr->path);
fptr->path = strdup(RSTRING(fname)->ptr);
fptr->mode = rb_io_mode_flags(mode);
if (!fptr->f) {
fptr->f = rb_fopen(RSTRING(fname)->ptr, mode);
if (fptr->f2) {
fclose(fptr->f2);
fptr->f2 = NULL;
}
return file;
}
if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == NULL) {
rb_sys_fail(fptr->path);
}
if (fptr->f2) {
if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == NULL) {
rb_sys_fail(fptr->path);
}
}
return file;
}
static VALUE static VALUE
rb_io_clone(io) rb_io_clone(io)
VALUE io; VALUE io;
@ -1871,8 +2082,7 @@ next_argv()
#endif #endif
} }
fw = rb_fopen(fn, "w"); fw = rb_fopen(fn, "w");
#if !defined(MSDOS) && !defined(__CYGWIN32__) && !(NT) && !defined(__human68k__)\ #if !defined(MSDOS) && !defined(__CYGWIN32__) && !(NT) && !defined(__human68k__) && !defined(USE_CWGUSI) && !defined(__BEOS__)
&& !defined(USE_CWGUSI) && !defined(__BEOS__)
fstat(fileno(fw), &st2); fstat(fileno(fw), &st2);
fchmod(fileno(fw), st.st_mode); fchmod(fileno(fw), st.st_mode);
if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) { if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) {
@ -1901,7 +2111,12 @@ rb_f_gets_internal(argc, argv)
retry: retry:
if (!next_argv()) return Qnil; if (!next_argv()) return Qnil;
line = rb_io_gets_internal(argc, argv, file); if (rb_rs == rb_default_rs) {
line = rb_io_gets(file);
}
else {
line = rb_io_gets_internal(argc, argv, file);
}
if (NIL_P(line) && next_p != -1) { if (NIL_P(line) && next_p != -1) {
rb_io_close(file); rb_io_close(file);
next_p = 1; next_p = 1;
@ -1929,6 +2144,10 @@ rb_gets()
{ {
VALUE line; VALUE line;
if (rb_rs != rb_default_rs) {
return rb_f_gets(0, 0);
}
retry: retry:
if (!next_argv()) return Qnil; if (!next_argv()) return Qnil;
line = rb_io_gets(file); line = rb_io_gets(file);
@ -2453,8 +2672,8 @@ rb_io_s_pipe()
#endif #endif
rb_sys_fail(0); rb_sys_fail(0);
r = prep_stdio(fdopen(pipes[0], "r"), FMODE_READABLE, rb_cIO); r = prep_stdio(rb_fdopen(pipes[0], "r"), FMODE_READABLE, rb_cIO);
w = prep_stdio(fdopen(pipes[1], "w"), FMODE_WRITABLE, rb_cIO); w = prep_stdio(rb_fdopen(pipes[1], "w"), FMODE_WRITABLE, rb_cIO);
ary = rb_ary_new2(2); ary = rb_ary_new2(2);
rb_ary_push(ary, r); rb_ary_push(ary, r);
@ -2867,4 +3086,30 @@ Init_IO()
#endif #endif
Init_File(); Init_File();
rb_define_method(rb_cFile, "reopen", rb_file_reopen, -1);
rb_define_singleton_method(rb_cFile, "new", rb_file_s_open, -1);
rb_define_singleton_method(rb_cFile, "open", rb_file_s_open, -1);
rb_file_const("RDONLY", INT2FIX(O_RDONLY));
rb_file_const("WRONLY", INT2FIX(O_WRONLY));
rb_file_const("RDWR", INT2FIX(O_RDWR));
rb_file_const("APPEND", INT2FIX(O_APPEND));
rb_file_const("CREAT", INT2FIX(O_CREAT));
rb_file_const("EXCL", INT2FIX(O_EXCL));
#if defined(O_NDELAY) || defined(O_NONBLOCK)
# ifdef O_NONBLOCK
rb_file_const("NONBLOCK", INT2FIX(O_NONBLOCK));
# else
rb_file_const("NONBLOCK", INT2FIX(O_NDELAY));
# endif
#endif
rb_file_const("TRUNC", INT2FIX(O_TRUNC));
#ifdef O_NOCTTY
rb_file_const("NOCTTY", INT2FIX(O_NOCTTY));
#endif
#ifdef O_BINARY
rb_file_const("BINARY", INT2FIX(O_BINARY));
#endif
} }

View file

@ -72,6 +72,8 @@ class Complex < Numeric
end end
def initialize(a, b = 0) def initialize(a, b = 0)
raise "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric
raise "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric
@real = a @real = a
@image = b @image = b
end end
@ -84,7 +86,7 @@ class Complex < Numeric
elsif Complex.generic?(other) elsif Complex.generic?(other)
Complex(@real + other, @image) Complex(@real + other, @image)
else else
x , y = a.coerce(self) x , y = other.coerce(self)
x + y x + y
end end
end end
@ -97,7 +99,7 @@ class Complex < Numeric
elsif Complex.generic?(other) elsif Complex.generic?(other)
Complex(@real - other, @image) Complex(@real - other, @image)
else else
x , y = a.coerce(self) x , y = other.coerce(self)
x - y x - y
end end
end end
@ -110,7 +112,7 @@ class Complex < Numeric
elsif Complex.generic?(other) elsif Complex.generic?(other)
Complex(@real * other, @image * other) Complex(@real * other, @image * other)
else else
x , y = a.coerce(self) x , y = other.coerce(self)
x * y x * y
end end
end end
@ -121,7 +123,7 @@ class Complex < Numeric
elsif Complex.generic?(other) elsif Complex.generic?(other)
Complex(@real / other, @image / other) Complex(@real / other, @image / other)
else else
x , y = a.coerce(self) x , y = other.coerce(self)
x / y x / y
end end
end end
@ -163,7 +165,7 @@ class Complex < Numeric
r, theta = polar r, theta = polar
Complex.polar(r.power!(other), theta * other) Complex.polar(r.power!(other), theta * other)
else else
x , y = a.coerce(self) x , y = other.coerce(self)
x / y x / y
end end
end end
@ -174,7 +176,7 @@ class Complex < Numeric
elsif Complex.generic?(other) elsif Complex.generic?(other)
Complex(@real % other, @image % other) Complex(@real % other, @image % other)
else else
x , y = a.coerce(self) x , y = other.coerce(self)
x % y x % y
end end
end end
@ -187,7 +189,7 @@ class Complex < Numeric
elsif Complex.generic?(other) elsif Complex.generic?(other)
Complex(@real.divmod(other), @image.divmod(other)) Complex(@real.divmod(other), @image.divmod(other))
else else
x , y = a.coerce(self) x , y = other.coerce(self)
x.divmod(y) x.divmod(y)
end end
end end
@ -222,7 +224,7 @@ class Complex < Numeric
elsif Complex.generic?(other) elsif Complex.generic?(other)
@real == other and @image == 0 @real == other and @image == 0
else else
x , y = a.coerce(self) x , y = other.coerce(self)
x == y x == y
end end
end end

View file

@ -72,7 +72,7 @@ else
end end
end end
# 過去の互換性のため # backward compatibility
def self.fail(err = nil, *rest) def self.fail(err = nil, *rest)
if form = E2MM_ErrorMSG[err] if form = E2MM_ErrorMSG[err]
$! = err.new(sprintf(form, *rest)) $! = err.new(sprintf(form, *rest))

View file

@ -12,7 +12,7 @@
# obj = Object.new # obj = Object.new
# obj.extend Mutex_m # obj.extend Mutex_m
# ... # ...
# 後はMutexと同じ使い方 # extended object can be handled like Mutex
# #
require "finalize" require "finalize"
@ -36,7 +36,7 @@ module Mutex_m
dummy = cl.new dummy = cl.new
Mutex_m.extendable_module(dummy) Mutex_m.extendable_module(dummy)
rescue NameError rescue NameError
# newが定義されていない時は, DATAとみなす. # if new is not defined, cl must be Data.
For_primitive_object For_primitive_object
end end
end end
@ -44,8 +44,8 @@ module Mutex_m
def Mutex_m.extend_class(cl) def Mutex_m.extend_class(cl)
return super if cl.instance_of?(Module) return super if cl.instance_of?(Module)
# モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定 # do nothing for Modules
# とaliasを行う. # make aliases and include the proper module.
real = includable_module(cl) real = includable_module(cl)
cl.module_eval %q{ cl.module_eval %q{
include real include real
@ -162,7 +162,6 @@ module Mutex_m
def For_primitive_object.mu_finalize(id) def For_primitive_object.mu_finalize(id)
Thread.critical = TRUE Thread.critical = TRUE
if wait = Mu_Locked.delete(id) if wait = Mu_Locked.delete(id)
# wait == [] ときだけ GCされるので, for w in wait は意味なし.
Thread.critical = FALSE Thread.critical = FALSE
for w in wait for w in wait
w.run w.run

View file

@ -1,5 +1,5 @@
# #
# sync.rb - カウント付2-フェーズロッククラス # sync.rb - 2 phase lock with counter
# $Release Version: 0.2$ # $Release Version: 0.2$
# $Revision$ # $Revision$
# $Date$ # $Date$
@ -54,7 +54,7 @@ module Sync_m
SH = :SH SH = :SH
EX = :EX EX = :EX
# 例外定義 # exceptions
class Err < StandardError class Err < StandardError
def Err.Fail(*opt) def Err.Fail(*opt)
fail self, sprintf(self::Message, *opt) fail self, sprintf(self::Message, *opt)
@ -97,7 +97,7 @@ module Sync_m
dummy = cl.new dummy = cl.new
Sync_m.extendable_module(dummy) Sync_m.extendable_module(dummy)
rescue NameError rescue NameError
# newが定義されていない時は, DATAとみなす. # if new is not defined, cl must be Data.
For_primitive_object For_primitive_object
end end
end end
@ -105,8 +105,8 @@ module Sync_m
def Sync_m.extend_class(cl) def Sync_m.extend_class(cl)
return super if cl.instance_of?(Module) return super if cl.instance_of?(Module)
# モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定 # do nothing for Modules
# とaliasを行う. # make aliases and include the proper module.
real = includable_module(cl) real = includable_module(cl)
cl.module_eval %q{ cl.module_eval %q{
include real include real
@ -267,7 +267,7 @@ module Sync_m
sync_sh_locker[Thread.current] = count + 1 sync_sh_locker[Thread.current] = count + 1
ret = TRUE ret = TRUE
when EX when EX
# 既に, モードがEXである時は, 必ずEXロックとなる. # in EX mode, lock will upgrade to EX lock
if sync_ex_locker == Thread.current if sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1 self.sync_ex_count = sync_ex_count + 1
ret = TRUE ret = TRUE
@ -342,7 +342,7 @@ module Sync_m
def For_primitive_object.sync_finalize(id) def For_primitive_object.sync_finalize(id)
wait = Sync_Locked.delete(id) wait = Sync_Locked.delete(id)
# waiting == [] ときだけ GCされるので, 待ち行列の解放は意味がない. # need not to free waiting
end end
def sync_mode def sync_mode

View file

@ -12,6 +12,10 @@
#include "rubyio.h" #include "rubyio.h"
#include "st.h" #include "st.h"
#ifndef atof
double strtod();
#endif
#define MARSHAL_MAJOR 4 #define MARSHAL_MAJOR 4
#define MARSHAL_MINOR 0 #define MARSHAL_MINOR 0
@ -641,13 +645,10 @@ r_object(arg)
case TYPE_FLOAT: case TYPE_FLOAT:
{ {
#ifndef atof
double atof();
#endif
char *buf; char *buf;
r_bytes(buf, arg); r_bytes(buf, arg);
v = rb_float_new(atof(buf)); v = rb_float_new(strtod(buf, 0));
return r_regist(v, arg); return r_regist(v, arg);
} }

View file

@ -794,14 +794,32 @@ static VALUE
rb_int_induced_from(klass, x) rb_int_induced_from(klass, x)
VALUE klass, x; VALUE klass, x;
{ {
return rb_funcall(x, rb_intern("to_i"), 0); switch (TYPE(x)) {
case T_FIXNUM:
case T_BIGNUM:
return x;
case T_FLOAT:
return rb_funcall(x, rb_intern("to_i"), 0);
default:
rb_raise(rb_eTypeError, "failed to convert %s into Integer",
rb_class2name(CLASS_OF(x)));
}
} }
static VALUE static VALUE
rb_flo_induced_from(klass, x) rb_flo_induced_from(klass, x)
VALUE klass, x; VALUE klass, x;
{ {
return rb_funcall(x, rb_intern("to_f"), 0); switch (TYPE(x)) {
case T_FIXNUM:
case T_BIGNUM:
return rb_funcall(x, rb_intern("to_f"), 0);
case T_FLOAT:
return x;
default:
rb_raise(rb_eTypeError, "failed to convert %s into Float",
rb_class2name(CLASS_OF(x)));
}
} }
static VALUE static VALUE

16
pack.c
View file

@ -14,6 +14,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h> #include <ctype.h>
#ifndef atof
double strtod();
#endif
#define define_swapx(x, xtype) \ #define define_swapx(x, xtype) \
static xtype \ static xtype \
TOKEN_PASTE(swap,x)(z) \ TOKEN_PASTE(swap,x)(z) \
@ -587,7 +591,7 @@ pack_pack(ary, fmt)
f = RFLOAT(from)->value; f = RFLOAT(from)->value;
break; break;
case T_STRING: case T_STRING:
f = atof(RSTRING(from)->ptr); f = strtod(RSTRING(from)->ptr, 0);
default: default:
f = (float)NUM2INT(from); f = (float)NUM2INT(from);
break; break;
@ -607,7 +611,7 @@ pack_pack(ary, fmt)
f = RFLOAT(from)->value; f = RFLOAT(from)->value;
break; break;
case T_STRING: case T_STRING:
f = atof(RSTRING(from)->ptr); f = strtod(RSTRING(from)->ptr, 0);
default: default:
f = (float)NUM2INT(from); f = (float)NUM2INT(from);
break; break;
@ -628,7 +632,7 @@ pack_pack(ary, fmt)
d = RFLOAT(from)->value; d = RFLOAT(from)->value;
break; break;
case T_STRING: case T_STRING:
d = atof(RSTRING(from)->ptr); d = strtod(RSTRING(from)->ptr, 0);
default: default:
d = (double)NUM2INT(from); d = (double)NUM2INT(from);
break; break;
@ -649,7 +653,7 @@ pack_pack(ary, fmt)
d = RFLOAT(from)->value; d = RFLOAT(from)->value;
break; break;
case T_STRING: case T_STRING:
d = atof(RSTRING(from)->ptr); d = strtod(RSTRING(from)->ptr, 0);
default: default:
d = (double)NUM2INT(from); d = (double)NUM2INT(from);
break; break;
@ -669,7 +673,7 @@ pack_pack(ary, fmt)
f = RFLOAT(from)->value; f = RFLOAT(from)->value;
break; break;
case T_STRING: case T_STRING:
f = atof(RSTRING(from)->ptr); f = strtod(RSTRING(from)->ptr, 0);
default: default:
f = (float)NUM2INT(from); f = (float)NUM2INT(from);
break; break;
@ -690,7 +694,7 @@ pack_pack(ary, fmt)
d = RFLOAT(from)->value; d = RFLOAT(from)->value;
break; break;
case T_STRING: case T_STRING:
d = atof(RSTRING(from)->ptr); d = strtod(RSTRING(from)->ptr, 0);
default: default:
d = (double)NUM2INT(from); d = (double)NUM2INT(from);
break; break;

37
parse.c
View file

@ -5376,7 +5376,7 @@ retry:
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
c = nextc(); c = nextc();
if (c == '\n') { if (c == '\n') {
ruby_sourceline++; pushback(c);
break; break;
} }
} }
@ -5689,23 +5689,44 @@ retry:
c = nextc(); c = nextc();
if (c == 'x' || c == 'X') { if (c == 'x' || c == 'X') {
/* hexadecimal */ /* hexadecimal */
while (c = nextc()) { c = nextc();
if (!ISXDIGIT(c)) {
yyerror("hexadecimal number without hex-digits");
}
do {
if (c == '_') continue; if (c == '_') continue;
if (!ISXDIGIT(c)) break; if (!ISXDIGIT(c)) break;
tokadd(c); tokadd(c);
} } while (c = nextc());
pushback(c); pushback(c);
tokfix(); tokfix();
yylval.val = rb_str2inum(tok(), 16); yylval.val = rb_str2inum(tok(), 16);
return tINTEGER; return tINTEGER;
} }
else if (c >= '0' && c <= '7') { if (c == 'b' || c == 'B') {
/* octal */ /* binary */
c = nextc();
if (c != '0' && c != '1') {
yyerror("numeric constant with no digits");
}
do { do {
if (c == '_') continue;
if (c != '0'&& c != '1') break;
tokadd(c); tokadd(c);
while ((c = nextc()) == '_') } while (c = nextc());
; pushback(c);
} while (c >= '0' && c <= '9'); tokfix();
yylval.val = rb_str2inum(tok(), 2);
return tINTEGER;
}
else if (c >= '0' && c <= '7' || c == '_') {
/* octal */
tokadd(c);
do {
if (c == '_') continue;
if (c < '0' || c > '7') break;
tokadd(c);
} while (c = nextc());
pushback(c); pushback(c);
tokfix(); tokfix();
yylval.val = rb_str2inum(tok(), 8); yylval.val = rb_str2inum(tok(), 8);

37
parse.y
View file

@ -2465,7 +2465,7 @@ retry:
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
c = nextc(); c = nextc();
if (c == '\n') { if (c == '\n') {
ruby_sourceline++; pushback(c);
break; break;
} }
} }
@ -2778,23 +2778,44 @@ retry:
c = nextc(); c = nextc();
if (c == 'x' || c == 'X') { if (c == 'x' || c == 'X') {
/* hexadecimal */ /* hexadecimal */
while (c = nextc()) { c = nextc();
if (!ISXDIGIT(c)) {
yyerror("hexadecimal number without hex-digits");
}
do {
if (c == '_') continue; if (c == '_') continue;
if (!ISXDIGIT(c)) break; if (!ISXDIGIT(c)) break;
tokadd(c); tokadd(c);
} } while (c = nextc());
pushback(c); pushback(c);
tokfix(); tokfix();
yylval.val = rb_str2inum(tok(), 16); yylval.val = rb_str2inum(tok(), 16);
return tINTEGER; return tINTEGER;
} }
else if (c >= '0' && c <= '7') { if (c == 'b' || c == 'B') {
/* octal */ /* binary */
c = nextc();
if (c != '0' && c != '1') {
yyerror("numeric constant with no digits");
}
do { do {
if (c == '_') continue;
if (c != '0'&& c != '1') break;
tokadd(c); tokadd(c);
while ((c = nextc()) == '_') } while (c = nextc());
; pushback(c);
} while (c >= '0' && c <= '9'); tokfix();
yylval.val = rb_str2inum(tok(), 2);
return tINTEGER;
}
else if (c >= '0' && c <= '7' || c == '_') {
/* octal */
tokadd(c);
do {
if (c == '_') continue;
if (c < '0' || c > '7') break;
tokadd(c);
} while (c = nextc());
pushback(c); pushback(c);
tokfix(); tokfix();
yylval.val = rb_str2inum(tok(), 8); yylval.val = rb_str2inum(tok(), 8);

23
re.c
View file

@ -392,6 +392,21 @@ match_clone(orig)
return (VALUE)match; return (VALUE)match;
} }
#define MATCH_BUSY FL_USER2
void
rb_match_busy(match, busy)
VALUE match;
int busy;
{
if (busy) {
FL_SET(match, MATCH_BUSY);
}
else {
FL_UNSET(match, MATCH_BUSY);
}
}
int ruby_ignorecase; int ruby_ignorecase;
static int may_need_recompile; static int may_need_recompile;
static VALUE matchcache; static VALUE matchcache;
@ -462,7 +477,7 @@ rb_reg_search(reg, str, start, reverse)
#else #else
match = rb_backref_get(); match = rb_backref_get();
#endif #endif
if (NIL_P(match)) { if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) {
if (matchcache) { if (matchcache) {
match = matchcache; match = matchcache;
matchcache = 0; matchcache = 0;
@ -481,7 +496,6 @@ rb_reg_search(reg, str, start, reverse)
} }
result = re_search(RREGEXP(reg)->ptr,RSTRING(str)->ptr,RSTRING(str)->len, result = re_search(RREGEXP(reg)->ptr,RSTRING(str)->ptr,RSTRING(str)->len,
start, range, regs); start, range, regs);
if (FL_TEST(reg, KCODE_FIXED)) if (FL_TEST(reg, KCODE_FIXED))
kcode_reset_option(); kcode_reset_option();
@ -1102,7 +1116,10 @@ ignorecase_setter(val)
static VALUE static VALUE
match_getter() match_getter()
{ {
return match_clone(rb_backref_get()); VALUE match = rb_backref_get();
if (NIL_P(match)) return Qnil;
return match_clone(match);
} }
static void static void

9
ruby.c
View file

@ -279,7 +279,11 @@ proc_options(argcp, argvp)
case 'e': case 'e':
forbid_setid("-e"); forbid_setid("-e");
if (!argv[1]) { if (!*++s) {
s = argv[1];
argc--,argv++;
}
if (!s) {
fprintf(stderr, "%s: no code specified for -e\n", origargv[0]); fprintf(stderr, "%s: no code specified for -e\n", origargv[0]);
exit(2); exit(2);
} }
@ -292,9 +296,8 @@ proc_options(argcp, argvp)
} }
if (script == 0) script = e_tmpname; if (script == 0) script = e_tmpname;
} }
fputs(argv[1], e_fp); fputs(s, e_fp);
putc('\n', e_fp); putc('\n', e_fp);
argc--, argv++;
break; break;
case 'r': case 'r':

6
ruby.h
View file

@ -525,7 +525,11 @@ rb_type(VALUE obj)
extern __inline__ int extern __inline__ int
rb_special_const_p(VALUE obj) rb_special_const_p(VALUE obj)
{ {
return (FIXNUM_P(obj)||obj == Qnil||obj == Qfalse||obj == Qtrue)?Qtrue:Qfalse; if (FIXNUM_P(obj)) return Qtrue;
if (obj == Qnil) return Qtrue;
if (obj == Qfalse) return Qtrue;
if (obj == Qtrue) return Qtrue;;
return Qfalse;
} }
extern __inline__ int extern __inline__ int

View file

@ -19,11 +19,11 @@ def usage()
print "Usage:\n" print "Usage:\n"
print "biorhythm.rb [options]\n" print "biorhythm.rb [options]\n"
print " options...\n" print " options...\n"
print " -D YYYYMMDD(birthday) : すべて default 値を使う. \n" print " -D YYYYMMDD(birthday) : use default values.\n"
print " --sdate | --date YYYYMMDD : system date もしくは指定した日付を使う.\n" print " --sdate | --date YYYYMMDD : use system date; use specified date.\n"
print " --birthday YYYYMMDD : 誕生日の指定をする. \n" print " --birthday YYYYMMDD : specifies your birthday.\n"
print " -v | -g : Values or Graph の指定. \n" print " -v | -g : show values or graph.\n"
print " --days DAYS : 期間の指定をする(Graph の時のみ有効). \n" print " --days DAYS : graph range (only in effect for graphs).\n"
print " --help : help\n" print " --help : help\n"
end end
$USAGE = 'usage' $USAGE = 'usage'

View file

@ -1,8 +1,8 @@
# Linked list example # Linked list example
class MyElem class MyElem
# オブジェクト生成時に自動的に呼ばれるメソッド # object initializer called from Class#new
def initialize(item) def initialize(item)
# @変数はインスタンス変数(宣言は要らない) # @variables are instance variable, no declaration needed
@data = item @data = item
@succ = nil @succ = nil
end end
@ -15,7 +15,7 @@ class MyElem
@succ @succ
end end
# 「obj.data = val」としたときに暗黙に呼ばれるメソッド # the method invoked by ``obj.data = val''
def succ=(new) def succ=(new)
@succ = new @succ = new
end end
@ -40,12 +40,12 @@ class MyList
end end
end end
# オブジェクトを文字列に変換するメソッド # the method to convert object into string.
# これを再定義するとprintでの表現が変わる # redefining this will affect print.
def to_s def to_s
str = "<MyList:\n"; str = "<MyList:\n";
for elt in self for elt in self
# 「str = str + elt.data.to_s + "\n"」の省略形 # short form of ``str = str + elt.data.to_s + "\n"''
str += elt.data.to_s + "\n" str += elt.data.to_s + "\n"
end end
str += ">" str += ">"
@ -64,7 +64,7 @@ class Point
end end
end end
# 大域変数は`$'で始まる. # global variables are start with `$'.
$list1 = MyList.new $list1 = MyList.new
$list1.add_to_list(10) $list1.add_to_list(10)
$list1.add_to_list(20) $list1.add_to_list(20)
@ -75,6 +75,6 @@ $list2.add_to_list(20)
$list2.add_to_list(Point.new(4, 5)) $list2.add_to_list(Point.new(4, 5))
$list2.add_to_list($list1) $list2.add_to_list($list1)
# 曖昧でない限りメソッド呼び出しの括弧は省略できる # parenthesises around method arguments can be ommitted unless ambiguous.
print "list1:\n", $list1, "\n" print "list1:\n", $list1, "\n"
print "list2:\n", $list2, "\n" print "list2:\n", $list2, "\n"

View file

@ -10,19 +10,19 @@ class Board
end end
def put(x, y, col, str) def put(x, y, col, str)
pos(x,y); colorstr(43,str) pos(x,y); colorstr(43,str)
pos(0,@hi); print "$B;D$j(B:",@mc,"/",@total," " pos(0,@hi); print "残り:",@mc,"/",@total," "
pos(x,y) pos(x,y)
end end
private :clr, :pos, :colorstr, :put private :clr, :pos, :colorstr, :put
CHR=["$B!&(B","$B#1(B","$B#2(B","$B#3(B","$B#4(B","$B#5(B","$B#6(B","$B#7(B","$B#8(B","$B!z(B","$B!|(B","@@"] CHR=["","","","","","","","","","","","@@"]
COL=[46,43,45] # default,opened,over COL=[46,43,45] # default,opened,over
def initialize(h,w,m) def initialize(h,w,m)
# $B%2!<%`HW$N@8@.(B(h:$B=D!$(Bw:$B2#!$(Bm:$BGzCF$N?t(B) # ゲーム盤の生成(h:縦w:横m:爆弾の数)
@hi=h; @wi=w; @m=m @hi=h; @wi=w; @m=m
reset reset
end end
def reset def reset
# $B%2!<%`HW$r(B($B:F(B)$B=i4|2=$9$k(B # ゲーム盤を(再)初期化する
srand() srand()
@cx=0; @cy=0; @mc=@m @cx=0; @cy=0; @mc=@m
@over=false @over=false
@ -44,7 +44,7 @@ class Board
pos(@cx,@cy) pos(@cx,@cy)
end end
def mark def mark
# $B8=:_$N%+!<%=%k0LCV$K%^!<%/$r$D$1$k(B # 現在のカーソル位置にマークをつける
if @state[@wi*@cy+@cx] != nil then return end if @state[@wi*@cy+@cx] != nil then return end
@state[@wi*@cy+@cx] = "MARK" @state[@wi*@cy+@cx] = "MARK"
@mc=@mc-1; @mc=@mc-1;
@ -52,8 +52,8 @@ class Board
put(@cx, @cy, COL[1], CHR[9]) put(@cx, @cy, COL[1], CHR[9])
end end
def open(x=@cx,y=@cy) def open(x=@cx,y=@cy)
# $B8=:_$N%+!<%=%k0LCV$r%*!<%W%s$K$9$k(B # 現在のカーソル位置をオープンにする
# $BGzCF$,$"$l$P%2!<%`%*!<%P!<(B # 爆弾があればゲームオーバー
if @state[@wi*y+x] =="OPEN" then return 0 end if @state[@wi*y+x] =="OPEN" then return 0 end
if @state[@wi*y+x] == nil then @total=@total-1 end if @state[@wi*y+x] == nil then @total=@total-1 end
if @state[@wi*y+x] =="MARK" then @mc=@mc+1 end if @state[@wi*y+x] =="MARK" then @mc=@mc+1 end
@ -73,7 +73,7 @@ class Board
pos(@cx,@cy) pos(@cx,@cy)
end end
def fetch(x,y) def fetch(x,y)
# (x,y)$B$N0LCV$NGzCF$N?t(B(0 or 1)$B$rJV$9(B # (x,y)の位置の爆弾の数(0 or 1)を返す
if x < 0 then 0 if x < 0 then 0
elsif x >= @wi then 0 elsif x >= @wi then 0
elsif y < 0 then 0 elsif y < 0 then 0
@ -83,13 +83,13 @@ class Board
end end
end end
def count(x,y) def count(x,y)
# (x,y)$B$KNY@\$9$kGzCF$N?t$rJV$9(B # (x,y)に隣接する爆弾の数を返す
fetch(x-1,y-1)+fetch(x,y-1)+fetch(x+1,y-1)+ fetch(x-1,y-1)+fetch(x,y-1)+fetch(x+1,y-1)+
fetch(x-1,y) + fetch(x+1,y)+ fetch(x-1,y) + fetch(x+1,y)+
fetch(x-1,y+1)+fetch(x,y+1)+fetch(x+1,y+1) fetch(x-1,y+1)+fetch(x,y+1)+fetch(x+1,y+1)
end end
def over(win) def over(win)
# $B%2!<%`$N=*N;(B # ゲームの終了
quit quit
unless win unless win
pos(@cx,@cy); print CHR[11] pos(@cx,@cy); print CHR[11]
@ -100,8 +100,8 @@ class Board
end end
end end
def over? def over?
# $B%2!<%`$N=*N;%A%'%C%/(B # ゲームの終了チェック
# $B=*N;=hM}$b8F$S=P$9(B # 終了処理も呼び出す
remain = (@mc+@total == 0) remain = (@mc+@total == 0)
if @over || remain if @over || remain
over(remain) over(remain)
@ -111,8 +111,8 @@ class Board
end end
end end
def quit def quit
# $B%2!<%`$NCfCG(B($B$^$?$O=*N;(B) # ゲームの中断(または終了)
# $BHWLL$rA4$F8+$;$k(B # 盤面を全て見せる
@hi.times do|y| @hi.times do|y|
pos(0,y) pos(0,y)
@wi.times do|x| @wi.times do|x|
@ -122,19 +122,19 @@ class Board
end end
end end
def down def down
# $B%+!<%=%k$r2<$K(B # カーソルを下に
if @cy < @hi-1 then @cy=@cy+1; pos(@cx, @cy) end if @cy < @hi-1 then @cy=@cy+1; pos(@cx, @cy) end
end end
def up def up
# $B%+!<%=%k$r>e$K(B # カーソルを上に
if @cy > 0 then @cy=@cy-1; pos(@cx, @cy) end if @cy > 0 then @cy=@cy-1; pos(@cx, @cy) end
end end
def left def left
# $B%+!<%=%k$r:8$K(B # カーソルを左に
if @cx > 0 then @cx=@cx-1; pos(@cx, @cy) end if @cx > 0 then @cx=@cx-1; pos(@cx, @cy) end
end end
def right def right
# $B%+!<%=%k$r1&$K(B # カーソルを右に
if @cx < @wi-1 then @cx=@cx+1; pos(@cx, @cy) end if @cx < @wi-1 then @cx=@cx+1; pos(@cx, @cy) end
end end
end end

View file

@ -273,7 +273,7 @@ module BC_APPLICATION__
rests.unshift op rests.unshift op
identify_number(rests) identify_number(rests)
else else
# obj.if などの対応 # handle ``obj.if'' and such
identify_identifier(rests, TRUE) identify_identifier(rests, TRUE)
@lex_state = EXPR_ARG @lex_state = EXPR_ARG
end end
@ -344,7 +344,7 @@ module BC_APPLICATION__
@lex_state = EXPR_BEG @lex_state = EXPR_BEG
end end
end end
@OP.def_rule('$') do @OP.def_rule('$') do #'
|op, rests| |op, rests|
identify_gvar(rests) identify_gvar(rests)
end end
@ -466,7 +466,7 @@ module BC_APPLICATION__
print token, "\n" if CONFIG[:DEBUG] print token, "\n" if CONFIG[:DEBUG]
if state = CLAUSE_STATE_TRANS[token] if state = CLAUSE_STATE_TRANS[token]
if @lex_state != EXPR_BEG and token =~ /^(if|unless|while|until)/ if @lex_state != EXPR_BEG and token =~ /^(if|unless|while|until)/
# 修飾子 # modifiers
else else
if ENINDENT_CLAUSE.include?(token) if ENINDENT_CLAUSE.include?(token)
@indent += 1 @indent += 1
@ -640,7 +640,7 @@ module BC_APPLICATION__
def_exception :ErrNodeAlreadyExists, "node already exists" def_exception :ErrNodeAlreadyExists, "node already exists"
class Node class Node
# postprocがなければ抽象ード, nilじゃなければ具象ード # abstract node if postproc is nil.
def initialize(preproc = nil, postproc = nil) def initialize(preproc = nil, postproc = nil)
@Tree = {} @Tree = {}
@preproc = preproc @preproc = preproc

View file

@ -1,12 +1,12 @@
# random dot steraogram # random dot steraogram
# usage: rcs.rb rcs.dat # usage: rcs.rb rcs.dat
sw = 40.0 # 元のパターンの幅 sw = 40.0 # width of original pattern
dw = 78.0 # 生成される Random Character Streogram の幅 dw = 78.0 # width of generating Random Character Streogram
hdw = dw / 2.0 hdw = dw / 2.0
w = 20.0 # 両眼の幅 w = 20.0 # distance between eyes
h =1.0 # 画面と基準面の距離 h =1.0 # distance from screen and base plane
d = 0.2 # 単位当たりの浮き上がり方 d = 0.2 # z value unit
ss="abcdefghijklmnopqrstuvwxyz0123456789#!$%^&*()-=\\[];'`,./" ss="abcdefghijklmnopqrstuvwxyz0123456789#!$%^&*()-=\\[];'`,./"
rnd = srand() rnd = srand()

View file

@ -13,6 +13,10 @@
#include "ruby.h" #include "ruby.h"
#include <ctype.h> #include <ctype.h>
#ifndef atof
double strtod();
#endif
#ifdef USE_CWGUSI #ifdef USE_CWGUSI
static void fmt_setup(); static void fmt_setup();
#else #else
@ -570,7 +574,7 @@ rb_f_sprintf(argc, argv)
fval = rb_big2dbl(val); fval = rb_big2dbl(val);
break; break;
case T_STRING: case T_STRING:
fval = atof(RSTRING(val)->ptr); fval = strtod(RSTRING(val)->ptr, 0);
break; break;
default: default:
Check_Type(val, T_FLOAT); Check_Type(val, T_FLOAT);

View file

@ -22,6 +22,10 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifndef atof
double strtod();
#endif
VALUE rb_cString; VALUE rb_cString;
#define STR_FREEZE FL_USER1 #define STR_FREEZE FL_USER1
@ -60,14 +64,20 @@ rb_tainted_str_new(ptr, len)
char *ptr; char *ptr;
int len; int len;
{ {
return rb_obj_taint(rb_str_new(ptr, len)); VALUE str = rb_str_new(ptr, len);
FL_SET(str, FL_TAINT);
return str;
} }
VALUE VALUE
rb_tainted_str_new2(ptr) rb_tainted_str_new2(ptr)
char *ptr; char *ptr;
{ {
return rb_obj_taint(rb_str_new2(ptr)); VALUE str = rb_str_new2(ptr);
FL_SET(str, FL_TAINT);
return str;
} }
VALUE VALUE
@ -102,7 +112,7 @@ rb_str_new4(orig)
str->ptr = RSTRING(orig)->ptr; str->ptr = RSTRING(orig)->ptr;
RSTRING(orig)->orig = (VALUE)str; RSTRING(orig)->orig = (VALUE)str;
str->orig = 0; str->orig = 0;
if (rb_safe_level() >= 3) { if (FL_TEST(str, FL_TAINT)) {
FL_SET(str, FL_TAINT); FL_SET(str, FL_TAINT);
} }
return (VALUE)str; return (VALUE)str;
@ -1028,7 +1038,10 @@ rb_str_sub_bang(argc, argv, str)
regs = RMATCH(match)->regs; regs = RMATCH(match)->regs;
if (iter) { if (iter) {
rb_match_busy(match, Qtrue);
repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match))); repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
rb_match_busy(match, Qfalse);
rb_backref_set(match);
} }
else { else {
repl = rb_reg_regsub(repl, str, regs); repl = rb_reg_regsub(repl, str, regs);
@ -1102,7 +1115,10 @@ rb_str_gsub_bang(argc, argv, str)
match = rb_backref_get(); match = rb_backref_get();
regs = RMATCH(match)->regs; regs = RMATCH(match)->regs;
if (iter) { if (iter) {
rb_match_busy(match, Qtrue);
val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match))); val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
rb_match_busy(match, Qfalse);
rb_backref_set(match);
} }
else { else {
val = rb_reg_regsub(repl, str, regs); val = rb_reg_regsub(repl, str, regs);
@ -1313,7 +1329,7 @@ static VALUE
rb_str_to_f(str) rb_str_to_f(str)
VALUE str; VALUE str;
{ {
double f = atof(RSTRING(str)->ptr); double f = strtod(RSTRING(str)->ptr, 0);
return rb_float_new(f); return rb_float_new(f);
} }

2
util.c
View file

@ -761,7 +761,7 @@ void ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp)
if (t < 0) {mmswap(L,l); l = L; goto loopB;} /*535-5*/ if (t < 0) {mmswap(L,l); l = L; goto loopB;} /*535-5*/
} }
loopA: eq_l = 1; eq_r = 1; /* splitting type A */ /* left <= median < right±¦*/ loopA: eq_l = 1; eq_r = 1; /* splitting type A */ /* left <= median < right */
for (;;) { for (;;) {
for (;;) { for (;;) {
if ((l += size) == r) if ((l += size) == r)

View file

@ -873,8 +873,6 @@ rb_ivar_defined(obj, id)
VALUE obj; VALUE obj;
ID id; ID id;
{ {
if (!rb_is_instance_id(id)) return Qfalse;
switch (TYPE(obj)) { switch (TYPE(obj)) {
case T_OBJECT: case T_OBJECT:
case T_CLASS: case T_CLASS:

View file

@ -1,2 +1,2 @@
#define RUBY_VERSION "1.3.1" #define RUBY_VERSION "1.3.1"
#define VERSION_DATE "99/02/05" #define VERSION_DATE "99/02/09"

View file

@ -46,3 +46,9 @@
#define RUBY_ARCHLIB "/usr/local/lib/ruby/i386-mswin32" #define RUBY_ARCHLIB "/usr/local/lib/ruby/i386-mswin32"
#define RUBY_PLATFORM "i386-mswin32" #define RUBY_PLATFORM "i386-mswin32"
#define SIZEOF_INT 4
#define SIZEOF_SHORT 2
#define SIZEOF_LONG 4
#define SIZEOF_VOIDP 4
#define SIZEOF_FLOAT 4
#define SIZEOF_DOUBLE 8