summaryrefslogtreecommitdiff
path: root/time.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-10-02 08:25:00 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-10-02 08:25:00 +0000
commit10c4bb29b237ccdbf99cfe8ef44c81de5a4a9018 (patch)
treecb4ae14994972651eed5db1489218c1a64663990 /time.c
parenta70a430f83a725decf1826aca35ebfca791e5b54 (diff)
* 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
Diffstat (limited to 'time.c')
-rw-r--r--time.c140
1 files changed, 96 insertions, 44 deletions
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
}