date 1.0.0 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/date/date_core.c CHANGED
@@ -51,18 +51,21 @@ static double positive_inf, negative_inf;
51
51
  #define f_add3(x,y,z) f_add(f_add(x, y), z)
52
52
  #define f_sub3(x,y,z) f_sub(f_sub(x, y), z)
53
53
 
54
- inline static VALUE
54
+ static VALUE date_initialize(int argc, VALUE *argv, VALUE self);
55
+ static VALUE datetime_initialize(int argc, VALUE *argv, VALUE self);
56
+
57
+ inline static int
55
58
  f_cmp(VALUE x, VALUE y)
56
59
  {
57
60
  if (FIXNUM_P(x) && FIXNUM_P(y)) {
58
61
  long c = FIX2LONG(x) - FIX2LONG(y);
59
62
  if (c > 0)
60
- c = 1;
63
+ return 1;
61
64
  else if (c < 0)
62
- c = -1;
63
- return INT2FIX(c);
65
+ return -1;
66
+ return 0;
64
67
  }
65
- return rb_funcall(x, id_cmp, 1, y);
68
+ return rb_cmpint(rb_funcallv(x, id_cmp, 1, &y), x, y);
66
69
  }
67
70
 
68
71
  inline static VALUE
@@ -94,7 +97,7 @@ f_ge_p(VALUE x, VALUE y)
94
97
  {
95
98
  if (FIXNUM_P(x) && FIXNUM_P(y))
96
99
  return f_boolcast(FIX2LONG(x) >= FIX2LONG(y));
97
- return rb_funcall(x, rb_intern(">="), 1, y);
100
+ return rb_funcall(x, id_ge_p, 1, y);
98
101
  }
99
102
 
100
103
  inline static VALUE
@@ -102,7 +105,7 @@ f_eqeq_p(VALUE x, VALUE y)
102
105
  {
103
106
  if (FIXNUM_P(x) && FIXNUM_P(y))
104
107
  return f_boolcast(FIX2LONG(x) == FIX2LONG(y));
105
- return rb_funcall(x, rb_intern("=="), 1, y);
108
+ return rb_funcall(x, id_eqeq_p, 1, y);
106
109
  }
107
110
 
108
111
  inline static VALUE
@@ -236,11 +239,8 @@ f_negative_p(VALUE x)
236
239
  struct SimpleDateData
237
240
  {
238
241
  unsigned flags;
239
- VALUE nth; /* not always canonicalized */
240
242
  int jd; /* as utc */
241
- /* df is zero */
242
- /* sf is zero */
243
- /* of is zero */
243
+ VALUE nth; /* not always canonicalized */
244
244
  date_sg_t sg; /* 2298874..2426355 or -/+oo -- at most 22 bits */
245
245
  /* decoded as utc=local */
246
246
  int year; /* truncated */
@@ -259,11 +259,8 @@ struct SimpleDateData
259
259
  struct ComplexDateData
260
260
  {
261
261
  unsigned flags;
262
- VALUE nth; /* not always canonicalized */
263
262
  int jd; /* as utc */
264
- int df; /* as utc, in secs */
265
- VALUE sf; /* in nano secs */
266
- int of; /* in secs */
263
+ VALUE nth; /* not always canonicalized */
267
264
  date_sg_t sg; /* 2298874..2426355 or -/+oo -- at most 22 bits */
268
265
  /* decoded as local */
269
266
  int year; /* truncated */
@@ -277,6 +274,9 @@ struct ComplexDateData
277
274
  /* packed civil */
278
275
  unsigned pc;
279
276
  #endif
277
+ int df; /* as utc, in secs */
278
+ int of; /* in secs */
279
+ VALUE sf; /* in nano secs */
280
280
  };
281
281
 
282
282
  union DateData {
@@ -315,31 +315,31 @@ canon(VALUE x)
315
315
 
316
316
  #ifndef USE_PACK
317
317
  #define set_to_simple(obj, x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
318
- {\
318
+ do {\
319
319
  RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth)); \
320
320
  (x)->jd = _jd;\
321
321
  (x)->sg = (date_sg_t)(_sg);\
322
322
  (x)->year = _year;\
323
323
  (x)->mon = _mon;\
324
324
  (x)->mday = _mday;\
325
- (x)->flags = _flags;\
326
- }
325
+ (x)->flags = (_flags) & ~COMPLEX_DAT;\
326
+ } while (0)
327
327
  #else
328
328
  #define set_to_simple(obj, x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
329
- {\
329
+ do {\
330
330
  RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth)); \
331
331
  (x)->jd = _jd;\
332
332
  (x)->sg = (date_sg_t)(_sg);\
333
333
  (x)->year = _year;\
334
334
  (x)->pc = PACK2(_mon, _mday);\
335
- (x)->flags = _flags;\
336
- }
335
+ (x)->flags = (_flags) & ~COMPLEX_DAT;\
336
+ } while (0)
337
337
  #endif
338
338
 
339
339
  #ifndef USE_PACK
340
340
  #define set_to_complex(obj, x, _nth, _jd ,_df, _sf, _of, _sg,\
341
341
  _year, _mon, _mday, _hour, _min, _sec, _flags) \
342
- {\
342
+ do {\
343
343
  RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth));\
344
344
  (x)->jd = _jd;\
345
345
  (x)->df = _df;\
@@ -352,12 +352,12 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
352
352
  (x)->hour = _hour;\
353
353
  (x)->min = _min;\
354
354
  (x)->sec = _sec;\
355
- (x)->flags = _flags;\
356
- }
355
+ (x)->flags = (_flags) | COMPLEX_DAT;\
356
+ } while (0)
357
357
  #else
358
358
  #define set_to_complex(obj, x, _nth, _jd ,_df, _sf, _of, _sg,\
359
359
  _year, _mon, _mday, _hour, _min, _sec, _flags) \
360
- {\
360
+ do {\
361
361
  RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth));\
362
362
  (x)->jd = _jd;\
363
363
  (x)->df = _df;\
@@ -366,13 +366,13 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
366
366
  (x)->sg = (date_sg_t)(_sg);\
367
367
  (x)->year = _year;\
368
368
  (x)->pc = PACK5(_mon, _mday, _hour, _min, _sec);\
369
- (x)->flags = _flags;\
370
- }
369
+ (x)->flags = (_flags) | COMPLEX_DAT;\
370
+ } while (0)
371
371
  #endif
372
372
 
373
373
  #ifndef USE_PACK
374
374
  #define copy_simple_to_complex(obj, x, y) \
375
- {\
375
+ do {\
376
376
  RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
377
377
  (x)->jd = (y)->jd;\
378
378
  (x)->df = 0;\
@@ -386,10 +386,10 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
386
386
  (x)->min = 0;\
387
387
  (x)->sec = 0;\
388
388
  (x)->flags = (y)->flags;\
389
- }
389
+ } while (0)
390
390
  #else
391
391
  #define copy_simple_to_complex(obj, x, y) \
392
- {\
392
+ do {\
393
393
  RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
394
394
  (x)->jd = (y)->jd;\
395
395
  (x)->df = 0;\
@@ -399,12 +399,12 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
399
399
  (x)->year = (y)->year;\
400
400
  (x)->pc = PACK5(EX_MON((y)->pc), EX_MDAY((y)->pc), 0, 0, 0);\
401
401
  (x)->flags = (y)->flags;\
402
- }
402
+ } while (0)
403
403
  #endif
404
404
 
405
405
  #ifndef USE_PACK
406
406
  #define copy_complex_to_simple(obj, x, y) \
407
- {\
407
+ do {\
408
408
  RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
409
409
  (x)->jd = (y)->jd;\
410
410
  (x)->sg = (date_sg_t)((y)->sg);\
@@ -412,17 +412,17 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
412
412
  (x)->mon = (y)->mon;\
413
413
  (x)->mday = (y)->mday;\
414
414
  (x)->flags = (y)->flags;\
415
- }
415
+ } while (0)
416
416
  #else
417
417
  #define copy_complex_to_simple(obj, x, y) \
418
- {\
418
+ do {\
419
419
  RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
420
420
  (x)->jd = (y)->jd;\
421
421
  (x)->sg = (date_sg_t)((y)->sg);\
422
422
  (x)->year = (y)->year;\
423
423
  (x)->pc = PACK2(EX_MON((y)->pc), EX_MDAY((y)->pc));\
424
424
  (x)->flags = (y)->flags;\
425
- }
425
+ } while (0)
426
426
  #endif
427
427
 
428
428
  /* base */
@@ -1109,7 +1109,7 @@ m_virtual_sg(union DateData *x)
1109
1109
  }
1110
1110
 
1111
1111
  #define canonicalize_jd(_nth, _jd) \
1112
- {\
1112
+ do {\
1113
1113
  if (_jd < 0) {\
1114
1114
  _nth = f_sub(_nth, INT2FIX(1));\
1115
1115
  _jd += CM_PERIOD;\
@@ -1118,7 +1118,7 @@ m_virtual_sg(union DateData *x)
1118
1118
  _nth = f_add(_nth, INT2FIX(1));\
1119
1119
  _jd -= CM_PERIOD;\
1120
1120
  }\
1121
- }
1121
+ } while (0)
1122
1122
 
1123
1123
  inline static void
1124
1124
  canonicalize_s_jd(VALUE obj, union DateData *x)
@@ -1928,13 +1928,13 @@ m_sec(union DateData *x)
1928
1928
  }
1929
1929
 
1930
1930
  #define decode_offset(of,s,h,m)\
1931
- {\
1931
+ do {\
1932
1932
  int a;\
1933
1933
  s = (of < 0) ? '-' : '+';\
1934
1934
  a = (of < 0) ? -of : of;\
1935
1935
  h = a / HOUR_IN_SECONDS;\
1936
1936
  m = a % HOUR_IN_SECONDS / MINUTE_IN_SECONDS;\
1937
- }
1937
+ } while (0)
1938
1938
 
1939
1939
  static VALUE
1940
1940
  of2str(int of)
@@ -2333,6 +2333,9 @@ VALUE date_zone_to_diff(VALUE);
2333
2333
  static int
2334
2334
  offset_to_sec(VALUE vof, int *rof)
