From 10c4bb29b237ccdbf99cfe8ef44c81de5a4a9018 Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 2 Oct 2003 08:25:00 +0000 Subject: * time.c (time_load): restore instance variables (if any) before loading from marshaled data. * time.c (time_mdump): new marshal dumper. _dump is still available for compatibility. * time.c (time_mload): new marshal loader. * marshal.c (w_object): preserve instance variables for objects with marshal_dump. * marshal.c (r_object0): restore instance variables before calling marshal_load. * error.c (rb_warn_m): always return nil. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 20 ++++++++ error.c | 9 ++-- eval.c | 14 +++++- marshal.c | 73 ++++++++++++++++++---------- misc/ruby-mode.el | 13 +++-- time.c | 140 +++++++++++++++++++++++++++++++++++++----------------- 6 files changed, 189 insertions(+), 80 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b260ddce3..8f7d291731 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Oct 2 17:22:37 2003 Yukihiro Matsumoto + + * time.c (time_load): restore instance variables (if any) before + loading from marshaled data. + Thu Oct 2 14:19:15 2003 Nobuyoshi Nakada * ext/iconv/iconv.c (iconv_fail): now yield erred substring, and @@ -37,6 +42,21 @@ Thu Oct 2 03:25:01 2003 NAKAMURA Usaku * eval.c (rb_thread_raise): prototype; avoid VC++ warning. +Thu Oct 2 01:37:34 2003 Yukihiro Matsumoto + + * time.c (time_mdump): new marshal dumper. _dump is still + available for compatibility. + + * time.c (time_mload): new marshal loader. + + * marshal.c (w_object): preserve instance variables for objects + with marshal_dump. + + * marshal.c (r_object0): restore instance variables before calling + marshal_load. + + * error.c (rb_warn_m): always return nil. + Thu Oct 2 01:32:46 2003 Yukihiro Matsumoto * eval.c (rb_f_block_given_p): real required condition is diff --git a/error.c b/error.c index 4cf39d0e1f..f2a3c8ba5f 100644 --- a/error.c +++ b/error.c @@ -166,10 +166,11 @@ static VALUE rb_warn_m(self, mesg) VALUE self, mesg; { - if (NIL_P(ruby_verbose)) return; - rb_io_write(rb_stderr, mesg); - rb_io_write(rb_stderr, rb_default_rs); - return mesg; + if (!NIL_P(ruby_verbose)) { + rb_io_write(rb_stderr, mesg); + rb_io_write(rb_stderr, rb_default_rs); + } + return Qnil; } void diff --git a/eval.c b/eval.c index 7726edb9e8..e14215f7a7 100644 --- a/eval.c +++ b/eval.c @@ -10187,7 +10187,19 @@ rb_catch(tag, func, data) VALUE (*func)(); VALUE data; { - return rb_iterate((VALUE(*)_((VALUE)))catch_i, ID2SYM(rb_intern(tag)), func, data); + int state; + VALUE val = Qnil; /* OK */ + + PUSH_TAG(PROT_NONE); + PUSH_SCOPE(); + if ((state = EXEC_TAG()) == 0) { + val = rb_iterate((VALUE(*)_((VALUE)))catch_i, ID2SYM(rb_intern(tag)), func, data); + } + POP_SCOPE(); + POP_TAG(); + if (state) JUMP_TAG(state); + + return val; } static VALUE diff --git a/marshal.c b/marshal.c index cf947e44d9..38d8516f09 100644 --- a/marshal.c +++ b/marshal.c @@ -482,11 +482,15 @@ w_object(obj, arg, limit) if (rb_respond_to(obj, s_mdump)) { VALUE v; + if (TYPE(obj) == T_OBJECT) { + w_byte(TYPE_IVAR, arg); + ivtbl = ROBJECT(obj)->iv_tbl; + } v = rb_funcall(obj, s_mdump, 0, 0); w_byte(TYPE_USRMARSHAL, arg); w_unique(rb_class2name(CLASS_OF(obj)), arg); w_object(v, arg, limit); - if (ivtbl) w_ivar(0, &c_arg); /* do not dump generic_ivar */ + if (ivtbl) w_ivar(ivtbl, &c_arg); return; } if (rb_respond_to(obj, s_dump)) { @@ -498,7 +502,7 @@ w_object(obj, arg, limit) } w_class(TYPE_USERDEF, obj, arg); w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg); - if (ivtbl) w_ivar(0, &c_arg); + if (ivtbl) w_ivar(ivtbl, &c_arg); return; } @@ -897,7 +901,7 @@ r_string(arg) } static VALUE -r_regist(v, arg) +r_entry(v, arg) VALUE v; struct load_arg *arg; { @@ -948,9 +952,10 @@ path2module(path) } static VALUE -r_object0(arg, proc) +r_object0(arg, proc, ivp) struct load_arg *arg; VALUE proc; + int *ivp; { VALUE v = Qnil; int type = r_byte(arg); @@ -966,15 +971,19 @@ r_object0(arg, proc) return v; case TYPE_IVAR: - v = r_object0(arg, 0); - r_ivar(v, arg); + { + int ivar = Qtrue; + + v = r_object0(arg, 0, &ivar); + if (ivar) r_ivar(v, arg); + } break; case TYPE_EXTENDED: { VALUE m = path2module(r_unique(arg)); - v = r_object0(arg, 0); + v = r_object0(arg, 0, 0); rb_extend_object(v, m); } break; @@ -986,7 +995,7 @@ r_object0(arg, proc) if (FL_TEST(c, FL_SINGLETON)) { rb_raise(rb_eTypeError, "singleton can't be loaded"); } - v = r_object0(arg, 0); + v = r_object0(arg, 0, 0); if (rb_special_const_p(v) || TYPE(v) == T_OBJECT || TYPE(v) == T_CLASS) { format_error: rb_raise(rb_eArgError, "dump format error (user class)"); @@ -1040,7 +1049,7 @@ r_object0(arg, proc) d = load_mantissa(d, e, RSTRING(str)->len - (e - ptr)); } v = rb_float_new(d); - r_regist(v, arg); + r_entry(v, arg); } break; @@ -1085,19 +1094,19 @@ r_object0(arg, proc) len--; } v = rb_big_norm((VALUE)big); - r_regist(v, arg); + r_entry(v, arg); } break; case TYPE_STRING: - v = r_regist(r_string(arg), arg); + v = r_entry(r_string(arg), arg); break; case TYPE_REGEXP: { volatile VALUE str = r_bytes(arg); int options = r_byte(arg); - v = r_regist(rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, options), arg); + v = r_entry(rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, options), arg); } break; @@ -1106,7 +1115,7 @@ r_object0(arg, proc) volatile long len = r_long(arg); /* gcc 2.7.2.3 -O2 bug?? */ v = rb_ary_new2(len); - r_regist(v, arg); + r_entry(v, arg); while (len--) { rb_ary_push(v, r_object(arg)); } @@ -1119,7 +1128,7 @@ r_object0(arg, proc) long len = r_long(arg); v = rb_hash_new(); - r_regist(v, arg); + r_entry(v, arg); while (len--) { VALUE key = r_object(arg); VALUE value = r_object(arg); @@ -1150,7 +1159,7 @@ r_object0(arg, proc) rb_ary_push(values, Qnil); } v = rb_struct_alloc(klass, values); - r_regist(v, arg); + r_entry(v, arg); for (i=0; iptr); - r_regist(v, arg); + r_entry(v, arg); } break; @@ -1246,7 +1267,7 @@ r_object0(arg, proc) volatile VALUE str = r_bytes(arg); v = path2class(RSTRING(str)->ptr); - r_regist(v, arg); + r_entry(v, arg); } break; @@ -1255,7 +1276,7 @@ r_object0(arg, proc) volatile VALUE str = r_bytes(arg); v = path2module(RSTRING(str)->ptr); - r_regist(v, arg); + r_entry(v, arg); } break; @@ -1280,7 +1301,7 @@ static VALUE r_object(arg) struct load_arg *arg; { - return r_object0(arg, arg->proc); + return r_object0(arg, arg->proc, 0); } static VALUE diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index 8d9df41a4a..7728734b39 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -685,15 +685,18 @@ The variable ruby-indent-level controls the amount of indentation. (setq bol (point)) (end-of-line) (skip-chars-backward " \t") - (let ((pos (point))) - (while (and (re-search-backward "#" bol t) - (ruby-special-char-p)) - (forward-char -1)) + (let (end (pos (point))) + (beginning-of-line) + (while (and (re-search-forward "#" pos t) + (setq end (1- (point))) + (ruby-special-char-p end)) + (setq end nil)) + (goto-char (or end pos)) (skip-chars-backward " \t") (and (setq state (ruby-parse-region parse-start (point))) (nth 0 state) - (setq begin (nth 1 state)) + (setq begin (cdr (nth 1 state))) (goto-char pos))) (or (bobp) (forward-char -1)) (and diff --git a/time.c b/time.c index d8e6bbca0e..5ae9b56f63 100644 --- a/time.c +++ b/time.c @@ -51,32 +51,47 @@ time_s_alloc(klass) obj = Data_Make_Struct(klass, struct time_object, 0, time_free, tobj); tobj->tm_got=0; - if (gettimeofday(&tobj->tv, 0) < 0) { - rb_sys_fail("gettimeofday"); - } + tobj->tv.tv_sec = 0; + tobj->tv.tv_usec = 0; return obj; } -static VALUE -time_s_now(klass) - VALUE klass; +static void +time_modify(time) + VALUE time; { - return rb_obj_alloc(klass); + rb_check_frozen(time); + if (!OBJ_TAINTED(time) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't modify Time"); } +static VALUE +time_init(time) + VALUE time; +{ + struct time_object *tobj; + + time_modify(time); + GetTimeval(time, tobj); + tobj->tm_got=0; + tobj->tv.tv_sec = 0; + tobj->tv.tv_usec = 0; + if (gettimeofday(&tobj->tv, 0) < 0) { + rb_sys_fail("gettimeofday"); + } + + return time; +} #define NDIV(x,y) (-(-((x)+1)/(y))-1) #define NMOD(x,y) ((y)-(-((x)+1)%(y))-1) -static VALUE -time_new_internal(klass, sec, usec) - VALUE klass; +void +time_overflow_p(sec, usec) time_t sec, usec; { - VALUE obj; time_t tmp; - struct time_object *tobj; if (usec >= 1000000) { /* usec positive overflow */ tmp = sec + usec / 1000000; @@ -98,13 +113,22 @@ time_new_internal(klass, sec, usec) if (sec < 0 || (sec == 0 && usec < 0)) rb_raise(rb_eArgError, "time must be positive"); #endif +} - obj = Data_Make_Struct(klass, struct time_object, 0, time_free, tobj); - tobj->tm_got = 0; +static VALUE +time_new_internal(klass, sec, usec) + VALUE klass; + time_t sec, usec; +{ + VALUE time = time_s_alloc(klass); + struct time_object *tobj; + + GetTimeval(time, tobj); + time_overflow_p(sec, usec); tobj->tv.tv_sec = sec; tobj->tv.tv_usec = usec; - return obj; + return time; } VALUE @@ -757,15 +781,6 @@ time_hash(time) return LONG2FIX(hash); } -static void -time_modify(time) - VALUE time; -{ - rb_check_frozen(time); - if (!OBJ_TAINTED(time) && rb_safe_level() >= 4) - rb_raise(rb_eSecurityError, "Insecure: can't modify Time"); -} - static VALUE time_init_copy(copy, time) VALUE copy, time; @@ -1293,12 +1308,9 @@ time_s_times(obj) } static VALUE -time_dump(argc, argv, time) - int argc; - VALUE *argv; +time_mdump(time) VALUE time; { - VALUE dummy; struct time_object *tobj; struct tm *tm; unsigned long p, s; @@ -1306,7 +1318,6 @@ time_dump(argc, argv, time) time_t t; int i; - rb_scan_args(argc, argv, "01", &dummy); GetTimeval(time, tobj); t = tobj->tv.tv_sec; @@ -1337,15 +1348,29 @@ time_dump(argc, argv, time) } static VALUE -time_load(klass, str) - VALUE klass, str; +time_dump(argc, argv, time) + int argc; + VALUE *argv; + VALUE time; +{ + VALUE dummy; + + rb_scan_args(argc, argv, "01", &dummy); + return time_mdump(time); +} + +static VALUE +time_mload(time, str) + VALUE time, str; { + struct time_object *tobj; unsigned long p, s; time_t sec, usec; unsigned char *buf; struct tm tm; int i; + time_modify(time); StringValue(str); buf = (unsigned char *)RSTRING(str)->ptr; if (RSTRING(str)->len != 8) { @@ -1361,21 +1386,43 @@ time_load(klass, str) } if ((p & (1<<31)) == 0) { - return time_new_internal(klass, p, s); + sec = p; + usec = s; } - p &= ~(1<<31); - tm.tm_year = (p >> 14) & 0x1ffff; - tm.tm_mon = (p >> 10) & 0xf; - tm.tm_mday = (p >> 5) & 0x1f; - tm.tm_hour = p & 0x1f; - tm.tm_min = (s >> 26) & 0x3f; - tm.tm_sec = (s >> 20) & 0x3f; - tm.tm_isdst = 0; + else { + p &= ~(1<<31); + tm.tm_year = (p >> 14) & 0x1ffff; + tm.tm_mon = (p >> 10) & 0xf; + tm.tm_mday = (p >> 5) & 0x1f; + tm.tm_hour = p & 0x1f; + tm.tm_min = (s >> 26) & 0x3f; + tm.tm_sec = (s >> 20) & 0x3f; + tm.tm_isdst = 0; + + sec = make_time_t(&tm, Qtrue); + usec = (time_t)(s & 0xfffff); + } + time_overflow_p(sec, usec); + + GetTimeval(time, tobj); + tobj->tm_got = 0; + tobj->tv.tv_sec = sec; + tobj->tv.tv_usec = usec; + return time; +} - sec = make_time_t(&tm, Qtrue); - usec = (time_t)(s & 0xfffff); +static VALUE +time_load(klass, str) + VALUE klass, str; +{ + VALUE time = time_s_alloc(klass); - return time_new_internal(klass, sec, usec); + if (FL_TEST(str, FL_EXIVAR)) { + rb_copy_generic_ivar(time, str); + FL_SET(time, FL_EXIVAR); + } + time_mload(time, str); + return time; } void @@ -1384,8 +1431,8 @@ Init_Time() rb_cTime = rb_define_class("Time", rb_cObject); rb_include_module(rb_cTime, rb_mComparable); - rb_define_singleton_method(rb_cTime, "now", time_s_now, 0); rb_define_alloc_func(rb_cTime, time_s_alloc); + rb_define_singleton_method(rb_cTime, "now", rb_class_new_instance, -1); rb_define_singleton_method(rb_cTime, "at", time_s_at, -1); rb_define_singleton_method(rb_cTime, "utc", time_s_mkutc, -1); rb_define_singleton_method(rb_cTime, "gm", time_s_mkutc, -1); @@ -1446,4 +1493,9 @@ Init_Time() /* methods for marshaling */ rb_define_method(rb_cTime, "_dump", time_dump, -1); rb_define_singleton_method(rb_cTime, "_load", time_load, 1); +#if 0 + /* Time will support marshal_dump and marshal_load in the future (1.9 maybe) */ + rb_define_method(rb_cTime, "marshal_dump", time_mdump, 0); + rb_define_method(rb_cTime, "marshal_load", time_mload, 1); +#endif } -- cgit v1.2.3