ed-precompiled_date 3.4.1-x86_64-linux

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.
@@ -0,0 +1,3086 @@
1
+ /*
2
+ date_parse.c: Coded by Tadayoshi Funaba 2011,2012
3
+ */
4
+
5
+ #include "ruby.h"
6
+ #include "ruby/encoding.h"
7
+ #include "ruby/re.h"
8
+ #include <ctype.h>
9
+
10
+ #undef strncasecmp
11
+ #define strncasecmp STRNCASECMP
12
+
13
+ RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y);
14
+ RUBY_EXTERN unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);
15
+
16
+ /* #define TIGHT_PARSER */
17
+
18
+ #define sizeof_array(o) (sizeof o / sizeof o[0])
19
+
20
+ #define f_negate(x) rb_funcall(x, rb_intern("-@"), 0)
21
+ #define f_add(x,y) rb_funcall(x, '+', 1, y)
22
+ #define f_sub(x,y) rb_funcall(x, '-', 1, y)
23
+ #define f_mul(x,y) rb_funcall(x, '*', 1, y)
24
+ #define f_div(x,y) rb_funcall(x, '/', 1, y)
25
+ #define f_idiv(x,y) rb_funcall(x, rb_intern("div"), 1, y)
26
+ #define f_mod(x,y) rb_funcall(x, '%', 1, y)
27
+ #define f_expt(x,y) rb_funcall(x, rb_intern("**"), 1, y)
28
+
29
+ #define f_lt_p(x,y) rb_funcall(x, '<', 1, y)
30
+ #define f_gt_p(x,y) rb_funcall(x, '>', 1, y)
31
+ #define f_le_p(x,y) rb_funcall(x, rb_intern("<="), 1, y)
32
+ #define f_ge_p(x,y) rb_funcall(x, rb_intern(">="), 1, y)
33
+
34
+ #define f_to_s(x) rb_funcall(x, rb_intern("to_s"), 0)
35
+
36
+ #define f_match(r,s) rb_funcall(r, rb_intern("match"), 1, s)
37
+ #define f_aref(o,i) rb_funcall(o, rb_intern("[]"), 1, i)
38
+ #define f_aref2(o,i,j) rb_funcall(o, rb_intern("[]"), 2, i, j)
39
+ #define f_begin(o,i) rb_funcall(o, rb_intern("begin"), 1, i)
40
+ #define f_end(o,i) rb_funcall(o, rb_intern("end"), 1, i)
41
+ #define f_aset(o,i,v) rb_funcall(o, rb_intern("[]="), 2, i, v)
42
+ #define f_aset2(o,i,j,v) rb_funcall(o, rb_intern("[]="), 3, i, j, v)
43
+ #define f_sub_bang(s,r,x) rb_funcall(s, rb_intern("sub!"), 2, r, x)
44
+ #define f_gsub_bang(s,r,x) rb_funcall(s, rb_intern("gsub!"), 2, r, x)
45
+
46
+ #define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k"")), v)
47
+ #define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k"")))
48
+ #define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k"")))
49
+
50
+ #define cstr2num(s) rb_cstr_to_inum(s, 10, 0)
51
+ #define str2num(s) rb_str_to_inum(s, 10, 0)
52
+
53
+ static const char abbr_days[][4] = {
54
+ "sun", "mon", "tue", "wed",
55
+ "thu", "fri", "sat"
56
+ };
57
+
58
+ static const char abbr_months[][4] = {
59
+ "jan", "feb", "mar", "apr", "may", "jun",
60
+ "jul", "aug", "sep", "oct", "nov", "dec"
61
+ };
62
+
63
+ #define issign(c) ((c) == '-' || (c) == '+')
64
+ #define asp_string() rb_str_new(" ", 1)
65
+ #ifdef TIGHT_PARSER
66
+ #define asuba_string() rb_str_new("\001", 1)
67
+ #define asubb_string() rb_str_new("\002", 1)
68
+ #define asubw_string() rb_str_new("\027", 1)
69
+ #define asubt_string() rb_str_new("\024", 1)
70
+ #endif
71
+
72
+ static size_t
73
+ digit_span(const char *s, const char *e)
74
+ {
75
+ size_t i = 0;
76
+ while (s + i < e && isdigit((unsigned char)s[i])) i++;
77
+ return i;
78
+ }
79
+
80
+ static void
81
+ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
82
+ {
83
+ VALUE vbuf = 0;
84
+ VALUE c = Qnil;
85
+
86
+ if (!RB_TYPE_P(m, T_STRING))
87
+ m = f_to_s(m);
88
+
89
+ if (!NIL_P(y) && !NIL_P(m) && NIL_P(d)) {
90
+ VALUE oy = y;
91
+ VALUE om = m;
92
+ VALUE od = d;
93
+
94
+ y = od;
95
+ m = oy;
96
+ d = om;
97
+ }
98
+
99
+ if (NIL_P(y)) {
100
+ if (!NIL_P(d) && RSTRING_LEN(d) > 2) {
101
+ y = d;
102
+ d = Qnil;
103
+ }
104
+ if (!NIL_P(d) && RSTRING_LEN(d) > 0 && *RSTRING_PTR(d) == '\'') {
105
+ y = d;
106
+ d = Qnil;
107
+ }
108
+ }
109
+
110
+ if (!NIL_P(y)) {
111
+ const char *s, *bp, *ep;
112
+ size_t l;
113
+
114
+ s = RSTRING_PTR(y);
115
+ ep = RSTRING_END(y);
116
+ while (s < ep && !issign(*s) && !isdigit((unsigned char)*s))
117
+ s++;
118
+ if (s >= ep) goto no_date;
119
+ bp = s;
120
+ if (issign((unsigned char)*s))
121
+ s++;
122
+ l = digit_span(s, ep);
123
+ ep = s + l;
124
+ if (*ep) {
125
+ y = d;
126
+ d = rb_str_new(bp, ep - bp);
127
+ }
128
+ no_date:;
129
+ }
130
+
131
+ if (!NIL_P(m)) {
132
+ const char *s;
133
+
134
+ s = RSTRING_PTR(m);
135
+ if (*s == '\'' || RSTRING_LEN(m) > 2) {
136
+ /* us -> be */
137
+ VALUE oy = y;
138
+ VALUE om = m;
139
+ VALUE od = d;
140
+
141
+ y = om;
142
+ m = od;
143
+ d = oy;
144
+ }
145
+ }
146
+
147
+ if (!NIL_P(d)) {
148
+ const char *s;
149
+
150
+ s = RSTRING_PTR(d);
151
+ if (*s == '\'' || RSTRING_LEN(d) > 2) {
152
+ VALUE oy = y;
153
+ VALUE od = d;
154
+
155
+ y = od;
156
+ d = oy;
157
+ }
158
+ }
159
+
160
+ if (!NIL_P(y)) {
161
+ const char *s, *bp, *ep;
162
+ int sign = 0;
163
+ size_t l;
164
+ VALUE iy;
165
+
166
+ s = RSTRING_PTR(y);
167
+ ep = RSTRING_END(y);
168
+ while (s < ep && !issign(*s) && !isdigit((unsigned char)*s))
169
+ s++;
170
+ if (s >= ep) goto no_year;
171
+ bp = s;
172
+ if (issign(*s)) {
173
+ s++;
174
+ sign = 1;
175
+ }
176
+ if (sign)
177
+ c = Qfalse;
178
+ l = digit_span(s, ep);
179
+ ep = s + l;
180
+ if (l > 2)
181
+ c = Qfalse;
182
+ {
183
+ char *buf;
184
+
185
+ buf = ALLOCV_N(char, vbuf, ep - bp + 1);
186
+ memcpy(buf, bp, ep - bp);
187
+ buf[ep - bp] = '\0';
188
+ iy = cstr2num(buf);
189
+ ALLOCV_END(vbuf);
190
+ }
191
+ set_hash("year", iy);
192
+ no_year:;
193
+ }
194
+
195
+ if (bc)
196
+ set_hash("_bc", Qtrue);
197
+
198
+ if (!NIL_P(m)) {
199
+ const char *s, *bp, *ep;
200
+ size_t l;
201
+ VALUE im;
202
+
203
+ s = RSTRING_PTR(m);
204
+ ep = RSTRING_END(m);
205
+ while (s < ep && !isdigit((unsigned char)*s))
206
+ s++;
207
+ if (s >= ep) goto no_month;
208
+ bp = s;
209
+ l = digit_span(s, ep);
210
+ ep = s + l;
211
+ {
212
+ char *buf;
213
+
214
+ buf = ALLOCV_N(char, vbuf, ep - bp + 1);
215
+ memcpy(buf, bp, ep - bp);
216
+ buf[ep - bp] = '\0';
217
+ im = cstr2num(buf);
218
+ ALLOCV_END(vbuf);
219
+ }
220
+ set_hash("mon", im);
221
+ no_month:;
222
+ }
223
+
224
+ if (!NIL_P(d)) {
225
+ const char *s, *bp, *ep;
226
+ size_t l;
227
+ VALUE id;
228
+
229
+ s = RSTRING_PTR(d);
230
+ ep = RSTRING_END(d);
231
+ while (s < ep && !isdigit((unsigned char)*s))
232
+ s++;
233
+ if (s >= ep) goto no_mday;
234
+ bp = s;
235
+ l = digit_span(s, ep);
236
+ ep = s + l;
237
+ {
238
+ char *buf;
239
+
240
+ buf = ALLOCV_N(char, vbuf, ep - bp + 1);
241
+ memcpy(buf, bp, ep - bp);
242
+ buf[ep - bp] = '\0';
243
+ id = cstr2num(buf);
244
+ ALLOCV_END(vbuf);
245
+ }
246
+ set_hash("mday", id);
247
+ no_mday:;
248
+ }
249
+
250
+ if (!NIL_P(c))
251
+ set_hash("_comp", c);
252
+ }
253
+
254
+ #define DAYS "sunday|monday|tuesday|wednesday|thursday|friday|saturday"
255
+ #define MONTHS "january|february|march|april|may|june|july|august|september|october|november|december"
256
+ #define ABBR_DAYS "sun|mon|tue|wed|thu|fri|sat"
257
+ #define ABBR_MONTHS "jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec"
258
+
259
+ #define NUMBER "(?<!\\d)\\d"
260
+
261
+ #ifdef TIGHT_PARSER
262
+ #define VALID_DAYS "(?:" DAYS ")" "|(?:tues|wednes|thurs|thur|" ABBR_DAYS ")\\.?"
263
+ #define VALID_MONTHS "(?:" MONTHS ")" "|(?:sept|" ABBR_MONTHS ")\\.?"
264
+ #define DOTLESS_VALID_MONTHS "(?:" MONTHS ")" "|(?:sept|" ABBR_MONTHS ")"
265
+ #define BOS "\\A\\s*"
266
+ #define FPA "\\001"
267
+ #define FPB "\\002"
268
+ #define FPW "\\027"
269
+ #define FPT "\\024"
270
+ #define FPW_COM "\\s*(?:" FPW "\\s*,?)?\\s*"
271
+ #define FPT_COM "\\s*(?:" FPT "\\s*,?)?\\s*"
272
+ #define COM_FPW "\\s*(?:,?\\s*" FPW ")?\\s*"
273
+ #define COM_FPT "\\s*(?:,?\\s*(?:@|\\b[aA][tT]\\b)?\\s*" FPT ")?\\s*"
274
+ #define TEE_FPT "\\s*(?:[tT]?" FPT ")?"
275
+ #define EOS "\\s*\\z"
276
+ #endif
277
+
278
+ static VALUE
279
+ regcomp(const char *source, long len, int opt)
280
+ {
281
+ VALUE pat;
282
+
283
+ pat = rb_reg_new(source, len, opt);
284
+ rb_obj_freeze(pat);
285
+ rb_gc_register_mark_object(pat);
286
+ return pat;
287
+ }
288
+
289
+ #define REGCOMP(pat,opt) \
290
+ do { \
291
+ if (NIL_P(pat)) \
292
+ pat = regcomp(pat##_source, sizeof pat##_source - 1, opt); \
293
+ } while (0)
294
+
295
+ #define REGCOMP_0(pat) REGCOMP(pat, 0)
296
+ #define REGCOMP_I(pat) REGCOMP(pat, ONIG_OPTION_IGNORECASE)
297
+
298
+ #define MATCH(s,p,c) \
299
+ do { \
300
+ return match(s, p, hash, c); \
301
+ } while (0)
302
+
303
+ static int
304
+ match(VALUE str, VALUE pat, VALUE hash, int (*cb)(VALUE, VALUE))
305
+ {
306
+ VALUE m;
307
+
308
+ m = f_match(pat, str);
309
+
310
+ if (NIL_P(m))
311
+ return 0;
312
+
313
+ (*cb)(m, hash);
314
+
315
+ return 1;
316
+ }
317
+
318
+ static int
319
+ subx(VALUE str, VALUE rep, VALUE pat, VALUE hash, int (*cb)(VALUE, VALUE))
320
+ {
321
+ VALUE m;
322
+
323
+ m = f_match(pat, str);
324
+
325
+ if (NIL_P(m))
326
+ return 0;
327
+
328
+ {
329
+ VALUE be, en;
330
+
331
+ be = f_begin(m, INT2FIX(0));
332
+ en = f_end(m, INT2FIX(0));
333
+ f_aset2(str, be, LONG2NUM(NUM2LONG(en) - NUM2LONG(be)), rep);
334
+ (*cb)(m, hash);
335
+ }
336
+
337
+ return 1;
338
+ }
339
+
340
+ #define SUBS(s,p,c) \
341
+ do { \
342
+ return subx(s, asp_string(), p, hash, c); \
343
+ } while (0)
344
+
345
+ #ifdef TIGHT_PARSER
346
+ #define SUBA(s,p,c) \
347
+ do { \
348
+ return subx(s, asuba_string(), p, hash, c); \
349
+ } while (0)
350
+
351
+ #define SUBB(s,p,c) \
352
+ do { \
353
+ return subx(s, asubb_string(), p, hash, c); \
354
+ } while (0)
355
+
356
+ #define SUBW(s,p,c) \
357
+ do { \
358
+ return subx(s, asubw_string(), p, hash, c); \
359
+ } while (0)
360
+
361
+ #define SUBT(s,p,c) \
362
+ do { \
363
+ return subx(s, asubt_string(), p, hash, c); \
364
+ } while (0)
365
+ #endif
366
+
367
+ #include "zonetab.h"
368
+
369
+ static int
370
+ str_end_with_word(const char *s, long l, const char *w)
371
+ {
372
+ int n = (int)strlen(w);
373
+ if (l <= n || !isspace((unsigned char)s[l - n - 1])) return 0;
374
+ if (strncasecmp(&s[l - n], w, n)) return 0;
375
+ do ++n; while (l > n && isspace((unsigned char)s[l - n - 1]));
376
+ return n;
377
+ }
378
+
379
+ static long
380
+ shrunk_size(const char *s, long l)
381
+ {
382
+ long i, ni;
383
+ int sp = 0;
384
+ for (i = ni = 0; i < l; ++i) {
385
+ if (!isspace((unsigned char)s[i])) {
386
+ if (sp) ni++;
387
+ sp = 0;
388
+ ni++;
389
+ }
390
+ else {
391
+ sp = 1;
392
+ }
393
+ }
394
+ return ni < l ? ni : 0;
395
+ }
396
+
397
+ static long
398
+ shrink_space(char *d, const char *s, long l)
399
+ {
400
+ long i, ni;
401
+ int sp = 0;
402
+ for (i = ni = 0; i < l; ++i) {
403
+ if (!isspace((unsigned char)s[i])) {
404
+ if (sp) d[ni++] = ' ';
405
+ sp = 0;
406
+ d[ni++] = s[i];
407
+ }
408
+ else {
409
+ sp = 1;
410
+ }
411
+ }
412
+ return ni;
413
+ }
414
+
415
+ VALUE
416
+ date_zone_to_diff(VALUE str)
417
+ {
418
+ VALUE offset = Qnil;
419
+ long l = RSTRING_LEN(str);
420
+ const char *s = RSTRING_PTR(str);
421
+
422
+ {
423
+ int dst = 0;
424
+ int w;
425
+
426
+ if ((w = str_end_with_word(s, l, "time")) > 0) {
427
+ int wtime = w;
428
+ l -= w;
429
+ if ((w = str_end_with_word(s, l, "standard")) > 0) {
430
+ l -= w;
431
+ }
432
+ else if ((w = str_end_with_word(s, l, "daylight")) > 0) {
433
+ l -= w;
434
+ dst = 1;
435
+ }
436
+ else {
437
+ l += wtime;
438
+ }
439
+ }
440
+ else if ((w = str_end_with_word(s, l, "dst")) > 0) {
441
+ l -= w;
442
+ dst = 1;
443
+ }
444
+
445
+ {
446
+ const char *zn = s;
447
+ long sl = shrunk_size(s, l);
448
+ char shrunk_buff[MAX_WORD_LENGTH]; /* no terminator to be added */
449
+ const struct zone *z = 0;
450
+
451
+ if (sl <= 0) {
452
+ sl = l;
453
+ }
454
+ else if (sl <= MAX_WORD_LENGTH) {
455
+ char *d = shrunk_buff;
456
+ sl = shrink_space(d, s, l);
457
+ zn = d;
458
+ }
459
+
460
+ if (sl > 0 && sl <= MAX_WORD_LENGTH) {
461
+ z = zonetab(zn, (unsigned int)sl);
462
+ }
463
+
464
+ if (z) {
465
+ int d = z->offset;
466
+ if (dst)
467
+ d += 3600;
468
+ offset = INT2FIX(d);
469
+ goto ok;
470
+ }
471
+ }
472
+
473
+ {
474
+ char *p;
475
+ int sign = 0;
476
+ long hour = 0, min = 0, sec = 0;
477
+
478
+ if (l > 3 &&
479
+ (strncasecmp(s, "gmt", 3) == 0 ||
480
+ strncasecmp(s, "utc", 3) == 0)) {
481
+ s += 3;
482
+ l -= 3;
483
+ }
484
+ if (issign(*s)) {
485
+ sign = *s == '-';
486
+ s++;
487
+ l--;
488
+
489
+ #define out_of_range(v, min, max) ((v) < (min) || (max) < (v))
490
+ hour = STRTOUL(s, &p, 10);
491
+ if (*p == ':') {
492
+ if (out_of_range(hour, 0, 23)) return Qnil;
493
+ s = ++p;
494
+ min = STRTOUL(s, &p, 10);
495
+ if (out_of_range(min, 0, 59)) return Qnil;
496
+ if (*p == ':') {
497
+ s = ++p;
498
+ sec = STRTOUL(s, &p, 10);
499
+ if (out_of_range(sec, 0, 59)) return Qnil;
500
+ }
501
+ }
502
+ else if (*p == ',' || *p == '.') {
503
+ /* fractional hour */
504
+ size_t n;
505
+ int ov;
506
+ /* no over precision for offset; 10**-7 hour = 0.36
507
+ * milliseconds should be enough. */
508
+ const size_t max_digits = 7; /* 36 * 10**7 < 32-bit FIXNUM_MAX */
509
+
510
+ if (out_of_range(hour, 0, 23)) return Qnil;
511
+
512
+ n = (s + l) - ++p;
513
+ if (n > max_digits) n = max_digits;
514
+ sec = ruby_scan_digits(p, n, 10, &n, &ov);
515
+ if ((p += n) < s + l && *p >= ('5' + !(sec & 1)) && *p <= '9') {
516
+ /* round half to even */
517
+ sec++;
518
+ }
519
+ sec *= 36;
520
+ if (sign) {
521
+ hour = -hour;
522
+ sec = -sec;
523
+ }
524
+ if (n <= 2) {
525
+ /* HH.nn or HH.n */
526
+ if (n == 1) sec *= 10;
527
+ offset = INT2FIX(sec + hour * 3600);
528
+ }
529
+ else {
530
+ VALUE denom = rb_int_positive_pow(10, (int)(n - 2));
531
+ offset = f_add(rb_rational_new(INT2FIX(sec), denom), INT2FIX(hour * 3600));
532
+ if (rb_rational_den(offset) == INT2FIX(1)) {
533
+ offset = rb_rational_num(offset);
534
+ }
535
+ }
536
+ goto ok;
537
+ }
538
+ else if (l > 2) {
539
+ size_t n;
540
+ int ov;
541
+
542
+ if (l >= 1)
543
+ hour = ruby_scan_digits(&s[0], 2 - l % 2, 10, &n, &ov);
544
+ if (l >= 3)
545
+ min = ruby_scan_digits(&s[2 - l % 2], 2, 10, &n, &ov);
546
+ if (l >= 5)
547
+ sec = ruby_scan_digits(&s[4 - l % 2], 2, 10, &n, &ov);
548
+ }
549
+ sec += min * 60 + hour * 3600;
550
+ if (sign) sec = -sec;
551
+ offset = INT2FIX(sec);
552
+ #undef out_of_range
553
+ }
554
+ }
555
+ }
556
+ RB_GC_GUARD(str);
557
+ ok:
558
+ return offset;
559
+ }
560
+
561
+ static int
562
+ day_num(VALUE s)
563
+ {
564
+ int i;
565
+
566
+ for (i = 0; i < (int)sizeof_array(abbr_days); i++)
567
+ if (strncasecmp(abbr_days[i], RSTRING_PTR(s), 3) == 0)
568
+ break;
569
+ return i;
570
+ }
571
+
572
+ static int
573
+ mon_num(VALUE s)
574
+ {
575
+ int i;
576
+
577
+ for (i = 0; i < (int)sizeof_array(abbr_months); i++)
578
+ if (strncasecmp(abbr_months[i], RSTRING_PTR(s), 3) == 0)
579
+ break;
580
+ return i + 1;
581
+ }
582
+
583
+ static int
584
+ parse_day_cb(VALUE m, VALUE hash)
585
+ {
586
+ VALUE s;
587
+
588
+ s = rb_reg_nth_match(1, m);
589
+ set_hash("wday", INT2FIX(day_num(s)));
590
+ return 1;
591
+ }
592
+
593
+ static int
594
+ parse_day(VALUE str, VALUE hash)
595
+ {
596
+ static const char pat_source[] =
597
+ #ifndef TIGHT_PARSER
598
+ "\\b(" ABBR_DAYS ")[^-/\\d\\s]*"
599
+ #else
600
+ "(" VALID_DAYS ")"
601
+ #endif
602
+ ;
603
+ static VALUE pat = Qnil;
604
+
605
+ REGCOMP_I(pat);
606
+ #ifndef TIGHT_PARSER
607
+ SUBS(str, pat, parse_day_cb);
608
+ #else
609
+ SUBW(str, pat, parse_day_cb);
610
+ #endif
611
+ }
612
+
613
+ static int
614
+ parse_time2_cb(VALUE m, VALUE hash)
615
+ {
616
+ VALUE h, min, s, f, p;
617
+
618
+ h = rb_reg_nth_match(1, m);
619
+ h = str2num(h);
620
+
621
+ min = rb_reg_nth_match(2, m);
622
+ if (!NIL_P(min))
623
+ min = str2num(min);
624
+
625
+ s = rb_reg_nth_match(3, m);
626
+ if (!NIL_P(s))
627
+ s = str2num(s);
628
+
629
+ f = rb_reg_nth_match(4, m);
630
+
631
+ if (!NIL_P(f))
632
+ f = rb_rational_new2(str2num(f),
633
+ f_expt(INT2FIX(10), LONG2NUM(RSTRING_LEN(f))));
634
+
635
+ p = rb_reg_nth_match(5, m);
636
+
637
+ if (!NIL_P(p)) {
638
+ int ih = NUM2INT(h);
639
+ ih %= 12;
640
+ if (*RSTRING_PTR(p) == 'P' || *RSTRING_PTR(p) == 'p')
641
+ ih += 12;
642
+ h = INT2FIX(ih);
643
+ }
644
+
645
+ set_hash("hour", h);
646
+ if (!NIL_P(min))
647
+ set_hash("min", min);
648
+ if (!NIL_P(s))
649
+ set_hash("sec", s);
650
+ if (!NIL_P(f))
651
+ set_hash("sec_fraction", f);
652
+
653
+ return 1;
654
+ }
655
+
656
+ static int
657
+ parse_time_cb(VALUE m, VALUE hash)
658
+ {
659
+ static const char pat_source[] =
660
+ "\\A(\\d+)h?"
661
+ "(?:\\s*:?\\s*(\\d+)m?"
662
+ "(?:"
663
+ "\\s*:?\\s*(\\d+)(?:[,.](\\d+))?s?"
664
+ ")?"
665
+ ")?"
666
+ "(?:\\s*([ap])(?:m\\b|\\.m\\.))?";
667
+ static VALUE pat = Qnil;
668
+ VALUE s1, s2;
669
+
670
+ s1 = rb_reg_nth_match(1, m);
671
+ s2 = rb_reg_nth_match(2, m);
672
+
673
+ if (!NIL_P(s2))
674
+ set_hash("zone", s2);
675
+
676
+ REGCOMP_I(pat);
677
+
678
+ {
679
+ VALUE m = f_match(pat, s1);
680
+
681
+ if (NIL_P(m))
682
+ return 0;
683
+ parse_time2_cb(m, hash);
684
+ }
685
+
686
+ return 1;
687
+ }
688
+
689
+ static int
690
+ parse_time(VALUE str, VALUE hash)
691
+ {
692
+ static const char pat_source[] =
693
+ "("
694
+ "" NUMBER "+\\s*"
695
+ "(?:"
696
+ "(?:"
697
+ ":\\s*\\d+"
698
+ "(?:"
699
+ #ifndef TIGHT_PARSER
700
+ "\\s*:\\s*\\d+(?:[,.]\\d*)?"
701
+ #else
702
+ "\\s*:\\s*\\d+(?:[,.]\\d+)?"
703
+ #endif
704
+ ")?"
705
+ "|"
706
+ "h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?"
707
+ ")"
708
+ "(?:"
709
+ "\\s*"
710
+ "[ap](?:m\\b|\\.m\\.)"
711
+ ")?"
712
+ "|"
713
+ "[ap](?:m\\b|\\.m\\.)"
714
+ ")"
715
+ ")"
716
+ "(?:"
717
+ "\\s*"
718
+ "("
719
+ "(?:gmt|utc?)?[-+]\\d+(?:[,.:]\\d+(?::\\d+)?)?"
720
+ "|"
721
+ "(?-i:[[:alpha:].\\s]+)(?:standard|daylight)\\stime\\b"
722
+ "|"
723
+ "(?-i:[[:alpha:]]+)(?:\\sdst)?\\b"
724
+ ")"
725
+ ")?";
726
+ static VALUE pat = Qnil;
727
+
728
+ REGCOMP_I(pat);
729
+ #ifndef TIGHT_PARSER
730
+ SUBS(str, pat, parse_time_cb);
731
+ #else
732
+ SUBT(str, pat, parse_time_cb);
733
+ #endif
734
+ }
735
+
736
+ #define BEGIN_ERA "\\b"
737
+ #define END_ERA "(?!(?<!\\.)[a-z])"
738
+
739
+ #ifdef TIGHT_PARSER
740
+ static int
741
+ parse_era1_cb(VALUE m, VALUE hash)
742
+ {
743
+ return 1;
744
+ }
745
+
746
+ static int
747
+ parse_era1(VALUE str, VALUE hash)
748
+ {
749
+ static const char pat_source[] =
750
+ BEGIN_ERA "(a(?:d\\b|\\.d\\.))" END_ERA;
751
+ static VALUE pat = Qnil;
752
+
753
+ REGCOMP_I(pat);
754
+ SUBA(str, pat, parse_era1_cb);
755
+ }
756
+
757
+ static int
758
+ parse_era2_cb(VALUE m, VALUE hash)
759
+ {
760
+ VALUE b;
761
+
762
+ b = rb_reg_nth_match(1, m);
763
+ if (*RSTRING_PTR(b) == 'B' ||
764
+ *RSTRING_PTR(b) == 'b')
765
+ set_hash("_bc", Qtrue);
766
+ return 1;
767
+ }
768
+
769
+ static int
770
+ parse_era2(VALUE str, VALUE hash)
771
+ {
772
+ static const char pat_source[] = BEGIN_ERA
773
+ "(c(?:e\\b|\\.e\\.)|b(?:ce\\b|\\.c\\.e\\.)|b(?:c\\b|\\.c\\.))"
774
+ END_ERA;
775
+ static VALUE pat = Qnil;
776
+
777
+ REGCOMP_I(pat);
778
+ SUBB(str, pat, parse_era2_cb);
779
+ }
780
+
781
+ static int
782
+ parse_era(VALUE str, VALUE hash)
783
+ {
784
+ if (parse_era1(str, hash)) /* pre */
785
+ goto ok;
786
+ if (parse_era2(str, hash)) /* post */
787
+ goto ok;
788
+ return 0;
789
+ ok:
790
+ return 1;
791
+ }
792
+ #endif
793
+
794
+ #ifdef TIGHT_PARSER
795
+ static int
796
+ check_year_width(VALUE y)
797
+ {
798
+ const char *s;
799
+ long l;
800
+
801
+ l = RSTRING_LEN(y);
802
+ if (l < 2) return 0;
803
+ s = RSTRING_PTR(y);
804
+ if (!isdigit((unsigned char)s[1])) return 0;
805
+ return (l == 2 || !isdigit((unsigned char)s[2]));
806
+ }
807
+
808
+ static int
809
+ check_apost(VALUE a, VALUE b, VALUE c)
810
+ {
811
+ int f = 0;
812
+
813
+ if (!NIL_P(a) && *RSTRING_PTR(a) == '\'') {
814
+ if (!check_year_width(a))
815
+ return 0;
816
+ f++;
817
+ }
818
+ if (!NIL_P(b) && *RSTRING_PTR(b) == '\'') {
819
+ if (!check_year_width(b))
820
+ return 0;
821
+ if (!NIL_P(c))
822
+ return 0;
823
+ f++;
824
+ }
825
+ if (!NIL_P(c) && *RSTRING_PTR(c) == '\'') {
826
+ if (!check_year_width(c))
827
+ return 0;
828
+ f++;
829
+ }
830
+ if (f > 1)
831
+ return 0;
832
+ return 1;
833
+ }
834
+ #endif
835
+
836
+ static int
837
+ parse_eu_cb(VALUE m, VALUE hash)
838
+ {
839
+ #ifndef TIGHT_PARSER
840
+ VALUE y, mon, d, b;
841
+
842
+ d = rb_reg_nth_match(1, m);
843
+ mon = rb_reg_nth_match(2, m);
844
+ b = rb_reg_nth_match(3, m);
845
+ y = rb_reg_nth_match(4, m);
846
+
847
+ mon = INT2FIX(mon_num(mon));
848
+
849
+ s3e(hash, y, mon, d, !NIL_P(b) &&
850
+ (*RSTRING_PTR(b) == 'B' ||
851
+ *RSTRING_PTR(b) == 'b'));
852
+ #else
853
+ VALUE y, mon, d;
854
+
855
+ d = rb_reg_nth_match(1, m);
856
+ mon = rb_reg_nth_match(2, m);
857
+ y = rb_reg_nth_match(3, m);
858
+
859
+ if (!check_apost(d, mon, y))
860
+ return 0;
861
+
862
+ mon = INT2FIX(mon_num(mon));
863
+
864
+ s3e(hash, y, mon, d, 0);
865
+ #endif
866
+ return 1;
867
+ }
868
+
869
+ static int
870
+ parse_eu(VALUE str, VALUE hash)
871
+ {
872
+ static const char pat_source[] =
873
+ #ifdef TIGHT_PARSER
874
+ BOS
875
+ FPW_COM FPT_COM
876
+ #endif
877
+ #ifndef TIGHT_PARSER
878
+ "('?" NUMBER "+)[^-\\d\\s]*"
879
+ #else
880
+ "(\\d+)(?:(?:st|nd|rd|th)\\b)?"
881
+ #endif
882
+ "\\s*"
883
+ #ifndef TIGHT_PARSER
884
+ "(" ABBR_MONTHS ")[^-\\d\\s']*"
885
+ #else
886
+ "(" VALID_MONTHS ")"
887
+ #endif
888
+ "(?:"
889
+ "\\s*"
890
+ #ifndef TIGHT_PARSER
891
+ "(?:"
892
+ BEGIN_ERA
893
+ "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))"
894
+ END_ERA
895
+ ")?"
896
+ "\\s*"
897
+ "('?-?\\d+(?:(?:st|nd|rd|th)\\b)?)"
898
+ #else
899
+ "(?:" FPA ")?"
900
+ "\\s*"
901
+ "([-']?\\d+)"
902
+ "\\s*"
903
+ "(?:" FPA "|" FPB ")?"
904
+ #endif
905
+ ")?"
906
+ #ifdef TIGHT_PARSER
907
+ COM_FPT COM_FPW
908
+ EOS
909
+ #endif
910
+ ;
911
+ static VALUE pat = Qnil;
912
+
913
+ REGCOMP_I(pat);
914
+ SUBS(str, pat, parse_eu_cb);
915
+ }
916
+
917
+ static int
918
+ parse_us_cb(VALUE m, VALUE hash)
919
+ {
920
+ #ifndef TIGHT_PARSER
921
+ VALUE y, mon, d, b;
922
+
923
+ mon = rb_reg_nth_match(1, m);
924
+ d = rb_reg_nth_match(2, m);
925
+
926
+ b = rb_reg_nth_match(3, m);
927
+ y = rb_reg_nth_match(4, m);
928
+
929
+ mon = INT2FIX(mon_num(mon));
930
+
931
+ s3e(hash, y, mon, d, !NIL_P(b) &&
932
+ (*RSTRING_PTR(b) == 'B' ||
933
+ *RSTRING_PTR(b) == 'b'));
934
+ #else
935
+ VALUE y, mon, d;
936
+
937
+ mon = rb_reg_nth_match(1, m);
938
+ d = rb_reg_nth_match(2, m);
939
+ y = rb_reg_nth_match(3, m);
940
+
941
+ if (!check_apost(mon, d, y))
942
+ return 0;
943
+
944
+ mon = INT2FIX(mon_num(mon));
945
+
946
+ s3e(hash, y, mon, d, 0);
947
+ #endif
948
+ return 1;
949
+ }
950
+
951
+ static int
952
+ parse_us(VALUE str, VALUE hash)
953
+ {
954
+ static const char pat_source[] =
955
+ #ifdef TIGHT_PARSER
956
+ BOS
957
+ FPW_COM FPT_COM
958
+ #endif
959
+ #ifndef TIGHT_PARSER
960
+ "\\b(" ABBR_MONTHS ")[^-\\d\\s']*"
961
+ #else
962
+ "\\b(" VALID_MONTHS ")"
963
+ #endif
964
+ "\\s*"
965
+ #ifndef TIGHT_PARSER
966
+ "('?\\d+)[^-\\d\\s']*"
967
+ #else
968
+ "('?\\d+)(?:(?:st|nd|rd|th)\\b)?"
969
+ COM_FPT
970
+ #endif
971
+ "(?:"
972
+ "\\s*+,?"
973
+ "\\s*+"
974
+ #ifndef TIGHT_PARSER
975
+ "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?"
976
+ "\\s*"
977
+ "('?-?\\d+)"
978
+ #else
979
+ "(?:" FPA ")?"
980
+ "\\s*"
981
+ "([-']?\\d+)"
982
+ "\\s*"
983
+ "(?:" FPA "|" FPB ")?"
984
+ #endif
985
+ ")?"
986
+ #ifdef TIGHT_PARSER
987
+ COM_FPT COM_FPW
988
+ EOS
989
+ #endif
990
+ ;
991
+ static VALUE pat = Qnil;
992
+
993
+ REGCOMP_I(pat);
994
+ SUBS(str, pat, parse_us_cb);
995
+ }
996
+
997
+ static int
998
+ parse_iso_cb(VALUE m, VALUE hash)
999
+ {
1000
+ VALUE y, mon, d;
1001
+
1002
+ y = rb_reg_nth_match(1, m);
1003
+ mon = rb_reg_nth_match(2, m);
1004
+ d = rb_reg_nth_match(3, m);
1005
+
1006
+ #ifdef TIGHT_PARSER
1007
+ if (!check_apost(y, mon, d))
1008
+ return 0;
1009
+ #endif
1010
+
1011
+ s3e(hash, y, mon, d, 0);
1012
+ return 1;
1013
+ }
1014
+
1015
+ static int
1016
+ parse_iso(VALUE str, VALUE hash)
1017
+ {
1018
+ static const char pat_source[] =
1019
+ #ifndef TIGHT_PARSER
1020
+ "('?[-+]?" NUMBER "+)-(\\d+)-('?-?\\d+)"
1021
+ #else
1022
+ BOS
1023
+ FPW_COM FPT_COM
1024
+ "([-+']?\\d+)-(\\d+)-([-']?\\d+)"
1025
+ TEE_FPT COM_FPW
1026
+ EOS
1027
+ #endif
1028
+ ;
1029
+ static VALUE pat = Qnil;
1030
+
1031
+ REGCOMP_0(pat);
1032
+ SUBS(str, pat, parse_iso_cb);
1033
+ }
1034
+
1035
+ static int
1036
+ parse_iso21_cb(VALUE m, VALUE hash)
1037
+ {
1038
+ VALUE y, w, d;
1039
+
1040
+ y = rb_reg_nth_match(1, m);
1041
+ w = rb_reg_nth_match(2, m);
1042
+ d = rb_reg_nth_match(3, m);
1043
+
1044
+ if (!NIL_P(y))
1045
+ set_hash("cwyear", str2num(y));
1046
+ set_hash("cweek", str2num(w));
1047
+ if (!NIL_P(d))
1048
+ set_hash("cwday", str2num(d));
1049
+
1050
+ return 1;
1051
+ }
1052
+
1053
+ static int
1054
+ parse_iso21(VALUE str, VALUE hash)
1055
+ {
1056
+ static const char pat_source[] =
1057
+ #ifndef TIGHT_PARSER
1058
+ "\\b(\\d{2}|\\d{4})?-?w(\\d{2})(?:-?(\\d))?\\b"
1059
+ #else
1060
+ BOS
1061
+ FPW_COM FPT_COM
1062
+ "(\\d{2}|\\d{4})?-?w(\\d{2})(?:-?(\\d))?"
1063
+ TEE_FPT COM_FPW
1064
+ EOS
1065
+ #endif
1066
+ ;
1067
+ static VALUE pat = Qnil;
1068
+
1069
+ REGCOMP_I(pat);
1070
+ SUBS(str, pat, parse_iso21_cb);
1071
+ }
1072
+
1073
+ static int
1074
+ parse_iso22_cb(VALUE m, VALUE hash)
1075
+ {
1076
+ VALUE d;
1077
+
1078
+ d = rb_reg_nth_match(1, m);
1079
+ set_hash("cwday", str2num(d));
1080
+ return 1;
1081
+ }
1082
+
1083
+ static int
1084
+ parse_iso22(VALUE str, VALUE hash)
1085
+ {
1086
+ static const char pat_source[] =
1087
+ #ifndef TIGHT_PARSER
1088
+ "-w-(\\d)\\b"
1089
+ #else
1090
+ BOS
1091
+ FPW_COM FPT_COM
1092
+ "-w-(\\d)"
1093
+ TEE_FPT COM_FPW
1094
+ EOS
1095
+ #endif
1096
+ ;
1097
+ static VALUE pat = Qnil;
1098
+
1099
+ REGCOMP_I(pat);
1100
+ SUBS(str, pat, parse_iso22_cb);
1101
+ }
1102
+
1103
+ static int
1104
+ parse_iso23_cb(VALUE m, VALUE hash)
1105
+ {
1106
+ VALUE mon, d;
1107
+
1108
+ mon = rb_reg_nth_match(1, m);
1109
+ d = rb_reg_nth_match(2, m);
1110
+
1111
+ if (!NIL_P(mon))
1112
+ set_hash("mon", str2num(mon));
1113
+ set_hash("mday", str2num(d));
1114
+
1115
+ return 1;
1116
+ }
1117
+
1118
+ static int
1119
+ parse_iso23(VALUE str, VALUE hash)
1120
+ {
1121
+ static const char pat_source[] =
1122
+ #ifndef TIGHT_PARSER
1123
+ "--(\\d{2})?-(\\d{2})\\b"
1124
+ #else
1125
+ BOS
1126
+ FPW_COM FPT_COM
1127
+ "--(\\d{2})?-(\\d{2})"
1128
+ TEE_FPT COM_FPW
1129
+ EOS
1130
+ #endif
1131
+ ;
1132
+ static VALUE pat = Qnil;
1133
+
1134
+ REGCOMP_0(pat);
1135
+ SUBS(str, pat, parse_iso23_cb);
1136
+ }
1137
+
1138
+ static int
1139
+ parse_iso24_cb(VALUE m, VALUE hash)
1140
+ {
1141
+ VALUE mon, d;
1142
+
1143
+ mon = rb_reg_nth_match(1, m);
1144
+ d = rb_reg_nth_match(2, m);
1145
+
1146
+ set_hash("mon", str2num(mon));
1147
+ if (!NIL_P(d))
1148
+ set_hash("mday", str2num(d));
1149
+
1150
+ return 1;
1151
+ }
1152
+
1153
+ static int
1154
+ parse_iso24(VALUE str, VALUE hash)
1155
+ {
1156
+ static const char pat_source[] =
1157
+ #ifndef TIGHT_PARSER
1158
+ "--(\\d{2})(\\d{2})?\\b"
1159
+ #else
1160
+ BOS
1161
+ FPW_COM FPT_COM
1162
+ "--(\\d{2})(\\d{2})?"
1163
+ TEE_FPT COM_FPW
1164
+ EOS
1165
+ #endif
1166
+ ;
1167
+ static VALUE pat = Qnil;
1168
+
1169
+ REGCOMP_0(pat);
1170
+ SUBS(str, pat, parse_iso24_cb);
1171
+ }
1172
+
1173
+ static int
1174
+ parse_iso25_cb(VALUE m, VALUE hash)
1175
+ {
1176
+ VALUE y, d;
1177
+
1178
+ y = rb_reg_nth_match(1, m);
1179
+ d = rb_reg_nth_match(2, m);
1180
+
1181
+ set_hash("year", str2num(y));
1182
+ set_hash("yday", str2num(d));
1183
+
1184
+ return 1;
1185
+ }
1186
+
1187
+ static int
1188
+ parse_iso25(VALUE str, VALUE hash)
1189
+ {
1190
+ static const char pat0_source[] =
1191
+ #ifndef TIGHT_PARSER
1192
+ "[,.](\\d{2}|\\d{4})-\\d{3}\\b"
1193
+ #else
1194
+ BOS
1195
+ FPW_COM FPT_COM
1196
+ "[,.](\\d{2}|\\d{4})-\\d{3}"
1197
+ TEE_FPT COM_FPW
1198
+ EOS
1199
+ #endif
1200
+ ;
1201
+ static VALUE pat0 = Qnil;
1202
+ static const char pat_source[] =
1203
+ #ifndef TIGHT_PARSER
1204
+ "\\b(\\d{2}|\\d{4})-(\\d{3})\\b"
1205
+ #else
1206
+ BOS
1207
+ FPW_COM FPT_COM
1208
+ "(\\d{2}|\\d{4})-(\\d{3})"
1209
+ TEE_FPT COM_FPW
1210
+ EOS
1211
+ #endif
1212
+ ;
1213
+ static VALUE pat = Qnil;
1214
+
1215
+ REGCOMP_0(pat0);
1216
+ REGCOMP_0(pat);
1217
+
1218
+ if (!NIL_P(f_match(pat0, str)))
1219
+ return 0;
1220
+ SUBS(str, pat, parse_iso25_cb);
1221
+ }
1222
+
1223
+ static int
1224
+ parse_iso26_cb(VALUE m, VALUE hash)
1225
+ {
1226
+ VALUE d;
1227
+
1228
+ d = rb_reg_nth_match(1, m);
1229
+ set_hash("yday", str2num(d));
1230
+
1231
+ return 1;
1232
+ }
1233
+ static int
1234
+ parse_iso26(VALUE str, VALUE hash)
1235
+ {
1236
+ static const char pat0_source[] =
1237
+ #ifndef TIGHT_PARSER
1238
+ "\\d-\\d{3}\\b"
1239
+ #else
1240
+ BOS
1241
+ FPW_COM FPT_COM
1242
+ "\\d-\\d{3}"
1243
+ TEE_FPT COM_FPW
1244
+ EOS
1245
+ #endif
1246
+ ;
1247
+ static VALUE pat0 = Qnil;
1248
+ static const char pat_source[] =
1249
+ #ifndef TIGHT_PARSER
1250
+ "\\b-(\\d{3})\\b"
1251
+ #else
1252
+ BOS
1253
+ FPW_COM FPT_COM
1254
+ "-(\\d{3})"
1255
+ TEE_FPT COM_FPW
1256
+ EOS
1257
+ #endif
1258
+ ;
1259
+ static VALUE pat = Qnil;
1260
+
1261
+ REGCOMP_0(pat0);
1262
+ REGCOMP_0(pat);
1263
+
1264
+ if (!NIL_P(f_match(pat0, str)))
1265
+ return 0;
1266
+ SUBS(str, pat, parse_iso26_cb);
1267
+ }
1268
+
1269
+ static int
1270
+ parse_iso2(VALUE str, VALUE hash)
1271
+ {
1272
+ if (parse_iso21(str, hash))
1273
+ goto ok;
1274
+ if (parse_iso22(str, hash))
1275
+ goto ok;
1276
+ if (parse_iso23(str, hash))
1277
+ goto ok;
1278
+ if (parse_iso24(str, hash))
1279
+ goto ok;
1280
+ if (parse_iso25(str, hash))
1281
+ goto ok;
1282
+ if (parse_iso26(str, hash))
1283
+ goto ok;
1284
+ return 0;
1285
+
1286
+ ok:
1287
+ return 1;
1288
+ }
1289
+
1290
+ #define JISX0301_ERA_INITIALS "mtshr"
1291
+ #define JISX0301_DEFAULT_ERA 'H' /* obsolete */
1292
+
1293
+ static int
1294
+ gengo(int c)
1295
+ {
1296
+ int e;
1297
+
1298
+ switch (c) {
1299
+ case 'M': case 'm': e = 1867; break;
1300
+ case 'T': case 't': e = 1911; break;
1301
+ case 'S': case 's': e = 1925; break;
1302
+ case 'H': case 'h': e = 1988; break;
1303
+ case 'R': case 'r': e = 2018; break;
1304
+ default: e = 0; break;
1305
+ }
1306
+ return e;
1307
+ }
1308
+
1309
+ static int
1310
+ parse_jis_cb(VALUE m, VALUE hash)
1311
+ {
1312
+ VALUE e, y, mon, d;
1313
+ int ep;
1314
+
1315
+ e = rb_reg_nth_match(1, m);
1316
+ y = rb_reg_nth_match(2, m);
1317
+ mon = rb_reg_nth_match(3, m);
1318
+ d = rb_reg_nth_match(4, m);
1319
+
1320
+ ep = gengo(*RSTRING_PTR(e));
1321
+
1322
+ set_hash("year", f_add(str2num(y), INT2FIX(ep)));
1323
+ set_hash("mon", str2num(mon));
1324
+ set_hash("mday", str2num(d));
1325
+
1326
+ return 1;
1327
+ }
1328
+
1329
+ static int
1330
+ parse_jis(VALUE str, VALUE hash)
1331
+ {
1332
+ static const char pat_source[] =
1333
+ #ifndef TIGHT_PARSER
1334
+ "\\b([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
1335
+ #else
1336
+ BOS
1337
+ FPW_COM FPT_COM
1338
+ "([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
1339
+ TEE_FPT COM_FPW
1340
+ EOS
1341
+ #endif
1342
+ ;
1343
+ static VALUE pat = Qnil;
1344
+
1345
+ REGCOMP_I(pat);
1346
+ SUBS(str, pat, parse_jis_cb);
1347
+ }
1348
+
1349
+ static int
1350
+ parse_vms11_cb(VALUE m, VALUE hash)
1351
+ {
1352
+ VALUE y, mon, d;
1353
+
1354
+ d = rb_reg_nth_match(1, m);
1355
+ mon = rb_reg_nth_match(2, m);
1356
+ y = rb_reg_nth_match(3, m);
1357
+
1358
+ #ifdef TIGHT_PARSER
1359
+ if (!check_apost(d, mon, y))
1360
+ return 0;
1361
+ #endif
1362
+
1363
+ mon = INT2FIX(mon_num(mon));
1364
+
1365
+ s3e(hash, y, mon, d, 0);
1366
+ return 1;
1367
+ }
1368
+
1369
+ static int
1370
+ parse_vms11(VALUE str, VALUE hash)
1371
+ {
1372
+ static const char pat_source[] =
1373
+ #ifndef TIGHT_PARSER
1374
+ "('?-?" NUMBER "+)-(" ABBR_MONTHS ")[^-/.]*"
1375
+ "-('?-?\\d+)"
1376
+ #else
1377
+ BOS
1378
+ FPW_COM FPT_COM
1379
+ "([-']?\\d+)-(" DOTLESS_VALID_MONTHS ")"
1380
+ "-([-']?\\d+)"
1381
+ COM_FPT COM_FPW
1382
+ EOS
1383
+ #endif
1384
+ ;
1385
+ static VALUE pat = Qnil;
1386
+
1387
+ REGCOMP_I(pat);
1388
+ SUBS(str, pat, parse_vms11_cb);
1389
+ }
1390
+
1391
+ static int
1392
+ parse_vms12_cb(VALUE m, VALUE hash)
1393
+ {
1394
+ VALUE y, mon, d;
1395
+
1396
+ mon = rb_reg_nth_match(1, m);
1397
+ d = rb_reg_nth_match(2, m);
1398
+ y = rb_reg_nth_match(3, m);
1399
+
1400
+ #ifdef TIGHT_PARSER
1401
+ if (!check_apost(mon, d, y))
1402
+ return 0;
1403
+ #endif
1404
+
1405
+ mon = INT2FIX(mon_num(mon));
1406
+
1407
+ s3e(hash, y, mon, d, 0);
1408
+ return 1;
1409
+ }
1410
+
1411
+ static int
1412
+ parse_vms12(VALUE str, VALUE hash)
1413
+ {
1414
+ static const char pat_source[] =
1415
+ #ifndef TIGHT_PARSER
1416
+ "\\b(" ABBR_MONTHS ")[^-/.]*"
1417
+ "-('?-?\\d+)(?:-('?-?\\d+))?"
1418
+ #else
1419
+ BOS
1420
+ FPW_COM FPT_COM
1421
+ "(" DOTLESS_VALID_MONTHS ")"
1422
+ "-([-']?\\d+)(?:-([-']?\\d+))?"
1423
+ COM_FPT COM_FPW
1424
+ EOS
1425
+ #endif
1426
+ ;
1427
+ static VALUE pat = Qnil;
1428
+
1429
+ REGCOMP_I(pat);
1430
+ SUBS(str, pat, parse_vms12_cb);
1431
+ }
1432
+
1433
+ static int
1434
+ parse_vms(VALUE str, VALUE hash)
1435
+ {
1436
+ if (parse_vms11(str, hash))
1437
+ goto ok;
1438
+ if (parse_vms12(str, hash))
1439
+ goto ok;
1440
+ return 0;
1441
+
1442
+ ok:
1443
+ return 1;
1444
+ }
1445
+
1446
+ static int
1447
+ parse_sla_cb(VALUE m, VALUE hash)
1448
+ {
1449
+ VALUE y, mon, d;
1450
+
1451
+ y = rb_reg_nth_match(1, m);
1452
+ mon = rb_reg_nth_match(2, m);
1453
+ d = rb_reg_nth_match(3, m);
1454
+
1455
+ #ifdef TIGHT_PARSER
1456
+ if (!check_apost(y, mon, d))
1457
+ return 0;
1458
+ #endif
1459
+
1460
+ s3e(hash, y, mon, d, 0);
1461
+ return 1;
1462
+ }
1463
+
1464
+ static int
1465
+ parse_sla(VALUE str, VALUE hash)
1466
+ {
1467
+ static const char pat_source[] =
1468
+ #ifndef TIGHT_PARSER
1469
+ "('?-?" NUMBER "+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?"
1470
+ #else
1471
+ BOS
1472
+ FPW_COM FPT_COM
1473
+ "([-']?\\d+)/\\s*('?\\d+)(?:(?:[-/]|\\s+)\\s*([-']?\\d+))?"
1474
+ COM_FPT COM_FPW
1475
+ EOS
1476
+ #endif
1477
+ ;
1478
+ static VALUE pat = Qnil;
1479
+
1480
+ REGCOMP_I(pat);
1481
+ SUBS(str, pat, parse_sla_cb);
1482
+ }
1483
+
1484
+ #ifdef TIGHT_PARSER
1485
+ static int
1486
+ parse_sla2_cb(VALUE m, VALUE hash)
1487
+ {
1488
+ VALUE y, mon, d;
1489
+
1490
+ d = rb_reg_nth_match(1, m);
1491
+ mon = rb_reg_nth_match(2, m);
1492
+ y = rb_reg_nth_match(3, m);
1493
+
1494
+ if (!check_apost(d, mon, y))
1495
+ return 0;
1496
+
1497
+ mon = INT2FIX(mon_num(mon));
1498
+
1499
+ s3e(hash, y, mon, d, 0);
1500
+ return 1;
1501
+ }
1502
+
1503
+ static int
1504
+ parse_sla2(VALUE str, VALUE hash)
1505
+ {
1506
+ static const char pat_source[] =
1507
+ BOS
1508
+ FPW_COM FPT_COM
1509
+ "([-']?\\d+)/\\s*(" DOTLESS_VALID_MONTHS ")(?:(?:[-/]|\\s+)\\s*([-']?\\d+))?"
1510
+ COM_FPT COM_FPW
1511
+ EOS
1512
+ ;
1513
+ static VALUE pat = Qnil;
1514
+
1515
+ REGCOMP_I(pat);
1516
+ SUBS(str, pat, parse_sla2_cb);
1517
+ }
1518
+
1519
+ static int
1520
+ parse_sla3_cb(VALUE m, VALUE hash)
1521
+ {
1522
+ VALUE y, mon, d;
1523
+
1524
+ mon = rb_reg_nth_match(1, m);
1525
+ d = rb_reg_nth_match(2, m);
1526
+ y = rb_reg_nth_match(3, m);
1527
+
1528
+ if (!check_apost(mon, d, y))
1529
+ return 0;
1530
+
1531
+ mon = INT2FIX(mon_num(mon));
1532
+
1533
+ s3e(hash, y, mon, d, 0);
1534
+ return 1;
1535
+ }
1536
+
1537
+ static int
1538
+ parse_sla3(VALUE str, VALUE hash)
1539
+ {
1540
+ static const char pat_source[] =
1541
+ BOS
1542
+ FPW_COM FPT_COM
1543
+ "(" DOTLESS_VALID_MONTHS ")/\\s*([-']?\\d+)(?:(?:[-/]|\\s+)\\s*([-']?\\d+))?"
1544
+ COM_FPT COM_FPW
1545
+ EOS
1546
+ ;
1547
+ static VALUE pat = Qnil;
1548
+
1549
+ REGCOMP_I(pat);
1550
+ SUBS(str, pat, parse_sla3_cb);
1551
+ }
1552
+ #endif
1553
+
1554
+ static int
1555
+ parse_dot_cb(VALUE m, VALUE hash)
1556
+ {
1557
+ VALUE y, mon, d;
1558
+
1559
+ y = rb_reg_nth_match(1, m);
1560
+ mon = rb_reg_nth_match(2, m);
1561
+ d = rb_reg_nth_match(3, m);
1562
+
1563
+ #ifdef TIGHT_PARSER
1564
+ if (!check_apost(y, mon, d))
1565
+ return 0;
1566
+ #endif
1567
+
1568
+ s3e(hash, y, mon, d, 0);
1569
+ return 1;
1570
+ }
1571
+
1572
+ static int
1573
+ parse_dot(VALUE str, VALUE hash)
1574
+ {
1575
+ static const char pat_source[] =
1576
+ #ifndef TIGHT_PARSER
1577
+ "('?-?" NUMBER "+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)"
1578
+ #else
1579
+ BOS
1580
+ FPW_COM FPT_COM
1581
+ "([-']?\\d+)\\.\\s*(\\d+)\\.\\s*([-']?\\d+)"
1582
+ COM_FPT COM_FPW
1583
+ EOS
1584
+ #endif
1585
+ ;
1586
+ static VALUE pat = Qnil;
1587
+
1588
+ REGCOMP_I(pat);
1589
+ SUBS(str, pat, parse_dot_cb);
1590
+ }
1591
+
1592
+ #ifdef TIGHT_PARSER
1593
+ static int
1594
+ parse_dot2_cb(VALUE m, VALUE hash)
1595
+ {
1596
+ VALUE y, mon, d;
1597
+
1598
+ d = rb_reg_nth_match(1, m);
1599
+ mon = rb_reg_nth_match(2, m);
1600
+ y = rb_reg_nth_match(3, m);
1601
+
1602
+ if (!check_apost(d, mon, y))
1603
+ return 0;
1604
+
1605
+ mon = INT2FIX(mon_num(mon));
1606
+
1607
+ s3e(hash, y, mon, d, 0);
1608
+ return 1;
1609
+ }
1610
+
1611
+ static int
1612
+ parse_dot2(VALUE str, VALUE hash)
1613
+ {
1614
+ static const char pat_source[] =
1615
+ BOS
1616
+ FPW_COM FPT_COM
1617
+ "([-']?\\d+)\\.\\s*(" DOTLESS_VALID_MONTHS ")(?:(?:[./])\\s*([-']?\\d+))?"
1618
+ COM_FPT COM_FPW
1619
+ EOS
1620
+ ;
1621
+ static VALUE pat = Qnil;
1622
+
1623
+ REGCOMP_I(pat);
1624
+ SUBS(str, pat, parse_dot2_cb);
1625
+ }
1626
+
1627
+ static int
1628
+ parse_dot3_cb(VALUE m, VALUE hash)
1629
+ {
1630
+ VALUE y, mon, d;
1631
+
1632
+ mon = rb_reg_nth_match(1, m);
1633
+ d = rb_reg_nth_match(2, m);
1634
+ y = rb_reg_nth_match(3, m);
1635
+
1636
+ if (!check_apost(mon, d, y))
1637
+ return 0;
1638
+
1639
+ mon = INT2FIX(mon_num(mon));
1640
+
1641
+ s3e(hash, y, mon, d, 0);
1642
+ return 1;
1643
+ }
1644
+
1645
+ static int
1646
+ parse_dot3(VALUE str, VALUE hash)
1647
+ {
1648
+ static const char pat_source[] =
1649
+ BOS
1650
+ FPW_COM FPT_COM
1651
+ "(" DOTLESS_VALID_MONTHS ")\\.\\s*([-']?\\d+)(?:(?:[./])\\s*([-']?\\d+))?"
1652
+ COM_FPT COM_FPW
1653
+ EOS
1654
+ ;
1655
+ static VALUE pat = Qnil;
1656
+
1657
+ REGCOMP_I(pat);
1658
+ SUBS(str, pat, parse_dot3_cb);
1659
+ }
1660
+ #endif
1661
+
1662
+ static int
1663
+ parse_year_cb(VALUE m, VALUE hash)
1664
+ {
1665
+ VALUE y;
1666
+
1667
+ y = rb_reg_nth_match(1, m);
1668
+ set_hash("year", str2num(y));
1669
+ return 1;
1670
+ }
1671
+
1672
+ static int
1673
+ parse_year(VALUE str, VALUE hash)
1674
+ {
1675
+ static const char pat_source[] =
1676
+ #ifndef TIGHT_PARSER
1677
+ "'(\\d+)\\b"
1678
+ #else
1679
+ BOS
1680
+ FPW_COM FPT_COM
1681
+ "'(\\d+)"
1682
+ COM_FPT COM_FPW
1683
+ EOS
1684
+ #endif
1685
+ ;
1686
+ static VALUE pat = Qnil;
1687
+
1688
+ REGCOMP_0(pat);
1689
+ SUBS(str, pat, parse_year_cb);
1690
+ }
1691
+
1692
+ static int
1693
+ parse_mon_cb(VALUE m, VALUE hash)
1694
+ {
1695
+ VALUE mon;
1696
+
1697
+ mon = rb_reg_nth_match(1, m);
1698
+ set_hash("mon", INT2FIX(mon_num(mon)));
1699
+ return 1;
1700
+ }
1701
+
1702
+ static int
1703
+ parse_mon(VALUE str, VALUE hash)
1704
+ {
1705
+ static const char pat_source[] =
1706
+ #ifndef TIGHT_PARSER
1707
+ "\\b(" ABBR_MONTHS ")\\S*"
1708
+ #else
1709
+ BOS
1710
+ FPW_COM FPT_COM
1711
+ "(" VALID_MONTHS ")"
1712
+ COM_FPT COM_FPW
1713
+ EOS
1714
+ #endif
1715
+ ;
1716
+ static VALUE pat = Qnil;
1717
+
1718
+ REGCOMP_I(pat);
1719
+ SUBS(str, pat, parse_mon_cb);
1720
+ }
1721
+
1722
+ static int
1723
+ parse_mday_cb(VALUE m, VALUE hash)
1724
+ {
1725
+ VALUE d;
1726
+
1727
+ d = rb_reg_nth_match(1, m);
1728
+ set_hash("mday", str2num(d));
1729
+ return 1;
1730
+ }
1731
+
1732
+ static int
1733
+ parse_mday(VALUE str, VALUE hash)
1734
+ {
1735
+ static const char pat_source[] =
1736
+ #ifndef TIGHT_PARSER
1737
+ "(" NUMBER "+)(st|nd|rd|th)\\b"
1738
+ #else
1739
+ BOS
1740
+ FPW_COM FPT_COM
1741
+ "(\\d+)(st|nd|rd|th)"
1742
+ COM_FPT COM_FPW
1743
+ EOS
1744
+ #endif
1745
+ ;
1746
+ static VALUE pat = Qnil;
1747
+
1748
+ REGCOMP_I(pat);
1749
+ SUBS(str, pat, parse_mday_cb);
1750
+ }
1751
+
1752
+ static int
1753
+ n2i(const char *s, long f, long w)
1754
+ {
1755
+ long e, i;
1756
+ int v;
1757
+
1758
+ e = f + w;
1759
+ v = 0;
1760
+ for (i = f; i < e; i++) {
1761
+ v *= 10;
1762
+ v += s[i] - '0';
1763
+ }
1764
+ return v;
1765
+ }
1766
+
1767
+ static int
1768
+ parse_ddd_cb(VALUE m, VALUE hash)
1769
+ {
1770
+ VALUE s1, s2, s3, s4, s5;
1771
+ const char *cs2, *cs3, *cs5;
1772
+ long l2, l3, l4, l5;
1773
+
1774
+ s1 = rb_reg_nth_match(1, m);
1775
+ s2 = rb_reg_nth_match(2, m);
1776
+ s3 = rb_reg_nth_match(3, m);
1777
+ s4 = rb_reg_nth_match(4, m);
1778
+ s5 = rb_reg_nth_match(5, m);
1779
+
1780
+ cs2 = RSTRING_PTR(s2);
1781
+ l2 = RSTRING_LEN(s2);
1782
+
1783
+ switch (l2) {
1784
+ case 2:
1785
+ if (NIL_P(s3) && !NIL_P(s4))
1786
+ set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1787
+ else
1788
+ set_hash("mday", INT2FIX(n2i(cs2, 0, 2)));
1789
+ break;
1790
+ case 4:
1791
+ if (NIL_P(s3) && !NIL_P(s4)) {
1792
+ set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1793
+ set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1794
+ }
1795
+ else {
1796
+ set_hash("mon", INT2FIX(n2i(cs2, 0, 2)));
1797
+ set_hash("mday", INT2FIX(n2i(cs2, 2, 2)));
1798
+ }
1799
+ break;
1800
+ case 6:
1801
+ if (NIL_P(s3) && !NIL_P(s4)) {
1802
+ set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1803
+ set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1804
+ set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2)));
1805
+ }
1806
+ else {
1807
+ int y = n2i(cs2, 0, 2);
1808
+ if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1809
+ y = -y;
1810
+ set_hash("year", INT2FIX(y));
1811
+ set_hash("mon", INT2FIX(n2i(cs2, 2, 2)));
1812
+ set_hash("mday", INT2FIX(n2i(cs2, 4, 2)));
1813
+ }
1814
+ break;
1815
+ case 8:
1816
+ case 10:
1817
+ case 12:
1818
+ case 14:
1819
+ if (NIL_P(s3) && !NIL_P(s4)) {
1820
+ set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1821
+ set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1822
+ set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2)));
1823
+ set_hash("mday", INT2FIX(n2i(cs2, l2-8, 2)));
1824
+ if (l2 >= 10)
1825
+ set_hash("mon", INT2FIX(n2i(cs2, l2-10, 2)));
1826
+ if (l2 == 12) {
1827
+ int y = n2i(cs2, l2-12, 2);
1828
+ if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1829
+ y = -y;
1830
+ set_hash("year", INT2FIX(y));
1831
+ }
1832
+ if (l2 == 14) {
1833
+ int y = n2i(cs2, l2-14, 4);
1834
+ if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1835
+ y = -y;
1836
+ set_hash("year", INT2FIX(y));
1837
+ set_hash("_comp", Qfalse);
1838
+ }
1839
+ }
1840
+ else {
1841
+ int y = n2i(cs2, 0, 4);
1842
+ if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1843
+ y = -y;
1844
+ set_hash("year", INT2FIX(y));
1845
+ set_hash("mon", INT2FIX(n2i(cs2, 4, 2)));
1846
+ set_hash("mday", INT2FIX(n2i(cs2, 6, 2)));
1847
+ if (l2 >= 10)
1848
+ set_hash("hour", INT2FIX(n2i(cs2, 8, 2)));
1849
+ if (l2 >= 12)
1850
+ set_hash("min", INT2FIX(n2i(cs2, 10, 2)));
1851
+ if (l2 >= 14)
1852
+ set_hash("sec", INT2FIX(n2i(cs2, 12, 2)));
1853
+ set_hash("_comp", Qfalse);
1854
+ }
1855
+ break;
1856
+ case 3:
1857
+ if (NIL_P(s3) && !NIL_P(s4)) {
1858
+ set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1859
+ set_hash("min", INT2FIX(n2i(cs2, l2-3, 1)));
1860
+ }
1861
+ else
1862
+ set_hash("yday", INT2FIX(n2i(cs2, 0, 3)));
1863
+ break;
1864
+ case 5:
1865
+ if (NIL_P(s3) && !NIL_P(s4)) {
1866
+ set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1867
+ set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1868
+ set_hash("hour", INT2FIX(n2i(cs2, l2-5, 1)));
1869
+ }
1870
+ else {
1871
+ int y = n2i(cs2, 0, 2);
1872
+ if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1873
+ y = -y;
1874
+ set_hash("year", INT2FIX(y));
1875
+ set_hash("yday", INT2FIX(n2i(cs2, 2, 3)));
1876
+ }
1877
+ break;
1878
+ case 7:
1879
+ if (NIL_P(s3) && !NIL_P(s4)) {
1880
+ set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1881
+ set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1882
+ set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2)));
1883
+ set_hash("mday", INT2FIX(n2i(cs2, l2-7, 1)));
1884
+ }
1885
+ else {
1886
+ int y = n2i(cs2, 0, 4);
1887
+ if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1888
+ y = -y;
1889
+ set_hash("year", INT2FIX(y));
1890
+ set_hash("yday", INT2FIX(n2i(cs2, 4, 3)));
1891
+ }
1892
+ break;
1893
+ }
1894
+ RB_GC_GUARD(s2);
1895
+ if (!NIL_P(s3)) {
1896
+ cs3 = RSTRING_PTR(s3);
1897
+ l3 = RSTRING_LEN(s3);
1898
+
1899
+ if (!NIL_P(s4)) {
1900
+ switch (l3) {
1901
+ case 2:
1902
+ case 4:
1903
+ case 6:
1904
+ set_hash("sec", INT2FIX(n2i(cs3, l3-2, 2)));
1905
+ if (l3 >= 4)
1906
+ set_hash("min", INT2FIX(n2i(cs3, l3-4, 2)));
1907
+ if (l3 >= 6)
1908
+ set_hash("hour", INT2FIX(n2i(cs3, l3-6, 2)));
1909
+ break;
1910
+ }
1911
+ }
1912
+ else {
1913
+ switch (l3) {
1914
+ case 2:
1915
+ case 4:
1916
+ case 6:
1917
+ set_hash("hour", INT2FIX(n2i(cs3, 0, 2)));
1918
+ if (l3 >= 4)
1919
+ set_hash("min", INT2FIX(n2i(cs3, 2, 2)));
1920
+ if (l3 >= 6)
1921
+ set_hash("sec", INT2FIX(n2i(cs3, 4, 2)));
1922
+ break;
1923
+ }
1924
+ }
1925
+ RB_GC_GUARD(s3);
1926
+ }
1927
+ if (!NIL_P(s4)) {
1928
+ l4 = RSTRING_LEN(s4);
1929
+
1930
+ set_hash("sec_fraction",
1931
+ rb_rational_new2(str2num(s4),
1932
+ f_expt(INT2FIX(10), LONG2NUM(l4))));
1933
+ }
1934
+ if (!NIL_P(s5)) {
1935
+ cs5 = RSTRING_PTR(s5);
1936
+ l5 = RSTRING_LEN(s5);
1937
+
1938
+ set_hash("zone", s5);
1939
+
1940
+ if (*cs5 == '[') {
1941
+ const char *s1, *s2;
1942
+ VALUE zone;
1943
+
1944
+ l5 -= 2;
1945
+ s1 = cs5 + 1;
1946
+ s2 = memchr(s1, ':', l5);
1947
+ if (s2) {
1948
+ s2++;
1949
+ zone = rb_str_subseq(s5, s2 - cs5, l5 - (s2 - s1));
1950
+ s5 = rb_str_subseq(s5, 1, s2 - s1);
1951
+ }
1952
+ else {
1953
+ zone = rb_str_subseq(s5, 1, l5);
1954
+ if (isdigit((unsigned char)*s1))
1955
+ s5 = rb_str_append(rb_str_new_cstr("+"), zone);
1956
+ else
1957
+ s5 = zone;
1958
+ }
1959
+ set_hash("zone", zone);
1960
+ set_hash("offset", date_zone_to_diff(s5));
1961
+ }
1962
+ RB_GC_GUARD(s5);
1963
+ }
1964
+
1965
+ return 1;
1966
+ }
1967
+
1968
+ static int
1969
+ parse_ddd(VALUE str, VALUE hash)
1970
+ {
1971
+ static const char pat_source[] =
1972
+ #ifdef TIGHT_PARSER
1973
+ BOS
1974
+ #endif
1975
+ "([-+]?)(" NUMBER "{2,14})"
1976
+ "(?:"
1977
+ "\\s*"
1978
+ "t?"
1979
+ "\\s*"
1980
+ "(\\d{2,6})?(?:[,.](\\d*))?"
1981
+ ")?"
1982
+ "(?:"
1983
+ "\\s*"
1984
+ "("
1985
+ "z\\b"
1986
+ "|"
1987
+ "[-+]\\d{1,4}\\b"
1988
+ "|"
1989
+ "\\[[-+]?\\d[^\\]]*\\]"
1990
+ ")"
1991
+ ")?"
1992
+ #ifdef TIGHT_PARSER
1993
+ EOS
1994
+ #endif
1995
+ ;
1996
+ static VALUE pat = Qnil;
1997
+
1998
+ REGCOMP_I(pat);
1999
+ SUBS(str, pat, parse_ddd_cb);
2000
+ }
2001
+
2002
+ #ifndef TIGHT_PARSER
2003
+ static int
2004
+ parse_bc_cb(VALUE m, VALUE hash)
2005
+ {
2006
+ set_hash("_bc", Qtrue);
2007
+ return 1;
2008
+ }
2009
+
2010
+ static int
2011
+ parse_bc(VALUE str, VALUE hash)
2012
+ {
2013
+ static const char pat_source[] =
2014
+ "\\b(bc\\b|bce\\b|b\\.c\\.|b\\.c\\.e\\.)";
2015
+ static VALUE pat = Qnil;
2016
+
2017
+ REGCOMP_I(pat);
2018
+ SUBS(str, pat, parse_bc_cb);
2019
+ }
2020
+
2021
+ static int
2022
+ parse_frag_cb(VALUE m, VALUE hash)
2023
+ {
2024
+ VALUE s, n;
2025
+
2026
+ s = rb_reg_nth_match(1, m);
2027
+
2028
+ if (!NIL_P(ref_hash("hour")) && NIL_P(ref_hash("mday"))) {
2029
+ n = str2num(s);
2030
+ if (f_ge_p(n, INT2FIX(1)) &&
2031
+ f_le_p(n, INT2FIX(31)))
2032
+ set_hash("mday", n);
2033
+ }
2034
+ if (!NIL_P(ref_hash("mday")) && NIL_P(ref_hash("hour"))) {
2035
+ n = str2num(s);
2036
+ if (f_ge_p(n, INT2FIX(0)) &&
2037
+ f_le_p(n, INT2FIX(24)))
2038
+ set_hash("hour", n);
2039
+ }
2040
+
2041
+ return 1;
2042
+ }
2043
+
2044
+ static int
2045
+ parse_frag(VALUE str, VALUE hash)
2046
+ {
2047
+ static const char pat_source[] = "\\A\\s*(\\d{1,2})\\s*\\z";
2048
+ static VALUE pat = Qnil;
2049
+
2050
+ REGCOMP_I(pat);
2051
+ SUBS(str, pat, parse_frag_cb);
2052
+ }
2053
+ #endif
2054
+
2055
+ #ifdef TIGHT_PARSER
2056
+ static int
2057
+ parse_dummy_cb(VALUE m, VALUE hash)
2058
+ {
2059
+ return 1;
2060
+ }
2061
+
2062
+ static int
2063
+ parse_wday_only(VALUE str, VALUE hash)
2064
+ {
2065
+ static const char pat_source[] = "\\A\\s*" FPW "\\s*\\z";
2066
+ static VALUE pat = Qnil;
2067
+
2068
+ REGCOMP_0(pat);
2069
+ SUBS(str, pat, parse_dummy_cb);
2070
+ }
2071
+
2072
+ static int
2073
+ parse_time_only(VALUE str, VALUE hash)
2074
+ {
2075
+ static const char pat_source[] = "\\A\\s*" FPT "\\s*\\z";
2076
+ static VALUE pat = Qnil;
2077
+
2078
+ REGCOMP_0(pat);
2079
+ SUBS(str, pat, parse_dummy_cb);
2080
+ }
2081
+
2082
+ static int
2083
+ parse_wday_and_time(VALUE str, VALUE hash)
2084
+ {
2085
+ static const char pat_source[] = "\\A\\s*(" FPW "\\s+" FPT "|" FPT "\\s+" FPW ")\\s*\\z";
2086
+ static VALUE pat = Qnil;
2087
+
2088
+ REGCOMP_0(pat);
2089
+ SUBS(str, pat, parse_dummy_cb);
2090
+ }
2091
+
2092
+ static unsigned
2093
+ have_invalid_char_p(VALUE s)
2094
+ {
2095
+ long i;
2096
+
2097
+ for (i = 0; i < RSTRING_LEN(s); i++)
2098
+ if (iscntrl((unsigned char)RSTRING_PTR(s)[i]) &&
2099
+ !isspace((unsigned char)RSTRING_PTR(s)[i]))
2100
+ return 1;
2101
+ return 0;
2102
+ }
2103
+ #endif
2104
+
2105
+ #define HAVE_ALPHA (1<<0)
2106
+ #define HAVE_DIGIT (1<<1)
2107
+ #define HAVE_DASH (1<<2)
2108
+ #define HAVE_DOT (1<<3)
2109
+ #define HAVE_SLASH (1<<4)
2110
+
2111
+ static unsigned
2112
+ check_class(VALUE s)
2113
+ {
2114
+ unsigned flags;
2115
+ long i;
2116
+
2117
+ flags = 0;
2118
+ for (i = 0; i < RSTRING_LEN(s); i++) {
2119
+ if (isalpha((unsigned char)RSTRING_PTR(s)[i]))
2120
+ flags |= HAVE_ALPHA;
2121
+ if (isdigit((unsigned char)RSTRING_PTR(s)[i]))
2122
+ flags |= HAVE_DIGIT;
2123
+ if (RSTRING_PTR(s)[i] == '-')
2124
+ flags |= HAVE_DASH;
2125
+ if (RSTRING_PTR(s)[i] == '.')
2126
+ flags |= HAVE_DOT;
2127
+ if (RSTRING_PTR(s)[i] == '/')
2128
+ flags |= HAVE_SLASH;
2129
+ }
2130
+ return flags;
2131
+ }
2132
+
2133
+ #define HAVE_ELEM_P(x) ((check_class(str) & (x)) == (x))
2134
+
2135
+ #ifdef TIGHT_PARSER
2136
+ #define PARSER_ERROR return rb_hash_new()
2137
+ #endif
2138
+
2139
+ VALUE
2140
+ date__parse(VALUE str, VALUE comp)
2141
+ {
2142
+ VALUE backref, hash;
2143
+
2144
+ #ifdef TIGHT_PARSER
2145
+ if (have_invalid_char_p(str))
2146
+ PARSER_ERROR;
2147
+ #endif
2148
+
2149
+ backref = rb_backref_get();
2150
+ rb_match_busy(backref);
2151
+
2152
+ {
2153
+ static const char pat_source[] =
2154
+ #ifndef TIGHT_PARSER
2155
+ "[^-+',./:@[:alnum:]\\[\\]]+"
2156
+ #else
2157
+ "[^[:graph:]]+"
2158
+ #endif
2159
+ ;
2160
+ static VALUE pat = Qnil;
2161
+
2162
+ REGCOMP_0(pat);
2163
+ str = rb_str_dup(str);
2164
+ f_gsub_bang(str, pat, asp_string());
2165
+ }
2166
+
2167
+ hash = rb_hash_new();
2168
+ set_hash("_comp", comp);
2169
+
2170
+ if (HAVE_ELEM_P(HAVE_ALPHA))
2171
+ parse_day(str, hash);
2172
+ if (HAVE_ELEM_P(HAVE_DIGIT))
2173
+ parse_time(str, hash);
2174
+
2175
+ #ifdef TIGHT_PARSER
2176
+ if (HAVE_ELEM_P(HAVE_ALPHA))
2177
+ parse_era(str, hash);
2178
+ #endif
2179
+
2180
+ if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT)) {
2181
+ if (parse_eu(str, hash))
2182
+ goto ok;
2183
+ if (parse_us(str, hash))
2184
+ goto ok;
2185
+ }
2186
+ if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DASH))
2187
+ if (parse_iso(str, hash))
2188
+ goto ok;
2189
+ if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DOT))
2190
+ if (parse_jis(str, hash))
2191
+ goto ok;
2192
+ if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT|HAVE_DASH))
2193
+ if (parse_vms(str, hash))
2194
+ goto ok;
2195
+ if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_SLASH))
2196
+ if (parse_sla(str, hash))
2197
+ goto ok;
2198
+ #ifdef TIGHT_PARSER
2199
+ if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT|HAVE_SLASH)) {
2200
+ if (parse_sla2(str, hash))
2201
+ goto ok;
2202
+ if (parse_sla3(str, hash))
2203
+ goto ok;
2204
+ }
2205
+ #endif
2206
+ if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DOT))
2207
+ if (parse_dot(str, hash))
2208
+ goto ok;
2209
+ #ifdef TIGHT_PARSER
2210
+ if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT|HAVE_DOT)) {
2211
+ if (parse_dot2(str, hash))
2212
+ goto ok;
2213
+ if (parse_dot3(str, hash))
2214
+ goto ok;
2215
+ }
2216
+ #endif
2217
+ if (HAVE_ELEM_P(HAVE_DIGIT))
2218
+ if (parse_iso2(str, hash))
2219
+ goto ok;
2220
+ if (HAVE_ELEM_P(HAVE_DIGIT))
2221
+ if (parse_year(str, hash))
2222
+ goto ok;
2223
+ if (HAVE_ELEM_P(HAVE_ALPHA))
2224
+ if (parse_mon(str, hash))
2225
+ goto ok;
2226
+ if (HAVE_ELEM_P(HAVE_DIGIT))
2227
+ if (parse_mday(str, hash))
2228
+ goto ok;
2229
+ if (HAVE_ELEM_P(HAVE_DIGIT))
2230
+ if (parse_ddd(str, hash))
2231
+ goto ok;
2232
+
2233
+ #ifdef TIGHT_PARSER
2234
+ if (parse_wday_only(str, hash))
2235
+ goto ok;
2236
+ if (parse_time_only(str, hash))
2237
+ goto ok;
2238
+ if (parse_wday_and_time(str, hash))
2239
+ goto ok;
2240
+
2241
+ PARSER_ERROR; /* not found */
2242
+ #endif
2243
+
2244
+ ok:
2245
+ #ifndef TIGHT_PARSER
2246
+ if (HAVE_ELEM_P(HAVE_ALPHA))
2247
+ parse_bc(str, hash);
2248
+ if (HAVE_ELEM_P(HAVE_DIGIT))
2249
+ parse_frag(str, hash);
2250
+ #endif
2251
+
2252
+ {
2253
+ if (RTEST(del_hash("_bc"))) {
2254
+ VALUE y;
2255
+
2256
+ y = ref_hash("cwyear");
2257
+ if (!NIL_P(y)) {
2258
+ y = f_add(f_negate(y), INT2FIX(1));
2259
+ set_hash("cwyear", y);
2260
+ }
2261
+ y = ref_hash("year");
2262
+ if (!NIL_P(y)) {
2263
+ y = f_add(f_negate(y), INT2FIX(1));
2264
+ set_hash("year", y);
2265
+ }
2266
+ }
2267
+
2268
+ if (RTEST(del_hash("_comp"))) {
2269
+ VALUE y;
2270
+
2271
+ y = ref_hash("cwyear");
2272
+ if (!NIL_P(y))
2273
+ if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99))) {
2274
+ if (f_ge_p(y, INT2FIX(69)))
2275
+ set_hash("cwyear", f_add(y, INT2FIX(1900)));
2276
+ else
2277
+ set_hash("cwyear", f_add(y, INT2FIX(2000)));
2278
+ }
2279
+ y = ref_hash("year");
2280
+ if (!NIL_P(y))
2281
+ if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99))) {
2282
+ if (f_ge_p(y, INT2FIX(69)))
2283
+ set_hash("year", f_add(y, INT2FIX(1900)));
2284
+ else
2285
+ set_hash("year", f_add(y, INT2FIX(2000)));
2286
+ }
2287
+ }
2288
+
2289
+ }
2290
+
2291
+ {
2292
+ VALUE zone = ref_hash("zone");
2293
+ if (!NIL_P(zone) && NIL_P(ref_hash("offset")))
2294
+ set_hash("offset", date_zone_to_diff(zone));
2295
+ }
2296
+
2297
+ rb_backref_set(backref);
2298
+
2299
+ return hash;
2300
+ }
2301
+
2302
+ static VALUE
2303
+ comp_year69(VALUE y)
2304
+ {
2305
+ if (f_ge_p(y, INT2FIX(69)))
2306
+ return f_add(y, INT2FIX(1900));
2307
+ return f_add(y, INT2FIX(2000));
2308
+ }
2309
+
2310
+ static VALUE
2311
+ comp_year50(VALUE y)
2312
+ {
2313
+ if (f_ge_p(y, INT2FIX(50)))
2314
+ return f_add(y, INT2FIX(1900));
2315
+ return f_add(y, INT2FIX(2000));
2316
+ }
2317
+
2318
+ static VALUE
2319
+ sec_fraction(VALUE f)
2320
+ {
2321
+ return rb_rational_new2(str2num(f),
2322
+ f_expt(INT2FIX(10),
2323
+ LONG2NUM(RSTRING_LEN(f))));
2324
+ }
2325
+
2326
+ #define SNUM 14
2327
+
2328
+ static int
2329
+ iso8601_ext_datetime_cb(VALUE m, VALUE hash)
2330
+ {
2331
+ VALUE s[SNUM + 1], y;
2332
+
2333
+ {
2334
+ int i;
2335
+ s[0] = Qnil;
2336
+ for (i = 1; i <= SNUM; i++)
2337
+ s[i] = rb_reg_nth_match(i, m);
2338
+ }
2339
+
2340
+ if (!NIL_P(s[1])) {
2341
+ if (!NIL_P(s[3])) set_hash("mday", str2num(s[3]));
2342
+ if (strcmp(RSTRING_PTR(s[1]), "-") != 0) {
2343
+ y = str2num(s[1]);
2344
+ if (RSTRING_LEN(s[1]) < 4)
2345
+ y = comp_year69(y);
2346
+ set_hash("year", y);
2347
+ }
2348
+ if (NIL_P(s[2])) {
2349
+ if (strcmp(RSTRING_PTR(s[1]), "-") != 0)
2350
+ return 0;
2351
+ }
2352
+ else
2353
+ set_hash("mon", str2num(s[2]));
2354
+ }
2355
+ else if (!NIL_P(s[5])) {
2356
+ set_hash("yday", str2num(s[5]));
2357
+ if (!NIL_P(s[4])) {
2358
+ y = str2num(s[4]);
2359
+ if (RSTRING_LEN(s[4]) < 4)
2360
+ y = comp_year69(y);
2361
+ set_hash("year", y);
2362
+ }
2363
+ }
2364
+ else if (!NIL_P(s[8])) {
2365
+ set_hash("cweek", str2num(s[7]));
2366
+ set_hash("cwday", str2num(s[8]));
2367
+ if (!NIL_P(s[6])) {
2368
+ y = str2num(s[6]);
2369
+ if (RSTRING_LEN(s[6]) < 4)
2370
+ y = comp_year69(y);
2371
+ set_hash("cwyear", y);
2372
+ }
2373
+ }
2374
+ else if (!NIL_P(s[9])) {
2375
+ set_hash("cwday", str2num(s[9]));
2376
+ }
2377
+ if (!NIL_P(s[10])) {
2378
+ set_hash("hour", str2num(s[10]));
2379
+ set_hash("min", str2num(s[11]));
2380
+ if (!NIL_P(s[12]))
2381
+ set_hash("sec", str2num(s[12]));
2382
+ }
2383
+ if (!NIL_P(s[13])) {
2384
+ set_hash("sec_fraction", sec_fraction(s[13]));
2385
+ }
2386
+ if (!NIL_P(s[14])) {
2387
+ set_hash("zone", s[14]);
2388
+ set_hash("offset", date_zone_to_diff(s[14]));
2389
+ }
2390
+
2391
+ return 1;
2392
+ }
2393
+
2394
+ static int
2395
+ iso8601_ext_datetime(VALUE str, VALUE hash)
2396
+ {
2397
+ static const char pat_source[] =
2398
+ "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?(?:-(\\d{2}))?|"
2399
+ "([-+]?\\d{2,})?-(\\d{3})|"
2400
+ "(\\d{4}|\\d{2})?-w(\\d{2})-(\\d)|"
2401
+ "-w-(\\d))"
2402
+ "(?:t"
2403
+ "(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d+))?)?"
2404
+ "(z|[-+]\\d{2}(?::?\\d{2})?)?)?\\s*\\z";
2405
+ static VALUE pat = Qnil;
2406
+
2407
+ REGCOMP_I(pat);
2408
+ MATCH(str, pat, iso8601_ext_datetime_cb);
2409
+ }
2410
+
2411
+ #undef SNUM
2412
+ #define SNUM 17
2413
+
2414
+ static int
2415
+ iso8601_bas_datetime_cb(VALUE m, VALUE hash)
2416
+ {
2417
+ VALUE s[SNUM + 1], y;
2418
+
2419
+ {
2420
+ int i;
2421
+ s[0] = Qnil;
2422
+ for (i = 1; i <= SNUM; i++)
2423
+ s[i] = rb_reg_nth_match(i, m);
2424
+ }
2425
+
2426
+ if (!NIL_P(s[3])) {
2427
+ set_hash("mday", str2num(s[3]));
2428
+ if (strcmp(RSTRING_PTR(s[1]), "--") != 0) {
2429
+ y = str2num(s[1]);
2430
+ if (RSTRING_LEN(s[1]) < 4)
2431
+ y = comp_year69(y);
2432
+ set_hash("year", y);
2433
+ }
2434
+ if (*RSTRING_PTR(s[2]) == '-') {
2435
+ if (strcmp(RSTRING_PTR(s[1]), "--") != 0)
2436
+ return 0;
2437
+ }
2438
+ else
2439
+ set_hash("mon", str2num(s[2]));
2440
+ }
2441
+ else if (!NIL_P(s[5])) {
2442
+ set_hash("yday", str2num(s[5]));
2443
+ y = str2num(s[4]);
2444
+ if (RSTRING_LEN(s[4]) < 4)
2445
+ y = comp_year69(y);
2446
+ set_hash("year", y);
2447
+ }
2448
+ else if (!NIL_P(s[6])) {
2449
+ set_hash("yday", str2num(s[6]));
2450
+ }
2451
+ else if (!NIL_P(s[9])) {
2452
+ set_hash("cweek", str2num(s[8]));
2453
+ set_hash("cwday", str2num(s[9]));
2454
+ y = str2num(s[7]);
2455
+ if (RSTRING_LEN(s[7]) < 4)
2456
+ y = comp_year69(y);
2457
+ set_hash("cwyear", y);
2458
+ }
2459
+ else if (!NIL_P(s[11])) {
2460
+ set_hash("cweek", str2num(s[10]));
2461
+ set_hash("cwday", str2num(s[11]));
2462
+ }
2463
+ else if (!NIL_P(s[12])) {
2464
+ set_hash("cwday", str2num(s[12]));
2465
+ }
2466
+ if (!NIL_P(s[13])) {
2467
+ set_hash("hour", str2num(s[13]));
2468
+ set_hash("min", str2num(s[14]));
2469
+ if (!NIL_P(s[15]))
2470
+ set_hash("sec", str2num(s[15]));
2471
+ }
2472
+ if (!NIL_P(s[16])) {
2473
+ set_hash("sec_fraction", sec_fraction(s[16]));
2474
+ }
2475
+ if (!NIL_P(s[17])) {
2476
+ set_hash("zone", s[17]);
2477
+ set_hash("offset", date_zone_to_diff(s[17]));
2478
+ }
2479
+
2480
+ return 1;
2481
+ }
2482
+
2483
+ static int
2484
+ iso8601_bas_datetime(VALUE str, VALUE hash)
2485
+ {
2486
+ static const char pat_source[] =
2487
+ "\\A\\s*(?:([-+]?(?:\\d{4}|\\d{2})|--)(\\d{2}|-)(\\d{2})|"
2488
+ "([-+]?(?:\\d{4}|\\d{2}))(\\d{3})|"
2489
+ "-(\\d{3})|"
2490
+ "(\\d{4}|\\d{2})w(\\d{2})(\\d)|"
2491
+ "-w(\\d{2})(\\d)|"
2492
+ "-w-(\\d))"
2493
+ "(?:t?"
2494
+ "(\\d{2})(\\d{2})(?:(\\d{2})(?:[,.](\\d+))?)?"
2495
+ "(z|[-+]\\d{2}(?:\\d{2})?)?)?\\s*\\z";
2496
+ static VALUE pat = Qnil;
2497
+
2498
+ REGCOMP_I(pat);
2499
+ MATCH(str, pat, iso8601_bas_datetime_cb);
2500
+ }
2501
+
2502
+ #undef SNUM
2503
+ #define SNUM 5
2504
+
2505
+ static int
2506
+ iso8601_ext_time_cb(VALUE m, VALUE hash)
2507
+ {
2508
+ VALUE s[SNUM + 1];
2509
+
2510
+ {
2511
+ int i;
2512
+ s[0] = Qnil;
2513
+ for (i = 1; i <= SNUM; i++)
2514
+ s[i] = rb_reg_nth_match(i, m);
2515
+ }
2516
+
2517
+ set_hash("hour", str2num(s[1]));
2518
+ set_hash("min", str2num(s[2]));
2519
+ if (!NIL_P(s[3]))
2520
+ set_hash("sec", str2num(s[3]));
2521
+ if (!NIL_P(s[4]))
2522
+ set_hash("sec_fraction", sec_fraction(s[4]));
2523
+ if (!NIL_P(s[5])) {
2524
+ set_hash("zone", s[5]);
2525
+ set_hash("offset", date_zone_to_diff(s[5]));
2526
+ }
2527
+
2528
+ return 1;
2529
+ }
2530
+
2531
+ #define iso8601_bas_time_cb iso8601_ext_time_cb
2532
+
2533
+ static int
2534
+ iso8601_ext_time(VALUE str, VALUE hash)
2535
+ {
2536
+ static const char pat_source[] =
2537
+ "\\A\\s*(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d+))?"
2538
+ "(z|[-+]\\d{2}(:?\\d{2})?)?)?\\s*\\z";
2539
+ static VALUE pat = Qnil;
2540
+
2541
+ REGCOMP_I(pat);
2542
+ MATCH(str, pat, iso8601_ext_time_cb);
2543
+ }
2544
+
2545
+ static int
2546
+ iso8601_bas_time(VALUE str, VALUE hash)
2547
+ {
2548
+ static const char pat_source[] =
2549
+ "\\A\\s*(\\d{2})(\\d{2})(?:(\\d{2})(?:[,.](\\d+))?"
2550
+ "(z|[-+]\\d{2}(\\d{2})?)?)?\\s*\\z";
2551
+ static VALUE pat = Qnil;
2552
+
2553
+ REGCOMP_I(pat);
2554
+ MATCH(str, pat, iso8601_bas_time_cb);
2555
+ }
2556
+
2557
+ VALUE
2558
+ date__iso8601(VALUE str)
2559
+ {
2560
+ VALUE backref, hash;
2561
+
2562
+ backref = rb_backref_get();
2563
+ rb_match_busy(backref);
2564
+
2565
+ hash = rb_hash_new();
2566
+
2567
+ if (iso8601_ext_datetime(str, hash))
2568
+ goto ok;
2569
+ if (iso8601_bas_datetime(str, hash))
2570
+ goto ok;
2571
+ if (iso8601_ext_time(str, hash))
2572
+ goto ok;
2573
+ if (iso8601_bas_time(str, hash))
2574
+ goto ok;
2575
+
2576
+ ok:
2577
+ rb_backref_set(backref);
2578
+
2579
+ return hash;
2580
+ }
2581
+
2582
+ #undef SNUM
2583
+ #define SNUM 8
2584
+
2585
+ static int
2586
+ rfc3339_cb(VALUE m, VALUE hash)
2587
+ {
2588
+ VALUE s[SNUM + 1];
2589
+
2590
+ {
2591
+ int i;
2592
+ s[0] = Qnil;
2593
+ for (i = 1; i <= SNUM; i++)
2594
+ s[i] = rb_reg_nth_match(i, m);
2595
+ }
2596
+
2597
+ set_hash("year", str2num(s[1]));
2598
+ set_hash("mon", str2num(s[2]));
2599
+ set_hash("mday", str2num(s[3]));
2600
+ set_hash("hour", str2num(s[4]));
2601
+ set_hash("min", str2num(s[5]));
2602
+ set_hash("sec", str2num(s[6]));
2603
+ set_hash("zone", s[8]);
2604
+ set_hash("offset", date_zone_to_diff(s[8]));
2605
+ if (!NIL_P(s[7]))
2606
+ set_hash("sec_fraction", sec_fraction(s[7]));
2607
+
2608
+ return 1;
2609
+ }
2610
+
2611
+ static int
2612
+ rfc3339(VALUE str, VALUE hash)
2613
+ {
2614
+ static const char pat_source[] =
2615
+ "\\A\\s*(-?\\d{4})-(\\d{2})-(\\d{2})"
2616
+ "(?:t|\\s)"
2617
+ "(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?"
2618
+ "(z|[-+]\\d{2}:\\d{2})\\s*\\z";
2619
+ static VALUE pat = Qnil;
2620
+
2621
+ REGCOMP_I(pat);
2622
+ MATCH(str, pat, rfc3339_cb);
2623
+ }
2624
+
2625
+ VALUE
2626
+ date__rfc3339(VALUE str)
2627
+ {
2628
+ VALUE backref, hash;
2629
+
2630
+ backref = rb_backref_get();
2631
+ rb_match_busy(backref);
2632
+
2633
+ hash = rb_hash_new();
2634
+ rfc3339(str, hash);
2635
+ rb_backref_set(backref);
2636
+ return hash;
2637
+ }
2638
+
2639
+ #undef SNUM
2640
+ #define SNUM 8
2641
+
2642
+ static int
2643
+ xmlschema_datetime_cb(VALUE m, VALUE hash)
2644
+ {
2645
+ VALUE s[SNUM + 1];
2646
+
2647
+ {
2648
+ int i;
2649
+ s[0] = Qnil;
2650
+ for (i = 1; i <= SNUM; i++)
2651
+ s[i] = rb_reg_nth_match(i, m);
2652
+ }
2653
+
2654
+ set_hash("year", str2num(s[1]));
2655
+ if (!NIL_P(s[2]))
2656
+ set_hash("mon", str2num(s[2]));
2657
+ if (!NIL_P(s[3]))
2658
+ set_hash("mday", str2num(s[3]));
2659
+ if (!NIL_P(s[4]))
2660
+ set_hash("hour", str2num(s[4]));
2661
+ if (!NIL_P(s[5]))
2662
+ set_hash("min", str2num(s[5]));
2663
+ if (!NIL_P(s[6]))
2664
+ set_hash("sec", str2num(s[6]));
2665
+ if (!NIL_P(s[7]))
2666
+ set_hash("sec_fraction", sec_fraction(s[7]));
2667
+ if (!NIL_P(s[8])) {
2668
+ set_hash("zone", s[8]);
2669
+ set_hash("offset", date_zone_to_diff(s[8]));
2670
+ }
2671
+
2672
+ return 1;
2673
+ }
2674
+
2675
+ static int
2676
+ xmlschema_datetime(VALUE str, VALUE hash)
2677
+ {
2678
+ static const char pat_source[] =
2679
+ "\\A\\s*(-?\\d{4,})(?:-(\\d{2})(?:-(\\d{2}))?)?"
2680
+ "(?:t"
2681
+ "(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?)?"
2682
+ "(z|[-+]\\d{2}:\\d{2})?\\s*\\z";
2683
+ static VALUE pat = Qnil;
2684
+
2685
+ REGCOMP_I(pat);
2686
+ MATCH(str, pat, xmlschema_datetime_cb);
2687
+ }
2688
+
2689
+ #undef SNUM
2690
+ #define SNUM 5
2691
+
2692
+ static int
2693
+ xmlschema_time_cb(VALUE m, VALUE hash)
2694
+ {
2695
+ VALUE s[SNUM + 1];
2696
+
2697
+ {
2698
+ int i;
2699
+ s[0] = Qnil;
2700
+ for (i = 1; i <= SNUM; i++)
2701
+ s[i] = rb_reg_nth_match(i, m);
2702
+ }
2703
+
2704
+ set_hash("hour", str2num(s[1]));
2705
+ set_hash("min", str2num(s[2]));
2706
+ if (!NIL_P(s[3]))
2707
+ set_hash("sec", str2num(s[3]));
2708
+ if (!NIL_P(s[4]))
2709
+ set_hash("sec_fraction", sec_fraction(s[4]));
2710
+ if (!NIL_P(s[5])) {
2711
+ set_hash("zone", s[5]);
2712
+ set_hash("offset", date_zone_to_diff(s[5]));
2713
+ }
2714
+
2715
+ return 1;
2716
+ }
2717
+
2718
+ static int
2719
+ xmlschema_time(VALUE str, VALUE hash)
2720
+ {
2721
+ static const char pat_source[] =
2722
+ "\\A\\s*(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?"
2723
+ "(z|[-+]\\d{2}:\\d{2})?\\s*\\z";
2724
+ static VALUE pat = Qnil;
2725
+
2726
+ REGCOMP_I(pat);
2727
+ MATCH(str, pat, xmlschema_time_cb);
2728
+ }
2729
+
2730
+ #undef SNUM
2731
+ #define SNUM 4
2732
+
2733
+ static int
2734
+ xmlschema_trunc_cb(VALUE m, VALUE hash)
2735
+ {
2736
+ VALUE s[SNUM + 1];
2737
+
2738
+ {
2739
+ int i;
2740
+ s[0] = Qnil;
2741
+ for (i = 1; i <= SNUM; i++)
2742
+ s[i] = rb_reg_nth_match(i, m);
2743
+ }
2744
+
2745
+ if (!NIL_P(s[1]))
2746
+ set_hash("mon", str2num(s[1]));
2747
+ if (!NIL_P(s[2]))
2748
+ set_hash("mday", str2num(s[2]));
2749
+ if (!NIL_P(s[3]))
2750
+ set_hash("mday", str2num(s[3]));
2751
+ if (!NIL_P(s[4])) {
2752
+ set_hash("zone", s[4]);
2753
+ set_hash("offset", date_zone_to_diff(s[4]));
2754
+ }
2755
+
2756
+ return 1;
2757
+ }
2758
+
2759
+ static int
2760
+ xmlschema_trunc(VALUE str, VALUE hash)
2761
+ {
2762
+ static const char pat_source[] =
2763
+ "\\A\\s*(?:--(\\d{2})(?:-(\\d{2}))?|---(\\d{2}))"
2764
+ "(z|[-+]\\d{2}:\\d{2})?\\s*\\z";
2765
+ static VALUE pat = Qnil;
2766
+
2767
+ REGCOMP_I(pat);
2768
+ MATCH(str, pat, xmlschema_trunc_cb);
2769
+ }
2770
+
2771
+ VALUE
2772
+ date__xmlschema(VALUE str)
2773
+ {
2774
+ VALUE backref, hash;
2775
+
2776
+ backref = rb_backref_get();
2777
+ rb_match_busy(backref);
2778
+
2779
+ hash = rb_hash_new();
2780
+
2781
+ if (xmlschema_datetime(str, hash))
2782
+ goto ok;
2783
+ if (xmlschema_time(str, hash))
2784
+ goto ok;
2785
+ if (xmlschema_trunc(str, hash))
2786
+ goto ok;
2787
+
2788
+ ok:
2789
+ rb_backref_set(backref);
2790
+
2791
+ return hash;
2792
+ }
2793
+
2794
+ #undef SNUM
2795
+ #define SNUM 8
2796
+
2797
+ static int
2798
+ rfc2822_cb(VALUE m, VALUE hash)
2799
+ {
2800
+ VALUE s[SNUM + 1], y;
2801
+
2802
+ {
2803
+ int i;
2804
+ s[0] = Qnil;
2805
+ for (i = 1; i <= SNUM; i++)
2806
+ s[i] = rb_reg_nth_match(i, m);
2807
+ }
2808
+
2809
+ if (!NIL_P(s[1])) {
2810
+ set_hash("wday", INT2FIX(day_num(s[1])));
2811
+ }
2812
+ set_hash("mday", str2num(s[2]));
2813
+ set_hash("mon", INT2FIX(mon_num(s[3])));
2814
+ y = str2num(s[4]);
2815
+ if (RSTRING_LEN(s[4]) < 4)
2816
+ y = comp_year50(y);
2817
+ set_hash("year", y);
2818
+ set_hash("hour", str2num(s[5]));
2819
+ set_hash("min", str2num(s[6]));
2820
+ if (!NIL_P(s[7]))
2821
+ set_hash("sec", str2num(s[7]));
2822
+ set_hash("zone", s[8]);
2823
+ set_hash("offset", date_zone_to_diff(s[8]));
2824
+
2825
+ return 1;
2826
+ }
2827
+
2828
+ static int
2829
+ rfc2822(VALUE str, VALUE hash)
2830
+ {
2831
+ static const char pat_source[] =
2832
+ "\\A\\s*(?:(" ABBR_DAYS ")\\s*,\\s+)?"
2833
+ "(\\d{1,2})\\s+"
2834
+ "(" ABBR_MONTHS ")\\s+"
2835
+ "(-?\\d{2,})\\s+"
2836
+ "(\\d{2}):(\\d{2})(?::(\\d{2}))?\\s*"
2837
+ "([-+]\\d{4}|ut|gmt|e[sd]t|c[sd]t|m[sd]t|p[sd]t|[a-ik-z])\\s*\\z";
2838
+ static VALUE pat = Qnil;
2839
+
2840
+ REGCOMP_I(pat);
2841
+ MATCH(str, pat, rfc2822_cb);
2842
+ }
2843
+
2844
+ VALUE
2845
+ date__rfc2822(VALUE str)
2846
+ {
2847
+ VALUE backref, hash;
2848
+
2849
+ backref = rb_backref_get();
2850
+ rb_match_busy(backref);
2851
+
2852
+ hash = rb_hash_new();
2853
+ rfc2822(str, hash);
2854
+ rb_backref_set(backref);
2855
+ return hash;
2856
+ }
2857
+
2858
+ #undef SNUM
2859
+ #define SNUM 8
2860
+
2861
+ static int
2862
+ httpdate_type1_cb(VALUE m, VALUE hash)
2863
+ {
2864
+ VALUE s[SNUM + 1];
2865
+
2866
+ {
2867
+ int i;
2868
+ s[0] = Qnil;
2869
+ for (i = 1; i <= SNUM; i++)
2870
+ s[i] = rb_reg_nth_match(i, m);
2871
+ }
2872
+
2873
+ set_hash("wday", INT2FIX(day_num(s[1])));
2874
+ set_hash("mday", str2num(s[2]));
2875
+ set_hash("mon", INT2FIX(mon_num(s[3])));
2876
+ set_hash("year", str2num(s[4]));
2877
+ set_hash("hour", str2num(s[5]));
2878
+ set_hash("min", str2num(s[6]));
2879
+ set_hash("sec", str2num(s[7]));
2880
+ set_hash("zone", s[8]);
2881
+ set_hash("offset", INT2FIX(0));
2882
+
2883
+ return 1;
2884
+ }
2885
+
2886
+ static int
2887
+ httpdate_type1(VALUE str, VALUE hash)
2888
+ {
2889
+ static const char pat_source[] =
2890
+ "\\A\\s*(" ABBR_DAYS ")\\s*,\\s+"
2891
+ "(\\d{2})\\s+"
2892
+ "(" ABBR_MONTHS ")\\s+"
2893
+ "(-?\\d{4})\\s+"
2894
+ "(\\d{2}):(\\d{2}):(\\d{2})\\s+"
2895
+ "(gmt)\\s*\\z";
2896
+ static VALUE pat = Qnil;
2897
+
2898
+ REGCOMP_I(pat);
2899
+ MATCH(str, pat, httpdate_type1_cb);
2900
+ }
2901
+
2902
+ #undef SNUM
2903
+ #define SNUM 8
2904
+
2905
+ static int
2906
+ httpdate_type2_cb(VALUE m, VALUE hash)
2907
+ {
2908
+ VALUE s[SNUM + 1], y;
2909
+
2910
+ {
2911
+ int i;
2912
+ s[0] = Qnil;
2913
+ for (i = 1; i <= SNUM; i++)
2914
+ s[i] = rb_reg_nth_match(i, m);
2915
+ }
2916
+
2917
+ set_hash("wday", INT2FIX(day_num(s[1])));
2918
+ set_hash("mday", str2num(s[2]));
2919
+ set_hash("mon", INT2FIX(mon_num(s[3])));
2920
+ y = str2num(s[4]);
2921
+ if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99)))
2922
+ y = comp_year69(y);
2923
+ set_hash("year", y);
2924
+ set_hash("hour", str2num(s[5]));
2925
+ set_hash("min", str2num(s[6]));
2926
+ set_hash("sec", str2num(s[7]));
2927
+ set_hash("zone", s[8]);
2928
+ set_hash("offset", INT2FIX(0));
2929
+
2930
+ return 1;
2931
+ }
2932
+
2933
+ static int
2934
+ httpdate_type2(VALUE str, VALUE hash)
2935
+ {
2936
+ static const char pat_source[] =
2937
+ "\\A\\s*(" DAYS ")\\s*,\\s+"
2938
+ "(\\d{2})\\s*-\\s*"
2939
+ "(" ABBR_MONTHS ")\\s*-\\s*"
2940
+ "(\\d{2})\\s+"
2941
+ "(\\d{2}):(\\d{2}):(\\d{2})\\s+"
2942
+ "(gmt)\\s*\\z";
2943
+ static VALUE pat = Qnil;
2944
+
2945
+ REGCOMP_I(pat);
2946
+ MATCH(str, pat, httpdate_type2_cb);
2947
+ }
2948
+
2949
+ #undef SNUM
2950
+ #define SNUM 7
2951
+
2952
+ static int
2953
+ httpdate_type3_cb(VALUE m, VALUE hash)
2954
+ {
2955
+ VALUE s[SNUM + 1];
2956
+
2957
+ {
2958
+ int i;
2959
+ s[0] = Qnil;
2960
+ for (i = 1; i <= SNUM; i++)
2961
+ s[i] = rb_reg_nth_match(i, m);
2962
+ }
2963
+
2964
+ set_hash("wday", INT2FIX(day_num(s[1])));
2965
+ set_hash("mon", INT2FIX(mon_num(s[2])));
2966
+ set_hash("mday", str2num(s[3]));
2967
+ set_hash("hour", str2num(s[4]));
2968
+ set_hash("min", str2num(s[5]));
2969
+ set_hash("sec", str2num(s[6]));
2970
+ set_hash("year", str2num(s[7]));
2971
+
2972
+ return 1;
2973
+ }
2974
+
2975
+ static int
2976
+ httpdate_type3(VALUE str, VALUE hash)
2977
+ {
2978
+ static const char pat_source[] =
2979
+ "\\A\\s*(" ABBR_DAYS ")\\s+"
2980
+ "(" ABBR_MONTHS ")\\s+"
2981
+ "(\\d{1,2})\\s+"
2982
+ "(\\d{2}):(\\d{2}):(\\d{2})\\s+"
2983
+ "(\\d{4})\\s*\\z";
2984
+ static VALUE pat = Qnil;
2985
+
2986
+ REGCOMP_I(pat);
2987
+ MATCH(str, pat, httpdate_type3_cb);
2988
+ }
2989
+
2990
+ VALUE
2991
+ date__httpdate(VALUE str)
2992
+ {
2993
+ VALUE backref, hash;
2994
+
2995
+ backref = rb_backref_get();
2996
+ rb_match_busy(backref);
2997
+
2998
+ hash = rb_hash_new();
2999
+
3000
+ if (httpdate_type1(str, hash))
3001
+ goto ok;
3002
+ if (httpdate_type2(str, hash))
3003
+ goto ok;
3004
+ if (httpdate_type3(str, hash))
3005
+ goto ok;
3006
+
3007
+ ok:
3008
+ rb_backref_set(backref);
3009
+
3010
+ return hash;
3011
+ }
3012
+
3013
+ #undef SNUM
3014
+ #define SNUM 9
3015
+
3016
+ static int
3017
+ jisx0301_cb(VALUE m, VALUE hash)
3018
+ {
3019
+ VALUE s[SNUM + 1];
3020
+ int ep;
3021
+
3022
+ {
3023
+ int i;
3024
+ s[0] = Qnil;
3025
+ for (i = 1; i <= SNUM; i++)
3026
+ s[i] = rb_reg_nth_match(i, m);
3027
+ }
3028
+
3029
+ ep = gengo(NIL_P(s[1]) ? JISX0301_DEFAULT_ERA : *RSTRING_PTR(s[1]));
3030
+ set_hash("year", f_add(str2num(s[2]), INT2FIX(ep)));
3031
+ set_hash("mon", str2num(s[3]));
3032
+ set_hash("mday", str2num(s[4]));
3033
+ if (!NIL_P(s[5])) {
3034
+ set_hash("hour", str2num(s[5]));
3035
+ if (!NIL_P(s[6]))
3036
+ set_hash("min", str2num(s[6]));
3037
+ if (!NIL_P(s[7]))
3038
+ set_hash("sec", str2num(s[7]));
3039
+ }
3040
+ if (!NIL_P(s[8]))
3041
+ set_hash("sec_fraction", sec_fraction(s[8]));
3042
+ if (!NIL_P(s[9])) {
3043
+ set_hash("zone", s[9]);
3044
+ set_hash("offset", date_zone_to_diff(s[9]));
3045
+ }
3046
+
3047
+ return 1;
3048
+ }
3049
+
3050
+ static int
3051
+ jisx0301(VALUE str, VALUE hash)
3052
+ {
3053
+ static const char pat_source[] =
3054
+ "\\A\\s*([" JISX0301_ERA_INITIALS "])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
3055
+ "(?:t"
3056
+ "(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d*))?)?"
3057
+ "(z|[-+]\\d{2}(?::?\\d{2})?)?)?)?\\s*\\z";
3058
+ static VALUE pat = Qnil;
3059
+
3060
+ REGCOMP_I(pat);
3061
+ MATCH(str, pat, jisx0301_cb);
3062
+ }
3063
+
3064
+ VALUE
3065
+ date__jisx0301(VALUE str)
3066
+ {
3067
+ VALUE backref, hash;
3068
+
3069
+ backref = rb_backref_get();
3070
+ rb_match_busy(backref);
3071
+
3072
+ hash = rb_hash_new();
3073
+ if (jisx0301(str, hash))
3074
+ goto ok;
3075
+ hash = date__iso8601(str);
3076
+
3077
+ ok:
3078
+ rb_backref_set(backref);
3079
+ return hash;
3080
+ }
3081
+
3082
+ /*
3083
+ Local variables:
3084
+ c-file-style: "ruby"
3085
+ End:
3086
+ */