2335
2335
  {
2336
+ int try_rational = 1;
2337
+
2338
+ again:
2336
2339
  switch (TYPE(vof)) {
2337
2340
  case T_FIXNUM:
2338
2341
  {
@@ -2359,10 +2362,11 @@ offset_to_sec(VALUE vof, int *rof)
2359
2362
  default:
2360
2363
  expect_numeric(vof);
2361
2364
  vof = f_to_r(vof);
2362
- #ifdef CANONICALIZATION_FOR_MATHN
2363
- if (!k_rational_p(vof))
2364
- return offset_to_sec(vof, rof);
2365
- #endif
2365
+ if (!k_rational_p(vof)) {
2366
+ if (!try_rational) Check_Type(vof, T_RATIONAL);
2367
+ try_rational = 0;
2368
+ goto again;
2369
+ }
2366
2370
  /* fall through */
2367
2371
  case T_RATIONAL:
2368
2372
  {
@@ -2371,17 +2375,10 @@ offset_to_sec(VALUE vof, int *rof)
2371
2375
 
2372
2376
  vs = day_to_sec(vof);
2373
2377
 
2374
- #ifdef CANONICALIZATION_FOR_MATHN
2375
2378
  if (!k_rational_p(vs)) {
2376
- if (!FIXNUM_P(vs))
2377
- return 0;
2378
- n = FIX2LONG(vs);
2379
- if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS)
2380
- return 0;
2381
- *rof = (int)n;
2382
- return 1;
2379
+ vn = vs;
2380
+ goto rounded;
2383
2381
  }
2384
- #endif
2385
2382
  vn = rb_rational_num(vs);
2386
2383
  vd = rb_rational_den(vs);
2387
2384
 
@@ -2391,6 +2388,7 @@ offset_to_sec(VALUE vof, int *rof)
2391
2388
  vn = f_round(vs);
2392
2389
  if (!f_eqeq_p(vn, vs))
2393
2390
  rb_warning("fraction of offset is ignored");
2391
+ rounded:
2394
2392
  if (!FIXNUM_P(vn))
2395
2393
  return 0;
2396
2394
  n = FIX2LONG(vn);
@@ -2420,12 +2418,12 @@ offset_to_sec(VALUE vof, int *rof)
2420
2418
  /* date */
2421
2419
 
2422
2420
  #define valid_sg(sg) \
2423
- {\
2421
+ do {\
2424
2422
  if (!c_valid_start_p(sg)) {\
2425
2423
  sg = 0;\
2426
2424
  rb_warning("invalid start is ignored");\
2427
2425
  }\
2428
- }
2426
+ } while (0)
2429
2427
 
2430
2428
  static VALUE
2431
2429
  valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
@@ -2968,7 +2966,7 @@ d_simple_new_internal(VALUE klass,
2968
2966
 
2969
2967
  obj = TypedData_Make_Struct(klass, struct SimpleDateData,
2970
2968
  &d_lite_type, dat);
2971
- set_to_simple(obj, dat, nth, jd, sg, y, m, d, flags & ~COMPLEX_DAT);
2969
+ set_to_simple(obj, dat, nth, jd, sg, y, m, d, flags);
2972
2970
 
2973
2971
  assert(have_jd_p(dat) || have_civil_p(dat));
2974
2972
 
@@ -2990,7 +2988,7 @@ d_complex_new_internal(VALUE klass,
2990
2988
  obj = TypedData_Make_Struct(klass, struct ComplexDateData,
2991
2989
  &d_lite_type, dat);
2992
2990
  set_to_complex(obj, dat, nth, jd, df, sf, of, sg,
2993
- y, m, d, h, min, s, flags | COMPLEX_DAT);
2991
+ y, m, d, h, min, s, flags);
2994
2992
 
2995
2993
  assert(have_jd_p(dat) || have_civil_p(dat));
2996
2994
  assert(have_df_p(dat) || have_time_p(dat));
@@ -3207,47 +3205,47 @@ s_trunc(VALUE s, VALUE *fr)
3207
3205
  }
3208
3206
 
3209
3207
  #define num2num_with_frac(s,n) \
3210
- {\
3208
+ do {\
3211
3209
  s = s##_trunc(v##s, &fr);\
3212
3210
  if (f_nonzero_p(fr)) {\
3213
3211
  if (argc > n)\
3214
3212
  rb_raise(rb_eArgError, "invalid fraction");\
3215
3213
  fr2 = fr;\
3216
3214
  }\
3217
- }
3215
+ } while (0)
3218
3216
 
3219
3217
  #define num2int_with_frac(s,n) \
3220
- {\
3218
+ do {\
3221
3219
  s = NUM2INT(s##_trunc(v##s, &fr));\
3222
3220
  if (f_nonzero_p(fr)) {\
3223
3221
  if (argc > n)\
3224
3222
  rb_raise(rb_eArgError, "invalid fraction");\
3225
3223
  fr2 = fr;\
3226
3224
  }\
3227
- }
3225
+ } while (0)
3228
3226
 
3229
3227
  #define canon24oc() \
3230
- {\
3228
+ do {\
3231
3229
  if (rh == 24) {\
3232
3230
  rh = 0;\
3233
3231
  fr2 = f_add(fr2, INT2FIX(1));\
3234
3232
  }\
3235
- }
3233
+ } while (0)
3236
3234
 
3237
3235
  #define add_frac() \
3238
- {\
3236
+ do {\
3239
3237
  if (f_nonzero_p(fr2))\
3240
3238
  ret = d_lite_plus(ret, fr2);\
3241
- }
3239
+ } while (0)
3242
3240
 
3243
3241
  #define val2sg(vsg,dsg) \
3244
- {\
3242
+ do {\
3245
3243
  dsg = NUM2DBL(vsg);\
3246
3244
  if (!c_valid_start_p(dsg)) {\
3247
3245
  dsg = DEFAULT_SG;\
3248
3246
  rb_warning("invalid start is ignored");\
3249
3247
  }\
3250
- }
3248
+ } while (0)
3251
3249
 
3252
3250
  static VALUE d_lite_plus(VALUE, VALUE);
3253
3251
 
@@ -3384,10 +3382,21 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
3384
3382
  */
3385
3383
  static VALUE
3386
3384
  date_s_civil(int argc, VALUE *argv, VALUE klass)
3385
+ {
3386
+ return date_initialize(argc, argv, d_lite_s_alloc_simple(klass));
3387
+ }
3388
+
3389
+ static VALUE
3390
+ date_initialize(int argc, VALUE *argv, VALUE self)
3387
3391
  {
3388
3392
  VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
3389
3393
  int m, d;
3390
3394
  double sg;
3395
+ struct SimpleDateData *dat = rb_check_typeddata(self, &d_lite_type);
3396
+
3397
+ if (!simple_dat_p(dat)) {
3398
+ rb_raise(rb_eTypeError, "Date expected");
3399
+ }
3391
3400
 
3392
3401
  rb_scan_args(argc, argv, "04", &vy, &vm, &vd, &vsg);
3393
3402
 
@@ -3417,11 +3426,7 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
3417
3426
  &rm, &rd))
3418
3427
  rb_raise(rb_eArgError, "invalid date");
3419
3428
 
3420
- ret = d_simple_new_internal(klass,
3421
- nth, 0,
3422
- sg,
3423
- ry, rm, rd,
3424
- HAVE_CIVIL);
3429
+ set_to_simple(self, dat, nth, 0, sg, ry, rm, rd, HAVE_CIVIL);
3425
3430
  }
3426
3431
  else {
3427
3432
  VALUE nth;
@@ -3433,12 +3438,9 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
3433
3438
  &ns))
3434
3439
  rb_raise(rb_eArgError, "invalid date");
3435
3440
 
3436
- ret = d_simple_new_internal(klass,
3437
- nth, rjd,
3438
- sg,
3439
- ry, rm, rd,
3440
- HAVE_JD | HAVE_CIVIL);
3441
+ set_to_simple(self, dat, nth, rjd, sg, ry, rm, rd, HAVE_JD | HAVE_CIVIL);
3441
3442
  }
3443
+ ret = self;
3442
3444
  add_frac();
3443
3445
  return ret;
3444
3446
  }
@@ -3679,9 +3681,11 @@ date_s_today(int argc, VALUE *argv, VALUE klass)
3679
3681
  #define ref_hash0(k) rb_hash_aref(hash, k)
3680
3682
  #define del_hash0(k) rb_hash_delete(hash, k)
3681
3683
 
3682
- #define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
3683
- #define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
3684
- #define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
3684
+ #define sym(x) ID2SYM(rb_intern(x""))
3685
+
3686
+ #define set_hash(k,v) set_hash0(sym(k), v)
3687
+ #define ref_hash(k) ref_hash0(sym(k))
3688
+ #define del_hash(k) del_hash0(sym(k))
3685
3689
 
3686
3690
  static VALUE
3687
3691
  rt_rewrite_frags(VALUE hash)
@@ -3718,8 +3722,6 @@ rt_rewrite_frags(VALUE hash)
3718
3722
  return hash;
3719
3723
  }
3720
3724
 
3721
- #define sym(x) ID2SYM(rb_intern(x))
3722
-
3723
3725
  static VALUE d_lite_year(VALUE);
3724
3726
  static VALUE d_lite_wday(VALUE);
3725
3727
  static VALUE d_lite_jd(VALUE);
@@ -4290,12 +4292,40 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass)
4290
4292
 
4291
4293
  VALUE date__parse(VALUE str, VALUE comp);
4292
4294
 
