date 3.2.1 → 3.5.1
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.
- checksums.yaml +4 -4
- data/BSDL +22 -0
- data/COPYING +56 -0
- data/README.md +102 -0
- data/ext/date/date_core.c +1145 -1056
- data/ext/date/date_parse.c +92 -42
- data/ext/date/date_strptime.c +56 -55
- data/ext/date/extconf.rb +2 -0
- data/ext/date/prereq.mk +1 -1
- data/ext/date/zonetab.h +627 -625
- data/ext/date/zonetab.list +6 -3
- data/lib/date.rb +5 -0
- metadata +15 -11
data/ext/date/date_parse.c
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
#include "ruby/re.h"
|
|
8
8
|
#include <ctype.h>
|
|
9
9
|
|
|
10
|
+
#undef strncasecmp
|
|
11
|
+
#define strncasecmp STRNCASECMP
|
|
12
|
+
|
|
10
13
|
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y);
|
|
11
14
|
RUBY_EXTERN unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);
|
|
12
15
|
|
|
@@ -253,6 +256,8 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
|
|
|
253
256
|
#define ABBR_DAYS "sun|mon|tue|wed|thu|fri|sat"
|
|
254
257
|
#define ABBR_MONTHS "jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec"
|
|
255
258
|
|
|
259
|
+
#define NUMBER "(?<!\\d)\\d"
|
|
260
|
+
|
|
256
261
|
#ifdef TIGHT_PARSER
|
|
257
262
|
#define VALID_DAYS "(?:" DAYS ")" "|(?:tues|wednes|thurs|thur|" ABBR_DAYS ")\\.?"
|
|
258
263
|
#define VALID_MONTHS "(?:" MONTHS ")" "|(?:sept|" ABBR_MONTHS ")\\.?"
|
|
@@ -411,7 +416,6 @@ VALUE
|
|
|
411
416
|
date_zone_to_diff(VALUE str)
|
|
412
417
|
{
|
|
413
418
|
VALUE offset = Qnil;
|
|
414
|
-
VALUE vbuf = 0;
|
|
415
419
|
long l = RSTRING_LEN(str);
|
|
416
420
|
const char *s = RSTRING_PTR(str);
|
|
417
421
|
|
|
@@ -437,16 +441,26 @@ date_zone_to_diff(VALUE str)
|
|
|
437
441
|
l -= w;
|
|
438
442
|
dst = 1;
|
|
439
443
|
}
|
|
444
|
+
|
|
440
445
|
{
|
|
446
|
+
const char *zn = s;
|
|
441
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
|
+
|
|
442
460
|
if (sl > 0 && sl <= MAX_WORD_LENGTH) {
|
|
443
|
-
|
|
444
|
-
l = shrink_space(d, s, l);
|
|
445
|
-
s = d;
|
|
461
|
+
z = zonetab(zn, (unsigned int)sl);
|
|
446
462
|
}
|
|
447
|
-
|
|
448
|
-
if (l > 0 && l <= MAX_WORD_LENGTH) {
|
|
449
|
-
const struct zone *z = zonetab(s, (unsigned int)l);
|
|
463
|
+
|
|
450
464
|
if (z) {
|
|
451
465
|
int d = z->offset;
|
|
452
466
|
if (dst)
|
|
@@ -455,6 +469,7 @@ date_zone_to_diff(VALUE str)
|
|
|
455
469
|
goto ok;
|
|
456
470
|
}
|
|
457
471
|
}
|
|
472
|
+
|
|
458
473
|
{
|
|
459
474
|
char *p;
|
|
460
475
|
int sign = 0;
|
|
@@ -471,27 +486,53 @@ date_zone_to_diff(VALUE str)
|
|
|
471
486
|
s++;
|
|
472
487
|
l--;
|
|
473
488
|
|
|
489
|
+
#define out_of_range(v, min, max) ((v) < (min) || (max) < (v))
|
|
474
490
|
hour = STRTOUL(s, &p, 10);
|
|
475
491
|
if (*p == ':') {
|
|
492
|
+
if (out_of_range(hour, 0, 23)) return Qnil;
|
|
476
493
|
s = ++p;
|
|
477
494
|
min = STRTOUL(s, &p, 10);
|
|
495
|
+
if (out_of_range(min, 0, 59)) return Qnil;
|
|
478
496
|
if (*p == ':') {
|
|
479
497
|
s = ++p;
|
|
480
498
|
sec = STRTOUL(s, &p, 10);
|
|
499
|
+
if (out_of_range(sec, 0, 59)) return Qnil;
|
|
481
500
|
}
|
|
482
|
-
goto num;
|
|
483
501
|
}
|
|
484
|
-
if (*p == ',' || *p == '.') {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
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;
|
|
488
520
|
if (sign) {
|
|
489
521
|
hour = -hour;
|
|
490
|
-
|
|
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
|
+
}
|
|
491
535
|
}
|
|
492
|
-
offset = rb_rational_new(INT2FIX(min),
|
|
493
|
-
rb_int_positive_pow(10, (int)(e - p)));
|
|
494
|
-
offset = f_add(INT2FIX(hour * 3600), offset);
|
|
495
536
|
goto ok;
|
|
496
537
|
}
|
|
497
538
|
else if (l > 2) {
|
|
@@ -504,18 +545,16 @@ date_zone_to_diff(VALUE str)
|
|
|
504
545
|
min = ruby_scan_digits(&s[2 - l % 2], 2, 10, &n, &ov);
|
|
505
546
|
if (l >= 5)
|
|
506
547
|
sec = ruby_scan_digits(&s[4 - l % 2], 2, 10, &n, &ov);
|
|
507
|
-
goto num;
|
|
508
548
|
}
|
|
509
|
-
num:
|
|
510
549
|
sec += min * 60 + hour * 3600;
|
|
511
550
|
if (sign) sec = -sec;
|
|
512
551
|
offset = INT2FIX(sec);
|
|
552
|
+
#undef out_of_range
|
|
513
553
|
}
|
|
514
554
|
}
|
|
515
555
|
}
|
|
516
556
|
RB_GC_GUARD(str);
|
|
517
557
|
ok:
|
|
518
|
-
ALLOCV_END(vbuf);
|
|
519
558
|
return offset;
|
|
520
559
|
}
|
|
521
560
|
|
|
@@ -652,24 +691,27 @@ parse_time(VALUE str, VALUE hash)
|
|
|
652
691
|
{
|
|
653
692
|
static const char pat_source[] =
|
|
654
693
|
"("
|
|
694
|
+
"" NUMBER "+\\s*"
|
|
655
695
|
"(?:"
|
|
656
|
-
"\\d+\\s*:\\s*\\d+"
|
|
657
696
|
"(?:"
|
|
697
|
+
":\\s*\\d+"
|
|
698
|
+
"(?:"
|
|
658
699
|
#ifndef TIGHT_PARSER
|
|
659
|
-
|
|
700
|
+
"\\s*:\\s*\\d+(?:[,.]\\d*)?"
|
|
660
701
|
#else
|
|
661
|
-
|
|
702
|
+
"\\s*:\\s*\\d+(?:[,.]\\d+)?"
|
|
662
703
|
#endif
|
|
704
|
+
")?"
|
|
705
|
+
"|"
|
|
706
|
+
"h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?"
|
|
707
|
+
")"
|
|
708
|
+
"(?:"
|
|
709
|
+
"\\s*"
|
|
710
|
+
"[ap](?:m\\b|\\.m\\.)"
|
|
663
711
|
")?"
|
|
664
712
|
"|"
|
|
665
|
-
"\\d+\\s*h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?"
|
|
666
|
-
")"
|
|
667
|
-
"(?:"
|
|
668
|
-
"\\s*"
|
|
669
713
|
"[ap](?:m\\b|\\.m\\.)"
|
|
670
|
-
")
|
|
671
|
-
"|"
|
|
672
|
-
"\\d+\\s*[ap](?:m\\b|\\.m\\.)"
|
|
714
|
+
")"
|
|
673
715
|
")"
|
|
674
716
|
"(?:"
|
|
675
717
|
"\\s*"
|
|
@@ -691,6 +733,9 @@ parse_time(VALUE str, VALUE hash)
|
|
|
691
733
|
#endif
|
|
692
734
|
}
|
|
693
735
|
|
|
736
|
+
#define BEGIN_ERA "\\b"
|
|
737
|
+
#define END_ERA "(?!(?<!\\.)[a-z])"
|
|
738
|
+
|
|
694
739
|
#ifdef TIGHT_PARSER
|
|
695
740
|
static int
|
|
696
741
|
parse_era1_cb(VALUE m, VALUE hash)
|
|
@@ -702,7 +747,7 @@ static int
|
|
|
702
747
|
parse_era1(VALUE str, VALUE hash)
|
|
703
748
|
{
|
|
704
749
|
static const char pat_source[] =
|
|
705
|
-
"(a(?:d|\\.d\\.))";
|
|
750
|
+
BEGIN_ERA "(a(?:d\\b|\\.d\\.))" END_ERA;
|
|
706
751
|
static VALUE pat = Qnil;
|
|
707
752
|
|
|
708
753
|
REGCOMP_I(pat);
|
|
@@ -724,8 +769,9 @@ parse_era2_cb(VALUE m, VALUE hash)
|
|
|
724
769
|
static int
|
|
725
770
|
parse_era2(VALUE str, VALUE hash)
|
|
726
771
|
{
|
|
727
|
-
static const char pat_source[] =
|
|
728
|
-
"(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|b(?:c|\\.c\\.))"
|
|
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;
|
|
729
775
|
static VALUE pat = Qnil;
|
|
730
776
|
|
|
731
777
|
REGCOMP_I(pat);
|
|
@@ -829,7 +875,7 @@ parse_eu(VALUE str, VALUE hash)
|
|
|
829
875
|
FPW_COM FPT_COM
|
|
830
876
|
#endif
|
|
831
877
|
#ifndef TIGHT_PARSER
|
|
832
|
-
"('
|
|
878
|
+
"('?" NUMBER "+)[^-\\d\\s]*"
|
|
833
879
|
#else
|
|
834
880
|
"(\\d+)(?:(?:st|nd|rd|th)\\b)?"
|
|
835
881
|
#endif
|
|
@@ -842,7 +888,11 @@ parse_eu(VALUE str, VALUE hash)
|
|
|
842
888
|
"(?:"
|
|
843
889
|
"\\s*"
|
|
844
890
|
#ifndef TIGHT_PARSER
|
|
845
|
-
"(
|
|
891
|
+
"(?:"
|
|
892
|
+
BEGIN_ERA
|
|
893
|
+
"(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))"
|
|
894
|
+
END_ERA
|
|
895
|
+
")?"
|
|
846
896
|
"\\s*"
|
|
847
897
|
"('?-?\\d+(?:(?:st|nd|rd|th)\\b)?)"
|
|
848
898
|
#else
|
|
@@ -919,8 +969,8 @@ parse_us(VALUE str, VALUE hash)
|
|
|
919
969
|
COM_FPT
|
|
920
970
|
#endif
|
|
921
971
|
"(?:"
|
|
922
|
-
"\\s
|
|
923
|
-
"\\s
|
|
972
|
+
"\\s*+,?"
|
|
973
|
+
"\\s*+"
|
|
924
974
|
#ifndef TIGHT_PARSER
|
|
925
975
|
"(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?"
|
|
926
976
|
"\\s*"
|
|
@@ -967,7 +1017,7 @@ parse_iso(VALUE str, VALUE hash)
|
|
|
967
1017
|
{
|
|
968
1018
|
static const char pat_source[] =
|
|
969
1019
|
#ifndef TIGHT_PARSER
|
|
970
|
-
"('?[-+]
|
|
1020
|
+
"('?[-+]?" NUMBER "+)-(\\d+)-('?-?\\d+)"
|
|
971
1021
|
#else
|
|
972
1022
|
BOS
|
|
973
1023
|
FPW_COM FPT_COM
|
|
@@ -1321,7 +1371,7 @@ parse_vms11(VALUE str, VALUE hash)
|
|
|
1321
1371
|
{
|
|
1322
1372
|
static const char pat_source[] =
|
|
1323
1373
|
#ifndef TIGHT_PARSER
|
|
1324
|
-
"('
|
|
1374
|
+
"('?-?" NUMBER "+)-(" ABBR_MONTHS ")[^-/.]*"
|
|
1325
1375
|
"-('?-?\\d+)"
|
|
1326
1376
|
#else
|
|
1327
1377
|
BOS
|
|
@@ -1416,7 +1466,7 @@ parse_sla(VALUE str, VALUE hash)
|
|
|
1416
1466
|
{
|
|
1417
1467
|
static const char pat_source[] =
|
|
1418
1468
|
#ifndef TIGHT_PARSER
|
|
1419
|
-
"('
|
|
1469
|
+
"('?-?" NUMBER "+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?"
|
|
1420
1470
|
#else
|
|
1421
1471
|
BOS
|
|
1422
1472
|
FPW_COM FPT_COM
|
|
@@ -1524,7 +1574,7 @@ parse_dot(VALUE str, VALUE hash)
|
|
|
1524
1574
|
{
|
|
1525
1575
|
static const char pat_source[] =
|
|
1526
1576
|
#ifndef TIGHT_PARSER
|
|
1527
|
-
"('
|
|
1577
|
+
"('?-?" NUMBER "+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)"
|
|
1528
1578
|
#else
|
|
1529
1579
|
BOS
|
|
1530
1580
|
FPW_COM FPT_COM
|
|
@@ -1684,7 +1734,7 @@ parse_mday(VALUE str, VALUE hash)
|
|
|
1684
1734
|
{
|
|
1685
1735
|
static const char pat_source[] =
|
|
1686
1736
|
#ifndef TIGHT_PARSER
|
|
1687
|
-
"(
|
|
1737
|
+
"(" NUMBER "+)(st|nd|rd|th)\\b"
|
|
1688
1738
|
#else
|
|
1689
1739
|
BOS
|
|
1690
1740
|
FPW_COM FPT_COM
|
|
@@ -1922,7 +1972,7 @@ parse_ddd(VALUE str, VALUE hash)
|
|
|
1922
1972
|
#ifdef TIGHT_PARSER
|
|
1923
1973
|
BOS
|
|
1924
1974
|
#endif
|
|
1925
|
-
"([-+]?)(
|
|
1975
|
+
"([-+]?)(" NUMBER "{2,14})"
|
|
1926
1976
|
"(?:"
|
|
1927
1977
|
"\\s*"
|
|
1928
1978
|
"t?"
|
data/ext/date/date_strptime.c
CHANGED
|
@@ -7,31 +7,21 @@
|
|
|
7
7
|
#include "ruby/re.h"
|
|
8
8
|
#include <ctype.h>
|
|
9
9
|
|
|
10
|
+
#undef strncasecmp
|
|
11
|
+
#define strncasecmp STRNCASECMP
|
|
12
|
+
|
|
10
13
|
static const char *day_names[] = {
|
|
11
14
|
"Sunday", "Monday", "Tuesday", "Wednesday",
|
|
12
15
|
"Thursday", "Friday", "Saturday",
|
|
13
|
-
"Sun", "Mon", "Tue", "Wed",
|
|
14
|
-
"Thu", "Fri", "Sat"
|
|
15
16
|
};
|
|
17
|
+
static const int ABBREVIATED_DAY_NAME_LENGTH = 3;
|
|
16
18
|
|
|
17
19
|
static const char *month_names[] = {
|
|
18
20
|
"January", "February", "March", "April",
|
|
19
21
|
"May", "June", "July", "August", "September",
|
|
20
22
|
"October", "November", "December",
|
|
21
|
-
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
22
|
-
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
static const char *merid_names[] = {
|
|
26
|
-
"am", "pm",
|
|
27
|
-
"a.m.", "p.m."
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
static const char *extz_pats[] = {
|
|
31
|
-
":z",
|
|
32
|
-
"::z",
|
|
33
|
-
":::z"
|
|
34
23
|
};
|
|
24
|
+
static const int ABBREVIATED_MONTH_NAME_LENGTH = 3;
|
|
35
25
|
|
|
36
26
|
#define sizeof_array(o) (sizeof o / sizeof o[0])
|
|
37
27
|
|
|
@@ -75,7 +65,7 @@ num_pattern_p(const char *s)
|
|
|
75
65
|
#define NUM_PATTERN_P() num_pattern_p(&fmt[fi + 1])
|
|
76
66
|
|
|
77
67
|
static long
|
|
78
|
-
read_digits(const char *s, VALUE *n, size_t width)
|
|
68
|
+
read_digits(const char *s, size_t slen, VALUE *n, size_t width)
|
|
79
69
|
{
|
|
80
70
|
size_t l;
|
|
81
71
|
|
|
@@ -83,7 +73,7 @@ read_digits(const char *s, VALUE *n, size_t width)
|
|
|
83
73
|
return 0;
|
|
84
74
|
|
|
85
75
|
l = 0;
|
|
86
|
-
while (ISDIGIT(s[l])) {
|
|
76
|
+
while (l < slen && ISDIGIT(s[l])) {
|
|
87
77
|
if (++l == width) break;
|
|
88
78
|
}
|
|
89
79
|
|
|
@@ -131,9 +121,10 @@ do { \
|
|
|
131
121
|
#define READ_DIGITS(n,w) \
|
|
132
122
|
do { \
|
|
133
123
|
size_t l; \
|
|
134
|
-
l = read_digits(&str[si], &n, w); \
|
|
135
|
-
if (l == 0) \
|
|
124
|
+
l = read_digits(&str[si], slen - si, &n, w); \
|
|
125
|
+
if (l == 0) { \
|
|
136
126
|
fail(); \
|
|
127
|
+
} \
|
|
137
128
|
si += l; \
|
|
138
129
|
} while (0)
|
|
139
130
|
|
|
@@ -161,6 +152,12 @@ do { \
|
|
|
161
152
|
|
|
162
153
|
VALUE date_zone_to_diff(VALUE);
|
|
163
154
|
|
|
155
|
+
static inline int
|
|
156
|
+
head_match_p(size_t len, const char *name, const char *str, size_t slen, size_t si)
|
|
157
|
+
{
|
|
158
|
+
return slen - si >= len && strncasecmp(name, &str[si], len) == 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
164
161
|
static size_t
|
|
165
162
|
date__strptime_internal(const char *str, size_t slen,
|
|
166
163
|
const char *fmt, size_t flen, VALUE hash)
|
|
@@ -168,9 +165,18 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
168
165
|
size_t si, fi;
|
|
169
166
|
int c;
|
|
170
167
|
|
|
168
|
+
#define HEAD_MATCH_P(len, name) head_match_p(len, name, str, slen, si)
|
|
171
169
|
si = fi = 0;
|
|
172
170
|
|
|
173
171
|
while (fi < flen) {
|
|
172
|
+
if (isspace((unsigned char)fmt[fi])) {
|
|
173
|
+
while (si < slen && isspace((unsigned char)str[si]))
|
|
174
|
+
si++;
|
|
175
|
+
while (++fi < flen && isspace((unsigned char)fmt[fi]));
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (si >= slen) fail();
|
|
174
180
|
|
|
175
181
|
switch (fmt[fi]) {
|
|
176
182
|
case '%':
|
|
@@ -194,12 +200,11 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
194
200
|
{
|
|
195
201
|
int i;
|
|
196
202
|
|
|
197
|
-
for (i =
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
+
for (i = 1; i < 3 && fi + i < flen && fmt[fi+i] == ':'; ++i);
|
|
204
|
+
if (fmt[fi+i] == 'z') {
|
|
205
|
+
fi += i - 1;
|
|
206
|
+
goto again;
|
|
207
|
+
}
|
|
203
208
|
fail();
|
|
204
209
|
}
|
|
205
210
|
|
|
@@ -209,10 +214,12 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
209
214
|
int i;
|
|
210
215
|
|
|
211
216
|
for (i = 0; i < (int)sizeof_array(day_names); i++) {
|
|
212
|
-
|
|
213
|
-
|
|
217
|
+
const char *day_name = day_names[i];
|
|
218
|
+
size_t l = strlen(day_name);
|
|
219
|
+
if (HEAD_MATCH_P(l, day_name) ||
|
|
220
|
+
HEAD_MATCH_P(l = ABBREVIATED_DAY_NAME_LENGTH, day_name)) {
|
|
214
221
|
si += l;
|
|
215
|
-
set_hash("wday", INT2FIX(i
|
|
222
|
+
set_hash("wday", INT2FIX(i));
|
|
216
223
|
goto matched;
|
|
217
224
|
}
|
|
218
225
|
}
|
|
@@ -225,10 +232,12 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
225
232
|
int i;
|
|
226
233
|
|
|
227
234
|
for (i = 0; i < (int)sizeof_array(month_names); i++) {
|
|
228
|
-
|
|
229
|
-
|
|
235
|
+
const char *month_name = month_names[i];
|
|
236
|
+
size_t l = strlen(month_name);
|
|
237
|
+
if (HEAD_MATCH_P(l, month_name) ||
|
|
238
|
+
HEAD_MATCH_P(l = ABBREVIATED_MONTH_NAME_LENGTH, month_name)) {
|
|
230
239
|
si += l;
|
|
231
|
-
set_hash("mon", INT2FIX(
|
|
240
|
+
set_hash("mon", INT2FIX(i + 1));
|
|
232
241
|
goto matched;
|
|
233
242
|
}
|
|
234
243
|
}
|
|
@@ -402,18 +411,19 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
402
411
|
|
|
403
412
|
case 'P':
|
|
404
413
|
case 'p':
|
|
414
|
+
if (slen - si < 2) fail();
|
|
405
415
|
{
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
if (
|
|
411
|
-
|
|
412
|
-
set_hash("_merid", INT2FIX((i % 2) == 0 ? 0 : 12));
|
|
413
|
-
goto matched;
|
|
414
|
-
}
|
|
416
|
+
char c = str[si];
|
|
417
|
+
const int hour = (c == 'P' || c == 'p') ? 12 : 0;
|
|
418
|
+
if (!hour && !(c == 'A' || c == 'a')) fail();
|
|
419
|
+
if ((c = str[si+1]) == '.') {
|
|
420
|
+
if (slen - si < 4 || str[si+3] != '.') fail();
|
|
421
|
+
c = str[si += 2];
|
|
415
422
|
}
|
|
416
|
-
fail();
|
|
423
|
+
if (!(c == 'M' || c == 'm')) fail();
|
|
424
|
+
si += 2;
|
|
425
|
+
set_hash("_merid", INT2FIX(hour));
|
|
426
|
+
goto matched;
|
|
417
427
|
}
|
|
418
428
|
|
|
419
429
|
case 'Q':
|
|
@@ -587,7 +597,7 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
587
597
|
|
|
588
598
|
b = rb_backref_get();
|
|
589
599
|
rb_match_busy(b);
|
|
590
|
-
m = f_match(pat,
|
|
600
|
+
m = f_match(pat, rb_usascii_str_new(&str[si], slen - si));
|
|
591
601
|
|
|
592
602
|
if (!NIL_P(m)) {
|
|
593
603
|
VALUE s, l, o;
|
|
@@ -619,22 +629,13 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
619
629
|
if (str[si] != '%')
|
|
620
630
|
fail();
|
|
621
631
|
si++;
|
|
622
|
-
if (fi < flen)
|
|
623
|
-
if (str[si] != fmt[fi])
|
|
632
|
+
if (fi < flen) {
|
|
633
|
+
if (si >= slen || str[si] != fmt[fi])
|
|
624
634
|
fail();
|
|
625
|
-
|
|
635
|
+
si++;
|
|
636
|
+
}
|
|
626
637
|
goto matched;
|
|
627
638
|
}
|
|
628
|
-
case ' ':
|
|
629
|
-
case '\t':
|
|
630
|
-
case '\n':
|
|
631
|
-
case '\v':
|
|
632
|
-
case '\f':
|
|
633
|
-
case '\r':
|
|
634
|
-
while (isspace((unsigned char)str[si]))
|
|
635
|
-
si++;
|
|
636
|
-
fi++;
|
|
637
|
-
break;
|
|
638
639
|
default:
|
|
639
640
|
ordinal:
|
|
640
641
|
if (str[si] != fmt[fi])
|
data/ext/date/extconf.rb
CHANGED
|
@@ -3,6 +3,8 @@ require 'mkmf'
|
|
|
3
3
|
|
|
4
4
|
config_string("strict_warnflags") {|w| $warnflags += " #{w}"}
|
|
5
5
|
|
|
6
|
+
append_cflags("-Wno-compound-token-split-by-macro") if RUBY_VERSION < "2.7."
|
|
7
|
+
have_func("rb_category_warn")
|
|
6
8
|
with_werror("", {:werror => true}) do |opt, |
|
|
7
9
|
have_var("timezone", "time.h", opt)
|
|
8
10
|
have_var("altzone", "time.h", opt)
|