date 3.3.1 → 3.4.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/ext/date/date_core.c +210 -83
- data/ext/date/date_parse.c +3 -0
- data/ext/date/date_strptime.c +54 -54
- data/ext/date/extconf.rb +1 -0
- data/ext/date/prereq.mk +1 -1
- data/ext/date/zonetab.h +627 -625
- data/ext/date/zonetab.list +5 -2
- data/lib/date.rb +1 -1
- metadata +10 -9
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,7 +121,7 @@ do { \
|
|
131
121
|
#define READ_DIGITS(n,w) \
|
132
122
|
do { \
|
133
123
|
size_t l; \
|
134
|
-
l = read_digits(&str[si], &n, w); \
|
124
|
+
l = read_digits(&str[si], slen - si, &n, w); \
|
135
125
|
if (l == 0) \
|
136
126
|
fail(); \
|
137
127
|
si += l; \
|
@@ -161,6 +151,12 @@ do { \
|
|
161
151
|
|
162
152
|
VALUE date_zone_to_diff(VALUE);
|
163
153
|
|
154
|
+
static inline int
|
155
|
+
head_match_p(size_t len, const char *name, const char *str, size_t slen, size_t si)
|
156
|
+
{
|
157
|
+
return slen - si >= len && strncasecmp(name, &str[si], len) == 0;
|
158
|
+
}
|
159
|
+
|
164
160
|
static size_t
|
165
161
|
date__strptime_internal(const char *str, size_t slen,
|
166
162
|
const char *fmt, size_t flen, VALUE hash)
|
@@ -168,9 +164,18 @@ date__strptime_internal(const char *str, size_t slen,
|
|
168
164
|
size_t si, fi;
|
169
165
|
int c;
|
170
166
|
|
167
|
+
#define HEAD_MATCH_P(len, name) head_match_p(len, name, str, slen, si)
|
171
168
|
si = fi = 0;
|
172
169
|
|
173
170
|
while (fi < flen) {
|
171
|
+
if (isspace((unsigned char)fmt[fi])) {
|
172
|
+
while (si < slen && isspace((unsigned char)str[si]))
|
173
|
+
si++;
|
174
|
+
while (++fi < flen && isspace((unsigned char)fmt[fi]));
|
175
|
+
continue;
|
176
|
+
}
|
177
|
+
|
178
|
+
if (si >= slen) fail();
|
174
179
|
|
175
180
|
switch (fmt[fi]) {
|
176
181
|
case '%':
|
@@ -194,12 +199,11 @@ date__strptime_internal(const char *str, size_t slen,
|
|
194
199
|
{
|
195
200
|
int i;
|
196
201
|
|
197
|
-
for (i =
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
}
|
202
|
+
for (i = 1; i < 3 && fi + i < flen && fmt[fi+i] == ':'; ++i);
|
203
|
+
if (fmt[fi+i] == 'z') {
|
204
|
+
fi += i - 1;
|
205
|
+
goto again;
|
206
|
+
}
|
203
207
|
fail();
|
204
208
|
}
|
205
209
|
|
@@ -209,10 +213,12 @@ date__strptime_internal(const char *str, size_t slen,
|
|
209
213
|
int i;
|
210
214
|
|
211
215
|
for (i = 0; i < (int)sizeof_array(day_names); i++) {
|
212
|
-
|
213
|
-
|
216
|
+
const char *day_name = day_names[i];
|
217
|
+
size_t l = strlen(day_name);
|
218
|
+
if (HEAD_MATCH_P(l, day_name) ||
|
219
|
+
HEAD_MATCH_P(l = ABBREVIATED_DAY_NAME_LENGTH, day_name)) {
|
214
220
|
si += l;
|
215
|
-
set_hash("wday", INT2FIX(i
|
221
|
+
set_hash("wday", INT2FIX(i));
|
216
222
|
goto matched;
|
217
223
|
}
|
218
224
|
}
|
@@ -225,10 +231,12 @@ date__strptime_internal(const char *str, size_t slen,
|
|
225
231
|
int i;
|
226
232
|
|
227
233
|
for (i = 0; i < (int)sizeof_array(month_names); i++) {
|
228
|
-
|
229
|
-
|
234
|
+
const char *month_name = month_names[i];
|
235
|
+
size_t l = strlen(month_name);
|
236
|
+
if (HEAD_MATCH_P(l, month_name) ||
|
237
|
+
HEAD_MATCH_P(l = ABBREVIATED_MONTH_NAME_LENGTH, month_name)) {
|
230
238
|
si += l;
|
231
|
-
set_hash("mon", INT2FIX(
|
239
|
+
set_hash("mon", INT2FIX(i + 1));
|
232
240
|
goto matched;
|
233
241
|
}
|
234
242
|
}
|
@@ -402,18 +410,19 @@ date__strptime_internal(const char *str, size_t slen,
|
|
402
410
|
|
403
411
|
case 'P':
|
404
412
|
case 'p':
|
413
|
+
if (slen - si < 2) fail();
|
405
414
|
{
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
if (
|
411
|
-
|
412
|
-
set_hash("_merid", INT2FIX((i % 2) == 0 ? 0 : 12));
|
413
|
-
goto matched;
|
414
|
-
}
|
415
|
+
char c = str[si];
|
416
|
+
const int hour = (c == 'P' || c == 'p') ? 12 : 0;
|
417
|
+
if (!hour && !(c == 'A' || c == 'a')) fail();
|
418
|
+
if ((c = str[si+1]) == '.') {
|
419
|
+
if (slen - si < 4 || str[si+3] != '.') fail();
|
420
|
+
c = str[si += 2];
|
415
421
|
}
|
416
|
-
fail();
|
422
|
+
if (!(c == 'M' || c == 'm')) fail();
|
423
|
+
si += 2;
|
424
|
+
set_hash("_merid", INT2FIX(hour));
|
425
|
+
goto matched;
|
417
426
|
}
|
418
427
|
|
419
428
|
case 'Q':
|
@@ -587,7 +596,7 @@ date__strptime_internal(const char *str, size_t slen,
|
|
587
596
|
|
588
597
|
b = rb_backref_get();
|
589
598
|
rb_match_busy(b);
|
590
|
-
m = f_match(pat,
|
599
|
+
m = f_match(pat, rb_usascii_str_new(&str[si], slen - si));
|
591
600
|
|
592
601
|
if (!NIL_P(m)) {
|
593
602
|
VALUE s, l, o;
|
@@ -619,22 +628,13 @@ date__strptime_internal(const char *str, size_t slen,
|
|
619
628
|
if (str[si] != '%')
|
620
629
|
fail();
|
621
630
|
si++;
|
622
|
-
if (fi < flen)
|
623
|
-
if (str[si] != fmt[fi])
|
631
|
+
if (fi < flen) {
|
632
|
+
if (si >= slen || str[si] != fmt[fi])
|
624
633
|
fail();
|
625
|
-
|
634
|
+
si++;
|
635
|
+
}
|
626
636
|
goto matched;
|
627
637
|
}
|
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
638
|
default:
|
639
639
|
ordinal:
|
640
640
|
if (str[si] != fmt[fi])
|
data/ext/date/extconf.rb
CHANGED
@@ -3,6 +3,7 @@ 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."
|
6
7
|
have_func("rb_category_warn")
|
7
8
|
with_werror("", {:werror => true}) do |opt, |
|
8
9
|
have_var("timezone", "time.h", opt)
|