summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-27 07:42:55 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-27 07:42:55 +0000
commit74ba517411b5926b1da584f921daf03ff8a72ec4 (patch)
tree6fc8090140e2f30685e4d720ca400ce6cda61f61
parent652f15029b099ebae0cfb89f5adc435faeb5fb09 (diff)
downloadruby-74ba517411b5926b1da584f921daf03ff8a72ec4.tar.gz
* merged from trunk r20281:20375.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/mvm@20376 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--.merged-trunk-revision2
-rw-r--r--ChangeLog243
-rw-r--r--array.c6
-rw-r--r--configure.in3
-rw-r--r--ext/bigdecimal/bigdecimal.c129
-rw-r--r--ext/bigdecimal/bigdecimal.h2
-rw-r--r--ext/curses/curses.c23
-rw-r--r--ext/curses/extconf.rb2
-rw-r--r--ext/gdbm/gdbm.c1
-rw-r--r--ext/pty/pty.c117
-rw-r--r--ext/syck/rubyext.c37
-rw-r--r--ext/tk/ChangeLog.tkextlib11
-rw-r--r--ext/tk/lib/tkextlib/blt.rb4
-rw-r--r--ext/tk/lib/tkextlib/blt/tabnotebook.rb91
-rw-r--r--ext/tk/lib/tkextlib/blt/tabset.rb102
-rw-r--r--ext/tk/lib/tkextlib/blt/vector.rb12
-rw-r--r--ext/tk/lib/tkextlib/version.rb2
-rw-r--r--file.c2
-rw-r--r--lib/date.rb4
-rw-r--r--lib/date/format.rb2
-rw-r--r--lib/logger.rb8
-rw-r--r--lib/minitest/unit.rb10
-rw-r--r--lib/time.rb88
-rw-r--r--node.h2
-rw-r--r--numeric.c13
-rw-r--r--process.c10
-rw-r--r--ruby.c2
-rw-r--r--sampledriver/main.c16
-rw-r--r--signal.c67
-rw-r--r--strftime.c91
-rw-r--r--test/bigdecimal/test_bigdecimal.rb10
-rw-r--r--test/cgi/test_cgi_session.rb17
-rw-r--r--test/date/test_date.rb4
-rw-r--r--test/date/test_date_attr.rb4
-rw-r--r--test/date/test_date_strftime.rb18
-rw-r--r--test/ruby/test_method.rb16
-rw-r--r--test/ruby/test_time.rb26
-rw-r--r--test/yaml/test_yaml.rb4
-rw-r--r--thread.c9
-rw-r--r--version.h6
-rw-r--r--vm.c2
41 files changed, 931 insertions, 287 deletions
diff --git a/.merged-trunk-revision b/.merged-trunk-revision
index c20f5c10e4..015035283b 100644
--- a/.merged-trunk-revision
+++ b/.merged-trunk-revision
@@ -1 +1 @@
-20281
+20375
diff --git a/ChangeLog b/ChangeLog
index 625a92aed8..e539640ba6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,246 @@
+Thu Nov 27 16:32:53 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * signal.c (register_sigaltstack): stores alt stack for debug
+ purpose.
+
+Thu Nov 27 16:12:33 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * signal.c (ruby_sigaction_t): added.
+
+Thu Nov 27 15:59:16 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * gc.c (ruby_stack_check): no check if using sigaltstack.
+
+ * signal.c (ALT_STACK_SIZE): default minimum size is insufficient
+ for method calls.
+
+ * signal.c (sigsegv): handles stack overflow if possible.
+
+ * thread.c (ruby_thread_stack_overflow): helper function to raise
+ sysstack_error.
+
+ * thread_pthread.c (ruby_stack_overflowed_p): checks for stack
+ overflow.
+
+Thu Nov 27 10:40:52 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_div2): should return
+ Integer for #div operation.
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_div2): should raise
+ ZeroDivisionError if divisor is zero. [ruby-dev:37207]
+
+Wed Nov 26 23:15:47 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * strftime.c (STRFTIME): use rb_strftime() recursively, instead of
+ platform's strftime().
+
+Wed Nov 26 22:46:23 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/bigdecimal/bigdecimal.c (VpException): bigdecimal zero
+ division should raise FloatDomainError if mode
+ VP_EXCEPTION_ZERODIVIDE is set. [ruby-dev:37204]
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_mode): should handle
+ VP_EXCEPTION_ZERODIVIDE.
+
+Wed Nov 26 15:16:07 2008 Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
+
+ * ext/gdbm/gdbm.c (rb_gdbm_nextkey): fix memory leak.
+
+Wed Nov 26 03:17:48 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_to_r): raise exception
+ for nan/inf conversion. [ruby-dev:37187] fix #793
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_to_i): ditto.
+
+Wed Nov 26 03:00:59 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/bigdecimal/bigdecimal.c (VpAlloc): avoid ALLOCA_N() to avoid
+ segmentation fault caused by (insanely) long decimal values.
+ [ruby-dev:37189] fix #794
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_dump, BigDecimal_to_i,
+ BigDecimal_to_f, BigDecimal_to_s, BigDecimal_split,
+ BigDecimal_inspect): ditto.
+
+ * ext/bigdecimal/bigdecimal.c (VpToString): small performance
+ improvement.
+
+Wed Nov 26 00:26:30 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * strftime.c (STRFTIME): should add padding for %[xXrR] etc.
+ [ruby-dev:37185] fix: #792
+
+Tue Nov 25 16:26:12 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (rb_ary_times): taint (and untrust) status should be
+ inherited by "ary * 0". [ruby-dev:37024]
+
+Tue Nov 25 15:54:07 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * strftime.c (rb_strftime): should not swallow incomplete
+ formatter, e.g. "%E". [ruby-dev:37170] fix: #787
+
+ * strftime.c (rb_strftime): clear flags before processing unknown
+ formatter, e.g. "%i". [ruby-dev:37180]
+
+Tue Nov 25 10:35:29 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * strftime.c (rb_strftime): "%^P" should convert to upper case.
+ [ruby-dev:37180]
+
+Tue Nov 25 07:51:18 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * strftime.c (FMT): use "%0d" formatter for zero padding, not "%.d".
+ [ruby-dev:37168] fix: #768
+
+ * strftime.c (rb_strftime): %s to use zero padding by default.
+ [ruby-dev:37180]
+
+Tue Nov 25 03:37:42 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkextlib/blt/tabset.rb,
+ ext/tk/lib/tkextlib/blt/tabnotebook.rb:
+ fix many bugs. Now, those work properly.
+
+Tue Nov 25 03:26:04 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * numeric.c (num_step): treat infinite step specially.
+ [ruby-dev:37157] fix: #781.
+
+Tue Nov 25 01:23:25 2008 Tadayoshi Funaba <tadf@dotrb.org>
+
+ * lib/date/format.rb (strftime): ignores '_' flag for %[LN].
+
+Tue Nov 25 00:08:22 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * process.c (rb_fork): stops the timer thread during fork.
+ [ruby-dev:37117]
+
+ * thread.c (rb_thread_start_timer_thread): timer thread needs
+ system_working to be set.
+
+Mon Nov 24 23:27:28 2008 Shugo Maeda <shugo@ruby-lang.org>
+
+ * strftime.c (rb_strftime): The # flag should work with %a, %A, %b,
+ %B, and %h. [ruby-dev:37162]
+
+ * test/ruby/test_time.rb (test_strftime): ditto.
+
+Mon Nov 24 23:16:32 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * signal.c (register_sigaltstack): should not add external
+ variable (with some cosmetic changes). [ruby-dev:37158]
+
+Mon Nov 24 22:57:25 2008 Shugo Maeda <shugo@ruby-lang.org>
+
+ * strftime.c (rb_strftime): A width specifier for %t and %n should
+ work. [ruby-dev:37160]
+
+ * test/ruby/test_time.rb (test_strftime): ditto.
+
+Mon Nov 24 22:07:07 2008 Shugo Maeda <shugo@ruby-lang.org>
+
+ * strftime.c (rb_strftime): The precision of %0N should be 9.
+ [ruby-dev:37156]
+
+ * test/ruby/test_time.rb (test_strftime): ditto.
+
+Mon Nov 24 21:38:23 2008 Shugo Maeda <shugo@ruby-lang.org>
+
+ * strftime.c (rb_strftime): The default precision should be 1, not
+ 0. [ruby-dev:37155]
+
+ * test/ruby/test_time.rb (test_strftime): ditto.
+
+Mon Nov 24 19:53:47 2008 Tadayoshi Funaba <tadf@dotrb.org>
+
+ * lib/date.rb (inspect): changed again.
+
+Mon Nov 24 18:35:00 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/time.rb: r20251 reverted. The patched behavior do not round
+ trip. [ruby-core:19988]
+
+Sun Nov 23 16:04:05 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
+
+ * signal.c (default_handler, Init_signal): compile error if
+ USE_SIGALTSTACK is not defined.
+
+Sun Nov 23 00:04:14 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
+
+ * signal.c (ALT_STACK_SIZE): 4KB is not enough on Mac OS X.
+ Uses SIGSTKSZ.
+
+Sat Nov 22 21:29:54 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
+
+ * test/ruby/test_method.rb (test_default_accessiblity): test case for
+ [ruby-dev:37124].
+
+Sat Nov 22 18:24:24 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * file.c (rb_file_world_writable_p): should return nil for non
+ world-writable files.
+
+Sat Nov 22 10:31:25 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkextlib/blt.rb, ext/tk/lib/tkextlib/blt/vector.rb:
+ fix NameError bug.
+
+Sat Nov 22 03:41:22 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/pty/pty.c (get_device_once): abandon asynchronous exception
+ that might cause serious problem if a program terminated early.
+ asynchronous exception is a very bad thing anyway. use
+ Process.waitpid(pid) or PTY.check(pid) to poll program
+ termination. if PTY.check is called with optional second
+ argument being true, it raises an exception same as one from
+ previous behavior. [incompatible] fix: [ruby-core:19583]
+
+Fri Nov 21 22:24:31 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/curses/curses.c (curses_escdelay_set): support ESCDELAY. a
+ patch from Giancarlo F Bellido <support at coaxialhost.com> in
+ [ruby-core:19961].
+
+Fri Nov 21 22:17:15 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ruby.c (usage): -W description updated. [ruby-core:19858]
+
+Fri Nov 21 21:50:54 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * signal.c (register_sigaltstack): use alternative stack for
+ SIGSEGV to avoid uncaught stack overflow. based on a patch from
+ Hiro Yoshioka <hyoshiok at miraclelinux.com> in [ruby-dev:37134].
+ [ruby-dev:36993]
+
+Fri Nov 21 16:06:54 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * vm.c (thread_free): th->vm may be NULL when pthread_create
+ failed for ENOMEM. [ruby-dev:37095]
+
+Thu Nov 20 07:33:15 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/logger.rb (Logger): should handle the case that cvs/svn do
+ not expand $Id keyword. [ruby-core:19991]
+
+Thu Nov 20 07:27:36 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/minitest/unit.rb (MiniTest::Assertions#capture_io): adjust
+ indentation to shut up warning. [ruby-core:19993]
+
+Wed Nov 19 17:48:05 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/syck/rubyext.c (rb_syck_mktime): return DateTime for a value
+ out of range of Time. [ruby-core:19919]
+
+Wed Nov 19 14:14:38 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * node.h (NOEX_MODFUNC): should be include NOEX_PRIVATE.
+ [ruby-dev:37124]
+
Wed Nov 19 03:01:04 2008 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* test/rinda/test_rinda.rb: fixed fails occasionally [ruby-dev:37119].
diff --git a/array.c b/array.c
index 26cbe5479b..1ff9a24b2e 100644
--- a/array.c
+++ b/array.c
@@ -2549,7 +2549,10 @@ rb_ary_times(VALUE ary, VALUE times)
}
len = NUM2LONG(times);
- if (len == 0) return ary_new(rb_obj_class(ary), 0);
+ if (len == 0) {
+ ary2 = ary_new(rb_obj_class(ary), 0);
+ goto out;
+ }
if (len < 0) {
rb_raise(rb_eArgError, "negative argument");
}
@@ -2564,6 +2567,7 @@ rb_ary_times(VALUE ary, VALUE times)
for (i=0; i<len; i+=RARRAY_LEN(ary)) {
MEMCPY(RARRAY_PTR(ary2)+i, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
}
+ out:
OBJ_INFECT(ary2, ary);
return ary2;
diff --git a/configure.in b/configure.in
index ef782295e1..771973d037 100644
--- a/configure.in
+++ b/configure.in
@@ -789,7 +789,7 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync getcwd
setsid telldir seekdir fchmod cosh sinh tanh log2 round signbit\
setuid setgid daemon select_large_fdset setenv unsetenv\
mktime timegm gmtime_r clock_gettime gettimeofday\
- pread sendfile shutdown)
+ pread sendfile shutdown sigaltstack)
AC_CACHE_CHECK(for __builtin_setjmp, ac_cv_func___builtin_setjmp,
[AC_TRY_LINK([@%:@include <setjmp.h>
@@ -1157,7 +1157,6 @@ if test x"$enable_pthread" = xyes; then
AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled")
fi
AC_CHECK_FUNCS(nanosleep sched_yield pthread_attr_setinheritsched)
- AC_CHECK_FUNCS(sigaltstack)
AC_CHECK_FUNCS(pthread_getattr_np pthread_attr_getstack)
AC_CHECK_FUNCS(pthread_attr_get_np)
AC_CHECK_FUNCS(pthread_get_stackaddr_np pthread_get_stacksize_np)
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index 96bd88160c..62ff80a860 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -309,17 +309,19 @@ static VALUE
BigDecimal_dump(int argc, VALUE *argv, VALUE self)
{
ENTER(5);
- char sz[50];
Real *vp;
char *psz;
VALUE dummy;
+ volatile VALUE dump;
+
rb_scan_args(argc, argv, "01", &dummy);
GUARD_OBJ(vp,GetVpValue(self,1));
- sprintf(sz,"%lu:",VpMaxPrec(vp)*VpBaseFig());
- psz = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E")+strlen(sz));
- sprintf(psz,"%s",sz);
+ dump = rb_str_new(0,VpNumOfChars(vp,"E")+50);
+ psz = RSTRING_PTR(dump);
+ sprintf(psz,"%lu:",VpMaxPrec(vp)*VpBaseFig());
VpToString(vp, psz+strlen(psz), 0, 0);
- return rb_str_new2(psz);
+ rb_str_resize(dump, strlen(psz));
+ return dump;
}
/*
@@ -423,6 +425,11 @@ BigDecimal_mode(int argc, VALUE *argv, VALUE self)
(fo&(~VP_EXCEPTION_UNDERFLOW))));
}
fo = VpGetException();
+ if(f&VP_EXCEPTION_ZERODIVIDE) {
+ VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_ZERODIVIDE):
+ (fo&(~VP_EXCEPTION_ZERODIVIDE))));
+ }
+ fo = VpGetException();
return INT2FIX(fo);
}
if(VP_ROUND_MODE==f) {
@@ -519,6 +526,18 @@ BigDecimal_IsFinite(VALUE self)
return Qtrue;
}
+static void
+BigDecimal_check_num(Real *p)
+{
+ if(VpIsNaN(p)) {
+ VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",1);
+ } else if(VpIsPosInf(p)) {
+ VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",1);
+ } else if(VpIsNegInf(p)) {
+ VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",1);
+ }
+}
+
/* Returns the value as an integer (Fixnum or Bignum).
*
* If the BigNumber is infinity or NaN, returns nil.
@@ -529,22 +548,12 @@ BigDecimal_to_i(VALUE self)
ENTER(5);
int e,n,i,nf;
U_LONG v,b,j;
+ volatile VALUE str;
char *psz,*pch;
Real *p;
GUARD_OBJ(p,GetVpValue(self,1));
-
- /* Infinity or NaN not converted. */
- if(VpIsNaN(p)) {
- VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",0);
- return Qnil;
- } else if(VpIsPosInf(p)) {
- VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",0);
- return Qnil;
- } else if(VpIsNegInf(p)) {
- VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",0);
- return Qnil;
- }
+ BigDecimal_check_num(p);
e = VpExponent10(p);
if(e<=0) return INT2FIX(0);
@@ -553,7 +562,8 @@ BigDecimal_to_i(VALUE self)
e = VpGetSign(p)*p->frac[0];
return INT2FIX(e);
}
- psz = ALLOCA_N(char,(unsigned int)(e+nf+2));
+ str = rb_str_new(0, e+nf+2);
+ psz = RSTRING_PTR(str);
n = (e+nf-1)/nf;
pch = psz;
@@ -591,10 +601,12 @@ BigDecimal_to_f(VALUE self)
double d;
S_LONG e;
char *buf;
+ volatile VALUE str;
GUARD_OBJ(p,GetVpValue(self,1));
if(VpVtoD(&d, &e, p)!=1) return rb_float_new(d);
- buf = ALLOCA_N(char,(unsigned int)VpNumOfChars(p,"E"));
+ str = rb_str_new(0, VpNumOfChars(p,"E"));
+ buf = RSTRING_PTR(str);
VpToString(p, buf, 0, 0);
errno = 0;
d = strtod(buf, 0);
@@ -619,6 +631,8 @@ BigDecimal_to_r(VALUE self)
VALUE a, digits, numerator;
p = GetVpValue(self,1);
+ BigDecimal_check_num(p);
+
sign = VpGetSign(p);
power = VpExponent10(p);
a = BigDecimal_split(self);
@@ -1155,7 +1169,10 @@ BigDecimal_div2(int argc, VALUE *argv, VALUE self)
Real *mod;
obj = BigDecimal_DoDivmod(self,b,&div,&mod);
if(obj!=(VALUE)0) return obj;
- return ToValue(div);
+ if(VpIsNaN(div) && rb_equal(b, INT2FIX(0))) {
+ rb_raise(rb_eZeroDivError, "divided by 0");
+ }
+ return BigDecimal_to_i(ToValue(div));
} else { /* div in BigDecimal sense */
U_LONG ix = (U_LONG)GetPositiveInt(n);
if(ix==0) return BigDecimal_div(self,b);
@@ -1541,6 +1558,7 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
int fmt=0; /* 0:E format */
int fPlus=0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */
Real *vp;
+ volatile VALUE str;
char *psz;
char ch;
U_LONG nc;
@@ -1577,14 +1595,16 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
}
if(mc>0) nc += (nc + mc - 1) / mc + 1;
- psz = ALLOCA_N(char,(unsigned int)nc);
+ str = rb_str_new(0, nc);
+ psz = RSTRING_PTR(str);
if(fmt) {
VpToFString(vp, psz, mc, fPlus);
} else {
VpToString (vp, psz, mc, fPlus);
}
- return rb_str_new2(psz);
+ rb_str_resize(str, strlen(psz));
+ return str;
}
/* Splits a BigDecimal number into four parts, returned as an array of values.
@@ -1616,24 +1636,29 @@ BigDecimal_split(VALUE self)
{
ENTER(5);
Real *vp;
- VALUE obj,obj1;
+ VALUE obj,str;
S_LONG e;
S_LONG s;
char *psz1;
GUARD_OBJ(vp,GetVpValue(self,1));
- psz1 = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E"));
+ str = rb_str_new(0, VpNumOfChars(vp,"E"));
+ psz1 = RSTRING_PTR(str);
VpSzMantissa(vp,psz1);
s = 1;
if(psz1[0]=='-') {
- s = -1; ++psz1;
+ int len = strlen(psz1+1);
+
+ memmove(psz1, psz1+1, len);
+ psz1[len] = '\0';
+ s = -1;
}
if(psz1[0]=='N') s=0; /* NaN */
e = VpExponent10(vp);
- obj1 = rb_str_new2(psz1);
obj = rb_ary_new2(4);
rb_ary_push(obj, INT2FIX(s));
- rb_ary_push(obj, obj1);
+ rb_ary_push(obj, str);
+ rb_str_resize(str, strlen(psz1));
rb_ary_push(obj, INT2FIX(10));
rb_ary_push(obj, INT2NUM(e));
return obj;
@@ -1666,20 +1691,22 @@ BigDecimal_inspect(VALUE self)
{
ENTER(5);
Real *vp;
- VALUE obj;
+ volatile VALUE obj;
unsigned int nc;
- char *psz1;
- char *pszAll;
+ char *psz, *tmp;
GUARD_OBJ(vp,GetVpValue(self,1));
nc = VpNumOfChars(vp,"E");
nc +=(nc + 9) / 10;
- psz1 = ALLOCA_N(char,nc);
- pszAll = ALLOCA_N(char,nc+256);
- VpToString(vp, psz1, 10, 0);
- sprintf(pszAll,"#<BigDecimal:%lx,'%s',%lu(%lu)>",self,psz1,VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig());
- obj = rb_str_new2(pszAll);
+ obj = rb_str_new(0, nc+256);
+ psz = RSTRING_PTR(obj);
+ sprintf(psz,"#<BigDecimal:%lx,'",self);
+ tmp = psz + strlen(psz);
+ VpToString(vp, tmp, 10, 0);
+ tmp += strlen(tmp);
+ sprintf(tmp,"',%lu(%lu)>",VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig());
+ rb_str_resize(obj, strlen(psz));
return obj;
}
@@ -2251,18 +2278,12 @@ VpException(unsigned short f, const char *str,int always)
switch(f)
{
/*
- case VP_EXCEPTION_ZERODIVIDE:
case VP_EXCEPTION_OVERFLOW:
*/
+ case VP_EXCEPTION_ZERODIVIDE:
case VP_EXCEPTION_INFINITY:
- exc = rb_eFloatDomainError;
- goto raise;
case VP_EXCEPTION_NaN:
- exc = rb_eFloatDomainError;
- goto raise;
case VP_EXCEPTION_UNDERFLOW:
- exc = rb_eFloatDomainError;
- goto raise;
case VP_EXCEPTION_OP:
exc = rb_eFloatDomainError;
goto raise;
@@ -2534,6 +2555,7 @@ VpAlloc(U_LONG mx, const char *szVal)
int sign=1;
Real *vp = NULL;
U_LONG mf = VpGetPrecLimit();
+ volatile VALUE buf;
mx = (mx + BASE_FIG - 1) / BASE_FIG + 1; /* Determine allocation unit. */
if(szVal) {
@@ -2561,7 +2583,8 @@ VpAlloc(U_LONG mx, const char *szVal)
/* Skip all '_' after digit: 2006-6-30 */
ni = 0;
- psz = ALLOCA_N(char,strlen(szVal)+1);
+ buf = rb_str_new(0,strlen(szVal)+1);
+ psz = RSTRING_PTR(buf);
i = 0;
ipn = 0;
while((psz[i]=szVal[ipn])!=0) {
@@ -3656,7 +3679,7 @@ VPrint(FILE *fp, char *cntl_chr, Real *a)
nc += fprintf(fp, "0.");
n = a->Prec;
for(i=0;i < n;++i) {
- m = BASE1;
+ m = BASE1;
e = a->frac[i];
while(m) {
nn = e / m;
@@ -3838,7 +3861,7 @@ VpToString(Real *a,char *psz,int fFmt,int fPlus)
/* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */
{
U_LONG i, ZeroSup;
- U_LONG n, m, e, nn;
+ U_LONG n, e;
char *pszSav = psz;
S_LONG ex;
@@ -3854,18 +3877,12 @@ VpToString(Real *a,char *psz,int fFmt,int fPlus)
*psz++ = '.';
n = a->Prec;
for(i=0;i < n;++i) {
- m = BASE1;
e = a->frac[i];
- while(m) {
- nn = e / m;
- if((!ZeroSup) || nn) {
- sprintf(psz, "%lu", nn); /* The reading zero(s) */
- psz += strlen(psz);
- /* as 0.00xx will be ignored. */
- ZeroSup = 0; /* Set to print succeeding zeros */
- }
- e = e - nn * m;
- m /= 10;
+ if((!ZeroSup) || e) {
+ sprintf(psz, "%lu", e); /* The reading zero(s) */
+ psz += strlen(psz);
+ /* as 0.00xx will be ignored. */
+ ZeroSup = 0; /* Set to print succeeding zeros */
}
}
ex =(a->exponent) * BASE_FIG;
diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h
index 3a300f1df5..a30a08e615 100644
--- a/ext/bigdecimal/bigdecimal.h
+++ b/ext/bigdecimal/bigdecimal.h
@@ -45,7 +45,7 @@ extern "C" {
#define VP_EXCEPTION_NaN ((unsigned short)0x0002)
#define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004)
#define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */
-#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0001) /* 0x0010) */
+#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010)
/* Following 2 exceptions cann't controlled by user */
#define VP_EXCEPTION_OP ((unsigned short)0x0020)
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
index 778bee4da9..9f4e02ef42 100644
--- a/ext/curses/curses.c
+++ b/ext/curses/curses.c
@@ -573,6 +573,27 @@ curses_bkgd(VALUE obj, VALUE ch)
}
static VALUE
+curses_escdelay_set(VALUE obj, VALUE val)
+{
+#if defined(HAVE_ESCDELAY)
+ ESCDELAY=NUM2INT(val);
+ return INT2NUM(ESCDELAY);
+#else
+ rb_notimplement();
+#endif
+}
+
+static VALUE
+curses_escdelay_get(VALUE obj)
+{
+#if defined(HAVE_ESCDELAY)
+ return INT2NUM(ESCDELAY);
+#else
+ rb_notimplement();
+#endif
+}
+
+static VALUE
curses_resizeterm(VALUE obj, VALUE lin, VALUE col)
{
#if defined(HAVE_RESIZETERM)
@@ -1419,6 +1440,8 @@ Init_curses(void)
rb_define_method(cMouseEvent, "bstate", curs_mouse_bstate, 0);
#endif /* USE_MOUSE */
+ rb_define_module_function(mCurses, "ESCDELAY=", curses_escdelay_set, 1);
+ rb_define_module_function(mCurses, "ESCDELAY", curses_escdelay_get, 0);
rb_define_module_function(mCurses, "init_screen", curses_init_screen, 0);
rb_define_module_function(mCurses, "close_screen", curses_close_screen, 0);
rb_define_module_function(mCurses, "closed?", curses_closed, 0);
diff --git a/ext/curses/extconf.rb b/ext/curses/extconf.rb
index 799d1bfe5f..3aa91702e3 100644
--- a/ext/curses/extconf.rb
+++ b/ext/curses/extconf.rb
@@ -6,6 +6,7 @@ dir_config('termcap')
make=false
headers = []
+
have_library("mytinfo", "tgetent") if /bow/ =~ RUBY_PLATFORM
have_library("tinfo", "tgetent") or have_library("termcap", "tgetent")
if have_header(*curses=%w"ncurses.h") and have_library("ncurses", "initscr")
@@ -27,5 +28,6 @@ if make
if try_static_assert("sizeof(char*)>sizeof(int)", %w[stdio.h stdlib.h]+curses , flag)
$defs << flag
end
+ have_var("ESCDELAY", curses)
create_makefile("curses")
end
diff --git a/ext/gdbm/gdbm.c b/ext/gdbm/gdbm.c
index 1e83608132..edde0d19ab 100644
--- a/ext/gdbm/gdbm.c
+++ b/ext/gdbm/gdbm.c
@@ -344,6 +344,7 @@ rb_gdbm_nextkey(GDBM_FILE dbm, VALUE keystr)
return Qnil;
str = rb_str_new(key2.dptr, key2.dsize);
+ free(key2.dptr);
OBJ_TAINT(str);
return str;
}
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index e0d571a581..f0b8e66595 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -127,51 +127,8 @@ echild_status(VALUE self)
struct pty_info {
int fd;
rb_pid_t child_pid;
- VALUE thread;
};
-static void
-raise_from_wait(const char *state, const struct pty_info *info)
-{
- char buf[1024];
- VALUE exc;
-
- snprintf(buf, sizeof(buf), "pty - %s: %ld", state, (long)info->child_pid);
- exc = rb_exc_new2(eChildExited, buf);
- rb_iv_set(exc, "status", rb_last_status_get());
- rb_funcall(info->thread, rb_intern("raise"), 1, exc);
-}
-
-static VALUE
-pty_syswait(void *arg)
-{
- const struct pty_info *const info = arg;
- rb_pid_t cpid;
- int status;
-
- for (;;) {
- cpid = rb_waitpid(info->child_pid, &status, WUNTRACED);
- if (cpid == -1) return Qnil;
-
-#if defined(WIFSTOPPED)
-#elif defined(IF_STOPPED)
-#define WIFSTOPPED(status) IF_STOPPED(status)
-#else
----->> Either IF_STOPPED or WIFSTOPPED is needed <<----
-#endif /* WIFSTOPPED | IF_STOPPED */
- if (WIFSTOPPED(status)) { /* suspend */
- raise_from_wait("stopped", info);
- }
- else if (kill(info->child_pid, 0) == 0) {
- raise_from_wait("changed", info);
- }
- else {
- raise_from_wait("exited", info);
- return Qnil;
- }
- }
-}
-
static void getDevice(int*, int*, char [DEVICELEN]);
struct exec_info {
@@ -217,7 +174,6 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
}
getDevice(&master, &slave, SlaveName);
- info->thread = rb_thread_current();
if ((pid = fork()) < 0) {
close(master);
close(slave);
@@ -288,15 +244,6 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
info->fd = master;
}
-static VALUE
-pty_finalize_syswait(struct pty_info *info)
-{
- rb_thread_kill(info->thread);
- rb_funcall(info->thread, rb_intern("value"), 0);
- rb_detach_process(info->child_pid);
- return Qnil;
-}
-
static int
get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
{
@@ -396,13 +343,19 @@ getDevice(int *master, int *slave, char SlaveName[DEVICELEN])
}
}
+static VALUE
+pty_detach_process(struct pty_info *info)
+{
+ rb_detach_process(info->child_pid);
+ return Qnil;
+}
+
/* ruby function: getpty */
static VALUE
pty_getpty(int argc, VALUE *argv, VALUE self)
{
VALUE res;
struct pty_info info;
- struct pty_info thinfo;
rb_io_t *wfptr,*rfptr;
VALUE rport = rb_obj_alloc(rb_cFile);
VALUE wport = rb_obj_alloc(rb_cFile);
@@ -426,32 +379,55 @@ pty_getpty(int argc, VALUE *argv, VALUE self)
rb_ary_store(res,1,(VALUE)wport);
rb_ary_store(res,2,PIDT2NUM(info.child_pid));
- thinfo.thread = rb_thread_create(pty_syswait, (void*)&info);
- thinfo.child_pid = info.child_pid;
- rb_thread_schedule();
-
if (rb_block_given_p()) {
- rb_ensure(rb_yield, res, pty_finalize_syswait, (VALUE)&thinfo);
+ rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info);
return Qnil;
}
return res;
}
-/* ruby function: protect_signal - obsolete */
-static VALUE
-pty_protect(VALUE self)
+static void
+raise_from_check(pid_t pid, int status)
{
- rb_warn("PTY::protect_signal is no longer needed");
- rb_yield(Qnil);
- return self;
+ const char *state;
+ char buf[1024];
+ VALUE exc;
+
+#if defined(WIFSTOPPED)
+#elif defined(IF_STOPPED)
+#define WIFSTOPPED(status) IF_STOPPED(status)
+#else
+---->> Either IF_STOPPED or WIFSTOPPED is needed <<----
+#endif /* WIFSTOPPED | IF_STOPPED */
+ if (WIFSTOPPED(status)) { /* suspend */
+ state = "stopped";
+ }
+ else if (kill(pid, 0) == 0) {
+ state = "changed";
+ }
+ else {
+ state = "exited";
+ }
+ snprintf(buf, sizeof(buf), "pty - %s: %ld", state, (long)pid);
+ exc = rb_exc_new2(eChildExited, buf);
+ rb_iv_set(exc, "status", rb_last_status_get());
+ rb_exc_raise(exc);
}
-/* ruby function: reset_signal - obsolete */
static VALUE
-pty_reset_signal(VALUE self)
+pty_check(int argc, VALUE *argv, VALUE self)
{
- rb_warn("PTY::reset_signal is no longer needed");
- return self;
+ VALUE pid, exc;
+ pid_t cpid;
+ int status;
+
+ rb_scan_args(argc, argv, "11", &pid, &exc);
+ cpid = rb_waitpid(NUM2PIDT(pid), &status, WUNTRACED);
+ if (cpid == -1) return Qnil;
+
+ if (!RTEST(exc)) return status;
+ raise_from_check(pid, status);
+ return Qnil; /* not reached */
}
static VALUE cPTY;
@@ -462,8 +438,7 @@ Init_pty()
cPTY = rb_define_module("PTY");
rb_define_module_function(cPTY,"getpty",pty_getpty,-1);
rb_define_module_function(cPTY,"spawn",pty_getpty,-1);
- rb_define_module_function(cPTY,"protect_signal",pty_protect,0);
- rb_define_module_function(cPTY,"reset_signal",pty_reset_signal,0);
+ rb_define_singleton_function(cPTY,"check",pty_check,-1);
eChildExited = rb_define_class_under(cPTY,"ChildExited",rb_eRuntimeError);
rb_define_method(eChildExited,"status",echild_status,0);
diff --git a/ext/syck/rubyext.c b/ext/syck/rubyext.c
index d5c6372076..a8f0eec978 100644
--- a/ext/syck/rubyext.c
+++ b/ext/syck/rubyext.c
@@ -50,11 +50,11 @@ typedef struct {
* symbols and constants
*/
static ID s_new, s_utc, s_at, s_to_f, s_to_i, s_read, s_binmode, s_call, s_cmp, s_transfer, s_update, s_dup, s_haskey, s_match, s_keys, s_unpack, s_tr_bang, s_default_set, s_tag_read_class, s_tag_subclasses, s_resolver, s_push, s_emitter, s_level, s_detect_implicit, s_node_import, s_out, s_input, s_intern, s_transform, s_yaml_new, s_yaml_initialize, s_node_export, s_to_yaml, s_write, s_set_resolver, s_each;
-static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set;
+static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set, s_parse;
static VALUE sym_model, sym_generic, sym_input, sym_bytecode;
static VALUE sym_scalar, sym_seq, sym_map;
static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline;
-static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter;
+static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter, cDateTime;
static VALUE oDefaultResolver, oGenericResolver;
/*
@@ -207,10 +207,17 @@ syck_get_hash_aref(VALUE hsh, VALUE key)
/*
* creating timestamps
*/
+struct mktime_arg {
+ char *str;
+ long len;
+};
+
SYMID
-rb_syck_mktime(char *str, long len)
+mktime_do(struct mktime_arg *arg)
{
VALUE time;
+ char *str = arg->str;
+ long len = arg->len;
char *ptr = str;
VALUE year = INT2FIX(0);
VALUE mon = INT2FIX(0);
@@ -312,6 +319,29 @@ rb_syck_mktime(char *str, long len)
}
}
+SYMID
+mktime_r(struct mktime_arg *arg)
+{
+ if (!cDateTime) {
+ /*
+ * Load Date module
+ */
+ rb_require("date");
+ cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
+ }
+ return rb_funcall(cDateTime, s_parse, 1, rb_str_new(arg->str, arg->len));
+}
+
+SYMID
+rb_syck_mktime(char *str, long len)
+{
+ struct mktime_arg a;
+
+ a.str = str;
+ a.len = len;
+ return rb_rescue2(mktime_do, (VALUE)&a, mktime_r, (VALUE)&a, rb_eArgError, NULL);
+}
+
/*
* handles merging of an array of hashes
* (see http://www.yaml.org/type/merge/)
@@ -2112,6 +2142,7 @@ Init_syck()
s_yaml_new = rb_intern("yaml_new");
s_yaml_initialize = rb_intern("yaml_initialize");
s_each = rb_intern("each");
+ s_parse = rb_intern("parse");
s_tags = rb_intern("@tags");
s_name = rb_intern("@name");
diff --git a/ext/tk/ChangeLog.tkextlib b/ext/tk/ChangeLog.tkextlib
index 8c5d01a954..fc919a5eb5 100644
--- a/ext/tk/ChangeLog.tkextlib
+++ b/ext/tk/ChangeLog.tkextlib
@@ -1,3 +1,14 @@
+Tue Nov 25 03:37:42 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkextlib/blt/tabset.rb,
+ ext/tk/lib/tkextlib/blt/tabnotebook.rb:
+ fix many bugs. Now, those work properly.
+
+Sat Nov 22 10:31:25 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkextlib/blt.rb, ext/tk/lib/tkextlib/blt/vector.rb:
+ fix NameError bug.
+
2008-05-12 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tkextlib/tkDND/shape.rb: wrong package name.
diff --git a/ext/tk/lib/tkextlib/blt.rb b/ext/tk/lib/tkextlib/blt.rb
index 115eb927ba..8d58c1f1bc 100644
--- a/ext/tk/lib/tkextlib/blt.rb
+++ b/ext/tk/lib/tkextlib/blt.rb
@@ -26,14 +26,14 @@ module Tk
PATCH_LEVEL = tk_call('set', 'blt_patchLevel')
begin
- lib = INTERP._invoke('set', 'blt_library')
+ lib = TkCore::INTERP._invoke('set', 'blt_library')
rescue
lib = ''
end
LIBRARY = TkVarAccess.new('blt_library', lib)
begin
- lib = INTERP._invoke('set', 'blt_libPath')
+ lib = TkCore::INTERP._invoke('set', 'blt_libPath')
rescue
lib = ''
end
diff --git a/ext/tk/lib/tkextlib/blt/tabnotebook.rb b/ext/tk/lib/tkextlib/blt/tabnotebook.rb
index 508fa2b82f..510352ba48 100644
--- a/ext/tk/lib/tkextlib/blt/tabnotebook.rb
+++ b/ext/tk/lib/tkextlib/blt/tabnotebook.rb
@@ -13,9 +13,98 @@ module Tk::BLT
WidgetClassName = 'Tabnotebook'.freeze
WidgetClassNames[WidgetClassName] = self
+ class Tab < Tk::BLT::Tabset::Tab
+ def self.new(parent, pos=nil, name=nil, keys={})
+ if pos.kind_of?(Hash)
+ keys = pos
+ name = nil
+ pos = nil
+ end
+ if name.kind_of?(Hash)
+ keys = name
+ name = nil
+ end
+ obj = nil
+ TabID_TBL.mutex.synchronize{
+ if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name]
+ obj = TabID_TBL[parent.path][name]
+ if pos
+ if pos.to_s == 'end'
+ obj.move_after('end')
+ else
+ obj.move_before(pos)
+ end
+ end
+ obj.configure if keys && ! keys.empty?
+ else
+ (obj = self.allocate).instance_eval{
+ initialize(parent, pos, name, keys)
+ TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]
+ TabID_TBL[@tpath][@id] = self
+ }
+ end
+ }
+ obj
+ end
+
+ def initialize(parent, pos, name, keys)
+ @t = parent
+ @tpath = parent.path
+ if name
+ @path = @id = name
+ unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?)
+ if pos
+ idx = tk_call(@tpath, 'index', @id)
+ if pos.to_s == 'end'
+ tk_call(@tpath, 'move', idx, 'after', 'end')
+ else
+ tk_call(@tpath, 'move', idx, 'before', pos)
+ end
+ end
+ tk_call(@tpath, 'tab', 'configure', @id, keys)
+ else
+ fail ArgumentError, "can't find tab \"#{@id}\" in #{@t}"
+ end
+ else
+ pos = 'end' unless pos
+ @path = @id = tk_call(@tpath, 'insert', pos, keys)
+ end
+ end
+ end
+
+ #######################################
+
def get_tab(index)
- Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('id', tagindex(index)))
+ if (idx = tk_send_without_enc('id', tagindex(index))).empty?
+ nil
+ else
+ Tk::BLT::Tabset::Tab.id2obj(self, idx)
+ end
end
alias get_id get_tab
+
+ def get_tabobj(index)
+ if (idx = tk_send_without_enc('id', tagindex(index))).empty?
+ nil
+ else
+ Tk::BLT::Tabnotebook::Tab.new(self, nil, idx)
+ end
+ end
+
+ alias index_name index
+
+ def insert(pos=nil, keys={})
+ if pos.kind_of?(Hash)
+ keys = pos
+ pos = nil
+ end
+ pos = 'end' if pos.nil?
+ Tk::BLT::Tabnotebook::Tab.new(self, nil,
+ tk_send('insert', tagindex(pos), keys))
+
+ end
+ undef :insert_tabs
+
+ undef :tab_pageheight, :tab_pagewidth
end
end
diff --git a/ext/tk/lib/tkextlib/blt/tabset.rb b/ext/tk/lib/tkextlib/blt/tabset.rb
index ca81ad8f95..b5e076db3a 100644
--- a/ext/tk/lib/tkextlib/blt/tabset.rb
+++ b/ext/tk/lib/tkextlib/blt/tabset.rb
@@ -27,7 +27,7 @@ module Tk::BLT
tpath = tabset.path
TabID_TBL.mutex.synchronize{
if TabID_TBL[tpath]
- TabID_TBL[tpath][id]? TabID_TBL[tpath]: id
+ TabID_TBL[tpath][id]? TabID_TBL[tpath][id]: id
else
id
end
@@ -48,6 +48,13 @@ module Tk::BLT
TabID_TBL.mutex.synchronize{
if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name]
obj = TabID_TBL[parent.path][name]
+ if pos
+ if pos.to_s == 'end'
+ obj.move_after('end')
+ else
+ obj.move_before(pos)
+ end
+ end
obj.configure if keys && ! keys.empty?
else
(obj = self.allocate).instance_eval{
@@ -69,9 +76,9 @@ module Tk::BLT
if pos
idx = tk_call(@tpath, 'index', '-name', @id)
if pos.to_s == 'end'
- tk_call(@tpath, idx, 'moveto', 'after', 'end')
+ tk_call(@tpath, 'move', idx, 'after', 'end')
else
- tk_call(@tpath, idx, 'moveto', 'before', pos)
+ tk_call(@tpath, 'move', idx, 'before', pos)
end
end
tk_call(@tpath, 'tab', 'configure', @id, keys)
@@ -80,11 +87,11 @@ module Tk::BLT
tk_call(@tpath, 'insert', pos, @id, keys)
end
else
+ pos = 'end' unless pos
TabsetTab_ID.mutex.synchronize{
@path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_)
TabsetTab_ID[1].succ!
}
- pos = 'end' unless pos
tk_call(@tpath, 'insert', pos, @id, keys)
end
end
@@ -173,10 +180,10 @@ module Tk::BLT
end
def perforation_highlight(mode)
- @t.perforation.highlight(self.index, mode)
+ @t.perforation_highlight(self.index, mode)
end
def perforation_invoke()
- @t.perforation.invoke(self.index)
+ @t.perforation_invoke(self.index)
end
def see()
@@ -335,19 +342,43 @@ module Tk::BLT
end
def get_tab(index)
- Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('get', tagindex(index)))
+ if (idx = tk_send_without_enc('get', tagindex(index))).empty?
+ nil
+ else
+ Tk::BLT::Tabset::Tab.id2obj(self, idx)
+ end
+ end
+ def get_tabobj(index)
+ if (idx = tk_send_without_enc('get', tagindex(index))).empty?
+ nil
+ else
+ Tk::BLT::Tabset::Tab.new(self, nil, name, {})
+ end
end
def index(str)
num_or_str(tk_send('index', str))
end
def index_name(tab)
- num_or_str(tk_send('index', '-mame', tagid(tab)))
+ num_or_str(tk_send('index', '-name', tagid(tab)))
end
def insert(pos, tab, keys={})
+ pos = 'end' if pos.nil?
Tk::BLT::Tabset::Tab.new(self, tagindex(pos), tagid(tab), keys)
end
+ def insert_tabs(pos, *tabs)
+ pos = 'end' if pos.nil?
+ if tabs[-1].kind_of?(Hash)
+ keys = tabs.pop
+ else
+ keys = {}
+ end
+ fail ArgumentError, 'no tabs is given' if tabs.empty?
+ tabs.map!{|tab| tagid(tab)}
+ tk_send('insert', tagindex(pos), *(tabs + [keys]))
+ tabs.collect{|tab| Tk::BLT::Tabset::Tab.new(self, nil, tagid(tab))}
+ end
def invoke(index)
tk_send('invoke', tagindex(index))
@@ -363,15 +394,31 @@ module Tk::BLT
end
def nearest(x, y)
- Tk::BLT::Tabset::Tab.id2obj(num_or_str(tk_send_without_enc('nearest', x, y)))
+ Tk::BLT::Tabset::Tab.id2obj(self, num_or_str(tk_send_without_enc('nearest', x, y)))
end
- def perforation_highlight(index, mode)
- tk_send('perforation', 'highlight', tagindex(index), mode)
+ def perforation_activate(mode)
+ tk_send('perforation', 'activate', mode)
self
end
- def perforation_invoke(index)
- tk_send('perforation', 'invoke', tagindex(index))
+ def perforation_highlight(index, *args)
+ if args.empty?
+ # index --> mode
+ tk_send('perforation', 'highlight', index)
+ elsif args.size == 1
+ # args[0] --> mode
+ tk_send('perforation', 'highlight', tagindex(index), args[0])
+ else # Error: call to get Tcl's error message
+ tk_send('perforation', 'highlight', tagindex(index), *args)
+ end
+ self
+ end
+ def perforation_invoke(index=nil)
+ if index
+ tk_send('perforation', 'invoke', tagindex(index))
+ else
+ tk_send('perforation', 'invoke')
+ end
end
def scan_mark(x, y)
@@ -397,14 +444,37 @@ module Tk::BLT
self
end
+ def tab_dockall
+ tk_send('tab', 'dockall')
+ self
+ end
+
def tab_names(pat=None)
simplelist(tk_send('tab', 'names', pat)).collect{|name|
- Tk::BLT::Tabset::Tab.id2obj(name)
+ Tk::BLT::Tabset::Tab.id2obj(self, name)
+ }
+ end
+
+ def tab_objs(pat=None)
+ simplelist(tk_send('tab', 'names', pat)).collect{|name|
+ Tk::BLT::Tabset::Tab.new(self, nil, name, {})
}
end
- def tab_tearoff(index, name=None)
- window(tk_send('tab', 'tearoff', tagindex(index), name))
+ def tab_ids(pat=None)
+ simplelist(tk_send('tab', 'names', pat))
+ end
+
+ def tab_pageheight
+ number(tk_send('tab', 'pageheight'))
+ end
+
+ def tab_pagewidth
+ number(tk_send('tab', 'pagewidth'))
+ end
+
+ def tab_tearoff(index, parent=None)
+ window(tk_send('tab', 'tearoff', tagindex(index), parent))
end
def xscrollcommand(cmd=Proc.new)
diff --git a/ext/tk/lib/tkextlib/blt/vector.rb b/ext/tk/lib/tkextlib/blt/vector.rb
index 76c12a24e8..97fb1b96ff 100644
--- a/ext/tk/lib/tkextlib/blt/vector.rb
+++ b/ext/tk/lib/tkextlib/blt/vector.rb
@@ -49,11 +49,11 @@ module Tk::BLT
size = size.join(':')
end
if size
- @id = INTERP._invoke('::blt::vector', 'create',
- "#auto(#{size})", *hash_kv(keys))
+ @id = TkCore::INTERP._invoke('::blt::vector', 'create',
+ "#auto(#{size})", *hash_kv(keys))
else
- @id = INTERP._invoke('::blt::vector', 'create',
- "#auto", *hash_kv(keys))
+ @id = TkCore::INTERP._invoke('::blt::vector', 'create',
+ "#auto", *hash_kv(keys))
end
TkVar_ID_TBL.mutex.synchronize{
@@ -68,7 +68,7 @@ module Tk::BLT
@trace_opts = nil
# teach Tk-ip that @id is global var
- INTERP._invoke_without_enc('global', @id)
+ TkCore::INTERP._invoke_without_enc('global', @id)
end
def destroy
@@ -250,7 +250,7 @@ module Tk::BLT
@trace_opts = nil
# teach Tk-ip that @id is global var
- INTERP._invoke_without_enc('global', @id)
+ TkCore::INTERP._invoke_without_enc('global', @id)
end
end
end
diff --git a/ext/tk/lib/tkextlib/version.rb b/ext/tk/lib/tkextlib/version.rb
index 434ed11a2e..82ed7ef542 100644
--- a/ext/tk/lib/tkextlib/version.rb
+++ b/ext/tk/lib/tkextlib/version.rb
@@ -2,5 +2,5 @@
# release date of tkextlib
#
module Tk
- Tkextlib_RELEASE_DATE = '2008-05-23'.freeze
+ Tkextlib_RELEASE_DATE = '2008-11-25'.freeze
end
diff --git a/file.c b/file.c
index 48808fd709..3d4c7d630c 100644
--- a/file.c
+++ b/file.c
@@ -1298,7 +1298,7 @@ rb_file_world_writable_p(VALUE obj, VALUE fname)
#ifdef S_IWOTH
struct stat st;
- if (rb_stat(fname, &st) < 0) return Qfalse;
+ if (rb_stat(fname, &st) < 0) return Qnil;
if ((st.st_mode & (S_IWOTH)) == S_IWOTH) {
return UINT2NUM(st.st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
}
diff --git a/lib/date.rb b/lib/date.rb
index 3da3d21f8b..2c9792562b 100644
--- a/lib/date.rb
+++ b/lib/date.rb
@@ -1470,7 +1470,9 @@ class Date
def hash() @ajd.hash end
# Return internal object state as a programmer-readable string.
- def inspect() format('#<%s: %s,%s,%s>', self.class, @ajd, @of, @sg) end
+ def inspect
+ format('#<%s: %s (%s,%s,%s)>', self.class, to_s, @ajd, @of, @sg)
+ end
# Return the date as a human-readable string.
#
diff --git a/lib/date/format.rb b/lib/date/format.rb
index c8bc10fbac..161cf85891 100644
--- a/lib/date/format.rb
+++ b/lib/date/format.rb
@@ -255,6 +255,7 @@ class Date
when 'j'; emit_n(yday, 3, f)
when 'k'; emit_a(hour, 2, f)
when 'L'
+ f[:p] = nil
w = f[:w] || 3
u = 10**w
emit_n((sec_fraction * u).floor, w, f)
@@ -262,6 +263,7 @@ class Date
when 'M', 'OM'; emit_n(min, 2, f)
when 'm', 'Om'; emit_n(mon, 2, f)
when 'N'
+ f[:p] = nil
w = f[:w] || 9
u = 10**w
emit_n((sec_fraction * u).floor, w, f)
diff --git a/lib/logger.rb b/lib/logger.rb
index 26d7d9d560..07699e7017 100644
--- a/lib/logger.rb
+++ b/lib/logger.rb
@@ -182,7 +182,13 @@ require 'monitor'
class Logger
VERSION = "1.2.6"
id, name, rev = %w$Id$
- ProgName = "#{name.chomp(",v")}/#{rev}"
+ if name
+ name = name.chomp(",v")
+ else
+ name = File.basename(__FILE__)
+ end
+ rev ||= "v#{VERSION}"
+ ProgName = "#{name}/#{rev}"
class Error < RuntimeError; end
class ShiftingError < Error; end
diff --git a/lib/minitest/unit.rb b/lib/minitest/unit.rb
index 460258cdf2..df6394a8eb 100644
--- a/lib/minitest/unit.rb
+++ b/lib/minitest/unit.rb
@@ -191,12 +191,12 @@ module MiniTest
assert caught, message(msg) { default }
end
- def capture_io
- require 'stringio'
+ def capture_io
+ require 'stringio'
- orig_stdout, orig_stderr = $stdout, $stderr
- captured_stdout, captured_stderr = StringIO.new, StringIO.new
- $stdout, $stderr = captured_stdout, captured_stderr
+ orig_stdout, orig_stderr = $stdout, $stderr
+ captured_stdout, captured_stderr = StringIO.new, StringIO.new
+ $stdout, $stderr = captured_stdout, captured_stderr
yield
diff --git a/lib/time.rb b/lib/time.rb
index 2d0a96117d..3555571f22 100644
--- a/lib/time.rb
+++ b/lib/time.rb
@@ -84,9 +84,27 @@ class Time
end
def zone_utc?(zone)
- # * -0000 means localtime. [RFC 2822]
- # * GMT is a localtime abbreviation in Europe/London, etc.
- if /\A(?:\+00:00|\+0000|\+00|UTC|Z|UT)\z/i =~ zone
+ # * +0000
+ # In RFC 2822, +0000 indicate a time zone at Universal Time.
+ # Europe/London is "a time zone at Universal Time" in Winter.
+ # Europe/Lisbon is "a time zone at Universal Time" in Winter.
+ # Atlantic/Reykjavik is "a time zone at Universal Time".
+ # Africa/Dakar is "a time zone at Universal Time".
+ # So +0000 is a local time such as Europe/London, etc.
+ # * GMT
+ # GMT is used as a time zone abbreviation in Europe/London,
+ # Africa/Dakar, etc.
+ # So it is a local time.
+ #
+ # * -0000, -00:00
+ # In RFC 2822, -0000 the date-time contains no information about the
+ # local time zone.
+ # In RFC 3339, -00:00 is used for the time in UTC is known,
+ # but the offset to local time is unknown.
+ # They are not appropriate for specific time zone such as
+ # Europe/London because time zone neutral,
+ # So -00:00 and -0000 are treated as UTC.
+ if /\A(?:-00:00|-0000|-00|UTC|Z|UT)\z/i =~ zone
true
else
false
@@ -409,7 +427,7 @@ class Time
#
# where zone is [+-]hhmm.
#
- # If +self+ is a UTC time, +0000 is used as zone.
+ # If +self+ is a UTC time, -0000 is used as zone.
#
def rfc2822
sprintf('%s, %02d %s %d %02d:%02d:%02d ',
@@ -417,7 +435,7 @@ class Time
day, RFC2822_MONTH_NAME[mon-1], year,
hour, min, sec) +
if utc?
- '+0000'
+ '-0000'
else
off = utc_offset
sign = off < 0 ? '-' : '+'
@@ -730,86 +748,98 @@ if __FILE__ == $0
def test_zone_0000
assert_equal(true, Time.parse("2000-01-01T00:00:00Z").utc?)
- assert_equal(true, Time.parse("2000-01-01T00:00:00+00:00").utc?)
- assert_equal(false, Time.parse("2000-01-01T00:00:00-00:00").utc?)
+ assert_equal(true, Time.parse("2000-01-01T00:00:00-00:00").utc?)
+ assert_equal(false, Time.parse("2000-01-01T00:00:00+00:00").utc?)
assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 GMT").utc?)
- assert_equal(true, Time.parse("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
- assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+ assert_equal(true, Time.parse("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+ assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 GMT").utc?)
- assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
- assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+ assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+ assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 UTC").utc?)
end
+ def test_rfc2822_utc_roundtrip_winter
+ t1 = Time.local(2008,12,1)
+ t2 = Time.rfc2822(t1.rfc2822)
+ assert_equal(t1.utc?, t2.utc?, "[ruby-dev:37126]")
+ end
+
+ def test_rfc2822_utc_roundtrip_summer
+ t1 = Time.local(2008,8,1)
+ t2 = Time.rfc2822(t1.rfc2822)
+ assert_equal(t1.utc?, t2.utc?)
+ end
+
def test_parse_leap_second
t = Time.utc(1998,12,31,23,59,59)
assert_equal(t, Time.parse("Thu Dec 31 23:59:59 UTC 1998"))
- assert_equal(t, Time.parse("Fri Dec 31 23:59:59 +0000 1998"));t.localtime
+ assert_equal(t, Time.parse("Fri Dec 31 23:59:59 -0000 1998"));t.localtime
assert_equal(t, Time.parse("Fri Jan 1 08:59:59 +0900 1999"))
assert_equal(t, Time.parse("Fri Jan 1 00:59:59 +0100 1999"))
- assert_equal(t, Time.parse("Fri Dec 31 23:59:59 -0000 1998"))
+ assert_equal(t, Time.parse("Fri Dec 31 23:59:59 +0000 1998"))
assert_equal(t, Time.parse("Fri Dec 31 22:59:59 -0100 1998"));t.utc
t += 1
assert_equal(t, Time.parse("Thu Dec 31 23:59:60 UTC 1998"))
- assert_equal(t, Time.parse("Fri Dec 31 23:59:60 +0000 1998"));t.localtime
+ assert_equal(t, Time.parse("Fri Dec 31 23:59:60 -0000 1998"));t.localtime
assert_equal(t, Time.parse("Fri Jan 1 08:59:60 +0900 1999"))
assert_equal(t, Time.parse("Fri Jan 1 00:59:60 +0100 1999"))
- assert_equal(t, Time.parse("Fri Dec 31 23:59:60 -0000 1998"))
+ assert_equal(t, Time.parse("Fri Dec 31 23:59:60 +0000 1998"))
assert_equal(t, Time.parse("Fri Dec 31 22:59:60 -0100 1998"));t.utc
t += 1 if t.sec == 60
assert_equal(t, Time.parse("Thu Jan 1 00:00:00 UTC 1999"))
- assert_equal(t, Time.parse("Fri Jan 1 00:00:00 +0000 1999"));t.localtime
+ assert_equal(t, Time.parse("Fri Jan 1 00:00:00 -0000 1999"));t.localtime
assert_equal(t, Time.parse("Fri Jan 1 09:00:00 +0900 1999"))
assert_equal(t, Time.parse("Fri Jan 1 01:00:00 +0100 1999"))
- assert_equal(t, Time.parse("Fri Jan 1 00:00:00 -0000 1999"))
+ assert_equal(t, Time.parse("Fri Jan 1 00:00:00 +0000 1999"))
assert_equal(t, Time.parse("Fri Dec 31 23:00:00 -0100 1998"))
end
def test_rfc2822_leap_second
t = Time.utc(1998,12,31,23,59,59)
assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:59 UTC"))
- assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 +0000"));t.localtime
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 -0000"));t.localtime
assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 08:59:59 +0900"))
assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:59:59 +0100"))
- assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 -0000"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 +0000"))
assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:59 -0100"));t.utc
t += 1
assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:60 UTC"))
- assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 +0000"));t.localtime
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 -0000"));t.localtime
assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 08:59:60 +0900"))
assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:59:60 +0100"))
- assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 -0000"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 +0000"))
assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:60 -0100"));t.utc
t += 1 if t.sec == 60
assert_equal(t, Time.rfc2822("Thu, 1 Jan 1999 00:00:00 UTC"))
- assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:00:00 +0000"));t.localtime
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:00:00 -0000"));t.localtime
assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 09:00:00 +0900"))
assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 01:00:00 +0100"))
- assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:00:00 -0000"))
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:00:00 +0000"))
assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:00:00 -0100"))
end
def test_xmlschema_leap_second
t = Time.utc(1998,12,31,23,59,59)
assert_equal(t, Time.xmlschema("1998-12-31T23:59:59Z"))
- assert_equal(t, Time.xmlschema("1998-12-31T23:59:59+00:00"));t.localtime
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:59-00:00"));t.localtime
assert_equal(t, Time.xmlschema("1999-01-01T08:59:59+09:00"))
assert_equal(t, Time.xmlschema("1999-01-01T00:59:59+01:00"))
- assert_equal(t, Time.xmlschema("1998-12-31T23:59:59-00:00"))
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:59+00:00"))
assert_equal(t, Time.xmlschema("1998-12-31T22:59:59-01:00"));t.utc
t += 1
assert_equal(t, Time.xmlschema("1998-12-31T23:59:60Z"))
- assert_equal(t, Time.xmlschema("1998-12-31T23:59:60+00:00"));t.localtime
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:60-00:00"));t.localtime
assert_equal(t, Time.xmlschema("1999-01-01T08:59:60+09:00"))
assert_equal(t, Time.xmlschema("1999-01-01T00:59:60+01:00"))
- assert_equal(t, Time.xmlschema("1998-12-31T23:59:60-00:00"))
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:60+00:00"))
assert_equal(t, Time.xmlschema("1998-12-31T22:59:60-01:00"));t.utc
t += 1 if t.sec == 60
assert_equal(t, Time.xmlschema("1999-01-01T00:00:00Z"))
- assert_equal(t, Time.xmlschema("1999-01-01T00:00:00+00:00"));t.localtime
+ assert_equal(t, Time.xmlschema("1999-01-01T00:00:00-00:00"));t.localtime
assert_equal(t, Time.xmlschema("1999-01-01T09:00:00+09:00"))
assert_equal(t, Time.xmlschema("1999-01-01T01:00:00+01:00"))
- assert_equal(t, Time.xmlschema("1999-01-01T00:00:00-00:00"))
+ assert_equal(t, Time.xmlschema("1999-01-01T00:00:00+00:00"))
assert_equal(t, Time.xmlschema("1998-12-31T23:00:00-01:00"))
end
diff --git a/node.h b/node.h
index 9fc5543520..423dc4156e 100644
--- a/node.h
+++ b/node.h
@@ -468,7 +468,7 @@ typedef struct RNode {
#define NOEX_UNDEF NOEX_NOSUPER
-#define NOEX_MODFUNC 0x10
+#define NOEX_MODFUNC 0x12
#define NOEX_SUPER 0x20
#define NOEX_VCALL 0x40
diff --git a/numeric.c b/numeric.c
index 2ae4c6f4e5..ec7034fc35 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1495,10 +1495,15 @@ num_step(int argc, VALUE *argv, VALUE from)
double err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
long i;
- if (err>0.5) err=0.5;
- n = floor(n + err) + 1;
- for (i=0; i<n; i++) {
- rb_yield(DBL2NUM(i*unit+beg));
+ if (isinf(unit)) {
+ if (unit > 0) rb_yield(DBL2NUM(beg));
+ }
+ else {
+ if (err>0.5) err=0.5;
+ n = floor(n + err) + 1;
+ for (i=0; i<n; i++) {
+ rb_yield(DBL2NUM(i*unit+beg));
+ }
}
}
else {
diff --git a/process.c b/process.c
index 5dadfd6852..5cd537d851 100644
--- a/process.c
+++ b/process.c
@@ -969,6 +969,8 @@ void rb_thread_reset_timer_thread(void);
(rb_enable_interrupt(), rb_thread_stop_timer_thread())
#define after_exec() \
(rb_thread_start_timer_thread(), rb_disable_interrupt())
+#define before_fork() before_exec()
+#define after_fork() after_exec()
#include "dln.h"
@@ -2275,7 +2277,8 @@ rb_fork(int *status, int (*chfunc)(void*), void *charg, VALUE fds)
}
}
#endif
- for (; (pid = fork()) < 0; prefork()) {
+ for (; before_fork(), (pid = fork()) < 0; prefork()) {
+ after_fork();
switch (errno) {
case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
@@ -2301,7 +2304,6 @@ rb_fork(int *status, int (*chfunc)(void*), void *charg, VALUE fds)
}
}
if (!pid) {
- rb_thread_reset_timer_thread();
if (chfunc) {
#ifdef FD_CLOEXEC
close(ep[0]);
@@ -2317,10 +2319,10 @@ rb_fork(int *status, int (*chfunc)(void*), void *charg, VALUE fds)
_exit(127);
#endif
}
- rb_thread_start_timer_thread();
}
+ after_fork();
#ifdef FD_CLOEXEC
- else if (chfunc) {
+ if (pid && chfunc) {
close(ep[1]);
if ((state = read(ep[0], &err, sizeof(err))) < 0) {
err = errno;
diff --git a/ruby.c b/ruby.c
index 949d7db648..e619f16b42 100644
--- a/ruby.c
+++ b/ruby.c
@@ -146,7 +146,7 @@ usage(const char *name)
"-T[level] turn on tainting checks",
"-v print version number, then turn on verbose mode",
"-w turn warnings on for your script",
- "-W[level] set warning level; 0=silence, 1=medium, 2=verbose (default)",
+ "-W[level] set warning level; 0=silence, 1=medium, 2=verbose (default for level)",
"-x[directory] strip off text before #!ruby line and perhaps cd to directory",
"--copyright print the copyright",
"--version print the version",
diff --git a/sampledriver/main.c b/sampledriver/main.c
index d4633d7faf..9e02eaf865 100644
--- a/sampledriver/main.c
+++ b/sampledriver/main.c
@@ -28,17 +28,17 @@
*/
#include <stdio.h>
-#include <ruby/mvm.h>
+#include <ruby/vm.h>
/* simple interpreter */
static int
-simple_driver_example(int argc, const char *argv[])
+simple_driver_example(int argc, char *argv[])
{
rb_vm_t *vm;
int err;
/* create VM with command line options */
- vm = ruby_vm_new(argc-1, argv+1);
+ vm = ruby_vm_new(argc, argv);
/* invoke this VM in current thread (synchronous) */
err = ruby_vm_run(vm);
@@ -121,13 +121,21 @@ multivm_driver_example(int argc, const char *argv[])
return 0;
}
+static const char *pl[] = {
+ "",
+ "-E", "utf-8",
+ "-e", "p [RUBY_PLATFORM, RUBY_VERSION, Encoding::default_external]",
+ NULL
+};
+
int
main(int argc, char *argv[])
{
- RUBY_INITSTACK();
+ RUBY_INIT_STACK;
ruby_sysinit(&argc, &argv); /* process level initialize */
if (1) {
+ simple_driver_example(sizeof(pl)/sizeof(pl[0])-1, (char **)pl);
return simple_driver_example(argc, argv);
}
else {
diff --git a/signal.c b/signal.c
index 7629807ebe..6bafa4669b 100644
--- a/signal.c
+++ b/signal.c
@@ -418,7 +418,40 @@ typedef RETSIGTYPE ruby_sigaction_t(int);
#endif
#ifdef POSIX_SIGNAL
-static int
+#if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
+#define USE_SIGALTSTACK
+#endif
+
+#ifdef USE_SIGALTSTACK
+#ifdef SIGSTKSZ
+#define ALT_STACK_SIZE (SIGSTKSZ*2)
+#else
+#define ALT_STACK_SIZE (4*1024)
+#endif
+/* alternate stack for SIGSEGV */
+static void
+register_sigaltstack(void)
+{
+ static void *altstack = 0;
+ stack_t newSS, oldSS;
+
+ if (altstack) return;
+
+ newSS.ss_sp = altstack = malloc(ALT_STACK_SIZE);
+ if (newSS.ss_sp == NULL)
+ /* should handle error */
+ rb_bug("register_sigaltstack. malloc error\n");
+ newSS.ss_size = ALT_STACK_SIZE;
+ newSS.ss_flags = 0;
+
+ if (sigaltstack(&newSS, &oldSS) < 0)
+ rb_bug("register_sigaltstack. error\n");
+}
+#else
+#define register_sigaltstack() ((void)0)
+#endif
+
+static void
ruby_sigaction(int signum, ruby_sigaction_t *handler, int altstack, struct sigaction *old)
{
struct sigaction sigact;
@@ -431,10 +464,6 @@ ruby_sigaction(int signum, ruby_sigaction_t *handler, int altstack, struct sigac
#ifdef SA_SIGINFO
sigact.sa_sigaction = handler;
sigact.sa_flags = SA_SIGINFO;
-#ifdef HAVE_SIGALTSTACK
- if (altstack)
- sigact.sa_flags |= SA_ONSTACK;
-#endif
#else
sigact.sa_handler = (sighandler_t)handler;
sigact.sa_flags = 0;
@@ -444,7 +473,12 @@ ruby_sigaction(int signum, ruby_sigaction_t *handler, int altstack, struct sigac
if (signum == SIGCHLD && (sighandler_t)handler == SIG_IGN)
sigact.sa_flags |= SA_NOCLDWAIT;
#endif
- return sigaction(signum, &sigact, old);
+#ifdef SA_ONSTACK
+ if (altstack)
+ sigact.sa_flags |= SA_ONSTACK;
+#endif
+ if (sigaction(signum, &sigact, old) < 0)
+ rb_bug("sigaction error.\n");
}
static sighandler_t
@@ -464,16 +498,7 @@ posix_signal(int signum, sighandler_t handler)
void
ruby_install_altstack(rb_thread_t *th)
{
-#ifdef HAVE_SIGALTSTACK
- stack_t sigstk;
- static void *segv_stack;
-
- if (!segv_stack) segv_stack = malloc(SIGSTKSZ * 2);
- sigstk.ss_sp = segv_stack;
- sigstk.ss_size = SIGSTKSZ;
- sigstk.ss_flags = 0;
- sigaltstack(&sigstk, 0);
-#endif
+ register_sigaltstack();
}
#else /* !POSIX_SIGNAL */
@@ -572,13 +597,12 @@ static int segv_received = 0;
static RETSIGTYPE
sigsegv(int sig SIGINFO_ARG)
{
-#ifdef HAVE_SIGALTSTACK
+#ifdef USE_SIGALTSTACK
int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
+ NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th));
rb_thread_t *th = GET_THREAD();
if (ruby_stack_overflowed_p(th, info->si_addr)) {
- th->errinfo = sysstack_error;
- rb_thread_raised_clear(th);
- TH_JUMP_TAG(th, TAG_RAISE);
+ ruby_thread_stack_overflow(th);
}
#endif
if (segv_received) {
@@ -715,6 +739,7 @@ default_handler(int sig)
#ifdef SIGSEGV
case SIGSEGV:
func = (sighandler_t)sigsegv;
+ register_sigaltstack();
break;
#endif
#ifdef SIGPIPE
@@ -1109,8 +1134,8 @@ Init_signal(void)
#endif
}
#ifdef SIGSEGV
+ register_sigaltstack();
ruby_sigaction(SIGSEGV, sigsegv, Qtrue, NULL);
- ruby_install_altstack(GET_THREAD());
#endif
#ifdef SIGPIPE
install_sighandler(SIGPIPE, sigpipe);
diff --git a/strftime.c b/strftime.c
index af66fa6377..79c5fe4fa8 100644
--- a/strftime.c
+++ b/strftime.c
@@ -270,22 +270,37 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
goto unknown; \
} while (0)
#define NEEDS(n) do if (s + (n) >= endp - 1) goto err; while (0)
+#define FILL_PADDING(i) do { \
+ if (!(flags & BIT_OF(LEFT)) && precision > i) { \
+ NEEDS(precision); \
+ memset(s, padding ? padding : ' ', precision - i); \
+ s += precision - i; \
+ } \
+ else { \
+ NEEDS(i); \
+ } \
+} while (0);
#define FMT(def_pad, def_prec, fmt, val) \
do { \
int l; \
if (precision <= 0) precision = (def_prec); \
if (flags & BIT_OF(LEFT)) precision = 1; \
l = snprintf(s, endp - s, \
- ((padding == '0' || (!padding && def_pad == '0')) ? "%.*"fmt : "%*"fmt), \
+ ((padding == '0' || (!padding && def_pad == '0')) ? "%0*"fmt : "%*"fmt), \
precision, val); \
if (l < 0) goto err; \
s += l; \
} while (0)
-#define STRFTIME(fmt, tm) \
+#define STRFTIME(fmt) \
do { \
- i = strftime(s, endp - s, fmt, tm); \
+ i = rb_strftime(s, endp - s, fmt, timeptr, ts, gmt); \
if (!i) return 0; \
- s += i; \
+ if (precision > i) {\
+ memmove(s + precision - i, s, i);\
+ memset(s, padding ? padding : ' ', precision - i); \
+ s += precision; \
+ }\
+ else s += i; \
} while (0)
if (*format != '%') {
@@ -300,14 +315,18 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
again:
switch (*++format) {
case '\0':
- *s++ = '%';
- goto out;
+ format--;
+ goto unknown;
case '%':
*s++ = '%';
continue;
case 'a': /* abbreviated weekday name */
+ if (flags & BIT_OF(CHCASE)) {
+ flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
+ flags |= BIT_OF(UPPER);
+ }
if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
i = 1, tp = "?";
else
@@ -315,6 +334,10 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
break;
case 'A': /* full weekday name */
+ if (flags & BIT_OF(CHCASE)) {
+ flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
+ flags |= BIT_OF(UPPER);
+ }
if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
i = 1, tp = "?";
else
@@ -325,6 +348,10 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
case 'h': /* abbreviated month name */
#endif
case 'b': /* abbreviated month name */
+ if (flags & BIT_OF(CHCASE)) {
+ flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
+ flags |= BIT_OF(UPPER);
+ }
if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
i = 1, tp = "?";
else
@@ -332,6 +359,10 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
break;
case 'B': /* full month name */
+ if (flags & BIT_OF(CHCASE)) {
+ flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
+ flags |= BIT_OF(UPPER);
+ }
if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
i = 1, tp = "?";
else
@@ -339,7 +370,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
break;
case 'c': /* appropriate date and time representation */
- STRFTIME("%a %b %e %H:%M:%S %Y", timeptr);
+ STRFTIME("%a %b %e %H:%M:%S %Y");
continue;
case 'd': /* day of the month, 01 - 31 */
@@ -378,7 +409,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
case 'p': /* AM or PM based on 12-hour clock */
case 'P': /* am or pm based on 12-hour clock */
if ((*format == 'p' && (flags & BIT_OF(CHCASE))) ||
- (*format == 'P' && !(flags & BIT_OF(CHCASE)))) {
+ (*format == 'P' && !(flags & (BIT_OF(CHCASE)|BIT_OF(UPPER))))) {
flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE));
flags |= BIT_OF(LOWER);
}
@@ -391,7 +422,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
break;
case 's':
- FMT(' ', 1, "d", (int) ts->tv_sec);
+ FMT('0', 1, "d", (int) ts->tv_sec);
continue;
case 'S': /* second, 00 - 60 */
@@ -405,7 +436,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
case 'w': /* weekday, Sunday == 0, 0 - 6 */
i = range(0, timeptr->tm_wday, 6);
- FMT('0', 0, "d", i);
+ FMT('0', 1, "d", i);
continue;
case 'W': /* week of year, Monday is first day of week */
@@ -413,11 +444,11 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
continue;
case 'x': /* appropriate date representation */
- STRFTIME("%m/%d/%y", timeptr);
+ STRFTIME("%m/%d/%y");
continue;
case 'X': /* appropriate time representation */
- STRFTIME("%H:%M:%S", timeptr);
+ STRFTIME("%H:%M:%S");
continue;
case 'y': /* year without a century, 00 - 99 */
@@ -426,7 +457,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
continue;
case 'Y': /* year with century */
- FMT('0', 0, "ld", 1900L + timeptr->tm_year);
+ FMT('0', 1, "ld", 1900L + timeptr->tm_year);
continue;
#ifdef MAILHEADER_EXT
@@ -540,17 +571,17 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
#ifdef SYSV_EXT
case 'n': /* same as \n */
- NEEDS(1);
+ FILL_PADDING(1);
*s++ = '\n';
continue;
case 't': /* same as \t */
- NEEDS(1);
+ FILL_PADDING(1);
*s++ = '\t';
continue;
case 'D': /* date as %m/%d/%y */
- STRFTIME("%m/%d/%y", timeptr);
+ STRFTIME("%m/%d/%y");
continue;
case 'e': /* day of month, blank padded */
@@ -558,15 +589,15 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
continue;
case 'r': /* time as %I:%M:%S %p */
- STRFTIME("%I:%M:%S %p", timeptr);
+ STRFTIME("%I:%M:%S %p");
continue;
case 'R': /* time as %H:%M */
- STRFTIME("%H:%M", timeptr);
+ STRFTIME("%H:%M");
continue;
case 'T': /* time as %H:%M:%S */
- STRFTIME("%H:%M:%S", timeptr);
+ STRFTIME("%H:%M:%S");
continue;
#endif
@@ -623,7 +654,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
case 'u':
/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
- FMT('0', 0, "d", timeptr->tm_wday == 0 ? 7 : timeptr->tm_wday);
+ FMT('0', 1, "d", timeptr->tm_wday == 0 ? 7 : timeptr->tm_wday);
continue;
#endif /* POSIX2_DATE */
@@ -648,7 +679,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
y = 1900L + timeptr->tm_year;
if (*format == 'G')
- FMT('0', 0, "ld", y);
+ FMT('0', 1, "ld", y);
else
FMT('0', 2, "ld", y % 100);
continue;
@@ -673,8 +704,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
{
long n = ts->tv_nsec;
- if (precision == 0) continue;
- if (precision < 0) {
+ if (precision <= 0) {
precision = w;
}
NEEDS(precision);
@@ -737,19 +767,15 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
default:
unknown:
- tp = sp;
i = format - sp + 1;
+ tp = sp;
+ precision = -1;
+ flags = 0;
+ padding = 0;
break;
}
if (i) {
- if (!(flags & BIT_OF(LEFT)) && precision > i) {
- NEEDS(precision);
- memset(s, padding ? padding : ' ', precision - i);
- s += precision - i;
- }
- else {
- NEEDS(i);
- }
+ FILL_PADDING(i);
memcpy(s, tp, i);
switch (flags & (BIT_OF(UPPER)|BIT_OF(LOWER))) {
case BIT_OF(UPPER):
@@ -768,7 +794,6 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept
}
}
}
-out:
if (s >= endp) {
goto err;
}
diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb
index 35edc7a44a..d129d93068 100644
--- a/test/bigdecimal/test_bigdecimal.rb
+++ b/test/bigdecimal/test_bigdecimal.rb
@@ -77,6 +77,7 @@ class TestBigDecimal < Test::Unit::TestCase
end
def test_exception_zerodivide
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
_test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { 1 / BigDecimal.new("0") }
_test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { -1 / BigDecimal.new("0") }
end
@@ -275,6 +276,7 @@ class TestBigDecimal < Test::Unit::TestCase
def test_finite_infinite_nan
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
x = BigDecimal.new("0")
assert_equal(true, x.finite?)
@@ -303,9 +305,9 @@ class TestBigDecimal < Test::Unit::TestCase
x = BigDecimal.new("0")
assert_kind_of(Integer, x.to_i)
assert_equal(0, x.to_i)
- assert_nil(( 1 / x).to_i)
- assert_nil((-1 / x).to_i)
- assert_nil(( 0 / x).to_i)
+ assert_raise(FloatDomainError){( 1 / x).to_i}
+ assert_raise(FloatDomainError){(-1 / x).to_i}
+ assert_raise(FloatDomainError) {( 0 / x).to_i}
x = BigDecimal.new("1")
assert_equal(1, x.to_i)
x = BigDecimal.new((2**100).to_s)
@@ -315,6 +317,7 @@ class TestBigDecimal < Test::Unit::TestCase
def test_to_f
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
x = BigDecimal.new("0")
assert_instance_of(Float, x.to_f)
@@ -616,6 +619,7 @@ class TestBigDecimal < Test::Unit::TestCase
def test_sign
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("0").sign)
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-0").sign)
diff --git a/test/cgi/test_cgi_session.rb b/test/cgi/test_cgi_session.rb
index c041b9cf59..d5120b933c 100644
--- a/test/cgi/test_cgi_session.rb
+++ b/test/cgi/test_cgi_session.rb
@@ -3,19 +3,18 @@ require 'cgi'
require 'cgi/session'
require 'cgi/session/pstore'
require 'stringio'
+require 'tmpdir'
class CGISessionTest < Test::Unit::TestCase
-
-
def setup
- FileUtils.rm(Dir::glob(File.dirname(__FILE__)+"/session_dir/*"))
+ @session_dir = Dir.mktmpdir('__test_dir__')+'/session_dir/'
+ FileUtils.mkdir_p @session_dir
end
-
def teardown
@environ.each do |key, val| ENV.delete(key) end
$stdout = STDOUT
-# FileUtils.rm(Dir::glob(File.dirname(__FILE__)+"/session_dir/*"))
+ FileUtils.rm_rf(@session_dir)
end
def test_cgi_session_filestore
@@ -31,7 +30,7 @@ class CGISessionTest < Test::Unit::TestCase
value2.force_encoding("SJIS") if RUBY_VERSION>="1.9"
ENV.update(@environ)
cgi = CGI.new
- session = CGI::Session.new(cgi,"tmpdir"=>File.dirname(__FILE__)+"/session_dir")
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
session["key1"]=value1
session["key2"]=value2
assert_equal(value1,session["key1"])
@@ -49,7 +48,7 @@ class CGISessionTest < Test::Unit::TestCase
}
ENV.update(@environ)
cgi = CGI.new
- session = CGI::Session.new(cgi,"tmpdir"=>File.dirname(__FILE__)+"/session_dir")
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
$stdout = StringIO.new
assert_equal(value1,session["key1"])
assert_equal(value2,session["key2"])
@@ -69,7 +68,7 @@ class CGISessionTest < Test::Unit::TestCase
value2.force_encoding("SJIS") if RUBY_VERSION>="1.9"
ENV.update(@environ)
cgi = CGI.new
- session = CGI::Session.new(cgi,"tmpdir"=>File.dirname(__FILE__)+"/session_dir","database_manager"=>CGI::Session::PStore)
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
session["key1"]=value1
session["key2"]=value2
assert_equal(value1,session["key1"])
@@ -87,7 +86,7 @@ class CGISessionTest < Test::Unit::TestCase
}
ENV.update(@environ)
cgi = CGI.new
- session = CGI::Session.new(cgi,"tmpdir"=>File.dirname(__FILE__)+"/session_dir","database_manager"=>CGI::Session::PStore)
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
$stdout = StringIO.new
assert_equal(value1,session["key1"])
assert_equal(value2,session["key2"])
diff --git a/test/date/test_date.rb b/test/date/test_date.rb
index de7e4838c3..f2be9e24c4 100644
--- a/test/date/test_date.rb
+++ b/test/date/test_date.rb
@@ -41,9 +41,9 @@ class TestDate < Test::Unit::TestCase
assert_instance_of(DateSub, DateSub.today)
assert_instance_of(DateTimeSub, DateTimeSub.now)
- assert_equal('#<DateSub: -1/2,0,2299161>', d.inspect)
+ assert_equal('#<DateSub: -4712-01-01 (-1/2,0,2299161)>', d.inspect)
assert_equal('-4712-01-01', d.to_s)
- assert_equal('#<DateTimeSub: -1/2,0,2299161>', dt.inspect)
+ assert_equal('#<DateTimeSub: -4712-01-01T00:00:00+00:00 (-1/2,0,2299161)>', dt.inspect)
assert_equal('-4712-01-01T00:00:00+00:00', dt.to_s)
d2 = d + 1
diff --git a/test/date/test_date_attr.rb b/test/date/test_date_attr.rb
index 2e71b5f501..5187d5d3e5 100644
--- a/test/date/test_date_attr.rb
+++ b/test/date/test_date_attr.rb
@@ -9,10 +9,10 @@ class TestDateAttr < Test::Unit::TestCase
[date, datetime].each_with_index do |d, i|
if i == 0
- assert_match(/\#<Date\d?: 4877807\/2,0,2299161>/,
+ assert_match(/\#<Date\d?: 1965-05-23 \(4877807\/2,0,2299161\)>/,
d.inspect)
else
- assert_match(/\#<DateTime\d?: 210721343519\/86400,0,2299161>/,
+ assert_match(/\#<DateTime\d?: 1965-05-23T22:31:59\+00:00 \(210721343519\/86400,0,2299161\)>/,
d.inspect)
end
diff --git a/test/date/test_date_strftime.rb b/test/date/test_date_strftime.rb
index 1a190f21cc..4131af3aab 100644
--- a/test/date/test_date_strftime.rb
+++ b/test/date/test_date_strftime.rb
@@ -299,6 +299,24 @@ class TestDateStrftime < Test::Unit::TestCase
assert_equal('-2000', d.strftime('%05Y'))
end
+ def test_strftime__gnuext_LN # coreutils
+ d = DateTime.parse('2008-11-25T00:11:22.0123456789')
+ assert_equal('012', d.strftime('%L'))
+ assert_equal('012', d.strftime('%0L'))
+ assert_equal('0', d.strftime('%1L'))
+ assert_equal('01', d.strftime('%2L'))
+ assert_equal('01234567890', d.strftime('%11L'))
+ assert_equal('01234567890', d.strftime('%011L'))
+ assert_equal('01234567890', d.strftime('%_11L'))
+ assert_equal('012345678', d.strftime('%N'))
+ assert_equal('012345678', d.strftime('%0N'))
+ assert_equal('0', d.strftime('%1N'))
+ assert_equal('01', d.strftime('%2N'))
+ assert_equal('01234567890', d.strftime('%11N'))
+ assert_equal('01234567890', d.strftime('%011N'))
+ assert_equal('01234567890', d.strftime('%_11N'))
+ end
+
def test_strftime__gnuext_z # coreutils
d = DateTime.parse('2006-08-08T23:15:33+09:08:07')
assert_equal('+0908', d.strftime('%z'))
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index d978050dc8..1546ce3287 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -27,6 +27,15 @@ class TestMethod < Test::Unit::TestCase
class Derived < Base
def foo() :derived end
end
+ class T
+ def initialize; end
+ def normal_method; end
+ end
+ module M
+ def func; end
+ module_function :func
+ def meth; end
+ end
def test_arity
assert_equal(0, method(:m0).arity)
@@ -221,4 +230,11 @@ class TestMethod < Test::Unit::TestCase
assert_raise(ArgumentError) { o.method(:foo=).call(1, 2, 3) }
assert_raise(ArgumentError) { o.method(:foo).call(1) }
end
+
+ def test_default_accessibility
+ assert T.public_instance_methods.include?(:normal_method), 'normal methods are public by default'
+ assert !T.public_instance_methods.include?(:initialize), '#initialize is private'
+ assert !M.public_instance_methods.include?(:func), 'module methods are private by default'
+ assert M.public_instance_methods.include?(:meth), 'normal methods are public by default'
+ end
end
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index 3a9b055802..a1a5bfc7fb 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -396,7 +396,7 @@ class TestTime < Test::Unit::TestCase
assert_equal("123456", t.strftime("%6N"))
assert_equal("123456789", t.strftime("%9N"))
assert_equal("1234567890", t.strftime("%10N"))
- assert_equal("", t.strftime("%0N"))
+ assert_equal("123456789", t.strftime("%0N"))
assert_equal("000", t.strftime("%3S"))
assert_equal("946684800", t.strftime("%s"))
assert_equal("946684800", t.utc.strftime("%s"))
@@ -444,5 +444,29 @@ class TestTime < Test::Unit::TestCase
assert_equal(" 2", t.strftime("%l"))
assert_equal("02", t.strftime("%0l"))
assert_equal(" 2", t.strftime("%_l"))
+
+ # [ruby-dev:37155]
+ t = Time.mktime(1970, 1, 18)
+ assert_equal("0", t.strftime("%w"))
+ assert_equal("7", t.strftime("%u"))
+
+ # [ruby-dev:37160]
+ assert_equal("\t", T2000.strftime("%t"))
+ assert_equal("\t", T2000.strftime("%0t"))
+ assert_equal("\t", T2000.strftime("%1t"))
+ assert_equal(" \t", T2000.strftime("%3t"))
+ assert_equal("00\t", T2000.strftime("%03t"))
+ assert_equal("\n", T2000.strftime("%n"))
+ assert_equal("\n", T2000.strftime("%0n"))
+ assert_equal("\n", T2000.strftime("%1n"))
+ assert_equal(" \n", T2000.strftime("%3n"))
+ assert_equal("00\n", T2000.strftime("%03n"))
+
+ # [ruby-dev:37162]
+ assert_equal("SAT", T2000.strftime("%#a"))
+ assert_equal("SATURDAY", T2000.strftime("%#A"))
+ assert_equal("JAN", T2000.strftime("%#b"))
+ assert_equal("JANUARY", T2000.strftime("%#B"))
+ assert_equal("JAN", T2000.strftime("%#h"))
end
end
diff --git a/test/yaml/test_yaml.rb b/test/yaml/test_yaml.rb
index ed94705fcf..837f34722f 100644
--- a/test/yaml/test_yaml.rb
+++ b/test/yaml/test_yaml.rb
@@ -1306,6 +1306,10 @@ EOY
raise "id collision in ordered map" if omap.to_yaml =~ /id\d+/
end
+ def test_date_out_of_range
+ assert_nothing_raised{YAML::load('1900-01-01T00:00:00+00:00')}
+ end
+
def test_normal_exit
YAML.load("2000-01-01 00:00:00.#{"0"*1000} +00:00\n")
# '[ruby-core:13735]'
diff --git a/thread.c b/thread.c
index 24a5aace64..879c793bca 100644
--- a/thread.c
+++ b/thread.c
@@ -1268,6 +1268,14 @@ rb_thread_signal_exit(void *thptr)
rb_thread_raise(2, argv, th->vm->main_thread);
}
+void
+ruby_thread_stack_overflow(rb_thread_t *th)
+{
+ th->errinfo = sysstack_error;
+ th->raised_flag = 0;
+ TH_JUMP_TAG(th, TAG_RAISE);
+}
+
int
rb_thread_set_raised(rb_thread_t *th)
{
@@ -2489,6 +2497,7 @@ rb_thread_reset_timer_thread(void)
void
rb_thread_start_timer_thread(void)
{
+ system_working = 1;
rb_thread_create_timer_thread();
}
diff --git a/version.h b/version.h
index 8f337afa7f..d299f0ced5 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2008-11-19"
+#define RUBY_RELEASE_DATE "2008-11-27"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20081119
+#define RUBY_RELEASE_CODE 20081127
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2008
#define RUBY_RELEASE_MONTH 11
-#define RUBY_RELEASE_DAY 19
+#define RUBY_RELEASE_DAY 27
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];
diff --git a/vm.c b/vm.c
index 434ebfb208..1cdff09522 100644
--- a/vm.c
+++ b/vm.c
@@ -1478,7 +1478,7 @@ thread_free(void *ptr)
rb_queue_destroy(&th->queue.message);
rb_queue_destroy(&th->queue.signal);
- if (th->vm->main_thread == th) {
+ if (th->vm && th->vm->main_thread == th) {
RUBY_GC_INFO("main thread\n");
}
else {