4295
+ static size_t
4296
+ get_limit(VALUE opt)
4297
+ {
4298
+ if (!NIL_P(opt)) {
4299
+ VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit")));
4300
+ if (NIL_P(limit)) return SIZE_MAX;
4301
+ return NUM2SIZET(limit);
4302
+ }
4303
+ return 128;
4304
+ }
4305
+
4306
+ static void
4307
+ check_limit(VALUE str, VALUE opt)
4308
+ {
4309
+ if (NIL_P(str)) return;
4310
+ if (SYMBOL_P(str)) str = rb_sym2str(str);
4311
+
4312
+ StringValue(str);
4313
+ size_t slen = RSTRING_LEN(str);
4314
+ size_t limit = get_limit(opt);
4315
+ if (slen > limit) {
4316
+ rb_raise(rb_eArgError,
4317
+ "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit);
4318
+ }
4319
+ }
4320
+
4293
4321
  static VALUE
4294
4322
  date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4295
4323
  {
4296
- VALUE vstr, vcomp, hash;
4324
+ VALUE vstr, vcomp, hash, opt;
4297
4325
 
4298
- rb_scan_args(argc, argv, "11", &vstr, &vcomp);
4326
+ rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt);
4327
+ if (!NIL_P(opt)) argc--;
4328
+ check_limit(vstr, opt);
4299
4329
  StringValue(vstr);
4300
4330
  if (!rb_enc_str_asciicompat_p(vstr))
4301
4331
  rb_raise(rb_eArgError,
@@ -4320,7 +4350,7 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4320
4350
 
4321
4351
  /*
4322
4352
  * call-seq:
4323
- * Date._parse(string[, comp=true]) -> hash
4353
+ * Date._parse(string[, comp=true], limit: 128) -> hash
4324
4354
  *
4325
4355
  * Parses the given representation of date and time, and returns a
4326
4356
  * hash of parsed elements. This method does not function as a
@@ -4331,6 +4361,10 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4331
4361
  * it full.
4332
4362
  *
4333
4363
  * Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3}
4364
+ *
4365
+ * Raise an ArgumentError when the string length is longer than _limit_.
4366
+ * You can stop this check by passing `limit: nil`, but note that
4367
+ * it may take a long time to parse.
4334
4368
  */
4335
4369
  static VALUE
4336
4370
  date_s__parse(int argc, VALUE *argv, VALUE klass)
@@ -4340,7 +4374,7 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
4340
4374
 
4341
4375
  /*
4342
4376
  * call-seq:
4343
- * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]]) -> date
4377
+ * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]], limit: 128) -> date
4344
4378
  *
4345
4379
  * Parses the given representation of date and time, and creates a
4346
4380
  * date object. This method does not function as a validator.
@@ -4352,13 +4386,18 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
4352
4386
  * Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...>
4353
4387
  * Date.parse('20010203') #=> #<Date: 2001-02-03 ...>
4354
4388
  * Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...>
4389
+ *
4390
+ * Raise an ArgumentError when the string length is longer than _limit_.
4391
+ * You can stop this check by passing `limit: nil`, but note that
4392
+ * it may take a long time to parse.
4355
4393
  */
4356
4394
  static VALUE
4357
4395
  date_s_parse(int argc, VALUE *argv, VALUE klass)
4358
4396
  {
4359
- VALUE str, comp, sg;
4397
+ VALUE str, comp, sg, opt;
4360
4398
 
4361
- rb_scan_args(argc, argv, "03", &str, &comp, &sg);
4399
+ rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
4400
+ if (!NIL_P(opt)) argc--;
4362
4401
 
4363
4402
  switch (argc) {
4364
4403
  case 0:
@@ -4370,11 +4409,12 @@ date_s_parse(int argc, VALUE *argv, VALUE klass)
4370
4409
  }
4371
4410
 
4372
4411
  {
4373
- VALUE argv2[2], hash;
4374
-
4375
- argv2[0] = str;
4376
- argv2[1] = comp;
4377
- hash = date_s__parse(2, argv2, klass);
4412
+ int argc2 = 2;
4413
+ VALUE argv2[3];
4414
+ argv2[0] = str;
4415
+ argv2[1] = comp;
4416
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4417
+ VALUE hash = date_s__parse(argc2, argv2, klass);
4378
4418
  return d_new_by_frags(klass, hash, sg);
4379
4419
  }
4380
4420
  }
@@ -4388,19 +4428,28 @@ VALUE date__jisx0301(VALUE);
4388
4428
 
4389
4429
  /*
4390
4430
  * call-seq:
4391
- * Date._iso8601(string) -> hash
4431
+ * Date._iso8601(string, limit: 128) -> hash
4392
4432
  *
4393
4433
  * Returns a hash of parsed elements.
4434
+ *
4435
+ * Raise an ArgumentError when the string length is longer than _limit_.
4436
+ * You can stop this check by passing `limit: nil`, but note that
4437
+ * it may take a long time to parse.
4394
4438
  */
4395
4439
  static VALUE
4396
- date_s__iso8601(VALUE klass, VALUE str)
4440
+ date_s__iso8601(int argc, VALUE *argv, VALUE klass)
4397
4441
  {
4442
+ VALUE str, opt;
4443
+
4444
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4445
+ check_limit(str, opt);
4446
+
4398
4447
  return date__iso8601(str);
4399
4448
  }
4400
4449
 
4401
4450
  /*
4402
4451
  * call-seq:
4403
- * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY]) -> date
4452
+ * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
4404
4453
  *
4405
4454
  * Creates a new Date object by parsing from a string according to
4406
4455
  * some typical ISO 8601 formats.
@@ -4408,13 +4457,18 @@ date_s__iso8601(VALUE klass, VALUE str)
4408
4457
  * Date.iso8601('2001-02-03') #=> #<Date: 2001-02-03 ...>
4409
4458
  * Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...>
4410
4459
  * Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...>
4460
+ *
4461
+ * Raise an ArgumentError when the string length is longer than _limit_.
4462
+ * You can stop this check by passing `limit: nil`, but note that
4463
+ * it may take a long time to parse.
4411
4464
  */
4412
4465
  static VALUE
4413
4466
  date_s_iso8601(int argc, VALUE *argv, VALUE klass)
4414
4467
  {
4415
- VALUE str, sg;
4468
+ VALUE str, sg, opt;
4416
4469
 
4417
- rb_scan_args(argc, argv, "02", &str, &sg);
4470
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4471
+ if (!NIL_P(opt)) argc--;
4418
4472
 
4419
4473
  switch (argc) {
4420
4474
  case 0:
@@ -4424,38 +4478,56 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass)
4424
4478
  }
4425
4479
 
4426
4480
  {
4427
- VALUE hash = date_s__iso8601(klass, str);
4481
+ int argc2 = 1;
4482
+ VALUE argv2[2];
4483
+ argv2[0] = str;
4484
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4485
+ VALUE hash = date_s__iso8601(argc2, argv2, klass);
4428
4486
  return d_new_by_frags(klass, hash, sg);
4429
4487
  }
4430
4488
  }
4431
4489
 
4432
4490
  /*
4433
4491
  * call-seq:
4434
- * Date._rfc3339(string) -> hash
4492
+ * Date._rfc3339(string, limit: 128) -> hash
4435
4493
  *
4436
4494
  * Returns a hash of parsed elements.
4495
+ *
4496
+ * Raise an ArgumentError when the string length is longer than _limit_.
4497
+ * You can stop this check by passing `limit: nil`, but note that
4498
+ * it may take a long time to parse.
4437
4499
  */
4438
4500
  static VALUE
4439
- date_s__rfc3339(VALUE klass, VALUE str)
4501
+ date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
4440
4502
  {
4503
+ VALUE str, opt;
4504
+
4505
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4506
+ check_limit(str, opt);
4507
+
4441
4508
  return date__rfc3339(str);
4442
4509
  }
4443
4510
 
4444
4511
  /*
4445
4512
  * call-seq:
4446
- * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> date
4513
+ * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> date
4447
4514
  *
4448
4515
  * Creates a new Date object by parsing from a string according to
4449
4516
  * some typical RFC 3339 formats.
4450
4517
  *
4451
4518
  * Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...>
4519
+ *
4520
+ * Raise an ArgumentError when the string length is longer than _limit_.
4521
+ * You can stop this check by passing `limit: nil`, but note that
4522
+ * it may take a long time to parse.
4452
4523
  */
4453
4524
  static VALUE
4454
4525
  date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
4455
4526
  {
4456
- VALUE str, sg;
4527
+ VALUE str, sg, opt;
4457
4528
 
4458
- rb_scan_args(argc, argv, "02", &str, &sg);
4529
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4530
+ if (!NIL_P(opt)) argc--;
4459
4531
 
4460
4532
  switch (argc) {
4461
4533
  case 0:
@@ -4465,38 +4537,56 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
4465
4537
  }
4466
4538
 
4467
4539
  {
4468
- VALUE hash = date_s__rfc3339(klass, str);
4540
+ int argc2 = 1;
4541
+ VALUE argv2[2];
4542
+ argv2[0] = str;
4543
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4544
+ VALUE hash = date_s__rfc3339(argc2, argv2, klass);
4469
4545
  return d_new_by_frags(klass, hash, sg);
4470
4546
  }
4471
4547
  }
4472
4548
 
4473
4549
  /*
4474
4550
  * call-seq:
4475
- * Date._xmlschema(string) -> hash
4551
+ * Date._xmlschema(string, limit: 128) -> hash
4476
4552
  *
4477
4553
  * Returns a hash of parsed elements.
4554
+ *
4555
+ * Raise an ArgumentError when the string length is longer than _limit_.
4556
+ * You can stop this check by passing `limit: nil`, but note that
4557
+ * it may take a long time to parse.
4478
4558
  */
4479
4559
  static VALUE
4480
- date_s__xmlschema(VALUE klass, VALUE str)
4560
+ date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
4481
4561
  {
4562
+ VALUE str, opt;
4563
+
4564
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4565
+ check_limit(str, opt);
4566
+
4482
4567
  return date__xmlschema(str);
4483
4568
  }
4484
4569
 
4485
4570
  /*
4486
4571
  * call-seq:
4487
- * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY]) -> date
4572
+ * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
4488
4573
  *
4489
4574
  * Creates a new Date object by parsing from a string according to
4490
4575
  * some typical XML Schema formats.
4491
4576
  *
4492
4577
  * Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...>
4578
+ *
4579
+ * Raise an ArgumentError when the string length is longer than _limit_.
4580
+ * You can stop this check by passing `limit: nil`, but note that
4581
+ * it may take a long time to parse.
4493
4582
  */
4494
4583
  static VALUE
4495
4584
  date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
4496
4585
  {
4497
- VALUE str, sg;
4586
+ VALUE str, sg, opt;
4498
4587
 
4499
- rb_scan_args(argc, argv, "02", &str, &sg);
4588
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4589
+ if (!NIL_P(opt)) argc--;
4500
4590
 
4501
4591
  switch (argc) {
4502
4592
  case 0:
@@ -4506,41 +4596,58 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
4506
4596
  }
4507
4597
 
4508
4598
  {
4509
- VALUE hash = date_s__xmlschema(klass, str);
4599
+ int argc2 = 1;
4600
+ VALUE argv2[2];
4601
+ argv2[0] = str;
4602
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4603
+ VALUE hash = date_s__xmlschema(argc2, argv2, klass);
4510
4604
  return d_new_by_frags(klass, hash, sg);
4511
4605
  }
4512
4606
  }
4513
4607
 
4514
4608
  /*
4515
4609
  * call-seq:
4516
- * Date._rfc2822(string) -> hash
4517
- * Date._rfc822(string) -> hash
4610
+ * Date._rfc2822(string, limit: 128) -> hash
4611
+ * Date._rfc822(string, limit: 128) -> hash
4518
4612
  *
4519
4613
  * Returns a hash of parsed elements.
4614
+ *
4615
+ * Raise an ArgumentError when the string length is longer than _limit_.
4616
+ * You can stop this check by passing `limit: nil`, but note that
4617
+ * it may take a long time to parse.
4520
4618
  */
4521
4619
  static VALUE
4522
- date_s__rfc2822(VALUE klass, VALUE str)
4620
+ date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
4523
4621
  {
4622
+ VALUE str, opt;
4623
+
4624
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4625
+ check_limit(str, opt);
4626
+
4524
4627
  return date__rfc2822(str);
4525
4628
  }
4526
4629
 
4527
4630
  /*
4528
4631
  * call-seq:
4529
- * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date
4530
- * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date
4632
+ * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date
4633
+ * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date
4531
4634
  *
4532
4635
  * Creates a new Date object by parsing from a string according to
4533
4636
  * some typical RFC 2822 formats.
4534
4637
  *
4535
4638
  * Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
4536
4639
  * #=> #<Date: 2001-02-03 ...>
4640
+ *
4641
+ * Raise an ArgumentError when the string length is longer than _limit_.
4642
+ * You can stop this check by passing `limit: nil`, but note that
4643
+ * it may take a long time to parse.
4537
4644
  */
4538
4645
  static VALUE
4539
4646
  date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
4540
4647
  {
4541
- VALUE str, sg;
4648
+ VALUE str, sg, opt;
4542
4649
 
4543
- rb_scan_args(argc, argv, "02", &str, &sg);
4650
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4544
4651
 
4545
4652
  switch (argc) {
4546
4653
  case 0:
@@ -4550,39 +4657,56 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
4550
4657
  }
4551
4658
 
4552
4659
  {
4553
- VALUE hash = date_s__rfc2822(klass, str);
4660
+ int argc2 = 1;
4661
+ VALUE argv2[2];
4662
+ argv2[0] = str;
4663
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4664
+ VALUE hash = date_s__rfc2822(argc2, argv2, klass);
4554
4665
  return d_new_by_frags(klass, hash, sg);
4555
4666
  }
4556
4667
  }
4557
4668
 
4558
4669
  /*
4559
4670
  * call-seq:
4560
- * Date._httpdate(string) -> hash
4671
+ * Date._httpdate(string, limit: 128) -> hash
4561
4672
  *
4562
4673
  * Returns a hash of parsed elements.
4674
+ *
4675
+ * Raise an ArgumentError when the string length is longer than _limit_.
4676
+ * You can stop this check by passing `limit: nil`, but note that
4677
+ * it may take a long time to parse.
4563
4678
  */
4564
4679
  static VALUE
4565
- date_s__httpdate(VALUE klass, VALUE str)
4680
+ date_s__httpdate(int argc, VALUE *argv, VALUE klass)
4566
4681
  {
4682
+ VALUE str, opt;
4683
+
4684
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4685
+ check_limit(str, opt);
4686
+
4567
4687
  return date__httpdate(str);
4568
4688
  }
4569
4689
 
4570
4690
  /*
4571
4691
  * call-seq:
4572
- * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY]) -> date
4692
+ * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY], limit: 128) -> date
4573
4693
  *
4574
4694
  * Creates a new Date object by parsing from a string according to
4575
4695
  * some RFC 2616 format.
4576
4696
  *
4577
4697
  * Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT')
4578
4698
  * #=> #<Date: 2001-02-03 ...>
4699
+ *
4700
+ * Raise an ArgumentError when the string length is longer than _limit_.
4701
+ * You can stop this check by passing `limit: nil`, but note that
4702
+ * it may take a long time to parse.
4579
4703
  */
4580
4704
  static VALUE
4581
4705
  date_s_httpdate(int argc, VALUE *argv, VALUE klass)
4582
4706
  {
4583
- VALUE str, sg;
4707
+ VALUE str, sg, opt;
4584
4708
 
4585
- rb_scan_args(argc, argv, "02", &str, &sg);
4709
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4586
4710
 
4587
4711
  switch (argc) {
4588
4712
  case 0:
@@ -4592,38 +4716,60 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass)
4592
4716
  }
4593
4717
 
4594
4718
  {
4595
- VALUE hash = date_s__httpdate(klass, str);
4719
+ int argc2 = 1;
4720
+ VALUE argv2[2];
4721
+ argv2[0] = str;
4722
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4723
+ VALUE hash = date_s__httpdate(argc2, argv2, klass);
4596
4724
  return d_new_by_frags(klass, hash, sg);
4597
4725
  }
4598
4726
  }
