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