Skip to content
Browse files

2000-02-01

git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@611 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
1 parent ff338e4 commit b77b7c30d4855734384a095db41a734d315bb8fa matz committed Feb 1, 2000
Showing with 1,603 additions and 691 deletions.
  1. +85 −6 ChangeLog
  2. +18 −13 ToDo
  3. +31 −26 array.c
  4. +539 −258 configure
  5. +56 −32 configure.in
  6. +5 −1 defines.h
  7. +5 −3 dir.c
  8. +1 −1 dln.c
  9. +18 −7 error.c
  10. +186 −91 eval.c
  11. +20 −1 ext/socket/extconf.rb
  12. +21 −4 ext/socket/socket.c
  13. +2 −4 ext/tcltklib/tcltklib.c
  14. +45 −17 ext/tk/lib/tk.rb
  15. +2 −6 ext/tk/lib/tkentry.rb
  16. +2 −2 file.c
  17. +1 −1 gc.c
  18. +2 −27 hash.c
  19. +1 −0 intern.h
  20. +11 −4 io.c
  21. +1 −1 lib/getoptlong.rb
  22. +1 −1 lib/observer.rb
  23. +1 −1 lib/parsedate.rb
  24. +1 −1 marshal.c
  25. +2 −2 node.h
  26. +41 −2 numeric.c
  27. +21 −0 object.c
  28. +1 −1 pack.c
  29. +153 −46 parse.y
  30. +16 −11 ruby.h
  31. +8 −4 sample/test.rb
  32. +287 −106 string.c
  33. +2 −0 struct.c
  34. +4 −6 time.c
  35. +9 −2 variable.c
  36. +2 −2 version.h
  37. +2 −1 win32/win32.c
View
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.
View
31 ToDo
@@ -2,39 +2,39 @@ 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
* remove rb_eval() recursions
* 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
View
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);
View
797 configure
539 additions, 258 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
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)
;;
*)
;;
View
6 defines.h
@@ -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
View
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);
View
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"
View
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()
{
View
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)
@@ -598,6 +594,20 @@ rb_dvar_defined(id)
}
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,23 +5604,25 @@ 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
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,22 +5939,22 @@ 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,
argc, argv, data->body, 0);
}
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
View
21 ext/socket/extconf.rb
@@ -41,6 +41,7 @@
$ipv6type = nil
$ipv6lib = nil
$ipv6libdir = nil
+$ipv6trylibc = nil
if $ipv6
if egrep_cpp("yes", <<EOF)
#include <netinet/in.h>
@@ -59,6 +60,7 @@
$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 @@
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 @@
#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()
View
25 ext/socket/socket.c
@@ -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
View
6 ext/tcltklib/tcltklib.c
@@ -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");
View
62 ext/tk/lib/tk.rb
@@ -196,7 +196,9 @@ def procedure(val)
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 @@ def tk_call(*args)
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 @@ def xscrollcommand(cmd=Proc.new)
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 @@ def value
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 @@ def value=(val)
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 @@ def value=(val)
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 @@ def set(first, last)
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 @@ def activate(y)
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 @@ def selection_includes(index)
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
View
8 ext/tk/lib/tkentry.rb
@@ -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 @@ def self.to_eval
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 @@ def selection_range(s, e)
def selection_to(index)
tk_send 'selection', 'to', index
end
- def xview(*index)
- tk_send 'xview', *index
- end
def value
tk_send 'get'
View
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;
}
View
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:
View
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);
View
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));
View
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);
View
2 lib/getoptlong.rb
@@ -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.
View
2 lib/observer.rb
@@ -32,7 +32,7 @@ def changed?
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
View
2 lib/parsedate.rb
@@ -27,7 +27,7 @@ def parsedate(date, guess=false)
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
View
2 marshal.c
@@ -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);
View
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)
View
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);
@@ -353,6 +352,45 @@ flo_remainder(x, y)
}
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;