4599
4727
 
4600
4728
  /*
4601
4729
  * call-seq:
4602
- * Date._jisx0301(string) -> hash
4730
+ * Date._jisx0301(string, limit: 128) -> hash
4603
4731
  *
4604
4732
  * Returns a hash of parsed elements.
4733
+ *
4734
+ * Raise an ArgumentError when the string length is longer than _limit_.
4735
+ * You can stop this check by passing `limit: nil`, but note that
4736
+ * it may take a long time to parse.
4605
4737
  */
4606
4738
  static VALUE
4607
- date_s__jisx0301(VALUE klass, VALUE str)
4739
+ date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
4608
4740
  {
4741
+ VALUE str, opt;
4742
+
4743
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4744
+ check_limit(str, opt);
4745
+
4609
4746
  return date__jisx0301(str);
4610
4747
  }
4611
4748
 
4612
4749
  /*
4613
4750
  * call-seq:
4614
- * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY]) -> date
4751
+ * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
4615
4752
  *
4616
4753
  * Creates a new Date object by parsing from a string according to
4617
4754
  * some typical JIS X 0301 formats.
4618
4755
  *
4619
4756
  * Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
4757
+ *
4758
+ * For no-era year, legacy format, Heisei is assumed.
4759
+ *
4760
+ * Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...>
4761
+ *
4762
+ * Raise an ArgumentError when the string length is longer than _limit_.
4763
+ * You can stop this check by passing `limit: nil`, but note that
4764
+ * it may take a long time to parse.
4620
4765
  */
4621
4766
  static VALUE
4622
4767
  date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
4623
4768
  {
4624
- VALUE str, sg;
4769
+ VALUE str, sg, opt;
4625
4770
 
4626
- rb_scan_args(argc, argv, "02", &str, &sg);
4771
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4772
+ if (!NIL_P(opt)) argc--;
4627
4773
 
4628
4774
  switch (argc) {
4629
4775
  case 0:
@@ -4633,7 +4779,11 @@ date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
4633
4779
  }
4634
4780
 
4635
4781
  {
4636
- VALUE hash = date_s__jisx0301(klass, str);
4782
+ int argc2 = 1;
4783
+ VALUE argv2[2];
4784
+ argv2[0] = str;
4785
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4786
+ VALUE hash = date_s__jisx0301(argc2, argv2, klass);
4637
4787
  return d_new_by_frags(klass, hash, sg);
4638
4788
  }
4639
4789
  }
@@ -4691,14 +4841,14 @@ dup_obj_as_complex(VALUE self)
4691
4841
  }
4692
4842
 
4693
4843
  #define val2off(vof,iof) \
4694
- {\
4844
+ do {\
4695
4845
  if (!offset_to_sec(vof, &iof)) {\
4696
4846
  iof = 0;\
4697
4847
  rb_warning("invalid offset is ignored");\
4698
4848
  }\
4699
- }
4849
+ } while (0)
4700
4850
 
4701
- #ifndef NDEBUG
4851
+ #if 0
4702
4852
  static VALUE
4703
4853
  d_lite_initialize(int argc, VALUE *argv, VALUE self)
4704
4854
  {
@@ -4751,7 +4901,7 @@ d_lite_initialize(int argc, VALUE *argv, VALUE self)
4751
4901
  "cannot load complex into simple");
4752
4902
 
4753
4903
  set_to_complex(self, &dat->c, nth, rjd, df, sf, of, sg,
4754
- 0, 0, 0, 0, 0, 0, HAVE_JD | HAVE_DF | COMPLEX_DAT);
4904
+ 0, 0, 0, 0, 0, 0, HAVE_JD | HAVE_DF);
4755
4905
  }
4756
4906
  }
4757
4907
  return self;
@@ -4770,8 +4920,28 @@ d_lite_initialize_copy(VALUE copy, VALUE date)
4770
4920
  {
4771
4921
  get_d2(copy, date);
4772
4922
  if (simple_dat_p(bdat)) {
4773
- adat->s = bdat->s;
4774
- adat->s.flags &= ~COMPLEX_DAT;
4923
+ if (simple_dat_p(adat)) {
4924
+ adat->s = bdat->s;
4925
+ }
4926
+ else {
4927
+ adat->c.flags = bdat->s.flags | COMPLEX_DAT;
4928
+ adat->c.nth = bdat->s.nth;
4929
+ adat->c.jd = bdat->s.jd;
4930
+ adat->c.df = 0;
4931
+ adat->c.sf = INT2FIX(0);
4932
+ adat->c.of = 0;
4933
+ adat->c.sg = bdat->s.sg;
4934
+ adat->c.year = bdat->s.year;
4935
+ #ifndef USE_PACK
4936
+ adat->c.mon = bdat->s.mon;
4937
+ adat->c.mday = bdat->s.mday;
4938
+ adat->c.hour = bdat->s.hour;
4939
+ adat->c.min = bdat->s.min;
4940
+ adat->c.sec = bdat->s.sec;
4941
+ #else
4942
+ adat->c.pc = bdat->s.pc;
4943
+ #endif
4944
+ }
4775
4945
  }
4776
4946
  else {
4777
4947
  if (!complex_dat_p(adat))
@@ -4779,7 +4949,6 @@ d_lite_initialize_copy(VALUE copy, VALUE date)
4779
4949
  "cannot load complex into simple");
4780
4950
 
4781
4951
  adat->c = bdat->c;
4782
- adat->c.flags |= COMPLEX_DAT;
4783
4952
  }
4784
4953
  }
4785
4954
  return copy;
@@ -5513,8 +5682,10 @@ d_lite_new_offset(int argc, VALUE *argv, VALUE self)
5513
5682
  static VALUE
5514
5683
  d_lite_plus(VALUE self, VALUE other)
5515
5684
  {
5685
+ int try_rational = 1;
5516
5686
  get_d1(self);
5517
5687
 
5688
+ again:
5518
5689
  switch (TYPE(other)) {
5519
5690
  case T_FIXNUM:
5520
5691
  {
@@ -5724,18 +5895,21 @@ d_lite_plus(VALUE self, VALUE other)
5724
5895
  default:
5725
5896
  expect_numeric(other);
5726
5897
  other = f_to_r(other);
5727
- #ifdef CANONICALIZATION_FOR_MATHN
5728
- if (!k_rational_p(other))
5729
- return d_lite_plus(self, other);
5730
- #endif
5898
+ if (!k_rational_p(other)) {
5899
+ if (!try_rational) Check_Type(other, T_RATIONAL);
5900
+ try_rational = 0;
5901
+ goto again;
5902
+ }
5731
5903
  /* fall through */
5732
5904
  case T_RATIONAL:
5733
5905
  {
5734
5906
  VALUE nth, sf, t;
5735
5907
  int jd, df, s;
5736
5908
 
5737
- if (wholenum_p(other))
5738
- return d_lite_plus(self, rb_rational_num(other));
5909
+ if (wholenum_p(other)) {
5910
+ other = rb_rational_num(other);
5911
+ goto again;
5912
+ }
5739
5913
 
5740
5914
  if (f_positive_p(other))
5741
5915
  s = +1;
@@ -6154,6 +6328,7 @@ static VALUE
6154
6328
  d_lite_step(int argc, VALUE *argv, VALUE self)
6155
6329
  {
6156
6330
  VALUE limit, step, date;
6331
+ int c;
6157
6332
 
6158
6333
  rb_scan_args(argc, argv, "11", &limit, &step);
6159
6334
 
@@ -6168,25 +6343,22 @@ d_lite_step(int argc, VALUE *argv, VALUE self)
6168
6343
  RETURN_ENUMERATOR(self, argc, argv);
6169
6344
 
6170
6345
  date = self;
6171
- switch (FIX2INT(f_cmp(step, INT2FIX(0)))) {
6172
- case -1:
6346
+ c = f_cmp(step, INT2FIX(0));
6347
+ if (c < 0) {
6173
6348
  while (FIX2INT(d_lite_cmp(date, limit)) >= 0) {
6174
6349
  rb_yield(date);
6175
6350
  date = d_lite_plus(date, step);
6176
6351
  }
6177
- break;
6178
- case 0:
6352
+ }
6353
+ else if (c == 0) {
6179
6354
  while (1)
6180
6355
  rb_yield(date);
6181
- break;
6182
- case 1:
6356
+ }
6357
+ else /* if (c > 0) */ {
6183
6358
  while (FIX2INT(d_lite_cmp(date, limit)) <= 0) {
6184
6359
  rb_yield(date);
6185
6360
  date = d_lite_plus(date, step);
6186
6361
  }
6187
- break;
6188
- default:
6189
- abort();
6190
6362
  }
6191
6363
  return self;
6192
6364
  }
@@ -6241,10 +6413,10 @@ cmp_gen(VALUE self, VALUE other)
6241
6413
  get_d1(self);
6242
6414
 
6243
6415
  if (k_numeric_p(other))
6244
- return f_cmp(m_ajd(dat), other);
6416
+ return INT2FIX(f_cmp(m_ajd(dat), other));
6245
6417
  else if (k_date_p(other))
6246
- return f_cmp(m_ajd(dat), f_ajd(other));
6247
- return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
6418
+ return INT2FIX(f_cmp(m_ajd(dat), f_ajd(other)));
6419
+ return rb_num_coerce_cmp(self, other, id_cmp);
6248
6420
  }
6249
6421
 
6250
6422
  static VALUE
@@ -6373,7 +6545,7 @@ equal_gen(VALUE self, VALUE other)
6373
6545
  return f_eqeq_p(m_real_local_jd(dat), other);
6374
6546
  else if (k_date_p(other))
6375
6547
  return f_eqeq_p(m_real_local_jd(dat), f_jd(other));
6376
- return rb_num_coerce_cmp(self, other, rb_intern("=="));
6548
+ return rb_num_coerce_cmp(self, other, id_eqeq_p);
6377
6549
  }
6378
6550
 
6379
6551
  /*
@@ -6471,7 +6643,7 @@ d_lite_to_s(VALUE self)
6471
6643
  static VALUE
6472
6644
  mk_inspect_raw(union DateData *x, VALUE klass)
6473
6645
  {
6474
- char flags[5];
6646
+ char flags[6];
6475
6647
 
6476
6648
  flags[0] = (x->flags & COMPLEX_DAT) ? 'C' : 'S';
6477
6649
  flags[1] = (x->flags & HAVE_JD) ? 'j' : '-';
@@ -6637,7 +6809,9 @@ tmx_m_of(union DateData *x)
6637
6809
  static char *
6638
6810
  tmx_m_zone(union DateData *x)
6639
6811
  {
6640
- return RSTRING_PTR(m_zone(x));
6812
+ VALUE zone = m_zone(x);
6813
+ /* TODO: fix potential dangling pointer */
6814
+ return RSTRING_PTR(zone);
6641
6815
  }
6642
6816
 
6643
6817
  static const struct tmx_funcs tmx_funcs = {
@@ -6787,7 +6961,7 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
6787
6961
  *
6788
6962
  * %M - Minute of the hour (00..59)
6789
6963
  *
6790
- * %S - Second of the minute (00..59)
6964
+ * %S - Second of the minute (00..60)
6791
6965
  *
6792
6966
  * %L - Millisecond of the second (000..999)
6793
6967
  * %N - Fractional seconds digits, default is 9 digits (nanosecond)
@@ -7020,10 +7194,14 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y)
7020
7194
  c = 'S';
7021
7195
  s = 1925;
7022
7196
  }
7023
- else {
7197
+ else if (d < 2458605) {
7024
7198
  c = 'H';
7025
7199
  s = 1988;
7026
7200
  }
7201
+ else {
7202
+ c = 'R';
7203
+ s = 2018;
7204
+ }
7027
7205
  snprintf(fmt, size, "%c%02ld" ".%%m.%%d", c, FIX2INT(y) - s);
7028
7206
  return fmt;
7029
7207
  }
@@ -7101,6 +7279,10 @@ d_lite_marshal_dump(VALUE self)
7101
7279
  static VALUE
7102
7280
  d_lite_marshal_load(VALUE self, VALUE a)
7103
7281
  {
7282
+ VALUE nth, sf;
7283
+ int jd, df, of;
7284
+ double sg;
7285
+
7104
7286
  get_d1(self);
7105
7287
 
7106
7288
  rb_check_frozen(self);
@@ -7113,63 +7295,33 @@ d_lite_marshal_load(VALUE self, VALUE a)
7113
7295
  case 2: /* 1.6.x */
7114
7296
  case 3: /* 1.8.x, 1.9.2 */
7115
7297
  {
7116
- VALUE ajd, of, sg, nth, sf;
7117
- int jd, df, rof;
7118
- double rsg;
7119
-
7298
+ VALUE ajd, vof, vsg;
7120
7299
 
7121
7300
  if (RARRAY_LEN(a) == 2) {
7122
7301
  ajd = f_sub(RARRAY_AREF(a, 0), half_days_in_day);
7123
- of = INT2FIX(0);
7124
- sg = RARRAY_AREF(a, 1);
7125
- if (!k_numeric_p(sg))
7126
- sg = DBL2NUM(RTEST(sg) ? GREGORIAN : JULIAN);
7302
+ vof = INT2FIX(0);
7303
+ vsg = RARRAY_AREF(a, 1);
7304
+ if (!k_numeric_p(vsg))
7305
+ vsg = DBL2NUM(RTEST(vsg) ? GREGORIAN : JULIAN);
7127
7306
  }
7128
7307
  else {
7129
7308
  ajd = RARRAY_AREF(a, 0);
7130
- of = RARRAY_AREF(a, 1);
7131
- sg = RARRAY_AREF(a, 2);
7309
+ vof = RARRAY_AREF(a, 1);
7310
+ vsg = RARRAY_AREF(a, 2);
7132
7311
  }
7133
7312
 
7134
- old_to_new(ajd, of, sg,
7135
- &nth, &jd, &df, &sf, &rof, &rsg);
7136
-
7137
- if (!df && f_zero_p(sf) && !rof) {
7138
- set_to_simple(self, &dat->s, nth, jd, rsg, 0, 0, 0, HAVE_JD);
7139
- } else {
7140
- if (!complex_dat_p(dat))
7141
- rb_raise(rb_eArgError,
7142
- "cannot load complex into simple");
7143
-
7144
- set_to_complex(self, &dat->c, nth, jd, df, sf, rof, rsg,
7145
- 0, 0, 0, 0, 0, 0,
7146
- HAVE_JD | HAVE_DF | COMPLEX_DAT);
7147
- }
7313
+ old_to_new(ajd, vof, vsg,
7314
+ &nth, &jd, &df, &sf, &of, &sg);
7148
7315
  }
7149
7316
  break;
7150
7317
  case 6:
7151
7318
  {
7152
- VALUE nth, sf;
7153
- int jd, df, of;
7154
- double sg;
7155
-
7156
7319
  nth = RARRAY_AREF(a, 0);
7157
7320
  jd = NUM2INT(RARRAY_AREF(a, 1));
7158
7321
  df = NUM2INT(RARRAY_AREF(a, 2));
7159
7322
  sf = RARRAY_AREF(a, 3);
7160
7323
  of = NUM2INT(RARRAY_AREF(a, 4));
7161
7324
  sg = NUM2DBL(RARRAY_AREF(a, 5));
7162
- if (!df && f_zero_p(sf) && !of) {
7163
- set_to_simple(self, &dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
7164
- } else {
7165
- if (!complex_dat_p(dat))
7166
- rb_raise(rb_eArgError,
7167
- "cannot load complex into simple");
7168
-
7169
- set_to_complex(self, &dat->c, nth, jd, df, sf, of, sg,
7170
- 0, 0, 0, 0, 0, 0,
7171
- HAVE_JD | HAVE_DF | COMPLEX_DAT);
7172
- }
7173
7325
  }
7174
7326
  break;
7175
7327
  default:
@@ -7177,6 +7329,18 @@ d_lite_marshal_load(VALUE self, VALUE a)
7177
7329
  break;
7178
7330
  }
7179
7331
 
7332
+ if (simple_dat_p(dat)) {
7333
+ if (df || !f_zero_p(sf) || of) {
7334
+ rb_raise(rb_eArgError,
7335
+ "cannot load complex into simple");
7336
+ }
7337
+ set_to_simple(self, &dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
7338
+ } else {
7339
+ set_to_complex(self, &dat->c, nth, jd, df, sf, of, sg,
7340
+ 0, 0, 0, 0, 0, 0,
7341
+ HAVE_JD | HAVE_DF);
7342
+ }
7343
+
7180
7344
  if (FL_TEST(a, FL_EXIVAR)) {
7181
7345
  rb_copy_generic_ivar(self, a);
7182
7346
  FL_SET(self, FL_EXIVAR);
@@ -7356,10 +7520,21 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
7356
7520
  */
7357
7521
  static VALUE
7358
7522
  datetime_s_civil(int argc, VALUE *argv, VALUE klass)
7523
+ {
7524
+ return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
7525
+ }
7526
+
7527
+ static VALUE
7528
+ datetime_initialize(int argc, VALUE *argv, VALUE self)
7359
7529
  {
7360
7530
  VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7361
7531
  int m, d, h, min, s, rof;
7362
7532
  double sg;
7533
+ struct ComplexDateData *dat = rb_check_typeddata(self, &d_lite_type);
7534
+
7535
+ if (!complex_dat_p(dat)) {
7536
+ rb_raise(rb_eTypeError, "DateTime expected");
7537
+ }
7363
7538
 
7364
7539
  rb_scan_args(argc, argv, "08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg);
7365
7540
 
@@ -7403,13 +7578,13 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
7403
7578
  rb_raise(rb_eArgError, "invalid date");
7404
7579
  canon24oc();
7405
7580
 
7406
- ret = d_complex_new_internal(klass,
7407
- nth, 0,
7408
- 0, INT2FIX(0),
7409
- rof, sg,
7410
- ry, rm, rd,
7411
- rh, rmin, rs,
7412
- HAVE_CIVIL | HAVE_TIME);
7581
+ set_to_complex(self, dat,
7582
+ nth, 0,
7583
+ 0, INT2FIX(0),
7584
+ rof, sg,
7585
+ ry, rm, rd,
7586
+ rh, rmin, rs,
7587
+ HAVE_CIVIL | HAVE_TIME);
7413
7588
  }
7414
7589
  else {
7415
7590
  VALUE nth;
@@ -7428,14 +7603,15 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
7428
7603
  time_to_df(rh, rmin, rs),
7429
7604
  rof);
7430
7605
 
7431
- ret = d_complex_new_internal(klass,
7432
- nth, rjd2,
7433
- 0, INT2FIX(0),
7434
- rof, sg,
7435
- ry, rm, rd,
7436
- rh, rmin, rs,
7437
- HAVE_JD | HAVE_CIVIL | HAVE_TIME);
7606
+ set_to_complex(self, dat,
7607
+ nth, rjd2,
7608
+ 0, INT2FIX(0),
7609
+ rof, sg,
7610
+ ry, rm, rd,
7611
+ rh, rmin, rs,
7612
+ HAVE_JD | HAVE_CIVIL | HAVE_TIME);
7438
7613
  }
7614
+ ret = self;
7439
7615
  add_frac();
7440
7616
  return ret;
7441
7617
  }
@@ -7927,7 +8103,7 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
7927
8103
 
7928
8104
  /*
7929
8105
  * call-seq:
7930
- * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]]) -> datetime
8106
+ * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) -> datetime
7931
8107
  *
7932
8108
  * Parses the given representation of date and time, and creates a
7933
8109
  * DateTime object. This method does not function as a validator.
@@ -7941,13 +8117,18 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
7941
8117
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
7942
8118
  * DateTime.parse('3rd Feb 2001 04:05:06 PM')
7943
8119
  * #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
8120
+ *
8121
+ * Raise an ArgumentError when the string length is longer than _limit_.
8122
+ * You can stop this check by passing `limit: nil`, but note that
8123
+ * it may take a long time to parse.
7944
8124
  */
7945
8125
  static VALUE
7946
8126
  datetime_s_parse(int argc, VALUE *argv, VALUE klass)
7947
8127
  {
7948
- VALUE str, comp, sg;
8128
+ VALUE str, comp, sg, opt;
7949
8129
 
7950
- rb_scan_args(argc, argv, "03", &str, &comp, &sg);
8130
+ rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
8131
+ if (!NIL_P(opt)) argc--;
7951
8132
 
7952
8133
  switch (argc) {
7953
8134
  case 0:
@@ -7959,18 +8140,20 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
7959
8140
  }
7960
8141
 
7961
8142
  {
7962
- VALUE argv2[2], hash;
7963
-
7964
- argv2[0] = str;
7965
- argv2[1] = comp;
7966
- hash = date_s__parse(2, argv2, klass);
8143
+ int argc2 = 2;
8144
+ VALUE argv2[3];
8145
+ argv2[0] = str;
8146
+ argv2[1] = comp;
8147
+ argv2[2] = opt;
8148
+ if (!NIL_P(opt)) argc2++;
8149
+ VALUE hash = date_s__parse(argc2, argv2, klass);
7967
8150
  return dt_new_by_frags(klass, hash, sg);
7968
8151
  }
7969
8152
  }
7970
8153
 
7971
8154
  /*
7972
8155
  * call-seq:
7973
- * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
8156
+ * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
7974
8157
  *
7975
8158
  * Creates a new DateTime object by parsing from a string according to
7976
8159
  * some typical ISO 8601 formats.
@@ -7981,13 +8164,18 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
7981
8164
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
7982
8165
  * DateTime.iso8601('2001-W05-6T04:05:06+07:00')
7983
8166
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8167
+ *
8168
+ * Raise an ArgumentError when the string length is longer than _limit_.
8169
+ * You can stop this check by passing `limit: nil`, but note that
8170
+ * it may take a long time to parse.
7984
8171
  */
7985
8172
  static VALUE
7986
8173
  datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
7987
8174
  {
7988
- VALUE str, sg;
8175
+ VALUE str, sg, opt;
7989
8176
 
7990
- rb_scan_args(argc, argv, "02", &str, &sg);
8177
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8178
+ if (!NIL_P(opt)) argc--;
7991
8179
 
7992
8180
  switch (argc) {
7993
8181
  case 0:
@@ -7997,27 +8185,37 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
7997
8185
  }
7998
8186
 
7999
8187
  {
8000
- VALUE hash = date_s__iso8601(klass, str);
8188
+ int argc2 = 1;
8189
+ VALUE argv2[2];
8190
+ argv2[0] = str;
8191
+ argv2[1] = opt;
8192
+ if (!NIL_P(opt)) argc2--;
8193
+ VALUE hash = date_s__iso8601(argc2, argv2, klass);
8001
8194
  return dt_new_by_frags(klass, hash, sg);
8002
8195
  }
8003
8196
  }
8004
8197
 
8005
8198
  /*
8006
8199
  * call-seq:
8007
- * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
8200
+ * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
8008
8201
  *
8009
8202
  * Creates a new DateTime object by parsing from a string according to
8010
8203
  * some typical RFC 3339 formats.
8011
8204
  *
8012
8205
  * DateTime.rfc3339('2001-02-03T04:05:06+07:00')
8013
8206
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8207
+ *
8208
+ * Raise an ArgumentError when the string length is longer than _limit_.
8209
+ * You can stop this check by passing `limit: nil`, but note that
8210
+ * it may take a long time to parse.
8014
8211
  */
8015
8212
  static VALUE
8016
8213
  datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
8017
8214
  {
8018
- VALUE str, sg;
8215
+ VALUE str, sg, opt;
8019
8216
 
8020
- rb_scan_args(argc, argv, "02", &str, &sg);
8217
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8218
+ if (!NIL_P(opt)) argc--;
8021
8219
 
8022
8220
  switch (argc) {
8023
8221
  case 0:
@@ -8027,27 +8225,37 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
8027
8225
  }
8028
8226
 
8029
8227
  {
8030
- VALUE hash = date_s__rfc3339(klass, str);
8228
+ int argc2 = 1;
8229
+ VALUE argv2[2];
8230
+ argv2[0] = str;
8231
+ argv2[1] = opt;
8232
+ if (!NIL_P(opt)) argc2++;
8233
+ VALUE hash = date_s__rfc3339(argc2, argv2, klass);
8031
8234
  return dt_new_by_frags(klass, hash, sg);
8032
8235
  }
8033
8236
  }
8034
8237
 
8035
8238
  /*
8036
8239
  * call-seq:
8037
- * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
8240
+ * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
8038
8241
  *
8039
8242
  * Creates a new DateTime object by parsing from a string according to
8040
8243
  * some typical XML Schema formats.
8041
8244
  *
8042
8245
  * DateTime.xmlschema('2001-02-03T04:05:06+07:00')
8043
8246
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8247
+ *
8248
+ * Raise an ArgumentError when the string length is longer than _limit_.
8249
+ * You can stop this check by passing `limit: nil`, but note that
8250
+ * it may take a long time to parse.
8044
8251
  */
8045
8252
  static VALUE
8046
8253
  datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
8047
8254
  {
8048
- VALUE str, sg;
8255
+ VALUE str, sg, opt;
8049
8256
 
8050
- rb_scan_args(argc, argv, "02", &str, &sg);
8257
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8258
+ if (!NIL_P(opt)) argc--;
8051
8259
 
8052
8260
  switch (argc) {
8053
8261
  case 0:
@@ -8057,28 +8265,38 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
8057
8265
  }
8058
8266
 
8059
8267
  {
8060
- VALUE hash = date_s__xmlschema(klass, str);
8268
+ int argc2 = 1;
8269
+ VALUE argv2[2];
8270
+ argv2[0] = str;
8271
+ argv2[1] = opt;
8272
+ if (!NIL_P(opt)) argc2++;
8273
+ VALUE hash = date_s__xmlschema(argc2, argv2, klass);
8061
8274
  return dt_new_by_frags(klass, hash, sg);
8062
8275
  }
8063
8276
  }
8064
8277
 
8065
8278
  /*
8066
8279
  * call-seq:
8067
- * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime
8068
- * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime
8280
+ * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime
8281
+ * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime
8069
8282
  *
8070
8283
  * Creates a new DateTime object by parsing from a string according to
8071
8284
  * some typical RFC 2822 formats.
8072
8285
  *
8073
8286
  * DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
8074
8287
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8288
+ *
8289
+ * Raise an ArgumentError when the string length is longer than _limit_.
8290
+ * You can stop this check by passing `limit: nil`, but note that
8291
+ * it may take a long time to parse.
8075
8292
  */
8076
8293
  static VALUE
8077
8294
  datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
8078
8295
  {
8079
- VALUE str, sg;
8296
+ VALUE str, sg, opt;
8080
8297
 
8081
- rb_scan_args(argc, argv, "02", &str, &sg);
8298
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8299
+ if (!NIL_P(opt)) argc--;
8082
8300
 
8083
8301
  switch (argc) {
8084
8302
  case 0:
@@ -8088,7 +8306,12 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
8088
8306
  }
8089
8307
 
8090
8308
  {
8091
- VALUE hash = date_s__rfc2822(klass, str);
8309
+ int argc2 = 1;
8310
+ VALUE argv2[2];
8311
+ argv2[0] = str;
8312
+ argv2[1] = opt;
8313
+ if (!NIL_P(opt)) argc2++;
8314
+ VALUE hash = date_s__rfc2822(argc2, argv2, klass);
8092
8315
  return dt_new_by_frags(klass, hash, sg);
8093
8316
  }
8094
8317
  }
@@ -8102,13 +8325,18 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
8102
8325
  *
8103
8326
  * DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
8104
8327
  * #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>
8328
+ *
8329
+ * Raise an ArgumentError when the string length is longer than _limit_.
8330
+ * You can stop this check by passing `limit: nil`, but note that
8331
+ * it may take a long time to parse.
8105
8332
  */
8106
8333
  static VALUE
8107
8334
  datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
8108
8335
  {
8109
- VALUE str, sg;
8336
+ VALUE str, sg, opt;
8110
8337
 
8111
- rb_scan_args(argc, argv, "02", &str, &sg);
8338
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8339
+ if (!NIL_P(opt)) argc--;
8112
8340
 
8113
8341
  switch (argc) {
8114
8342
  case 0:
@@ -8118,27 +8346,42 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
8118
8346
  }
8119
8347
 
8120
8348
  {
8121
- VALUE hash = date_s__httpdate(klass, str);
8349
+ int argc2 = 1;
8350
+ VALUE argv2[2];
8351
+ argv2[0] = str;
8352
+ argv2[1] = opt;
8353
+ if (!NIL_P(opt)) argc2++;
8354
+ VALUE hash = date_s__httpdate(argc2, argv2, klass);
8122
8355
  return dt_new_by_frags(klass, hash, sg);
8123
8356
  }
8124
8357
  }
8125
8358
 
8126
8359
  /*
8127
8360
  * call-seq:
8128
- * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
8361
+ * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
8129
8362
  *
8130
8363
  * Creates a new DateTime object by parsing from a string according to
8131
8364
  * some typical JIS X 0301 formats.
8132
8365
  *
8133
8366
  * DateTime.jisx0301('H13.02.03T04:05:06+07:00')
8134
8367
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8368
+ *
8369
+ * For no-era year, legacy format, Heisei is assumed.
8370
+ *
8371
+ * DateTime.jisx0301('13.02.03T04:05:06+07:00')
8372
+ * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8373
+ *
8374
+ * Raise an ArgumentError when the string length is longer than _limit_.
8375
+ * You can stop this check by passing `limit: nil`, but note that
8376
+ * it may take a long time to parse.
8135
8377
  */
8136
8378
  static VALUE
8137
8379
  datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
8138
8380
  {
8139
- VALUE str, sg;
8381
+ VALUE str, sg, opt;
8140
8382
 
8141
- rb_scan_args(argc, argv, "02", &str, &sg);
8383
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8384
+ if (!NIL_P(opt)) argc--;
8142
8385
 
8143
8386
  switch (argc) {
8144
8387
  case 0:
@@ -8148,7 +8391,12 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
8148
8391
  }
8149
8392
 
8150
8393
  {
8151
- VALUE hash = date_s__jisx0301(klass, str);
8394
+ int argc2 = 1;
8395
+ VALUE argv2[2];
8396
+ argv2[0] = str;
8397
+ argv2[1] = opt;
8398
+ if (!NIL_P(opt)) argc2++;
8399
+ VALUE hash = date_s__jisx0301(argc2, argv2, klass);
8152
8400
  return dt_new_by_frags(klass, hash, sg);
8153
8401
  }
8154
8402
  }
@@ -8232,7 +8480,7 @@ dt_lite_to_s(VALUE self)
8232
8480
  *
8233
8481
  * %M - Minute of the hour (00..59)
8234
8482
  *
8235
- * %S - Second of the minute (00..59)
8483
+ * %S - Second of the minute (00..60)
8236
8484
  *
8237
8485
  * %L - Millisecond of the second (000..999)
8238
8486
  * %N - Fractional seconds digits, default is 9 digits (nanosecond)
@@ -8645,7 +8893,7 @@ datetime_to_date(VALUE self)
8645
8893
  VALUE new = d_lite_s_alloc_simple(cDate);
8646
8894
  {
8647
8895
  get_d1b(new);
8648
- copy_complex_to_simple(new, &bdat->s, &adat->c)
8896
+ copy_complex_to_simple(new, &bdat->s, &adat->c);
8649
8897
  bdat->s.jd = m_local_jd(adat);
8650
8898
  bdat->s.flags &= ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT);
8651
8899
  return new;
@@ -9010,14 +9258,18 @@ mk_ary_of_str(long len, const char *a[])
9010
9258
  return o;
9011
9259
  }
9012
9260
 
9261
+ static VALUE
9262
+ d_lite_zero(VALUE x)
9263
+ {
9264
+ return INT2FIX(0);
9265
+ }
9266
+
9013
9267
  void
9014
9268
  Init_date_core(void)
9015
9269
  {
9016
9270
  #undef rb_intern
9017
9271
  #define rb_intern(str) rb_intern_const(str)
9018
9272
 
9019
- assert(fprintf(stderr, "assert() is now active\n"));
9020
-
9021
9273
  id_cmp = rb_intern("<=>");
9022
9274
  id_le_p = rb_intern("<=");
9023
9275
  id_ge_p = rb_intern(">=");
@@ -9233,23 +9485,22 @@ Init_date_core(void)
9233
9485
  */
9234
9486
  rb_define_const(cDate, "GREGORIAN", DBL2NUM(GREGORIAN));
9235
9487
 
9236
- rb_define_alloc_func(cDate, d_lite_s_alloc);
9488
+ rb_define_alloc_func(cDate, d_lite_s_alloc_simple);
9237
9489
 
9238
9490
  #ifndef NDEBUG
9239
- #define de_define_private_method rb_define_private_method
9240
- de_define_private_method(CLASS_OF(cDate), "_valid_jd?",
9491
+ rb_define_private_method(CLASS_OF(cDate), "_valid_jd?",
9241
9492
  date_s__valid_jd_p, -1);
9242
- de_define_private_method(CLASS_OF(cDate), "_valid_ordinal?",
9493
+ rb_define_private_method(CLASS_OF(cDate), "_valid_ordinal?",
9243
9494
  date_s__valid_ordinal_p, -1);
9244
- de_define_private_method(CLASS_OF(cDate), "_valid_civil?",
9495
+ rb_define_private_method(CLASS_OF(cDate), "_valid_civil?",
9245
9496
  date_s__valid_civil_p, -1);
9246
- de_define_private_method(CLASS_OF(cDate), "_valid_date?",
9497
+ rb_define_private_method(CLASS_OF(cDate), "_valid_date?",
9247
9498
  date_s__valid_civil_p, -1);
9248
- de_define_private_method(CLASS_OF(cDate), "_valid_commercial?",
9499
+ rb_define_private_method(CLASS_OF(cDate), "_valid_commercial?",
9249
9500
  date_s__valid_commercial_p, -1);
9250
- de_define_private_method(CLASS_OF(cDate), "_valid_weeknum?",
9501
+ rb_define_private_method(CLASS_OF(cDate), "_valid_weeknum?",
9251
9502
  date_s__valid_weeknum_p, -1);
9252
- de_define_private_method(CLASS_OF(cDate), "_valid_nth_kday?",
9503
+ rb_define_private_method(CLASS_OF(cDate), "_valid_nth_kday?",
9253
9504
  date_s__valid_nth_kday_p, -1);
9254
9505
  #endif
9255
9506
 
@@ -9262,11 +9513,11 @@ Init_date_core(void)
9262
9513
  date_s_valid_commercial_p, -1);
9263
9514
 
9264
9515
  #ifndef NDEBUG
9265
- de_define_private_method(CLASS_OF(cDate), "valid_weeknum?",
9516
+ rb_define_private_method(CLASS_OF(cDate), "valid_weeknum?",
9266
9517
  date_s_valid_weeknum_p, -1);
9267
- de_define_private_method(CLASS_OF(cDate), "valid_nth_kday?",
9518
+ rb_define_private_method(CLASS_OF(cDate), "valid_nth_kday?",
9268
9519
  date_s_valid_nth_kday_p, -1);
9269
- de_define_private_method(CLASS_OF(cDate), "zone_to_diff",
9520
+ rb_define_private_method(CLASS_OF(cDate), "zone_to_diff",
9270
9521
  date_s_zone_to_diff, 1);
9271
9522
  #endif
9272
9523
 
@@ -9277,21 +9528,18 @@ Init_date_core(void)
9277
9528
  date_s_gregorian_leap_p, 1);
9278
9529
 
9279
9530
  #ifndef NDEBUG
9280
- #define de_define_singleton_method rb_define_singleton_method
9281
- #define de_define_alias rb_define_alias
9282
- de_define_singleton_method(cDate, "new!", date_s_new_bang, -1);
9283
- de_define_alias(rb_singleton_class(cDate), "new_l!", "new");
9531
+ rb_define_singleton_method(cDate, "new!", date_s_new_bang, -1);
9532
+ rb_define_alias(rb_singleton_class(cDate), "new_l!", "new");
9284
9533
  #endif
9285
9534
 
9286
9535
  rb_define_singleton_method(cDate, "jd", date_s_jd, -1);
9287
9536
  rb_define_singleton_method(cDate, "ordinal", date_s_ordinal, -1);
9288
9537
  rb_define_singleton_method(cDate, "civil", date_s_civil, -1);
9289
- rb_define_singleton_method(cDate, "new", date_s_civil, -1);
9290
9538
  rb_define_singleton_method(cDate, "commercial", date_s_commercial, -1);
9291
9539
 
9292
9540
  #ifndef NDEBUG
9293
- de_define_singleton_method(cDate, "weeknum", date_s_weeknum, -1);
9294
- de_define_singleton_method(cDate, "nth_kday", date_s_nth_kday, -1);
9541
+ rb_define_singleton_method(cDate, "weeknum", date_s_weeknum, -1);
9542
+ rb_define_singleton_method(cDate, "nth_kday", date_s_nth_kday, -1);
9295
9543
  #endif
9296
9544
 
9297
9545
  rb_define_singleton_method(cDate, "today", date_s_today, -1);
@@ -9299,29 +9547,26 @@ Init_date_core(void)
9299
9547
  rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1);
9300
9548
  rb_define_singleton_method(cDate, "_parse", date_s__parse, -1);
9301
9549
  rb_define_singleton_method(cDate, "parse", date_s_parse, -1);
9302
- rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, 1);
9550
+ rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1);
9303
9551
  rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1);
9304
- rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, 1);
9552
+ rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1);
9305
9553
  rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1);
9306
- rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, 1);
9554
+ rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1);
9307
9555
  rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1);
9308
- rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, 1);
9309
- rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, 1);
9556
+ rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1);
9557
+ rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1);
9310
9558
  rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1);
9311
9559
  rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1);
9312
- rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, 1);
9560
+ rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1);
9313
9561
  rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1);
9314
- rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1);
9562
+ rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1);
9315
9563
  rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1);
9316
9564
 
9317
- #ifndef NDEBUG
9318
- #define de_define_method rb_define_method
9319
- de_define_method(cDate, "initialize", d_lite_initialize, -1);
9320
- #endif
9565
+ rb_define_method(cDate, "initialize", date_initialize, -1);
9321
9566
  rb_define_method(cDate, "initialize_copy", d_lite_initialize_copy, 1);
9322
9567
 
9323
9568
  #ifndef NDEBUG
9324
- de_define_method(cDate, "fill", d_lite_fill, 0);
9569
+ rb_define_method(cDate, "fill", d_lite_fill, 0);
9325
9570
  #endif
9326
9571
 
9327
9572
  rb_define_method(cDate, "ajd", d_lite_ajd, 0);
@@ -9343,8 +9588,8 @@ Init_date_core(void)
9343
9588
  rb_define_method(cDate, "cwday", d_lite_cwday, 0);
9344
9589
 
9345
9590
  #ifndef NDEBUG
9346
- de_define_private_method(cDate, "wnum0", d_lite_wnum0, 0);
9347
- de_define_private_method(cDate, "wnum1", d_lite_wnum1, 0);
9591
+ rb_define_private_method(cDate, "wnum0", d_lite_wnum0, 0);
9592
+ rb_define_private_method(cDate, "wnum1", d_lite_wnum1, 0);
9348
9593
  #endif
9349
9594
 
9350
9595
  rb_define_method(cDate, "wday", d_lite_wday, 0);
@@ -9358,18 +9603,14 @@ Init_date_core(void)
9358
9603
  rb_define_method(cDate, "saturday?", d_lite_saturday_p, 0);
9359
9604
 
9360
9605
  #ifndef NDEBUG
9361
- de_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
9606
+ rb_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
9362
9607
  #endif
9363
9608
 
9364
- rb_define_private_method(cDate, "hour", d_lite_hour, 0);
9365
- rb_define_private_method(cDate, "min", d_lite_min, 0);
9366
- rb_define_private_method(cDate, "minute", d_lite_min, 0);
9367
- rb_define_private_method(cDate, "sec", d_lite_sec, 0);
9368
- rb_define_private_method(cDate, "second", d_lite_sec, 0);
9369
- rb_define_private_method(cDate, "sec_fraction", d_lite_sec_fraction, 0);
9370
- rb_define_private_method(cDate, "second_fraction", d_lite_sec_fraction, 0);
9371
- rb_define_private_method(cDate, "offset", d_lite_offset, 0);
9372
- rb_define_private_method(cDate, "zone", d_lite_zone, 0);
9609
+ rb_define_private_method(cDate, "hour", d_lite_zero, 0);
9610
+ rb_define_private_method(cDate, "min", d_lite_zero, 0);
9611
+ rb_define_private_method(cDate, "minute", d_lite_zero, 0);
9612
+ rb_define_private_method(cDate, "sec", d_lite_zero, 0);
9613
+ rb_define_private_method(cDate, "second", d_lite_zero, 0);
9373
9614
 
9374
9615
  rb_define_method(cDate, "julian?", d_lite_julian_p, 0);
9375
9616
  rb_define_method(cDate, "gregorian?", d_lite_gregorian_p, 0);
@@ -9382,8 +9623,6 @@ Init_date_core(void)
9382
9623
  rb_define_method(cDate, "julian", d_lite_julian, 0);
9383
9624
  rb_define_method(cDate, "gregorian", d_lite_gregorian, 0);
9384
9625
 
9385
- rb_define_private_method(cDate, "new_offset", d_lite_new_offset, -1);
9386
-
9387
9626
  rb_define_method(cDate, "+", d_lite_plus, 1);
9388
9627
  rb_define_method(cDate, "-", d_lite_minus, 1);
9389
9628
 
@@ -9411,7 +9650,7 @@ Init_date_core(void)
9411
9650
 
9412
9651
  rb_define_method(cDate, "to_s", d_lite_to_s, 0);
9413
9652
  #ifndef NDEBUG
9414
- de_define_method(cDate, "inspect_raw", d_lite_inspect_raw, 0);
9653
+ rb_define_method(cDate, "inspect_raw", d_lite_inspect_raw, 0);
9415
9654
  #endif
9416
9655
  rb_define_method(cDate, "inspect", d_lite_inspect, 0);
9417
9656
 
@@ -9428,7 +9667,7 @@ Init_date_core(void)
9428
9667
  rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0);
9429
9668
 
9430
9669
  #ifndef NDEBUG
9431
- de_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
9670
+ rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
9432
9671
  #endif
9433
9672
  rb_define_method(cDate, "marshal_dump", d_lite_marshal_dump, 0);
9434
9673
  rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1);
@@ -9575,6 +9814,7 @@ Init_date_core(void)
9575
9814
  */
9576
9815
 
9577
9816
  cDateTime = rb_define_class("DateTime", cDate);
9817
+ rb_define_alloc_func(cDateTime, d_lite_s_alloc_complex);
9578
9818
 
9579
9819
  rb_define_singleton_method(cDateTime, "jd", datetime_s_jd, -1);
9580
9820
  rb_define_singleton_method(cDateTime, "ordinal", datetime_s_ordinal, -1);
@@ -9584,9 +9824,9 @@ Init_date_core(void)
9584
9824
  datetime_s_commercial, -1);
9585
9825
 
9586
9826
  #ifndef NDEBUG
9587
- de_define_singleton_method(cDateTime, "weeknum",
9827
+ rb_define_singleton_method(cDateTime, "weeknum",
9588
9828
  datetime_s_weeknum, -1);
9589
- de_define_singleton_method(cDateTime, "nth_kday",
9829
+ rb_define_singleton_method(cDateTime, "nth_kday",
9590
9830
  datetime_s_nth_kday, -1);
9591
9831
  #endif
9592
9832
 
@@ -9614,19 +9854,16 @@ Init_date_core(void)
9614
9854
  rb_define_singleton_method(cDateTime, "jisx0301",
9615
9855
  datetime_s_jisx0301, -1);
9616
9856
 
9617
- #define f_public(m,s) rb_funcall(m, rb_intern("public"), 1,\
9618
- ID2SYM(rb_intern(s)))
9619
-
9620
- f_public(cDateTime, "hour");
9621
- f_public(cDateTime, "min");
9622
- f_public(cDateTime, "minute");
9623
- f_public(cDateTime, "sec");
9624
- f_public(cDateTime, "second");
9625
- f_public(cDateTime, "sec_fraction");
9626
- f_public(cDateTime, "second_fraction");
9627
- f_public(cDateTime, "offset");
9628
- f_public(cDateTime, "zone");
9629
- f_public(cDateTime, "new_offset");
9857
+ rb_define_method(cDateTime, "hour", d_lite_hour, 0);
9858
+ rb_define_method(cDateTime, "min", d_lite_min, 0);
9859
+ rb_define_method(cDateTime, "minute", d_lite_min, 0);
9860
+ rb_define_method(cDateTime, "sec", d_lite_sec, 0);
9861
+ rb_define_method(cDateTime, "second", d_lite_sec, 0);
9862
+ rb_define_method(cDateTime, "sec_fraction", d_lite_sec_fraction, 0);
9863
+ rb_define_method(cDateTime, "second_fraction", d_lite_sec_fraction, 0);
9864
+ rb_define_method(cDateTime, "offset", d_lite_offset, 0);
9865
+ rb_define_method(cDateTime, "zone", d_lite_zone, 0);
9866
+ rb_define_method(cDateTime, "new_offset", d_lite_new_offset, -1);
9630
9867
 
9631
9868
  rb_define_method(cDateTime, "to_s", dt_lite_to_s, 0);
9632
9869
 
@@ -9654,15 +9891,15 @@ Init_date_core(void)
9654
9891
  #ifndef NDEBUG
9655
9892
  /* tests */
9656
9893
 
9657
- de_define_singleton_method(cDate, "test_civil", date_s_test_civil, 0);
9658
- de_define_singleton_method(cDate, "test_ordinal", date_s_test_ordinal, 0);
9659
- de_define_singleton_method(cDate, "test_commercial",
9894
+ rb_define_singleton_method(cDate, "test_civil", date_s_test_civil, 0);
9895
+ rb_define_singleton_method(cDate, "test_ordinal", date_s_test_ordinal, 0);
9896
+ rb_define_singleton_method(cDate, "test_commercial",
9660
9897
  date_s_test_commercial, 0);
9661
- de_define_singleton_method(cDate, "test_weeknum", date_s_test_weeknum, 0);
9662
- de_define_singleton_method(cDate, "test_nth_kday", date_s_test_nth_kday, 0);
9663
- de_define_singleton_method(cDate, "test_unit_conv",
9898
+ rb_define_singleton_method(cDate, "test_weeknum", date_s_test_weeknum, 0);
9899
+ rb_define_singleton_method(cDate, "test_nth_kday", date_s_test_nth_kday, 0);
9900
+ rb_define_singleton_method(cDate, "test_unit_conv",
9664
9901
  date_s_test_unit_conv, 0);
9665
- de_define_singleton_method(cDate, "test_all", date_s_test_all, 0);
9902
+ rb_define_singleton_method(cDate, "test_all", date_s_test_all, 0);
9666
9903
  #endif
9667
9904
  }
9668
9905