зеркало из https://github.com/github/ruby.git
2000-02-01
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@611 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
005f125829
Коммит
e4b53b2222
91
ChangeLog
91
ChangeLog
|
@ -1,3 +1,82 @@
|
|||
Mon Jan 31 15:24:58 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* string.c (rb_str_sub): no bang method returns original string if
|
||||
no change is made.
|
||||
|
||||
* string.c (str_sub_bang): bang method returns string always.
|
||||
experimental.
|
||||
|
||||
Sun Jan 30 17:58:09 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
|
||||
|
||||
* eval.c: arrange to use setitimer(2) for BOW, DJGPP
|
||||
|
||||
* defines.h: ditto. use random(3) on cygwin b20.1.
|
||||
|
||||
Sun Jan 30 17:20:16 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
|
||||
|
||||
* eval.c: use getrlimit(2) on DJGPP.
|
||||
|
||||
Thu Jan 27 01:27:10 2000 GOTO Kentaro <gotoken@math.sci.hokudai.ac.jp>
|
||||
|
||||
* dir.c (glob): glob pattern "/*" did not match.
|
||||
|
||||
Wed Jan 26 22:30:47 2000 Shigeo Kobayashi <shigeo@tinyforest.gr.jp>
|
||||
|
||||
* numeric.c (flo_modulo): wrong result for negative modulo.
|
||||
|
||||
Wed Jan 26 02:01:57 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* file.c (test_c): should use S_ISCHR.
|
||||
|
||||
* file.c (rb_stat_c): ditto.
|
||||
|
||||
* string.c (rb_str_each_line): should propagate tainting.
|
||||
|
||||
Tue Jan 25 04:01:34 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* object.c (rb_obj_freeze): all objects made freezable.
|
||||
|
||||
Tue Jan 25 00:37:01 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
|
||||
|
||||
* configure.in: use AC_CHECK_TOOL for cross compiling.
|
||||
|
||||
Mon Jan 24 19:01:54 2000 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||
|
||||
* array.c (rb_protect_inspect): should be checked by id of
|
||||
objects; not by object themselves.
|
||||
|
||||
Mon Jan 24 18:48:08 2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
|
||||
|
||||
* eval.c (rb_eval): too many warnings; warned on every method
|
||||
overriding. should be on method discarding.
|
||||
|
||||
Mon Jan 24 02:56:44 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* parse.y (yylex): -2.abs should be `(-2).abs' to accomplish the
|
||||
principle of less surprise. `+2' too.
|
||||
|
||||
* eval.c (rb_eval): when defining class is already there, and
|
||||
superclass differ, throw away the old class.
|
||||
|
||||
* variable.c (rb_const_set): gives warining again on constant
|
||||
redefinition.
|
||||
|
||||
* error.c (Init_Exception): SyntaxError, NameError, LoadError and
|
||||
NotImplementError are subclasses of ScriptError<Exception, not
|
||||
StandardError. experimental.
|
||||
|
||||
Sat Jan 22 00:00:41 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* parse.y (parse_quotedwords): no longer use `String#split'.
|
||||
and enable space escape within quoted word list.
|
||||
e.g. %w(a\ b\ c abc) => ["a b c", "abc"].
|
||||
|
||||
* string.c (rb_str_slice_bang): new method `slice!'.
|
||||
|
||||
Fri Jan 21 16:15:59 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* eval.c (thgroup_s_new): new class ThreadGroup.
|
||||
|
||||
Tue Jan 18 12:24:28 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* struct.c (Init_Struct): remove Struct's own hash and eql?.
|
||||
|
@ -68,8 +147,8 @@ Tue Jan 4 06:04:14 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
|
|||
|
||||
Sat Jan 1 13:26:14 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* eval.c (rb_yield_0): force_recycle ruby_dyna_vars to performance
|
||||
gain.
|
||||
* eval.c (rb_yield_0): force_recycle ruby_dyna_vars to gain
|
||||
performance.
|
||||
|
||||
* array.c (rb_ary_delete_at_m): takes same argument pattern with
|
||||
rb_ary_aref.
|
||||
|
@ -85,8 +164,8 @@ Sat Jan 1 10:12:26 2000 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
|||
* ruby.h (FL_ABLE, FL_SET, FL_UNSET, FL_REVERSE): made expressions
|
||||
not statements.
|
||||
|
||||
* ruby.h (OBJ_INFECT): newly added which copies taint from `s' to
|
||||
`x'.
|
||||
* ruby.h (OBJ_INFECT): newly added macro which copies taint from
|
||||
`s' to `x'.
|
||||
|
||||
Sat Jan 1 02:04:18 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
|
@ -202,7 +281,7 @@ Mon Dec 13 15:15:31 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
|||
because of major performace drawback.
|
||||
|
||||
* class.c (rb_singleton_class): tainted status of the singleton
|
||||
class must synchronize with the object.
|
||||
class must be synchronized with the object.
|
||||
|
||||
* eval.c (rb_thread_schedule): implement thread priority.
|
||||
|
||||
|
@ -404,7 +483,7 @@ Mon Nov 15 04:50:33 1999 Koji Arai <JCA02266@nifty.ne.jp>
|
|||
Sat Nov 13 07:34:18 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* variable.c (rb_mod_constants): traverse superclasses to collect
|
||||
constants (shared variables).
|
||||
constants.
|
||||
|
||||
* eval.c (assign): modified for shared variables.
|
||||
|
||||
|
|
31
ToDo
31
ToDo
|
@ -2,31 +2,32 @@ Language Spec.
|
|||
|
||||
- def foo; .. rescue .. end
|
||||
- compile time string concatenation, "hello" "world" => "helloworld"
|
||||
- assignable constant, which now should be called shared variable.
|
||||
- class variable (prefix?) -- done by shared variable
|
||||
- rescue modifier; a rescue b => begin a rescue; b end
|
||||
* operator !! for rescue.
|
||||
- %w(a\ b\ c abc) => ["a b c", "abc"]
|
||||
* class variable (prefix @@?) ??
|
||||
* operator !! for rescue. ???
|
||||
* objectify symbols
|
||||
* objectify characters
|
||||
* ../... outside condition invokes operator method too.
|
||||
* ... inside condition turns off just before right condition.???
|
||||
* %w(a\ b\ c abc) => ["a b c", "abc"]
|
||||
* package or access control for global variables??
|
||||
* named arguments like foo(nation:="german") or foo(nation: "german").
|
||||
* method to retrieve argument information (need new C API)
|
||||
* method to retrieve argument information (needs new C API)
|
||||
* multiple return values, yield values. maybe incompatible ???
|
||||
* cascading method invocation ???
|
||||
* def Class#method .. end ??
|
||||
* class Foo::Bar<Baz .. end, module Boo::Bar .. end
|
||||
* def Foo::Bar::baz() .. end ??
|
||||
* I18N (or M17N) script/string/regexp
|
||||
|
||||
Hacking Interpreter
|
||||
|
||||
- use eban's fnmatch
|
||||
- RUBYOPT environment variable
|
||||
- alias $defout $>
|
||||
* retrieve STACK_LEVEL_MAX from users' limit.
|
||||
* remove end_proc registered out of require only
|
||||
- retrieve STACK_LEVEL_MAX from users' limit.
|
||||
- remove end_proc registered out of require only
|
||||
- all object made freezable
|
||||
* non-blocking open (e.g. for named pipe) for thread
|
||||
* avoid blocking with gethostbyname/gethostbyaddr
|
||||
* objectify interpreters
|
||||
|
@ -34,7 +35,6 @@ Hacking Interpreter
|
|||
* syntax tree -> bytecode ???
|
||||
* scrambled script, or script filter
|
||||
* setuid ruby
|
||||
* freeze all object
|
||||
|
||||
Standard Libraries
|
||||
|
||||
|
@ -45,9 +45,12 @@ Standard Libraries
|
|||
- sprintf/printf's $ to specify argument order
|
||||
- Dir.glob("**/*.c") ala zsh
|
||||
- Remove Enumerable#{size,length}
|
||||
* Marshal should handle generic instance variables.
|
||||
* SyntaxError and NameError should not be subclasses of StandardError, maybe.
|
||||
* debugger for thread programming
|
||||
- Array#slice, Array#slice!
|
||||
- String#slice, String#slice!
|
||||
- Marshal should handle generic instance variables.
|
||||
- debugger for thread programming
|
||||
- SyntaxError, NameError, LoadError and NotImplementError are subclasses of
|
||||
ScriptError<Exception, not StandardError.
|
||||
* Struct::new([name,]member,...) ??
|
||||
* String#scanf(?)
|
||||
* Object#fmt(?)
|
||||
|
@ -66,14 +69,16 @@ Extension Libraries
|
|||
|
||||
Ruby Libraries
|
||||
|
||||
* httplib.rb, urllib.rb, nttplib.rb, etc.
|
||||
- net/http.rb
|
||||
* urllib.rb, nttplib.rb, etc.
|
||||
* format like perl's
|
||||
|
||||
Tools
|
||||
|
||||
- extension library maker like XS or SWIG
|
||||
- extension library maker using SWIG
|
||||
* freeze or undump to bundle everything
|
||||
|
||||
Misc
|
||||
|
||||
- publish Ruby books
|
||||
* publish Ruby books in English
|
||||
|
|
57
array.c
57
array.c
|
@ -38,37 +38,24 @@ memfill(mem, size, val)
|
|||
}
|
||||
}
|
||||
|
||||
#define ARY_FREEZE FL_USER1
|
||||
#define ARY_TMPLOCK FL_USER2
|
||||
#define ARY_TMPLOCK FL_USER1
|
||||
|
||||
static void
|
||||
rb_ary_modify(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
if (FL_TEST(ary, ARY_FREEZE))
|
||||
rb_raise(rb_eTypeError, "can't modify frozen array");
|
||||
if (OBJ_FROZEN(ary)) rb_error_frozen("array");
|
||||
if (FL_TEST(ary, ARY_TMPLOCK))
|
||||
rb_raise(rb_eTypeError, "can't modify array during sort");
|
||||
if (!OBJ_TAINTED(ary) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify array");
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_ary_freeze(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(ary))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze array");
|
||||
|
||||
FL_SET(ary, ARY_FREEZE);
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_frozen_p(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
if (FL_TEST(ary, ARY_FREEZE|ARY_TMPLOCK))
|
||||
if (FL_TEST(ary, FL_FREEZE|ARY_TMPLOCK))
|
||||
return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
@ -355,7 +342,7 @@ rb_ary_entry(ary, offset)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_subary(ary, beg, len)
|
||||
rb_ary_subseq(ary, beg, len)
|
||||
VALUE ary;
|
||||
long beg, len;
|
||||
{
|
||||
|
@ -397,7 +384,7 @@ rb_ary_aref(argc, argv, ary)
|
|||
if (beg < 0) {
|
||||
beg = RARRAY(ary)->len + beg;
|
||||
}
|
||||
return rb_ary_subary(ary, beg, len);
|
||||
return rb_ary_subseq(ary, beg, len);
|
||||
}
|
||||
|
||||
/* special case - speeding up */
|
||||
|
@ -415,7 +402,7 @@ rb_ary_aref(argc, argv, ary)
|
|||
case Qnil:
|
||||
return Qnil;
|
||||
default:
|
||||
return rb_ary_subary(ary, beg, len);
|
||||
return rb_ary_subseq(ary, beg, len);
|
||||
}
|
||||
}
|
||||
return rb_ary_entry(ary, NUM2LONG(arg1));
|
||||
|
@ -790,8 +777,8 @@ rb_protect_inspect(func, obj, arg)
|
|||
VALUE obj, arg;
|
||||
{
|
||||
struct inspect_arg iarg;
|
||||
|
||||
VALUE inspect_tbl;
|
||||
VALUE id;
|
||||
|
||||
if (!inspect_key) {
|
||||
inspect_key = rb_intern("__inspect_key__");
|
||||
|
@ -801,10 +788,11 @@ rb_protect_inspect(func, obj, arg)
|
|||
inspect_tbl = rb_ary_new();
|
||||
rb_thread_local_aset(rb_thread_current(), inspect_key, inspect_tbl);
|
||||
}
|
||||
if (rb_ary_includes(inspect_tbl, obj)) {
|
||||
id = rb_obj_id(obj);
|
||||
if (rb_ary_includes(inspect_tbl, id)) {
|
||||
return (*func)(obj, arg);
|
||||
}
|
||||
rb_ary_push(inspect_tbl, obj);
|
||||
rb_ary_push(inspect_tbl, id);
|
||||
iarg.func = func;
|
||||
iarg.arg1 = obj;
|
||||
iarg.arg2 = arg;
|
||||
|
@ -821,7 +809,7 @@ rb_inspecting_p(obj)
|
|||
if (!inspect_key) return Qfalse;
|
||||
inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key);
|
||||
if (NIL_P(inspect_tbl)) return Qfalse;
|
||||
return rb_ary_includes(inspect_tbl, obj);
|
||||
return rb_ary_includes(inspect_tbl, rb_obj_id(obj));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1040,7 +1028,7 @@ rb_ary_delete_at_m(argc, argv, ary)
|
|||
if (pos < 0) {
|
||||
pos = RARRAY(ary)->len + pos;
|
||||
}
|
||||
arg2 = rb_ary_subary(ary, pos, len);
|
||||
arg2 = rb_ary_subseq(ary, pos, len);
|
||||
rb_ary_replace(ary, pos, len, Qnil); /* Qnil/rb_ary_new2(0) */
|
||||
return arg2;
|
||||
}
|
||||
|
@ -1064,6 +1052,7 @@ rb_ary_delete_at_m(argc, argv, ary)
|
|||
|
||||
return arg2;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_delete_if(ary)
|
||||
VALUE ary;
|
||||
|
@ -1500,11 +1489,26 @@ rb_ary_flatten_bang(ary)
|
|||
{
|
||||
long i;
|
||||
int mod = 0;
|
||||
VALUE flattening = Qnil;
|
||||
|
||||
rb_ary_modify(ary);
|
||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||
VALUE ary2 = RARRAY(ary)->ptr[i];
|
||||
if (TYPE(ary2) == T_ARRAY) {
|
||||
if (ary == ary2) {
|
||||
ary2 = Qnil;
|
||||
} else {
|
||||
VALUE id;
|
||||
|
||||
if (NIL_P(flattening)) {
|
||||
flattening = rb_ary_new();
|
||||
}
|
||||
id = rb_obj_id(ary2);
|
||||
if (rb_ary_includes(flattening, id)) {
|
||||
rb_raise(rb_eArgError, "tryed to flatten recursive array");
|
||||
}
|
||||
rb_ary_push(flattening, id);
|
||||
}
|
||||
rb_ary_replace(ary, i--, 1, ary2);
|
||||
mod = 1;
|
||||
}
|
||||
|
@ -1534,8 +1538,6 @@ Init_Array()
|
|||
rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0);
|
||||
rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
|
||||
rb_define_method(rb_cArray, "to_ary", rb_ary_to_a, 0);
|
||||
|
||||
rb_define_method(rb_cArray, "freeze", rb_ary_freeze, 0);
|
||||
rb_define_method(rb_cArray, "frozen?", rb_ary_frozen_p, 0);
|
||||
|
||||
rb_define_method(rb_cArray, "==", rb_ary_equal, 1);
|
||||
|
@ -1583,6 +1585,9 @@ Init_Array()
|
|||
rb_define_method(rb_cArray, "include?", rb_ary_includes, 1);
|
||||
rb_define_method(rb_cArray, "<=>", rb_ary_cmp, 1);
|
||||
|
||||
rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
|
||||
rb_define_method(rb_cArray, "slice!", rb_ary_delete_at_m, -1);
|
||||
|
||||
rb_define_method(rb_cArray, "assoc", rb_ary_assoc, 1);
|
||||
rb_define_method(rb_cArray, "rassoc", rb_ary_rassoc, 1);
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
88
configure.in
88
configure.in
|
@ -68,13 +68,27 @@ fi
|
|||
AC_ARG_PROGRAM
|
||||
|
||||
dnl Checks for programs.
|
||||
|
||||
if test x"${build}" != x"${host}"; then
|
||||
AC_CHECK_TOOL(CC, gcc)
|
||||
fi
|
||||
AC_PROG_CC
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
|
||||
AC_PROG_YACC
|
||||
AC_PROG_RANLIB
|
||||
AC_SUBST(AR)
|
||||
AC_CHECK_TOOL(RANLIB, ranlib, :)
|
||||
AC_CHECK_TOOL(AR, ar)
|
||||
AC_CHECK_PROGS(AR, ar aal, ar)
|
||||
|
||||
case "$target_os" in
|
||||
cygwin*)
|
||||
AC_CHECK_TOOL(NM, nm)
|
||||
AC_CHECK_TOOL(DLLWRAP, dllwrap)
|
||||
AC_CHECK_TOOL(AS, as)
|
||||
AC_CHECK_TOOL(DLLTOOL, dlltool)
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
|
@ -310,10 +324,14 @@ AC_SUBST(DEFAULT_KCODE)
|
|||
AC_ARG_WITH(default-kcode,
|
||||
[--with-default-kcode=CODE specify default value for \$KCODE (utf8|euc|sjis|none)],
|
||||
[case $withval in
|
||||
utf8) AC_DEFINE(DEFAULT_KCODE, KCODE_UTF8);;
|
||||
euc) AC_DEFINE(DEFAULT_KCODE, KCODE_EUC);;
|
||||
sjis) AC_DEFINE(DEFAULT_KCODE, KCODE_SJIS);;
|
||||
none) AC_DEFINE(DEFAULT_KCODE, KCODE_NONE);;
|
||||
utf8) AC_DEFINE(DEFAULT_KCODE, KCODE_UTF8)
|
||||
DEFAULT_KCODE="KCODE_UTF8";;
|
||||
euc) AC_DEFINE(DEFAULT_KCODE, KCODE_EUC)
|
||||
DEFAULT_KCODE="KCODE_EUC";;
|
||||
sjis) AC_DEFINE(DEFAULT_KCODE, KCODE_SJIS)
|
||||
DEFAULT_KCODE="KCODE_SJIS";;
|
||||
none) AC_DEFINE(DEFAULT_KCODE, KCODE_NONE)
|
||||
DEFAULT_KCODE="KCODE_NONE";;
|
||||
*) AC_MSG_WARN($withval is not valid kcode; ignored);;
|
||||
esac])
|
||||
|
||||
|
@ -327,10 +345,8 @@ AC_ARG_WITH(dln-a-out,
|
|||
|
||||
AC_SUBST(XLDFLAGS)dnl
|
||||
|
||||
case "$target_os" in
|
||||
linux*)
|
||||
AC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf,
|
||||
[AC_TRY_RUN([
|
||||
AC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf,
|
||||
[AC_TRY_RUN([
|
||||
/* Test for whether ELF binaries are produced */
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -347,15 +363,30 @@ main() {
|
|||
exit(0); /* succeed (yes, it's ELF) */
|
||||
}
|
||||
],
|
||||
rb_cv_binary_elf=yes,
|
||||
rb_cv_binary_elf=no,
|
||||
rb_cv_binary_elf=yes)])
|
||||
rb_cv_binary_elf=yes,
|
||||
rb_cv_binary_elf=no,
|
||||
rb_cv_binary_elf=yes)])
|
||||
|
||||
if test "$rb_cv_binary_elf" = yes; then
|
||||
AC_DEFINE(USE_ELF)
|
||||
fi
|
||||
|
||||
case "$target_os" in
|
||||
linux*)
|
||||
if test "$rb_cv_binary_elf" = no; then
|
||||
with_dln_a_out=yes
|
||||
target_os=${target_os}-a_out
|
||||
else
|
||||
LDFLAGS="-rdynamic"
|
||||
fi;;
|
||||
netbsd*)
|
||||
if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
|
||||
then
|
||||
netbsd_elf=yes
|
||||
else
|
||||
netbsd_elf=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(DLDFLAGS)dnl
|
||||
|
@ -420,20 +451,17 @@ if test "$with_dln_a_out" != yes; then
|
|||
linux*) LDSHARED="$CC -shared"
|
||||
rb_cv_dlopen=yes ;;
|
||||
freebsd*) LDSHARED="$CC -shared"
|
||||
if test -x /usr/bin/objformat && \
|
||||
test `/usr/bin/objformat` = "elf" ; then
|
||||
if test "$rb_cv_binary_elf" = yes; then
|
||||
LDFLAGS="-rdynamic"
|
||||
DLDFLAGS='-Wl,-soname,$(.TARGET)'
|
||||
rb_cv_freebsd_elf=yes
|
||||
else
|
||||
test "$GCC" = yes && `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null || LDSHARED="ld -Bshareable"
|
||||
fi
|
||||
rb_cv_dlopen=yes ;;
|
||||
netbsd*) LDSHARED="ld -shared"
|
||||
case "$target_cpu" in
|
||||
alpha)
|
||||
LDFLAGS="-export-dynamic" ;;
|
||||
esac
|
||||
netbsd*) LDSHARED="ld -shared"
|
||||
if test "$rb_cv_binary_elf" = yes; then
|
||||
LDFLAGS="-export-dynamic"
|
||||
fi
|
||||
rb_cv_dlopen=yes ;;
|
||||
openbsd*) LDSHARED="ld -Bforcearchive -Bshareable"
|
||||
rb_cv_dlopen=yes ;;
|
||||
|
@ -478,7 +506,7 @@ if test "$with_dln_a_out" != yes; then
|
|||
DLDFLAGS="ruby.def -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
|
||||
esac
|
||||
rb_cv_dlopen=yes ;;
|
||||
cygwin*) : ${LDSHARED='dllwrap --export-all -s'}
|
||||
cygwin*) : ${LDSHARED="${DLLWRAP} --as=${AS} --dlltool-name=${DLLTOOL} --driver-name=${CC} --export-all -s"}
|
||||
rb_cv_dlopen=yes ;;
|
||||
*) LDSHARED='ld' ;;
|
||||
esac
|
||||
|
@ -687,18 +715,18 @@ if test "$enable_shared" = 'yes'; then
|
|||
;;
|
||||
freebsd*)
|
||||
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR)$(MINOR)'
|
||||
if test "$rb_cv_freebsd_elf" != "yes" ; then
|
||||
if test "$rb_cv_binary_elf" != "yes" ; then
|
||||
LIBRUBY_SO="$LIBRUBY_SO.\$(TEENY)"
|
||||
LIBRUBY_ALIASES=''
|
||||
fi
|
||||
;;
|
||||
netbsd*)
|
||||
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR)'
|
||||
case "$target_cpu" in
|
||||
alpha|mipsel|mipseb|powerpc|sparc64) # ELF platforms
|
||||
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR) lib$(RUBY_INSTALL_NAME).so' ;;
|
||||
*) LIBRUBY_ALIASES= ;; # a.out platforms
|
||||
esac
|
||||
if test "$rb_cv_binary_elf" = yes; then # ELF platforms
|
||||
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR) lib$(RUBY_INSTALL_NAME).so'
|
||||
else
|
||||
LIBRUBY_ALIASES= # a.out platforms
|
||||
fi
|
||||
;;
|
||||
solaris*)
|
||||
XLDFLAGS='-R${prefix}/lib'
|
||||
|
@ -727,10 +755,6 @@ if test "$enable_shared" = 'yes'; then
|
|||
FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in
|
||||
LIBOBJS="$LIBOBJS strftime.o"
|
||||
CCDLFLAGS=-DUSEIMPORTLIB
|
||||
: ${NM=nm}
|
||||
AC_SUBST(NM)
|
||||
: ${DLLWRAP=dllwrap}
|
||||
AC_SUBST(DLLWRAP)
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
|
|
|
@ -55,11 +55,15 @@
|
|||
#endif
|
||||
#define PATH_SEP_CHAR PATH_SEP[0]
|
||||
|
||||
#if defined(__human68k__) || defined(__CYGWIN__)
|
||||
#if defined(__human68k__)
|
||||
#undef HAVE_RANDOM
|
||||
#undef HAVE_SETITIMER
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN__) || defined(DJGPP) || defined(__BOW__)
|
||||
#undef HAVE_SETITIMER
|
||||
#endif
|
||||
|
||||
#ifndef RUBY_PLATFORM
|
||||
#define RUBY_PLATFORM "unknown-unknown"
|
||||
#endif
|
||||
|
|
8
dir.c
8
dir.c
|
@ -510,7 +510,7 @@ extract_path(p, pend)
|
|||
len = pend - p;
|
||||
alloc = ALLOC_N(char, len+1);
|
||||
memcpy(alloc, p, len);
|
||||
if (len > 0 && pend[-1] == '/') {
|
||||
if (len > 1 && pend[-1] == '/') {
|
||||
alloc[len-1] = 0;
|
||||
}
|
||||
else {
|
||||
|
@ -584,19 +584,21 @@ glob(path, func, arg)
|
|||
free(base);
|
||||
break;
|
||||
}
|
||||
#define BASE (*base && !(*base == '/' && !base[1]))
|
||||
|
||||
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
|
||||
if (recursive) {
|
||||
if (strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0)
|
||||
continue;
|
||||
buf = ALLOC_N(char, strlen(base)+NAMLEN(dp)+strlen(m)+6);
|
||||
sprintf(buf, "%s%s%s/**%s", base, (*base)?"/":"", dp->d_name, m);
|
||||
sprintf(buf, "%s%s%s/**%s", base, (BASE)?"/":"", dp->d_name, m);
|
||||
glob(buf, func, arg);
|
||||
free(buf);
|
||||
continue;
|
||||
}
|
||||
if (fnmatch(magic, dp->d_name, FNM_PERIOD|FNM_PATHNAME) == 0) {
|
||||
buf = ALLOC_N(char, strlen(base)+NAMLEN(dp)+2);
|
||||
sprintf(buf, "%s%s%s", base, (*base)?"/":"", dp->d_name);
|
||||
sprintf(buf, "%s%s%s", base, (BASE)?"/":"", dp->d_name);
|
||||
if (!m) {
|
||||
(*func)(buf, arg);
|
||||
free(buf);
|
||||
|
|
2
dln.c
2
dln.c
|
@ -80,7 +80,7 @@ int eaccess();
|
|||
#endif
|
||||
|
||||
#ifndef FUNCNAME_PATTERN
|
||||
# if defined(__hp9000s300) || (defined(__NetBSD__) && (!defined(__alpha__) && !defined(__mips__))) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(__OpenBSD__) || defined(NeXT) || defined(__WATCOMC__) || defined(__APPLE__)
|
||||
# if defined(__hp9000s300) || (defined(__NetBSD__) && !defined(__ELF__)) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(__OpenBSD__) || defined(NeXT) || defined(__WATCOMC__) || defined(__APPLE__)
|
||||
# define FUNCNAME_PATTERN "_Init_%.200s"
|
||||
# else
|
||||
# define FUNCNAME_PATTERN "Init_%.200s"
|
||||
|
|
25
error.c
25
error.c
|
@ -239,16 +239,18 @@ VALUE rb_eSignal;
|
|||
VALUE rb_eFatal;
|
||||
VALUE rb_eStandardError;
|
||||
VALUE rb_eRuntimeError;
|
||||
VALUE rb_eSyntaxError;
|
||||
VALUE rb_eTypeError;
|
||||
VALUE rb_eArgError;
|
||||
VALUE rb_eNameError;
|
||||
VALUE rb_eIndexError;
|
||||
VALUE rb_eLoadError;
|
||||
VALUE rb_eSecurityError;
|
||||
VALUE rb_eNotImpError;
|
||||
VALUE rb_eNoMemError;
|
||||
|
||||
VALUE rb_eScriptError;
|
||||
VALUE rb_eNameError;
|
||||
VALUE rb_eSyntaxError;
|
||||
VALUE rb_eLoadError;
|
||||
|
||||
VALUE rb_eSystemCallError;
|
||||
VALUE rb_mErrno;
|
||||
|
||||
|
@ -533,16 +535,18 @@ Init_Exception()
|
|||
rb_eSignal = rb_define_class("SignalException", rb_eException);
|
||||
|
||||
rb_eStandardError = rb_define_class("StandardError", rb_eException);
|
||||
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eStandardError);
|
||||
rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
|
||||
rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
|
||||
rb_eNameError = rb_define_class("NameError", rb_eStandardError);
|
||||
rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
|
||||
rb_eLoadError = rb_define_class("LoadError", rb_eStandardError);
|
||||
|
||||
rb_eScriptError = rb_define_class("ScriptError", rb_eException);
|
||||
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
|
||||
rb_eNameError = rb_define_class("NameError", rb_eScriptError);
|
||||
rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
|
||||
rb_eNotImpError = rb_define_class("NotImplementError", rb_eScriptError);
|
||||
|
||||
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
|
||||
rb_eSecurityError = rb_define_class("SecurityError", rb_eStandardError);
|
||||
rb_eNotImpError = rb_define_class("NotImplementError", rb_eException);
|
||||
rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
|
||||
|
||||
init_syserr();
|
||||
|
@ -672,6 +676,13 @@ rb_sys_fail(mesg)
|
|||
rb_exc_raise(ee);
|
||||
}
|
||||
|
||||
void
|
||||
rb_error_frozen(what)
|
||||
char *what;
|
||||
{
|
||||
rb_raise(rb_eTypeError, "can't modify frozen %s", what);
|
||||
}
|
||||
|
||||
static void
|
||||
init_syserr()
|
||||
{
|
||||
|
|
277
eval.c
277
eval.c
|
@ -90,7 +90,7 @@ static int scope_vmode;
|
|||
#define SCOPE_SET(f) do {scope_vmode=(f);} while(0)
|
||||
#define SCOPE_TEST(f) (scope_vmode&(f))
|
||||
|
||||
static int safe_level = 0;
|
||||
int ruby_safe_level = 0;
|
||||
/* safe-level:
|
||||
0 - strings from streams/environment/ARGV are tainted (default)
|
||||
1 - no dangerous operation by tainted string
|
||||
|
@ -99,25 +99,19 @@ static int safe_level = 0;
|
|||
4 - no global (non-tainted) variable modification/no direct output
|
||||
*/
|
||||
|
||||
int
|
||||
rb_safe_level()
|
||||
{
|
||||
return safe_level;
|
||||
}
|
||||
|
||||
void
|
||||
rb_set_safe_level(level)
|
||||
int level;
|
||||
{
|
||||
if (level > safe_level) {
|
||||
safe_level = level;
|
||||
if (level > ruby_safe_level) {
|
||||
ruby_safe_level = level;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
safe_getter()
|
||||
{
|
||||
return INT2FIX(safe_level);
|
||||
return INT2FIX(ruby_safe_level);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -126,18 +120,18 @@ safe_setter(val)
|
|||
{
|
||||
int level = NUM2INT(val);
|
||||
|
||||
if (level < safe_level) {
|
||||
if (level < ruby_safe_level) {
|
||||
rb_raise(rb_eSecurityError, "tried to downgrade safe level from %d to %d",
|
||||
safe_level, level);
|
||||
ruby_safe_level, level);
|
||||
}
|
||||
safe_level = level;
|
||||
ruby_safe_level = level;
|
||||
}
|
||||
|
||||
void
|
||||
rb_check_safe_str(x)
|
||||
VALUE x;
|
||||
{
|
||||
if (safe_level > 0 && OBJ_TAINTED(x)){
|
||||
if (ruby_safe_level > 0 && OBJ_TAINTED(x)){
|
||||
rb_raise(rb_eSecurityError, "Insecure operation - %s",
|
||||
rb_id2name(ruby_frame->last_func));
|
||||
}
|
||||
|
@ -151,9 +145,9 @@ void
|
|||
rb_secure(level)
|
||||
int level;
|
||||
{
|
||||
if (level <= safe_level) {
|
||||
if (level <= ruby_safe_level) {
|
||||
rb_raise(rb_eSecurityError, "Insecure operation `%s' for level %d",
|
||||
rb_id2name(ruby_frame->last_func), safe_level);
|
||||
rb_id2name(ruby_frame->last_func), ruby_safe_level);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,9 +219,10 @@ rb_add_method(klass, mid, node, noex)
|
|||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(klass)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't define method");
|
||||
}
|
||||
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
||||
body = NEW_METHOD(node, noex);
|
||||
st_insert(RCLASS(klass)->m_tbl, mid, body);
|
||||
}
|
||||
|
@ -306,9 +301,10 @@ remove_method(klass, mid)
|
|||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(klass)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't remove method");
|
||||
}
|
||||
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
||||
if (!st_delete(RCLASS(klass)->m_tbl, &mid, &body)) {
|
||||
rb_raise(rb_eNameError, "method `%s' not defined in %s",
|
||||
rb_id2name(mid), rb_class2name(klass));
|
||||
|
@ -567,7 +563,7 @@ struct RVarmap *ruby_dyna_vars;
|
|||
ruby_dyna_vars = _old; \
|
||||
}
|
||||
|
||||
#define DVAR_DONT_RECYCLE FL_USER0
|
||||
#define DVAR_DONT_RECYCLE FL_USER2
|
||||
|
||||
static struct RVarmap*
|
||||
new_dvar(id, value, prev)
|
||||
|
@ -597,6 +593,20 @@ rb_dvar_defined(id)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_dvar_curr(id)
|
||||
ID id;
|
||||
{
|
||||
struct RVarmap *vars = ruby_dyna_vars;
|
||||
|
||||
while (vars) {
|
||||
if (vars->id == 0) break;
|
||||
if (vars->id == id) return Qtrue;
|
||||
vars = vars->next;
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_dvar_ref(id)
|
||||
ID id;
|
||||
|
@ -621,48 +631,48 @@ rb_dvar_push(id, value)
|
|||
}
|
||||
|
||||
static void
|
||||
dvar_asgn(id, value, push)
|
||||
dvar_asgn_internal(id, value, curr)
|
||||
ID id;
|
||||
VALUE value;
|
||||
int push;
|
||||
int curr;
|
||||
{
|
||||
int n = 0;
|
||||
struct RVarmap *vars = ruby_dyna_vars;
|
||||
|
||||
while (vars) {
|
||||
if (push && vars->id == 0) break;
|
||||
if (curr && vars->id == 0) {
|
||||
n++;
|
||||
if (n == 2) break;
|
||||
}
|
||||
if (vars->id == id) {
|
||||
vars->val = value;
|
||||
return;
|
||||
}
|
||||
vars = vars->next;
|
||||
}
|
||||
rb_dvar_push(id, value);
|
||||
if (!ruby_dyna_vars) {
|
||||
ruby_dyna_vars = new_dvar(id, value, 0);
|
||||
}
|
||||
else {
|
||||
vars = new_dvar(id, value, ruby_dyna_vars->next);
|
||||
ruby_dyna_vars->next = vars;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_dvar_asgn(id, value)
|
||||
dvar_asgn(id, value)
|
||||
ID id;
|
||||
VALUE value;
|
||||
{
|
||||
dvar_asgn(id, value, 0);
|
||||
dvar_asgn_internal(id, value, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
dvar_asgn_push(id, value)
|
||||
dvar_asgn_curr(id, value)
|
||||
ID id;
|
||||
VALUE value;
|
||||
{
|
||||
struct RVarmap* vars = 0;
|
||||
|
||||
if (ruby_dyna_vars && ruby_dyna_vars->id == 0) {
|
||||
vars = ruby_dyna_vars;
|
||||
ruby_dyna_vars = ruby_dyna_vars->next;
|
||||
}
|
||||
dvar_asgn(id, value, 1);
|
||||
if (vars) {
|
||||
vars->next = ruby_dyna_vars;
|
||||
ruby_dyna_vars = vars;
|
||||
}
|
||||
dvar_asgn_internal(id, value, 1);
|
||||
}
|
||||
|
||||
struct iter {
|
||||
|
@ -1198,7 +1208,7 @@ rb_eval_cmd(cmd, arg)
|
|||
int state;
|
||||
VALUE val; /* OK */
|
||||
struct SCOPE *saved_scope;
|
||||
volatile int safe = safe_level;
|
||||
volatile int safe = ruby_safe_level;
|
||||
|
||||
if (TYPE(cmd) != T_STRING) {
|
||||
return rb_funcall2(cmd, rb_intern("call"),
|
||||
|
@ -1212,7 +1222,7 @@ rb_eval_cmd(cmd, arg)
|
|||
|
||||
ruby_class = rb_cObject;
|
||||
if (OBJ_TAINTED(cmd)) {
|
||||
safe_level = 4;
|
||||
ruby_safe_level = 4;
|
||||
}
|
||||
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
|
@ -1222,7 +1232,7 @@ rb_eval_cmd(cmd, arg)
|
|||
if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE))
|
||||
FL_SET(saved_scope, SCOPE_DONT_RECYCLE);
|
||||
ruby_scope = saved_scope;
|
||||
safe_level = safe;
|
||||
ruby_safe_level = safe;
|
||||
POP_TAG();
|
||||
POP_CLASS();
|
||||
|
||||
|
@ -1405,9 +1415,10 @@ rb_undef(klass, id)
|
|||
if (ruby_class == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(klass)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't undef");
|
||||
}
|
||||
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
||||
body = search_method(ruby_class, id, &origin);
|
||||
if (!body || !body->nd_body) {
|
||||
char *s0 = " class";
|
||||
|
@ -1429,7 +1440,6 @@ rb_undef(klass, id)
|
|||
rb_raise(rb_eNameError, "undefined method `%s' for%s `%s'",
|
||||
rb_id2name(id),s0,rb_class2name(c));
|
||||
}
|
||||
rb_clear_cache_by_id(id);
|
||||
rb_add_method(klass, id, 0, NOEX_PUBLIC);
|
||||
rb_clear_cache_by_id(id);
|
||||
}
|
||||
|
@ -1653,7 +1663,7 @@ is_defined(self, node, buf)
|
|||
case NODE_MASGN:
|
||||
case NODE_LASGN:
|
||||
case NODE_DASGN:
|
||||
case NODE_DASGN_PUSH:
|
||||
case NODE_DASGN_CURR:
|
||||
case NODE_GASGN:
|
||||
case NODE_IASGN:
|
||||
case NODE_CASGN:
|
||||
|
@ -2466,12 +2476,12 @@ rb_eval(self, node)
|
|||
|
||||
case NODE_DASGN:
|
||||
result = rb_eval(self, node->nd_value);
|
||||
rb_dvar_asgn(node->nd_vid, result);
|
||||
dvar_asgn(node->nd_vid, result);
|
||||
break;
|
||||
|
||||
case NODE_DASGN_PUSH:
|
||||
case NODE_DASGN_CURR:
|
||||
result = rb_eval(self, node->nd_value);
|
||||
dvar_asgn_push(node->nd_vid, result);
|
||||
dvar_asgn_curr(node->nd_vid, result);
|
||||
break;
|
||||
|
||||
case NODE_GASGN:
|
||||
|
@ -2709,7 +2719,7 @@ rb_eval(self, node)
|
|||
}
|
||||
body = search_method(ruby_class, node->nd_mid, &origin);
|
||||
if (body){
|
||||
if (RTEST(ruby_verbose)) {
|
||||
if (RTEST(ruby_verbose) && ruby_class == origin) {
|
||||
rb_warning("discarding old %s", rb_id2name(node->nd_mid));
|
||||
}
|
||||
rb_clear_cache_by_id(node->nd_mid);
|
||||
|
@ -2760,12 +2770,13 @@ rb_eval(self, node)
|
|||
rb_class2name(CLASS_OF(recv)));
|
||||
}
|
||||
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(recv)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(recv)) {
|
||||
rb_raise(rb_eSecurityError, "can't define singleton method");
|
||||
}
|
||||
if (OBJ_FROZEN(recv)) rb_error_frozen("object");
|
||||
klass = rb_singleton_class(recv);
|
||||
if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) {
|
||||
if (safe_level >= 4) {
|
||||
if (rb_safe_level() >= 4) {
|
||||
rb_raise(rb_eSecurityError, "re-defining method prohibited");
|
||||
}
|
||||
if (RTEST(ruby_verbose)) {
|
||||
|
@ -2844,16 +2855,17 @@ rb_eval(self, node)
|
|||
tmp = RCLASS(tmp)->super;
|
||||
}
|
||||
if (tmp != super) {
|
||||
rb_raise(rb_eTypeError, "superclass mismatch for %s",
|
||||
rb_id2name(node->nd_cname));
|
||||
super = tmp;
|
||||
goto override_class;
|
||||
}
|
||||
}
|
||||
if (safe_level >= 4) {
|
||||
if (rb_safe_level() >= 4) {
|
||||
rb_raise(rb_eSecurityError, "extending class prohibited");
|
||||
}
|
||||
rb_clear_cache();
|
||||
}
|
||||
else {
|
||||
override_class:
|
||||
if (!super) super = rb_cObject;
|
||||
klass = rb_define_class_id(node->nd_cname, super);
|
||||
rb_const_set(ruby_class, node->nd_cname, klass);
|
||||
|
@ -2892,7 +2904,7 @@ rb_eval(self, node)
|
|||
rb_raise(rb_eTypeError, "%s is not a module",
|
||||
rb_id2name(node->nd_cname));
|
||||
}
|
||||
if (safe_level >= 4) {
|
||||
if (rb_safe_level() >= 4) {
|
||||
rb_raise(rb_eSecurityError, "extending module prohibited");
|
||||
}
|
||||
}
|
||||
|
@ -2919,8 +2931,9 @@ rb_eval(self, node)
|
|||
rb_raise(rb_eTypeError, "no virtual class for %s",
|
||||
rb_class2name(CLASS_OF(klass)));
|
||||
}
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(klass))
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't extend object");
|
||||
if (OBJ_FROZEN(klass)) rb_error_frozen("object");
|
||||
if (FL_TEST(CLASS_OF(klass), FL_SINGLETON)) {
|
||||
rb_clear_cache();
|
||||
}
|
||||
|
@ -3221,10 +3234,13 @@ rb_f_raise(argc, argv)
|
|||
set_backtrace(mesg, (argc>2)?argv[2]:Qnil);
|
||||
}
|
||||
|
||||
PUSH_FRAME(); /* fake frame */
|
||||
*ruby_frame = *_frame.prev->prev;
|
||||
if (ruby_frame != top_frame) {
|
||||
PUSH_FRAME(); /* fake frame */
|
||||
*ruby_frame = *_frame.prev->prev;
|
||||
rb_longjmp(TAG_RAISE, mesg);
|
||||
POP_FRAME();
|
||||
}
|
||||
rb_longjmp(TAG_RAISE, mesg);
|
||||
POP_FRAME();
|
||||
|
||||
return Qnil; /* not reached */
|
||||
}
|
||||
|
@ -3455,11 +3471,11 @@ assign(self, lhs, val, check)
|
|||
break;
|
||||
|
||||
case NODE_DASGN:
|
||||
rb_dvar_asgn(lhs->nd_vid, val);
|
||||
dvar_asgn(lhs->nd_vid, val);
|
||||
break;
|
||||
|
||||
case NODE_DASGN_PUSH:
|
||||
dvar_asgn_push(lhs->nd_vid, val);
|
||||
case NODE_DASGN_CURR:
|
||||
dvar_asgn_curr(lhs->nd_vid, val);
|
||||
break;
|
||||
|
||||
case NODE_CASGN:
|
||||
|
@ -3780,7 +3796,7 @@ rb_undefined(obj, id, argc, argv, call_status)
|
|||
}
|
||||
|
||||
#ifdef DJGPP
|
||||
# define STACK_LEVEL_MAX 65535
|
||||
static int STACK_LEVEL_MAX = 65535;
|
||||
#else
|
||||
#ifdef __human68k__
|
||||
extern int _stacksize;
|
||||
|
@ -4608,7 +4624,7 @@ static VALUE
|
|||
yield_under(under, self)
|
||||
VALUE under, self;
|
||||
{
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(self))
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(self))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't eval");
|
||||
return exec_under(yield_under_i, under, self);
|
||||
}
|
||||
|
@ -4842,7 +4858,7 @@ rb_f_require(obj, fname)
|
|||
char *ext, *file, *feature, *buf; /* OK */
|
||||
volatile VALUE load;
|
||||
int state;
|
||||
volatile int safe = safe_level;
|
||||
volatile int safe = ruby_safe_level;
|
||||
|
||||
Check_SafeStr(fname);
|
||||
if (rb_provided(RSTRING(fname)->ptr))
|
||||
|
@ -4910,7 +4926,7 @@ rb_f_require(obj, fname)
|
|||
return Qtrue;
|
||||
|
||||
load_rb:
|
||||
safe_level = 0;
|
||||
ruby_safe_level = 0;
|
||||
if (rb_thread_loading(feature)) return Qfalse;
|
||||
rb_provide(feature);
|
||||
|
||||
|
@ -4920,7 +4936,7 @@ rb_f_require(obj, fname)
|
|||
}
|
||||
POP_TAG();
|
||||
rb_thread_loading_done(feature);
|
||||
safe_level = safe;
|
||||
ruby_safe_level = safe;
|
||||
if (state) JUMP_TAG(state);
|
||||
|
||||
return Qtrue;
|
||||
|
@ -5588,7 +5604,7 @@ rb_f_binding(self)
|
|||
|
||||
#define PROC_T3 FL_USER1
|
||||
#define PROC_T4 FL_USER2
|
||||
#define PROC_T5 (FL_USER1|FL_USER2)
|
||||
#define PROC_TMAX (FL_USER1|FL_USER2)
|
||||
#define PROC_TMASK (FL_USER1|FL_USER2)
|
||||
|
||||
static void
|
||||
|
@ -5596,15 +5612,17 @@ proc_save_safe_level(data)
|
|||
VALUE data;
|
||||
{
|
||||
if (OBJ_TAINTED(data)) {
|
||||
switch (safe_level) {
|
||||
switch (rb_safe_level()) {
|
||||
case 3:
|
||||
FL_SET(data, PROC_T3);
|
||||
break;
|
||||
case 4:
|
||||
FL_SET(data, PROC_T4);
|
||||
break;
|
||||
case 5:
|
||||
FL_SET(data, PROC_T5);
|
||||
default:
|
||||
if (rb_safe_level() > 4) {
|
||||
FL_SET(data, PROC_TMAX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5617,13 +5635,13 @@ proc_set_safe_level(data)
|
|||
if (OBJ_TAINTED(data)) {
|
||||
switch (RBASIC(data)->flags & PROC_TMASK) {
|
||||
case PROC_T3:
|
||||
safe_level = 3;
|
||||
ruby_safe_level = 3;
|
||||
break;
|
||||
case PROC_T4:
|
||||
safe_level = 4;
|
||||
ruby_safe_level = 4;
|
||||
break;
|
||||
case PROC_T5:
|
||||
safe_level = 5;
|
||||
case PROC_TMAX:
|
||||
ruby_safe_level = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5695,7 +5713,7 @@ proc_call(proc, args)
|
|||
volatile VALUE result = Qnil;
|
||||
int state;
|
||||
volatile int orphan;
|
||||
volatile int safe = safe_level;
|
||||
volatile int safe = ruby_safe_level;
|
||||
|
||||
Data_Get_Struct(proc, struct BLOCK, data);
|
||||
orphan = blk_orphan(data);
|
||||
|
@ -5741,7 +5759,7 @@ proc_call(proc, args)
|
|||
state &= TAG_MASK;
|
||||
}
|
||||
ruby_block = old_block;
|
||||
safe_level = safe;
|
||||
ruby_safe_level = safe;
|
||||
|
||||
if (state) {
|
||||
if (orphan) {/* orphan procedure */
|
||||
|
@ -5799,7 +5817,7 @@ block_pass(self, node)
|
|||
volatile VALUE result = Qnil;
|
||||
int state;
|
||||
volatile int orphan;
|
||||
volatile int safe = safe_level;
|
||||
volatile int safe = ruby_safe_level;
|
||||
|
||||
if (NIL_P(block)) {
|
||||
return rb_eval(self, node->nd_iter);
|
||||
|
@ -5836,7 +5854,7 @@ block_pass(self, node)
|
|||
orphan = 2;
|
||||
}
|
||||
ruby_block = old_block;
|
||||
safe_level = safe;
|
||||
ruby_safe_level = safe;
|
||||
|
||||
if (state) {
|
||||
if (orphan == 2) {/* escape from orphan procedure */
|
||||
|
@ -5921,14 +5939,14 @@ method_call(argc, argv, method)
|
|||
VALUE result;
|
||||
struct METHOD *data;
|
||||
int state;
|
||||
volatile int safe = safe_level;
|
||||
volatile int safe = ruby_safe_level;
|
||||
|
||||
Data_Get_Struct(method, struct METHOD, data);
|
||||
PUSH_ITER(rb_iterator_p()?ITER_PRE:ITER_NOT);
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if (OBJ_TAINTED(data->recv) || OBJ_TAINTED(method)) {
|
||||
OBJ_TAINT(method);
|
||||
if (safe_level < 4) safe_level = 4;
|
||||
if (ruby_safe_level < 4) ruby_safe_level = 4;
|
||||
}
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
result = rb_call0(data->klass, data->recv, data->id,
|
||||
|
@ -5936,7 +5954,7 @@ method_call(argc, argv, method)
|
|||
}
|
||||
POP_TAG();
|
||||
POP_ITER();
|
||||
safe_level = safe;
|
||||
ruby_safe_level = safe;
|
||||
if (state) JUMP_TAG(state);
|
||||
return result;
|
||||
}
|
||||
|
@ -6123,6 +6141,7 @@ struct thread {
|
|||
|
||||
int abort;
|
||||
int priority;
|
||||
int gid;
|
||||
|
||||
st_table *locals;
|
||||
|
||||
|
@ -6274,7 +6293,7 @@ rb_thread_save_context(th)
|
|||
th->last_status = rb_last_status;
|
||||
th->last_line = rb_lastline_get();
|
||||
th->last_match = rb_backref_get();
|
||||
th->safe = safe_level;
|
||||
th->safe = ruby_safe_level;
|
||||
|
||||
th->file = ruby_sourcefile;
|
||||
th->line = ruby_sourceline;
|
||||
|
@ -6341,7 +6360,7 @@ rb_thread_restore_context(th, exit)
|
|||
tracing = th->tracing;
|
||||
ruby_errinfo = th->errinfo;
|
||||
rb_last_status = th->last_status;
|
||||
safe_level = th->safe;
|
||||
ruby_safe_level = th->safe;
|
||||
|
||||
ruby_sourcefile = th->file;
|
||||
ruby_sourceline = th->line;
|
||||
|
@ -6599,9 +6618,10 @@ rb_thread_schedule()
|
|||
curr_thread->file = ruby_sourcefile;
|
||||
curr_thread->line = ruby_sourceline;
|
||||
FOREACH_THREAD_FROM(curr, th) {
|
||||
fprintf(stderr, "%s:%d:deadlock 0x%lx: %d:%d %s\n",
|
||||
th->file, th->line, th->thread, th->status,
|
||||
th->wait_for, th==main_thread?"(main)":"");
|
||||
fprintf(stderr, "deadlock 0x%lx: %d:%d %s - %s:%d:\n",
|
||||
th->thread, th->status,
|
||||
th->wait_for, th==main_thread?"(main)":"",
|
||||
th->file, th->line);
|
||||
if (th->status == THREAD_STOPPED) {
|
||||
next = th;
|
||||
}
|
||||
|
@ -6610,6 +6630,7 @@ rb_thread_schedule()
|
|||
/* raise fatal error to main thread */
|
||||
rb_thread_deadlock();
|
||||
rb_thread_ready(next);
|
||||
next->gid = 0;
|
||||
next->status = THREAD_TO_KILL;
|
||||
}
|
||||
if (next->status == THREAD_RUNNABLE && next == curr_thread) {
|
||||
|
@ -6901,11 +6922,15 @@ rb_thread_kill(thread)
|
|||
{
|
||||
thread_t th = rb_thread_check(thread);
|
||||
|
||||
if (th != curr_thread && th->safe < 4) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (th->status == THREAD_TO_KILL || th->status == THREAD_KILLED)
|
||||
return thread;
|
||||
if (th == th->next || th == main_thread) rb_exit(0);
|
||||
|
||||
rb_thread_ready(th);
|
||||
th->gid = 0;
|
||||
th->status = THREAD_TO_KILL;
|
||||
rb_thread_schedule();
|
||||
return Qnil; /* not reached */
|
||||
|
@ -6982,7 +7007,7 @@ rb_thread_priority(thread)
|
|||
{
|
||||
thread_t th = rb_thread_check(thread);;
|
||||
|
||||
if (safe_level >= 4 && th != curr_thread) {
|
||||
if (rb_safe_level() >= 4 && th != curr_thread) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't get priority");
|
||||
}
|
||||
return INT2NUM(th->priority);
|
||||
|
@ -7078,6 +7103,7 @@ rb_thread_abort_exc_set(thread, val)
|
|||
th->last_match = 0;\
|
||||
th->abort = 0;\
|
||||
th->priority = 0;\
|
||||
th->gid = 1;\
|
||||
th->locals = 0;\
|
||||
} while(0)
|
||||
|
||||
|
@ -7096,6 +7122,7 @@ rb_thread_alloc(klass)
|
|||
th->next = curr_thread->next;
|
||||
curr_thread->next = th;
|
||||
th->priority = curr_thread->priority;
|
||||
th->gid = curr_thread->gid;
|
||||
}
|
||||
else {
|
||||
curr_thread = th->prev = th->next = th;
|
||||
|
@ -7105,7 +7132,7 @@ rb_thread_alloc(klass)
|
|||
return th;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SETITIMER) && !defined(__BOW__)
|
||||
#if defined(HAVE_SETITIMER)
|
||||
static void
|
||||
catch_timer(sig)
|
||||
int sig;
|
||||
|
@ -7128,7 +7155,7 @@ static VALUE rb_thread_raise _((int, VALUE*, VALUE));
|
|||
|
||||
#define SCOPE_SHARED FL_USER1
|
||||
|
||||
#if defined(HAVE_SETITIMER) && !defined(__BOW__)
|
||||
#if defined(HAVE_SETITIMER)
|
||||
static int thread_init = 0;
|
||||
|
||||
void
|
||||
|
@ -7167,7 +7194,7 @@ rb_thread_create_0(fn, arg, klass)
|
|||
enum thread_status status;
|
||||
int state;
|
||||
|
||||
#if defined(HAVE_SETITIMER) && !defined(__BOW__)
|
||||
#if defined(HAVE_SETITIMER)
|
||||
if (!thread_init) {
|
||||
#ifdef POSIX_SIGNAL
|
||||
posix_signal(SIGVTALRM, catch_timer);
|
||||
|
@ -7180,6 +7207,7 @@ rb_thread_create_0(fn, arg, klass)
|
|||
}
|
||||
#endif
|
||||
|
||||
scope_dup(ruby_scope);
|
||||
FL_SET(ruby_scope, SCOPE_SHARED);
|
||||
rb_thread_save_context(curr_thread);
|
||||
if (setjmp(curr_thread->context)) {
|
||||
|
@ -7325,6 +7353,7 @@ rb_thread_cleanup()
|
|||
FOREACH_THREAD(th) {
|
||||
if (th != curr_thread && th->status != THREAD_KILLED) {
|
||||
rb_thread_ready(th);
|
||||
th->gid = 0;
|
||||
th->status = THREAD_TO_KILL;
|
||||
}
|
||||
}
|
||||
|
@ -7417,6 +7446,9 @@ rb_thread_raise(argc, argv, thread)
|
|||
if (curr_thread == th) {
|
||||
rb_f_raise(argc, argv);
|
||||
}
|
||||
if (th->safe < 4) {
|
||||
rb_secure(4);
|
||||
}
|
||||
|
||||
if (curr_thread->status != THREAD_KILLED)
|
||||
rb_thread_save_context(curr_thread);
|
||||
|
@ -7473,7 +7505,7 @@ rb_thread_local_aref(thread, id)
|
|||
VALUE val;
|
||||
|
||||
th = rb_thread_check(thread);
|
||||
if (safe_level >= 4 && th != curr_thread) {
|
||||
if (rb_safe_level() >= 4 && th != curr_thread) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: thread locals");
|
||||
}
|
||||
if (!th->locals) return Qnil;
|
||||
|
@ -7498,9 +7530,10 @@ rb_thread_local_aset(thread, id, val)
|
|||
{
|
||||
thread_t th = rb_thread_check(thread);
|
||||
|
||||
if (safe_level >= 4 && th != curr_thread) {
|
||||
if (rb_safe_level() >= 4 && th != curr_thread) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
|
||||
}
|
||||
if (OBJ_FROZEN(thread)) rb_error_frozen("thread locals");
|
||||
|
||||
if (!th->locals) {
|
||||
th->locals = st_init_numtable();
|
||||
|
@ -7613,9 +7646,65 @@ rb_cont_call(argc, argv, cont)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
struct thgroup {
|
||||
int gid;
|
||||
};
|
||||
|
||||
static VALUE
|
||||
thgroup_s_new(klass)
|
||||
VALUE klass;
|
||||
{
|
||||
VALUE group;
|
||||
struct thgroup *data;
|
||||
static int serial = 1;
|
||||
|
||||
group = Data_Make_Struct(klass, struct thgroup, 0, free, data);
|
||||
data->gid = serial++;
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
thgroup_list(group)
|
||||
VALUE group;
|
||||
{
|
||||
struct thgroup *data;
|
||||
thread_t th;
|
||||
VALUE ary;
|
||||
|
||||
Data_Get_Struct(group, struct thgroup, data);
|
||||
ary = rb_ary_new();
|
||||
|
||||
FOREACH_THREAD(th) {
|
||||
if (th->gid == data->gid) {
|
||||
rb_ary_push(ary, th->thread);
|
||||
}
|
||||
}
|
||||
END_FOREACH(th);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
thgroup_add(group, thread)
|
||||
VALUE group, thread;
|
||||
{
|
||||
thread_t th;
|
||||
struct thgroup *data;
|
||||
|
||||
rb_secure(4);
|
||||
th = rb_thread_check(thread);
|
||||
Data_Get_Struct(group, struct thgroup, data);
|
||||
|
||||
th->gid = data->gid;
|
||||
return group;
|
||||
}
|
||||
|
||||
void
|
||||
Init_Thread()
|
||||
{
|
||||
VALUE cThGroup;
|
||||
|
||||
rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);
|
||||
rb_cThread = rb_define_class("Thread", rb_cObject);
|
||||
|
||||
|
@ -7669,6 +7758,12 @@ Init_Thread()
|
|||
rb_undef_method(CLASS_OF(rb_cCont), "new");
|
||||
rb_define_method(rb_cCont, "call", rb_cont_call, -1);
|
||||
rb_define_global_function("callcc", rb_callcc, 0);
|
||||
|
||||
cThGroup = rb_define_class("ThreadGroup", rb_cObject);
|
||||
rb_define_singleton_method(cThGroup, "new", thgroup_s_new, 0);
|
||||
rb_define_method(cThGroup, "list", thgroup_list, 0);
|
||||
rb_define_method(cThGroup, "add", thgroup_add, 1);
|
||||
rb_define_const(cThGroup, "Default", thgroup_s_new(cThGroup));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
|
@ -41,6 +41,7 @@ end
|
|||
$ipv6type = nil
|
||||
$ipv6lib = nil
|
||||
$ipv6libdir = nil
|
||||
$ipv6trylibc = nil
|
||||
if $ipv6
|
||||
if egrep_cpp("yes", <<EOF)
|
||||
#include <netinet/in.h>
|
||||
|
@ -59,6 +60,7 @@ EOF
|
|||
$ipv6type = "kame"
|
||||
$ipv6lib="inet6"
|
||||
$ipv6libdir="/usr/local/v6/lib"
|
||||
$ipv6trylibc=true
|
||||
$CFLAGS="-DINET6 "+$CFLAGS
|
||||
elsif File.directory? "/usr/inet6"
|
||||
$ipv6type = "linux"
|
||||
|
@ -100,7 +102,7 @@ EOF
|
|||
if $ipv6lib
|
||||
if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/lib#{$ipv6lib}.a"
|
||||
$LOCAL_LIBS = " -L#$ipv6libdir -l#$ipv6lib"
|
||||
else
|
||||
elsif !$ipv6trylibc
|
||||
print <<EOS
|
||||
|
||||
Fatal: no #$ipv6lib library found. cannot continue.
|
||||
|
@ -135,6 +137,23 @@ end
|
|||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
int
|
||||
main()
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
|
||||
ss.ss_family;
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
$CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS
|
||||
end
|
||||
|
||||
if try_link(<<EOF)
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
int
|
||||
main()
|
||||
|
|
|
@ -81,10 +81,27 @@ int Rconnect();
|
|||
#define INET_SERVER 1
|
||||
#define INET_SOCKS 2
|
||||
|
||||
#ifndef INET6
|
||||
# undef ss_family
|
||||
# define sockaddr_storage sockaddr
|
||||
# define ss_family sa_family
|
||||
#ifndef HAVE_SOCKADDR_STORAGE
|
||||
/*
|
||||
* RFC 2553: protocol-independent placeholder for socket addresses
|
||||
*/
|
||||
#define _SS_MAXSIZE 128
|
||||
#define _SS_ALIGNSIZE (sizeof(long long))
|
||||
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) * 2)
|
||||
#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \
|
||||
_SS_PAD1SIZE - _SS_ALIGNSIZE)
|
||||
|
||||
struct sockaddr_storage {
|
||||
#ifdef HAVE_SA_LEN
|
||||
unsigned char ss_len; /* address length */
|
||||
unsigned char ss_family; /* address family */
|
||||
#else
|
||||
unsigned short ss_family;
|
||||
#endif
|
||||
char __ss_pad1[_SS_PAD1SIZE];
|
||||
long long __ss_align; /* force desired structure storage alignment */
|
||||
char __ss_pad2[_SS_PAD2SIZE];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef NT
|
||||
|
|
|
@ -69,8 +69,7 @@ _timer_for_tcl(clientData)
|
|||
VALUE thread;
|
||||
|
||||
Tk_DeleteTimerHandler(timer_token);
|
||||
timer_token = Tk_CreateTimerHandler(100, _timer_for_tcl,
|
||||
(ClientData)0);
|
||||
timer_token = Tk_CreateTimerHandler(100, _timer_for_tcl, (ClientData)0);
|
||||
|
||||
CHECK_INTS;
|
||||
q = iqueue;
|
||||
|
@ -93,8 +92,7 @@ static VALUE
|
|||
lib_mainloop(self)
|
||||
VALUE self;
|
||||
{
|
||||
timer_token = Tk_CreateTimerHandler(100, _timer_for_tcl,
|
||||
(ClientData)0);
|
||||
timer_token = Tk_CreateTimerHandler(100, _timer_for_tcl, (ClientData)0);
|
||||
DUMP1("start Tk_Mainloop");
|
||||
Tk_MainLoop();
|
||||
DUMP1("stop Tk_Mainloop");
|
||||
|
|
|
@ -196,7 +196,9 @@ module TkComm
|
|||
|
||||
def _get_eval_string(str)
|
||||
return nil if str == None
|
||||
if str.kind_of?(Hash)
|
||||
if str.kind_of?(String)
|
||||
# do nothing
|
||||
elsif str.kind_of?(Hash)
|
||||
str = hash_kv(str).join(" ")
|
||||
elsif str.kind_of?(Array)
|
||||
str = array2tk_list(str)
|
||||
|
@ -417,11 +419,11 @@ module TkCore
|
|||
INTERP._invoke("proc", "rb_out", "args", "if {[set st [catch {ruby [format \"TkCore.callback %%Q!%s!\" $args]} ret]] != 0} {if {[regsub -all {!} $args {\\!} newargs] == 0} {return -code $st $ret} {if {[set st [catch {ruby [format \"TkCore.callback %%Q!%s!\" $newargs]} ret]] != 0} {return -code $st $ret} {return $ret}}} {return $ret}")
|
||||
|
||||
def callback_break
|
||||
raise TkCallbackBreak, "Tk callback returns 'break' status"
|
||||
fail TkCallbackBreak, "Tk callback returns 'break' status"
|
||||
end
|
||||
|
||||
def callback_continue
|
||||
raise TkCallbackContinue, "Tk callback returns 'continue' status"
|
||||
fail TkCallbackContinue, "Tk callback returns 'continue' status"
|
||||
end
|
||||
|
||||
def after(ms, cmd=Proc.new)
|
||||
|
@ -527,8 +529,8 @@ module TkCore
|
|||
args.unshift "unknown"
|
||||
res = INTERP._invoke(*args)
|
||||
rescue
|
||||
raise unless /^invalid command/ =~ $!
|
||||
raise err
|
||||
fail unless /^invalid command/ =~ $!
|
||||
fail err
|
||||
end
|
||||
end
|
||||
if INTERP._return_value() != 0
|
||||
|
@ -583,6 +585,32 @@ module Tk
|
|||
def yscrollcommand(cmd=Proc.new)
|
||||
configure_cmd 'yscrollcommand', cmd
|
||||
end
|
||||
def xview(*index)
|
||||
v = tk_send('xview', *index)
|
||||
list(v) if index.size == 0
|
||||
end
|
||||
def yview(*index)
|
||||
v = tk_send('yview', *index)
|
||||
list(v) if index.size == 0
|
||||
end
|
||||
def xscrollbar(bar=nil)
|
||||
if bar
|
||||
@xscrollbar = bar
|
||||
@xscrollbar.orient 'horizontal'
|
||||
self.xscrollcommand {|arg| @xscrollbar.set *arg}
|
||||
@xscrollbar.command {|arg| self.xview *arg}
|
||||
end
|
||||
@xscrollbar
|
||||
end
|
||||
def yscrollbar(bar=nil)
|
||||
if bar
|
||||
@yscrollbar = bar
|
||||
@yscrollbar.orient 'vertical'
|
||||
self.yscrollcommand {|arg| @yscrollbar.set *arg}
|
||||
@yscrollbar.command {|arg| self.yview *arg}
|
||||
end
|
||||
@yscrollbar
|
||||
end
|
||||
end
|
||||
|
||||
module Wm
|
||||
|
@ -784,7 +812,7 @@ class TkVariable
|
|||
INTERP._eval(format('global %s; set %s', @id, @id))
|
||||
rescue
|
||||
if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
|
||||
raise
|
||||
fail
|
||||
else
|
||||
Hash[*tk_split_simplelist(INTERP._eval(format('global %s; array get %s',
|
||||
@id, @id)))]
|
||||
|
@ -798,7 +826,7 @@ class TkVariable
|
|||
INTERP._eval(format('global %s; set %s %s', @id, @id, s))
|
||||
rescue
|
||||
if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
|
||||
raise
|
||||
fail
|
||||
else
|
||||
if val == []
|
||||
INTERP._eval(format('global %s; unset %s; set %s(0) 0; unset %s(0)',
|
||||
|
@ -815,7 +843,7 @@ class TkVariable
|
|||
INTERP._eval(format('global %s; unset %s; array set %s %s',
|
||||
@id, @id, @id, s))
|
||||
else
|
||||
raise
|
||||
fail
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2149,7 +2177,7 @@ end
|
|||
|
||||
class TkTextWin<TkWindow
|
||||
def create_self
|
||||
raise TypeError, "TkTextWin is abstract class"
|
||||
fail TypeError, "TkTextWin is abstract class"
|
||||
end
|
||||
|
||||
def bbox(index)
|
||||
|
@ -2195,6 +2223,14 @@ class TkListbox<TkTextWin
|
|||
def curselection
|
||||
list(tk_send('curselection'))
|
||||
end
|
||||
def get(*index)
|
||||
v = tk_send('get', *index)
|
||||
if index.size == 1
|
||||
v
|
||||
else
|
||||
tk_split_simplelist(v)
|
||||
end
|
||||
end
|
||||
def nearest(y)
|
||||
tk_send('nearest', y).to_i
|
||||
end
|
||||
|
@ -2213,14 +2249,6 @@ class TkListbox<TkTextWin
|
|||
def selection_set(first, last=None)
|
||||
tk_send 'selection', 'set', first, last
|
||||
end
|
||||
def xview(cmd, *more)
|
||||
v = tk_send('xview', cmd, *more)
|
||||
v.to_i if more.size == 0
|
||||
end
|
||||
def yview(cmd, *more)
|
||||
v = tk_send('yview', cmd, *more)
|
||||
v.to_i if more.size == 0
|
||||
end
|
||||
end
|
||||
|
||||
module TkTreatMenuEntryFont
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
require 'tk.rb'
|
||||
|
||||
class TkEntry<TkLabel
|
||||
include Scrollable
|
||||
|
||||
WidgetClassName = 'Entry'.freeze
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
|
@ -15,9 +17,6 @@ class TkEntry<TkLabel
|
|||
def create_self
|
||||
tk_call 'entry', @path
|
||||
end
|
||||
def xscrollcommand(cmd=Proc.new)
|
||||
configure_cmd 'xscrollcommand', cmd
|
||||
end
|
||||
|
||||
def delete(s, e=None)
|
||||
tk_send 'delete', s, e
|
||||
|
@ -59,9 +58,6 @@ class TkEntry<TkLabel
|
|||
def selection_to(index)
|
||||
tk_send 'selection', 'to', index
|
||||
end
|
||||
def xview(*index)
|
||||
tk_send 'xview', *index
|
||||
end
|
||||
|
||||
def value
|
||||
tk_send 'get'
|
||||
|
|
4
file.c
4
file.c
|
@ -531,7 +531,7 @@ test_c(obj, fname)
|
|||
struct stat st;
|
||||
|
||||
if (rb_stat(fname, &st) < 0) return Qfalse;
|
||||
if (S_ISBLK(st.st_mode)) return Qtrue;
|
||||
if (S_ISCHR(st.st_mode)) return Qtrue;
|
||||
|
||||
return Qfalse;
|
||||
}
|
||||
|
@ -1738,7 +1738,7 @@ static VALUE
|
|||
rb_stat_c(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
if (S_ISBLK(get_stat(obj)->st_mode)) return Qtrue;
|
||||
if (S_ISCHR(get_stat(obj)->st_mode)) return Qtrue;
|
||||
|
||||
return Qfalse;
|
||||
}
|
||||
|
|
2
gc.c
2
gc.c
|
@ -492,7 +492,7 @@ rb_gc_mark(ptr)
|
|||
case NODE_GASGN:
|
||||
case NODE_LASGN:
|
||||
case NODE_DASGN:
|
||||
case NODE_DASGN_PUSH:
|
||||
case NODE_DASGN_CURR:
|
||||
case NODE_IASGN:
|
||||
case NODE_CASGN:
|
||||
case NODE_MODULE:
|
||||
|
|
29
hash.c
29
hash.c
|
@ -23,39 +23,17 @@ char *strchr _((char*,char));
|
|||
char* strdup(const char*);
|
||||
#endif
|
||||
|
||||
#define HASH_FREEZE FL_USER1
|
||||
#define HASH_DELETED FL_USER2
|
||||
#define HASH_DELETED FL_USER1
|
||||
|
||||
static void
|
||||
rb_hash_modify(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
if (FL_TEST(hash, HASH_FREEZE))
|
||||
rb_raise(rb_eTypeError, "can't modify frozen hash");
|
||||
if (OBJ_FROZEN(hash)) rb_error_frozen("hash");
|
||||
if (!OBJ_TAINTED(hash) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_hash_freeze(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(hash))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze hash");
|
||||
|
||||
FL_SET(hash, HASH_FREEZE);
|
||||
return hash;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_hash_frozen_p(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
if (FL_TEST(hash, HASH_FREEZE))
|
||||
return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
VALUE rb_cHash;
|
||||
|
||||
static VALUE envtbl;
|
||||
|
@ -1387,9 +1365,6 @@ Init_Hash()
|
|||
rb_define_method(rb_cHash,"dup", rb_hash_dup, 0);
|
||||
rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0);
|
||||
|
||||
rb_define_method(rb_cHash,"freeze", rb_hash_freeze, 0);
|
||||
rb_define_method(rb_cHash,"frozen?",rb_hash_frozen_p, 0);
|
||||
|
||||
rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0);
|
||||
rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
|
||||
rb_define_method(rb_cHash,"to_s", rb_hash_to_s, 0);
|
||||
|
|
1
intern.h
1
intern.h
|
@ -101,6 +101,7 @@ void rb_alias _((VALUE, ID, ID));
|
|||
void rb_attr _((VALUE,ID,int,int,int));
|
||||
int rb_method_boundp _((VALUE, ID, int));
|
||||
VALUE rb_dvar_defined _((ID));
|
||||
VALUE rb_dvar_curr _((ID));
|
||||
VALUE rb_dvar_ref _((ID));
|
||||
void rb_dvar_asgn _((ID, VALUE));
|
||||
void rb_dvar_push _((ID, VALUE));
|
||||
|
|
15
io.c
15
io.c
|
@ -1576,7 +1576,12 @@ rb_io_s_popen(argc, argv, self)
|
|||
}
|
||||
Check_SafeStr(pname);
|
||||
port = pipe_open(RSTRING(pname)->ptr, mode);
|
||||
if (NIL_P(port)) return Qnil;
|
||||
if (NIL_P(port)) {
|
||||
rb_yield(port);
|
||||
}
|
||||
else if (rb_iterator_p()) {
|
||||
return rb_ensure(rb_yield, port, rb_io_close, port);
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
|
@ -1647,8 +1652,10 @@ rb_f_open(argc, argv)
|
|||
}
|
||||
|
||||
port = pipe_open(RSTRING(pname)->ptr+1, mode);
|
||||
if (NIL_P(port)) return Qnil;
|
||||
if (rb_iterator_p()) {
|
||||
if (NIL_P(port)) {
|
||||
rb_yield(port);
|
||||
}
|
||||
else if (rb_iterator_p()) {
|
||||
return rb_ensure(rb_yield, port, rb_io_close, port);
|
||||
}
|
||||
|
||||
|
@ -3222,7 +3229,7 @@ Init_IO()
|
|||
|
||||
rb_rs = rb_default_rs = rb_str_new2("\n"); rb_output_rs = Qnil;
|
||||
rb_global_variable(&rb_default_rs);
|
||||
rb_str_freeze(rb_default_rs); /* avoid modifying RS_default */
|
||||
OBJ_FREEZE(rb_default_rs); /* avoid modifying RS_default */
|
||||
rb_define_hooked_variable("$/", &rb_rs, 0, rb_str_setter);
|
||||
rb_define_hooked_variable("$-0", &rb_rs, 0, rb_str_setter);
|
||||
rb_define_hooked_variable("$\\", &rb_output_rs, 0, rb_str_setter);
|
||||
|
|
|
@ -35,7 +35,7 @@ class GetoptLong
|
|||
#
|
||||
# Status codes.
|
||||
#
|
||||
STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0..2
|
||||
STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0, 1, 2
|
||||
|
||||
#
|
||||
# Error types.
|
||||
|
|
|
@ -32,7 +32,7 @@ module Observable
|
|||
def notify_observers(*arg)
|
||||
if @observer_state
|
||||
if @observer_peers
|
||||
for i in @observer_peers
|
||||
for i in @observer_peers.dup
|
||||
i.update(*arg)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ module ParseDate
|
|||
if date.sub!(/(#{DAYPAT})[a-z]*,?/i, ' ')
|
||||
wday = DAYS[$1.downcase]
|
||||
end
|
||||
if date.sub!(/(\d+):(\d+)(?::(\d+))?(?:\s*(am|pm))?(?:\s+([a-z]{1,4}(?:\s+[a-z]{1,4}|[-+]\d{4})?))?/i, ' ')
|
||||
if date.sub!(/(\d+):(\d+)(?::(\d+))?(?:\s*(am|pm))?(?:\s+([a-z]{1,4}(?:\s+[a-z]{1,4}|[-+]\d{4})?|[-+]\d{4}))?/i, ' ')
|
||||
hour = $1.to_i
|
||||
min = $2.to_i
|
||||
if $3
|
||||
|
|
|
@ -227,7 +227,7 @@ w_object(obj, arg, limit)
|
|||
st_table *ivtbl = 0;
|
||||
|
||||
if (limit == 0) {
|
||||
rb_raise(rb_eRuntimeError, "exceed depth limit");
|
||||
rb_raise(rb_eArgError, "exceed depth limit");
|
||||
}
|
||||
if (obj == Qnil) {
|
||||
w_byte(TYPE_NIL, arg);
|
||||
|
|
4
node.h
4
node.h
|
@ -45,7 +45,7 @@ enum node_type {
|
|||
NODE_MASGN,
|
||||
NODE_LASGN,
|
||||
NODE_DASGN,
|
||||
NODE_DASGN_PUSH,
|
||||
NODE_DASGN_CURR,
|
||||
NODE_GASGN,
|
||||
NODE_IASGN,
|
||||
NODE_CASGN,
|
||||
|
@ -260,7 +260,7 @@ typedef struct RNode {
|
|||
#define NEW_GASGN(v,val) rb_node_newnode(NODE_GASGN,v,val,rb_global_entry(v))
|
||||
#define NEW_LASGN(v,val) rb_node_newnode(NODE_LASGN,v,val,local_cnt(v))
|
||||
#define NEW_DASGN(v,val) rb_node_newnode(NODE_DASGN,v,val,0);
|
||||
#define NEW_DASGN_PUSH(v,val) rb_node_newnode(NODE_DASGN_PUSH,v,val,0);
|
||||
#define NEW_DASGN_CURR(v,val) rb_node_newnode(NODE_DASGN_CURR,v,val,0);
|
||||
#define NEW_IASGN(v,val) rb_node_newnode(NODE_IASGN,v,val,0)
|
||||
#define NEW_CASGN(v,val) rb_node_newnode(NODE_CASGN,v,val,0)
|
||||
#define NEW_CDECL(v,val) rb_node_newnode(NODE_CDECL,v,val,0)
|
||||
|
|
43
numeric.c
43
numeric.c
|
@ -331,8 +331,7 @@ flo_modulo(x, y, modulo)
|
|||
result = value1 - value2 * value;
|
||||
}
|
||||
#endif
|
||||
if (modulo &&
|
||||
(RFLOAT(x)->value < 0.0) != (result < 0.0) && result != 0.0) {
|
||||
if (modulo && value*result<0.0) {
|
||||
result += value;
|
||||
}
|
||||
return rb_float_new(result);
|
||||
|
@ -352,6 +351,45 @@ flo_remainder(x, y)
|
|||
return flo_modulo(x,y,0);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
flo_divmod(x, y)
|
||||
VALUE x, y;
|
||||
{
|
||||
double value, div, mod;
|
||||
|
||||
switch (TYPE(y)) {
|
||||
case T_FIXNUM:
|
||||
value = (double)FIX2LONG(y);
|
||||
break;
|
||||
case T_BIGNUM:
|
||||
value = rb_big2dbl(y);
|
||||
break;
|
||||
case T_FLOAT:
|
||||
value = RFLOAT(y)->value;
|
||||
break;
|
||||
default:
|
||||
return rb_num_coerce_bin(x, y);
|
||||
}
|
||||
|
||||
#ifdef HAVE_FMOD
|
||||
mod = fmod(RFLOAT(x)->value, value);
|
||||
#else
|
||||
{
|
||||
double value1 = RFLOAT(x)->value;
|
||||
double value2;
|
||||
|
||||
modf(value1/value, &value2);
|
||||
mod = value1 - value2 * value;
|
||||
}
|
||||
#endif
|
||||
div = (RFLOAT(x)->value - mod) / value;
|
||||
if (value*mod<0.0) {
|
||||
mod += value;
|
||||
div -= 1.0;
|
||||
}
|
||||
return rb_assoc_new(rb_float_new(div), rb_float_new(mod));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
flo_pow(x, y)
|
||||
VALUE x, y;
|
||||
|
@ -1517,6 +1555,7 @@ Init_Numeric()
|
|||
rb_define_method(rb_cFloat, "*", flo_mul, 1);
|
||||
rb_define_method(rb_cFloat, "/", flo_div, 1);
|
||||
rb_define_method(rb_cFloat, "%", flo_mod, 1);
|
||||
rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
|
||||
rb_define_method(rb_cFloat, "remainder", flo_remainder, 1);
|
||||
rb_define_method(rb_cFloat, "**", flo_pow, 1);
|
||||
rb_define_method(rb_cFloat, "==", flo_eq, 1);
|
||||
|
|
21
object.c
21
object.c
|
@ -297,6 +297,25 @@ rb_obj_untaint(obj)
|
|||
return obj;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_obj_freeze(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(obj))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze object");
|
||||
|
||||
OBJ_FREEZE(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_obj_frozen_p(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
if (OBJ_FROZEN(obj)) return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
nil_to_i(obj)
|
||||
VALUE obj;
|
||||
|
@ -1004,6 +1023,8 @@ Init_Object()
|
|||
rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0);
|
||||
rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0);
|
||||
rb_define_method(rb_mKernel, "untaint", rb_obj_untaint, 0);
|
||||
rb_define_method(rb_mKernel, "freeze", rb_obj_freeze, 0);
|
||||
rb_define_method(rb_mKernel, "frozen?", rb_obj_frozen_p, 0);
|
||||
|
||||
rb_define_method(rb_mKernel, "to_a", rb_any_to_a, 0);
|
||||
rb_define_method(rb_mKernel, "to_s", rb_any_to_s, 0);
|
||||
|
|
2
pack.c
2
pack.c
|
@ -305,7 +305,7 @@ static void
|
|||
pack_add_ptr(str, add)
|
||||
VALUE str, add;
|
||||
{
|
||||
#define STR_NO_ORIG FL_USER3 /* copied from string.c */
|
||||
#define STR_NO_ORIG FL_USER2 /* copied from string.c */
|
||||
if (!RSTRING(str)->orig) {
|
||||
RSTRING(str)->orig = rb_ary_new();
|
||||
FL_SET(str, STR_NO_ORIG);
|
||||
|
|
199
parse.y
199
parse.y
|
@ -532,6 +532,10 @@ mlhs_node : variable
|
|||
{
|
||||
$$ = attrset($1, $3);
|
||||
}
|
||||
| primary tCOLON2 tIDENTIFIER
|
||||
{
|
||||
$$ = attrset($1, $3);
|
||||
}
|
||||
| backref
|
||||
{
|
||||
rb_backref_error($1);
|
||||
|
@ -550,6 +554,10 @@ lhs : variable
|
|||
{
|
||||
$$ = attrset($1, $3);
|
||||
}
|
||||
| primary tCOLON2 tIDENTIFIER
|
||||
{
|
||||
$$ = attrset($1, $3);
|
||||
}
|
||||
| backref
|
||||
{
|
||||
rb_backref_error($1);
|
||||
|
@ -683,6 +691,17 @@ arg : lhs '=' arg
|
|||
$$ = NEW_OP_ASGN2($1, $3, $4, $5);
|
||||
fixpos($$, $1);
|
||||
}
|
||||
| primary tCOLON2 tIDENTIFIER tOP_ASGN arg
|
||||
{
|
||||
if ($4 == tOROP) {
|
||||
$4 = 0;
|
||||
}
|
||||
else if ($4 == tANDOP) {
|
||||
$4 = 1;
|
||||
}
|
||||
$$ = NEW_OP_ASGN2($1, $3, $4, $5);
|
||||
fixpos($$, $1);
|
||||
}
|
||||
| backref tOP_ASGN arg
|
||||
{
|
||||
rb_backref_error($1);
|
||||
|
@ -968,15 +987,6 @@ primary : literal
|
|||
{
|
||||
$$ = NEW_LIT($1);
|
||||
}
|
||||
| primary tCOLON2 tCONSTANT
|
||||
{
|
||||
value_expr($1);
|
||||
$$ = NEW_COLON2($1, $3);
|
||||
}
|
||||
| tCOLON3 cname
|
||||
{
|
||||
$$ = NEW_COLON3($2);
|
||||
}
|
||||
| string
|
||||
| tXSTRING
|
||||
{
|
||||
|
@ -986,6 +996,43 @@ primary : literal
|
|||
| tDREGEXP
|
||||
| var_ref
|
||||
| backref
|
||||
| tFID
|
||||
{
|
||||
$$ = NEW_VCALL($1);
|
||||
}
|
||||
| kBEGIN
|
||||
compstmt
|
||||
rescue
|
||||
opt_else
|
||||
ensure
|
||||
kEND
|
||||
{
|
||||
if (!$3 && !$4 && !$5)
|
||||
$$ = NEW_BEGIN($2);
|
||||
else {
|
||||
if ($3) $2 = NEW_RESCUE($2, $3, $4);
|
||||
else if ($4) {
|
||||
rb_warn("else without rescue is useless");
|
||||
$2 = block_append($2, $4);
|
||||
}
|
||||
if ($5) $2 = NEW_ENSURE($2, $5);
|
||||
$$ = $2;
|
||||
}
|
||||
fixpos($$, $2);
|
||||
}
|
||||
| tLPAREN compstmt ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| primary tCOLON2 tCONSTANT
|
||||
{
|
||||
value_expr($1);
|
||||
$$ = NEW_COLON2($1, $3);
|
||||
}
|
||||
| tCOLON3 cname
|
||||
{
|
||||
$$ = NEW_COLON3($2);
|
||||
}
|
||||
| primary '[' aref_args ']'
|
||||
{
|
||||
value_expr($1);
|
||||
|
@ -1040,10 +1087,6 @@ primary : literal
|
|||
in_defined = 0;
|
||||
$$ = NEW_DEFINED($5);
|
||||
}
|
||||
| tFID
|
||||
{
|
||||
$$ = NEW_VCALL($1);
|
||||
}
|
||||
| operation brace_block
|
||||
{
|
||||
$2->nd_iter = NEW_FCALL($1, 0);
|
||||
|
@ -1109,30 +1152,6 @@ primary : literal
|
|||
$$ = NEW_FOR($2, $5, $8);
|
||||
fixpos($$, $2);
|
||||
}
|
||||
| kBEGIN
|
||||
compstmt
|
||||
rescue
|
||||
opt_else
|
||||
ensure
|
||||
kEND
|
||||
{
|
||||
if (!$3 && !$4 && !$5)
|
||||
$$ = NEW_BEGIN($2);
|
||||
else {
|
||||
if ($3) $2 = NEW_RESCUE($2, $3, $4);
|
||||
else if ($4) {
|
||||
rb_warn("else without rescue is useless");
|
||||
$2 = block_append($2, $4);
|
||||
}
|
||||
if ($5) $2 = NEW_ENSURE($2, $5);
|
||||
$$ = $2;
|
||||
}
|
||||
fixpos($$, $2);
|
||||
}
|
||||
| tLPAREN compstmt ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| kCLASS cname superclass
|
||||
{
|
||||
if (cur_mid || in_single)
|
||||
|
@ -2400,11 +2419,80 @@ parse_qstring(term, paren)
|
|||
}
|
||||
|
||||
static int
|
||||
parse_quotedword(term, paren)
|
||||
parse_quotedwords(term, paren)
|
||||
int term, paren;
|
||||
{
|
||||
if (parse_qstring(term, paren) == 0) return 0;
|
||||
yylval.node = NEW_CALL(NEW_STR(yylval.val), rb_intern("split"), 0);
|
||||
NODE *qwords = 0;
|
||||
int strstart;
|
||||
int c;
|
||||
int nest = 0;
|
||||
|
||||
strstart = ruby_sourceline;
|
||||
newtok();
|
||||
|
||||
while ((c = nextc()) == ' ')
|
||||
; /* skip preceding spaces */
|
||||
pushback(c);
|
||||
while ((c = nextc()) != term || nest > 0) {
|
||||
if (c == -1) {
|
||||
ruby_sourceline = strstart;
|
||||
rb_compile_error("unterminated string meets end of file");
|
||||
return 0;
|
||||
}
|
||||
if (ismbchar(c)) {
|
||||
int i, len = mbclen(c)-1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
tokadd(c);
|
||||
c = nextc();
|
||||
}
|
||||
}
|
||||
else if (c == '\\') {
|
||||
c = nextc();
|
||||
switch (c) {
|
||||
case '\n':
|
||||
continue;
|
||||
case '\\':
|
||||
c = '\\';
|
||||
break;
|
||||
case ' ':
|
||||
tokadd(' ');
|
||||
break;
|
||||
default:
|
||||
tokadd('\\');
|
||||
}
|
||||
}
|
||||
else if (c == ' ') {
|
||||
NODE *str;
|
||||
|
||||
tokfix();
|
||||
str = NEW_STR(rb_str_new(tok(), toklen()));
|
||||
newtok();
|
||||
if (!qwords) qwords = NEW_LIST(str);
|
||||
else list_append(qwords, str);
|
||||
while ((c = nextc()) == ' ')
|
||||
; /* skip continuous spaces */
|
||||
pushback(c);
|
||||
continue;
|
||||
}
|
||||
if (paren) {
|
||||
if (c == paren) nest++;
|
||||
if (c == term && nest-- == 0) break;
|
||||
}
|
||||
tokadd(c);
|
||||
}
|
||||
|
||||
tokfix();
|
||||
if (toklen() > 0) {
|
||||
NODE *str;
|
||||
|
||||
str = NEW_STR(rb_str_new(tok(), toklen()));
|
||||
if (!qwords) qwords = NEW_LIST(str);
|
||||
else list_append(qwords, str);
|
||||
}
|
||||
if (!qwords) qwords = NEW_ZARRAY();
|
||||
yylval.node = qwords;
|
||||
lex_state = EXPR_END;
|
||||
return tDSTRING;
|
||||
}
|
||||
|
||||
|
@ -2814,6 +2902,8 @@ yylex()
|
|||
if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
|
||||
(lex_state == EXPR_ARG && space_seen && !ISSPACE(c))) {
|
||||
pushback(c);
|
||||
if (lex_state == EXPR_ARG) arg_ambiguous();
|
||||
if (ISDIGIT(c)) goto start_num;
|
||||
lex_state = EXPR_BEG;
|
||||
return tUPLUS;
|
||||
}
|
||||
|
@ -2837,8 +2927,13 @@ yylex()
|
|||
}
|
||||
if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
|
||||
(lex_state == EXPR_ARG && space_seen && !ISSPACE(c))) {
|
||||
if (lex_state == EXPR_ARG) arg_ambiguous();
|
||||
lex_state = EXPR_BEG;
|
||||
pushback(c);
|
||||
if (ISDIGIT(c)) {
|
||||
c = '-';
|
||||
goto start_num;
|
||||
}
|
||||
return tUMINUS;
|
||||
}
|
||||
lex_state = EXPR_BEG;
|
||||
|
@ -3072,6 +3167,12 @@ yylex()
|
|||
lex_state = EXPR_BEG;
|
||||
}
|
||||
else {
|
||||
if (lex_state == EXPR_ARG) {
|
||||
if (space_seen) {
|
||||
arg_ambiguous();
|
||||
c = tLPAREN;
|
||||
}
|
||||
}
|
||||
lex_state = EXPR_BEG;
|
||||
}
|
||||
return c;
|
||||
|
@ -3147,7 +3248,7 @@ yylex()
|
|||
return parse_qstring(term, paren);
|
||||
|
||||
case 'w':
|
||||
return parse_quotedword(term, paren);
|
||||
return parse_quotedwords(term, paren);
|
||||
|
||||
case 'x':
|
||||
return parse_string('`', term, paren);
|
||||
|
@ -3766,15 +3867,18 @@ assignable(id, val)
|
|||
yyerror("Can't assign to __LINE__");
|
||||
}
|
||||
else if (is_local_id(id)) {
|
||||
if (rb_dvar_defined(id)) {
|
||||
if (rb_dvar_curr(id)) {
|
||||
lhs = NEW_DASGN_CURR(id, val);
|
||||
}
|
||||
else if (rb_dvar_defined(id)) {
|
||||
lhs = NEW_DASGN(id, val);
|
||||
}
|
||||
else if (local_id(id) || !dyna_in_block()) {
|
||||
lhs = NEW_LASGN(id, val);
|
||||
}
|
||||
else{
|
||||
rb_dvar_push(id, 0);
|
||||
lhs = NEW_DASGN_PUSH(id, val);
|
||||
rb_dvar_push(id, Qnil);
|
||||
lhs = NEW_DASGN_CURR(id, val);
|
||||
}
|
||||
}
|
||||
else if (is_global_id(id)) {
|
||||
|
@ -3871,7 +3975,7 @@ node_assign(lhs, rhs)
|
|||
case NODE_IASGN:
|
||||
case NODE_LASGN:
|
||||
case NODE_DASGN:
|
||||
case NODE_DASGN_PUSH:
|
||||
case NODE_DASGN_CURR:
|
||||
case NODE_MASGN:
|
||||
case NODE_CASGN:
|
||||
case NODE_CDECL:
|
||||
|
@ -4354,8 +4458,11 @@ top_local_setup()
|
|||
static struct RVarmap*
|
||||
dyna_push()
|
||||
{
|
||||
struct RVarmap* vars = ruby_dyna_vars;
|
||||
|
||||
rb_dvar_push(0, 0);
|
||||
lvtbl->dlev++;
|
||||
return ruby_dyna_vars;
|
||||
return vars;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
27
ruby.h
27
ruby.h
|
@ -160,11 +160,11 @@ VALUE rb_uint2inum _((unsigned long));
|
|||
#define T_DATA 0x22
|
||||
#define T_MATCH 0x23
|
||||
|
||||
#define T_VARMAP 0x7d
|
||||
#define T_SCOPE 0x7e
|
||||
#define T_NODE 0x7f
|
||||
#define T_VARMAP 0x3d
|
||||
#define T_SCOPE 0x3e
|
||||
#define T_NODE 0x3f
|
||||
|
||||
#define T_MASK 0x7f
|
||||
#define T_MASK 0x3f
|
||||
|
||||
#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
|
||||
|
||||
|
@ -176,6 +176,10 @@ void rb_check_safe_str _((VALUE));
|
|||
#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))
|
||||
void rb_secure _((int));
|
||||
|
||||
extern int ruby_safe_level;
|
||||
#define rb_safe_level() (ruby_safe_level)
|
||||
void rb_set_safe_level _((int));
|
||||
|
||||
long rb_num2long _((VALUE));
|
||||
unsigned long rb_num2ulong _((VALUE));
|
||||
#define NUM2LONG(x) (FIXNUM_P(x)?FIX2LONG(x):rb_num2long((VALUE)x))
|
||||
|
@ -326,10 +330,11 @@ struct RBignum {
|
|||
#define RFILE(obj) (R_CAST(RFile)(obj))
|
||||
|
||||
#define FL_SINGLETON FL_USER0
|
||||
#define FL_MARK (1<<7)
|
||||
#define FL_FINALIZE (1<<8)
|
||||
#define FL_TAINT (1<<9)
|
||||
#define FL_EXIVAR (1<<10)
|
||||
#define FL_MARK (1<<6)
|
||||
#define FL_FINALIZE (1<<7)
|
||||
#define FL_TAINT (1<<8)
|
||||
#define FL_EXIVAR (1<<9)
|
||||
#define FL_FREEZE (1<<10)
|
||||
|
||||
#define FL_USHIFT 11
|
||||
|
||||
|
@ -356,6 +361,9 @@ struct RBignum {
|
|||
#define OBJ_TAINT(x) FL_SET((x), FL_TAINT)
|
||||
#define OBJ_INFECT(x,s) (FL_ABLE(x) && FL_ABLE(s) && (RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT))
|
||||
|
||||
#define OBJ_FROZEN(x) FL_TEST((x), FL_FREEZE)
|
||||
#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
|
||||
|
||||
void *xmalloc _((size_t));
|
||||
void *xcalloc _((size_t,size_t));
|
||||
void *xrealloc _((void*,size_t));
|
||||
|
@ -417,9 +425,6 @@ VALUE rb_equal _((VALUE,VALUE));
|
|||
|
||||
EXTERN VALUE ruby_verbose, ruby_debug;
|
||||
|
||||
int rb_safe_level _((void));
|
||||
void rb_set_safe_level _((int));
|
||||
|
||||
void rb_raise __((VALUE, const char*, ...)) NORETURN;
|
||||
void rb_fatal __((const char*, ...)) NORETURN;
|
||||
void rb_bug __((const char*, ...)) NORETURN;
|
||||
|
|
|
@ -137,7 +137,9 @@ tmp.close
|
|||
$bad = false
|
||||
tmp = open("while_tmp", "r")
|
||||
while tmp.gets()
|
||||
if gsub!('vt100', 'VT100')
|
||||
line = $_
|
||||
$_ = gsub(/vt100/, 'VT100')
|
||||
if $_ != line
|
||||
gsub!('VT100', 'Vt100')
|
||||
redo;
|
||||
end
|
||||
|
@ -677,7 +679,8 @@ ok("a".upcase![0] == ?A)
|
|||
ok("A".downcase![0] == ?a)
|
||||
ok("abc".tr!("a-z", "A-Z") == "ABC")
|
||||
ok("aabbcccc".tr_s!("a-z", "A-Z") == "ABC")
|
||||
ok("abc".tr!("0-9", "A-Z") == nil)
|
||||
$x = "abc"
|
||||
ok($x.tr("0-9", "A-Z").equal?($x))
|
||||
ok("abcc".squeeze!("a-z") == "abc")
|
||||
ok("abcd".delete!("bc") == "ad")
|
||||
|
||||
|
@ -965,6 +968,7 @@ File.unlink "script_tmp.bak" or `/bin/rm -f "script_tmp.bak"`
|
|||
$bad = false
|
||||
for script in Dir["{lib,sample}/*.rb"]
|
||||
unless `./miniruby -c #{script}`.chomp == "Syntax OK"
|
||||
p `./miniruby -c #{script}`.chomp
|
||||
$bad = true
|
||||
end
|
||||
end
|
||||
|
@ -1009,7 +1013,7 @@ ok(foo.test == "test")
|
|||
begin
|
||||
foo.test2
|
||||
ok false
|
||||
rescue
|
||||
rescue NameError
|
||||
ok true
|
||||
end
|
||||
|
||||
|
@ -1061,7 +1065,7 @@ ok($$.instance_of?(Fixnum))
|
|||
begin
|
||||
$$ = 5
|
||||
ok false
|
||||
rescue
|
||||
rescue NameError
|
||||
ok true
|
||||
end
|
||||
|
||||
|
|
393
string.c
393
string.c
|
@ -24,8 +24,7 @@
|
|||
|
||||
VALUE rb_cString;
|
||||
|
||||
#define STR_FREEZE FL_USER1
|
||||
#define STR_NO_ORIG FL_USER3
|
||||
#define STR_NO_ORIG FL_USER2
|
||||
|
||||
VALUE rb_fs;
|
||||
|
||||
|
@ -94,11 +93,10 @@ VALUE
|
|||
rb_str_new4(orig)
|
||||
VALUE orig;
|
||||
{
|
||||
if (FL_TEST(orig, STR_FREEZE)) {
|
||||
return orig;
|
||||
}
|
||||
else if (RSTRING(orig)->orig && !FL_TEST(orig, STR_NO_ORIG)) {
|
||||
return rb_str_freeze(RSTRING(orig)->orig);
|
||||
if (OBJ_FROZEN(orig)) return orig;
|
||||
if (RSTRING(orig)->orig && !FL_TEST(orig, STR_NO_ORIG)) {
|
||||
OBJ_FREEZE(RSTRING(orig)->orig);
|
||||
return RSTRING(orig)->orig;
|
||||
}
|
||||
else {
|
||||
NEWOBJ(str, struct RString);
|
||||
|
@ -111,7 +109,8 @@ rb_str_new4(orig)
|
|||
if (OBJ_TAINTED(orig)) {
|
||||
OBJ_TAINT(str);
|
||||
}
|
||||
FL_SET(str, STR_FREEZE);
|
||||
OBJ_FREEZE(str);
|
||||
|
||||
return (VALUE)str;
|
||||
}
|
||||
}
|
||||
|
@ -328,8 +327,7 @@ rb_str_modify(str)
|
|||
{
|
||||
char *ptr;
|
||||
|
||||
if (FL_TEST(str, STR_FREEZE))
|
||||
rb_raise(rb_eTypeError, "can't modify frozen string");
|
||||
if (OBJ_FROZEN(str)) rb_error_frozen("string");
|
||||
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
|
||||
if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return;
|
||||
|
@ -342,36 +340,18 @@ rb_str_modify(str)
|
|||
RSTRING(str)->orig = 0;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_freeze(str)
|
||||
VALUE str;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(str))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze string");
|
||||
|
||||
FL_SET(str, STR_FREEZE);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_frozen_p(str)
|
||||
VALUE str;
|
||||
{
|
||||
if (FL_TEST(str, STR_FREEZE))
|
||||
return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_dup_frozen(str)
|
||||
VALUE str;
|
||||
{
|
||||
if (RSTRING(str)->orig && !FL_TEST(str, STR_NO_ORIG)) {
|
||||
return rb_str_freeze(RSTRING(str)->orig);
|
||||
OBJ_FREEZE(RSTRING(str)->orig);
|
||||
return RSTRING(str)->orig;
|
||||
}
|
||||
if (FL_TEST(str, STR_FREEZE))
|
||||
return str;
|
||||
return rb_str_freeze(rb_str_dup(str));
|
||||
if (OBJ_FROZEN(str)) return str;
|
||||
str = rb_str_dup(str);
|
||||
OBJ_FREEZE(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -966,6 +946,48 @@ rb_str_aset_m(argc, argv, str)
|
|||
return rb_str_aset(str, arg1, arg2);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_slice_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
VALUE arg1, arg2;
|
||||
long pos, len, i;
|
||||
|
||||
rb_str_modify(str);
|
||||
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
|
||||
pos = NUM2LONG(arg1);
|
||||
len = NUM2LONG(arg2);
|
||||
delete_pos_len:
|
||||
if (pos < 0) {
|
||||
pos = RSTRING(str)->len + pos;
|
||||
}
|
||||
arg2 = rb_str_substr(str, pos, len);
|
||||
rb_str_replace(str, pos, len, rb_str_new(0,0));
|
||||
return arg2;
|
||||
}
|
||||
|
||||
if (!FIXNUM_P(arg1) && rb_range_beg_len(arg1, &pos, &len, RSTRING(str)->len, 0)) {
|
||||
goto delete_pos_len;
|
||||
}
|
||||
|
||||
pos = NUM2LONG(arg1);
|
||||
len = RSTRING(str)->len;
|
||||
|
||||
if (pos >= len) return Qnil;
|
||||
if (pos < 0) pos += len;
|
||||
if (pos < 0) return Qnil;
|
||||
|
||||
arg2 = INT2FIX(RSTRING(str)->ptr[pos] & 0xff);
|
||||
memmove(RSTRING(str)->ptr + pos,
|
||||
RSTRING(str)->ptr + pos + 1,
|
||||
RSTRING(str)->len - (pos + 1));
|
||||
RSTRING(str)->len--;
|
||||
|
||||
return arg2;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
get_pat(pat)
|
||||
VALUE pat;
|
||||
|
@ -986,7 +1008,7 @@ get_pat(pat)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_sub_bang(argc, argv, str)
|
||||
str_sub_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
|
@ -1040,19 +1062,33 @@ rb_str_sub_bang(argc, argv, str)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_sub_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str_sub_bang(argc, argv, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_sub(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_sub_bang(argc, argv, str);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_sub_bang(argc, argv, dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_gsub_bang(argc, argv, str)
|
||||
str_gsub_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
|
@ -1150,15 +1186,29 @@ rb_str_gsub_bang(argc, argv, str)
|
|||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_gsub_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str_gsub_bang(argc, argv, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_gsub(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_gsub_bang(argc, argv, str);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_gsub_bang(argc, argv, dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1200,13 +1250,15 @@ rb_f_sub(argc, argv)
|
|||
int argc;
|
||||
VALUE *argv;
|
||||
{
|
||||
VALUE line;
|
||||
VALUE line = uscore_get();
|
||||
VALUE dup = rb_str_dup(line);
|
||||
|
||||
line = rb_str_dup(uscore_get());
|
||||
if (!NIL_P(rb_str_sub_bang(argc, argv, line))) {
|
||||
rb_lastline_set(line);
|
||||
if (NIL_P(str_sub_bang(argc, argv, dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return line;
|
||||
}
|
||||
return line;
|
||||
rb_lastline_set(dup);
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1222,13 +1274,15 @@ rb_f_gsub(argc, argv)
|
|||
int argc;
|
||||
VALUE *argv;
|
||||
{
|
||||
VALUE line;
|
||||
VALUE line = uscore_get();
|
||||
VALUE dup = rb_str_dup(line);
|
||||
|
||||
line = rb_str_dup(uscore_get());
|
||||
if (!NIL_P(rb_str_gsub_bang(argc, argv, line = rb_str_dup(line)))) {
|
||||
rb_lastline_set(line);
|
||||
if (NIL_P(str_gsub_bang(argc, argv, dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return line;
|
||||
}
|
||||
return line;
|
||||
rb_lastline_set(dup);
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1496,7 +1550,7 @@ rb_str_dump(str)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_upcase_bang(str)
|
||||
str_upcase_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
char *s, *send;
|
||||
|
@ -1520,16 +1574,28 @@ rb_str_upcase_bang(str)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_upcase(str)
|
||||
rb_str_upcase_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_upcase_bang(str);
|
||||
str_upcase_bang(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_downcase_bang(str)
|
||||
rb_str_upcase(str)
|
||||
VALUE str;
|
||||
{
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_upcase_bang(dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
str_downcase_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
char *s, *send;
|
||||
|
@ -1553,16 +1619,28 @@ rb_str_downcase_bang(str)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_downcase(str)
|
||||
rb_str_downcase_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_downcase_bang(str);
|
||||
str_downcase_bang(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_capitalize_bang(str)
|
||||
rb_str_downcase(str)
|
||||
VALUE str;
|
||||
{
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_downcase_bang(dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
str_capitalize_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
char *s, *send;
|
||||
|
@ -1588,16 +1666,28 @@ rb_str_capitalize_bang(str)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_capitalize(str)
|
||||
rb_str_capitalize_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_capitalize_bang(str);
|
||||
str_capitalize_bang(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_swapcase_bang(str)
|
||||
rb_str_capitalize(str)
|
||||
VALUE str;
|
||||
{
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_capitalize_bang(dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
str_swapcase_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
char *s, *send;
|
||||
|
@ -1624,13 +1714,25 @@ rb_str_swapcase_bang(str)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_swapcase_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
str_swapcase_bang(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_swapcase(str)
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_swapcase_bang(str);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_swapcase_bang(dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
typedef unsigned char *USTR;
|
||||
|
@ -1771,16 +1873,19 @@ static VALUE
|
|||
rb_str_tr_bang(str, src, repl)
|
||||
VALUE str, src, repl;
|
||||
{
|
||||
return tr_trans(str, src, repl, 0);
|
||||
tr_trans(str, src, repl, 0);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_tr(str, src, repl)
|
||||
VALUE str, src, repl;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
tr_trans(str, src, repl, 0);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(tr_trans(str, src, repl, 0)))
|
||||
return str;
|
||||
return dup;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1818,7 +1923,7 @@ tr_setup_table(str, table, init)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_delete_bang(argc, argv, str)
|
||||
str_delete_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
|
@ -1855,19 +1960,33 @@ rb_str_delete_bang(argc, argv, str)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_delete_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str_delete_bang(argc, argv, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_delete(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_delete_bang(argc, argv, str);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_delete_bang(argc, argv, dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_squeeze_bang(argc, argv, str)
|
||||
str_squeeze_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
|
@ -1915,31 +2034,48 @@ rb_str_squeeze_bang(argc, argv, str)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_squeeze_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str_squeeze_bang(argc, argv, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_squeeze(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_squeeze_bang(argc, argv, str);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_squeeze_bang(argc, argv, dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_tr_s_bang(str, src, repl)
|
||||
VALUE str, src, repl;
|
||||
{
|
||||
return tr_trans(str, src, repl, 1);
|
||||
tr_trans(str, src, repl, 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_tr_s(str, src, repl)
|
||||
VALUE str, src, repl;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
tr_trans(str, src, repl, 1);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(tr_trans(str, src, repl, 1)))
|
||||
return str;
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -2187,6 +2323,7 @@ rb_str_each_line(argc, argv, str)
|
|||
if (s != pend) {
|
||||
if (p > pend) p = pend;
|
||||
line = rb_str_new(s, p - s);
|
||||
OBJ_INFECT(line, str);
|
||||
rb_yield(line);
|
||||
}
|
||||
|
||||
|
@ -2206,7 +2343,7 @@ rb_str_each_byte(str)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_chop_bang(str)
|
||||
str_chop_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
if (RSTRING(str)->len > 0) {
|
||||
|
@ -2224,13 +2361,25 @@ rb_str_chop_bang(str)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_chop_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
str_chop_bang(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_chop(str)
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_chop_bang(str);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_chop_bang(dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -2243,16 +2392,18 @@ rb_f_chop_bang(str)
|
|||
static VALUE
|
||||
rb_f_chop()
|
||||
{
|
||||
VALUE str = rb_str_dup(uscore_get());
|
||||
VALUE line = uscore_get();
|
||||
VALUE dup = rb_str_dup(line);
|
||||
|
||||
if (!NIL_P(rb_str_chop_bang(str))) {
|
||||
rb_lastline_set(str);
|
||||
if (!NIL_P(str_chop_bang(dup))) {
|
||||
rb_lastline_set(dup);
|
||||
return dup;
|
||||
}
|
||||
return str;
|
||||
return line;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_chomp_bang(argc, argv, str)
|
||||
str_chomp_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
|
@ -2294,15 +2445,29 @@ rb_str_chomp_bang(argc, argv, str)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_chomp_bang(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str_chomp_bang(argc, argv, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_chomp(argc, argv, str)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_chomp_bang(argc, argv, str);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_chomp_bang(argc, argv, dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -2318,15 +2483,18 @@ rb_f_chomp(argc, argv)
|
|||
int argc;
|
||||
VALUE *argv;
|
||||
{
|
||||
VALUE str = rb_str_dup(uscore_get());
|
||||
if (!NIL_P(rb_str_chomp_bang(argc, argv, str))) {
|
||||
rb_lastline_set(str);
|
||||
VALUE str = uscore_get();
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (!NIL_P(str_chomp_bang(argc, argv, dup))) {
|
||||
rb_lastline_set(dup);
|
||||
return dup;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_strip_bang(str)
|
||||
str_strip_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
char *s, *t, *e;
|
||||
|
@ -2361,13 +2529,25 @@ rb_str_strip_bang(str)
|
|||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_strip_bang(str)
|
||||
VALUE str;
|
||||
{
|
||||
str_strip_bang(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_strip(str)
|
||||
VALUE str;
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
rb_str_strip_bang(str);
|
||||
return str;
|
||||
VALUE dup = rb_str_dup(str);
|
||||
|
||||
if (NIL_P(str_strip_bang(dup))) {
|
||||
rb_gc_force_recycle(dup);
|
||||
return str;
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -2621,9 +2801,6 @@ Init_String()
|
|||
rb_define_method(rb_cString, "rindex", rb_str_rindex, -1);
|
||||
rb_define_method(rb_cString, "replace", rb_str_replace_m, 1);
|
||||
|
||||
rb_define_method(rb_cString, "freeze", rb_str_freeze, 0);
|
||||
rb_define_method(rb_cString, "frozen?", rb_str_frozen_p, 0);
|
||||
|
||||
rb_define_method(rb_cString, "to_i", rb_str_to_i, 0);
|
||||
rb_define_method(rb_cString, "to_f", rb_str_to_f, 0);
|
||||
rb_define_method(rb_cString, "to_s", rb_str_to_s, 0);
|
||||
|
@ -2702,6 +2879,10 @@ Init_String()
|
|||
|
||||
rb_define_global_function("split", rb_f_split, -1);
|
||||
|
||||
rb_define_method(rb_cString, "slice", rb_str_aref_m, -1);
|
||||
rb_define_method(rb_cString, "slice!", rb_str_slice_bang, -1);
|
||||
rb_define_method(rb_cString, "delete_at", rb_str_slice_bang, -1);
|
||||
|
||||
to_str = rb_intern("to_s");
|
||||
|
||||
rb_fs = Qnil;
|
||||
|
|
2
struct.c
2
struct.c
|
@ -474,6 +474,7 @@ rb_struct_aset_id(s, id, val)
|
|||
rb_bug("non-initialized struct");
|
||||
}
|
||||
|
||||
if (OBJ_FROZEN(s)) rb_error_frozen("Struct");
|
||||
len = RARRAY(member)->len;
|
||||
for (i=0; i<len; i++) {
|
||||
if (FIX2UINT(RARRAY(member)->ptr[i]) == id) {
|
||||
|
@ -502,6 +503,7 @@ rb_struct_aset(s, idx, val)
|
|||
if (RSTRUCT(s)->len <= i)
|
||||
rb_raise(rb_eIndexError, "offset %d too large for struct(size:%d)",
|
||||
i, RSTRUCT(s)->len);
|
||||
if (OBJ_FROZEN(s)) rb_error_frozen("Struct");
|
||||
return RSTRUCT(s)->ptr[i] = val;
|
||||
}
|
||||
|
||||
|
|
10
time.c
10
time.c
|
@ -400,14 +400,12 @@ time_cmp(time1, time2)
|
|||
{
|
||||
double t;
|
||||
|
||||
if (tobj1->tv.tv_sec == (time_t)RFLOAT(time2)->value)
|
||||
return INT2FIX(0);
|
||||
t = (double)tobj1->tv.tv_sec + (double)tobj1->tv.tv_usec*1e-6;
|
||||
if (tobj1->tv.tv_sec == (time_t)RFLOAT(time2)->value)
|
||||
return INT2FIX(0);
|
||||
if (tobj1->tv.tv_sec > (time_t)RFLOAT(time2)->value)
|
||||
if (t > RFLOAT(time2)->value)
|
||||
return INT2FIX(1);
|
||||
return FIX2INT(-1);
|
||||
if (t < RFLOAT(time2)->value)
|
||||
return INT2FIX(-1);
|
||||
return INT2FIX(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
variable.c
11
variable.c
|
@ -898,6 +898,7 @@ rb_ivar_set(obj, id, val)
|
|||
{
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
|
||||
if (OBJ_FROZEN(obj)) rb_error_frozen("object");
|
||||
switch (TYPE(obj)) {
|
||||
case T_OBJECT:
|
||||
case T_CLASS:
|
||||
|
@ -984,6 +985,7 @@ rb_obj_remove_instance_variable(obj, name)
|
|||
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
|
||||
if (OBJ_FROZEN(obj)) rb_error_frozen("object");
|
||||
if (!rb_is_instance_id(id)) {
|
||||
rb_raise(rb_eNameError, "`%s' is not an instance variable",
|
||||
rb_id2name(id));
|
||||
|
@ -1099,11 +1101,12 @@ rb_mod_remove_const(mod, name)
|
|||
ID id = rb_to_id(name);
|
||||
VALUE val;
|
||||
|
||||
if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "`%s' is not constant", rb_id2name(id));
|
||||
}
|
||||
if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
|
||||
if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
|
||||
|
||||
if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, &id, &val)) {
|
||||
return val;
|
||||
|
@ -1221,9 +1224,13 @@ rb_const_set(klass, id, val)
|
|||
{
|
||||
if (!OBJ_TAINTED(klass) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't set constant");
|
||||
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
||||
if (!RCLASS(klass)->iv_tbl) {
|
||||
RCLASS(klass)->iv_tbl = st_init_numtable();
|
||||
}
|
||||
else if (st_lookup(RCLASS(klass)->iv_tbl, id, 0)) {
|
||||
rb_warn("already initialized constant %s", rb_id2name(id));
|
||||
}
|
||||
|
||||
st_insert(RCLASS(klass)->iv_tbl, id, val);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define RUBY_VERSION "1.5.2"
|
||||
#define RUBY_RELEASE_DATE "2000-01-18"
|
||||
#define RUBY_RELEASE_DATE "2000-02-01"
|
||||
#define RUBY_VERSION_CODE 152
|
||||
#define RUBY_RELEASE_CODE 20000118
|
||||
#define RUBY_RELEASE_CODE 20000201
|
||||
|
|
|
@ -1619,7 +1619,8 @@ myfdopen (int fd, const char *mode)
|
|||
void
|
||||
myfdclose(FILE *fp)
|
||||
{
|
||||
fclose(fp);
|
||||
_free_osfhnd(fileno(fp));
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче