date 2.0.2 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -70,7 +70,7 @@ static size_t
70
70
  digit_span(const char *s, const char *e)
71
71
  {
72
72
  size_t i = 0;
73
- while (s + i < e && isdigit(s[i])) i++;
73
+ while (s + i < e && isdigit((unsigned char)s[i])) i++;
74
74
  return i;
75
75
  }
76
76
 
@@ -110,7 +110,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
110
110
 
111
111
  s = RSTRING_PTR(y);
112
112
  ep = RSTRING_END(y);
113
- while (s < ep && !issign(*s) && !isdigit(*s))
113
+ while (s < ep && !issign(*s) && !isdigit((unsigned char)*s))
114
114
  s++;
115
115
  if (s >= ep) goto no_date;
116
116
  bp = s;
@@ -162,7 +162,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
162
162
 
163
163
  s = RSTRING_PTR(y);
164
164
  ep = RSTRING_END(y);
165
- while (s < ep && !issign(*s) && !isdigit(*s))
165
+ while (s < ep && !issign(*s) && !isdigit((unsigned char)*s))
166
166
  s++;
167
167
  if (s >= ep) goto no_year;
168
168
  bp = s;
@@ -199,7 +199,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
199
199
 
200
200
  s = RSTRING_PTR(m);
201
201
  ep = RSTRING_END(m);
202
- while (s < ep && !isdigit(*s))
202
+ while (s < ep && !isdigit((unsigned char)*s))
203
203
  s++;
204
204
  if (s >= ep) goto no_month;
205
205
  bp = s;
@@ -225,7 +225,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
225
225
 
226
226
  s = RSTRING_PTR(d);
227
227
  ep = RSTRING_END(d);
228
- while (s < ep && !isdigit(*s))
228
+ while (s < ep && !isdigit((unsigned char)*s))
229
229
  s++;
230
230
  if (s >= ep) goto no_mday;
231
231
  bp = s;
@@ -361,66 +361,90 @@ do { \
361
361
  #include "zonetab.h"
362
362
 
363
363
  static int
364
- str_end_with(const char *s, long l, const char *w)
364
+ str_end_with_word(const char *s, long l, const char *w)
365
365
  {
366
366
  int n = (int)strlen(w);
367
- return (l >= n && strncmp(s - n, w, n) == 0);
367
+ if (l <= n || !isspace((unsigned char)s[l - n - 1])) return 0;
368
+ if (strncasecmp(&s[l - n], w, n)) return 0;
369
+ do ++n; while (l > n && isspace((unsigned char)s[l - n - 1]));
370
+ return n;
368
371
  }
369
372
 
370
- VALUE
371
- date_zone_to_diff(VALUE str)
373
+ static long
374
+ shrunk_size(const char *s, long l)
372
375
  {
373
- VALUE offset = Qnil;
374
- VALUE vbuf = 0;
375
-
376
- long l, i;
377
- char *s, *dest, *d;
378
- int sp = 1;
379
-
380
- l = RSTRING_LEN(str);
381
- s = RSTRING_PTR(str);
382
-
383
- dest = d = ALLOCV_N(char, vbuf, l + 1);
384
-
385
- for (i = 0; i < l; i++) {
386
- if (isspace((unsigned char)s[i]) || s[i] == '\0') {
387
- if (!sp)
388
- *d++ = ' ';
389
- sp = 1;
376
+ long i, ni;
377
+ int sp = 0;
378
+ for (i = ni = 0; i < l; ++i) {
379
+ if (!isspace((unsigned char)s[i])) {
380
+ if (sp) ni++;
381
+ sp = 0;
382
+ ni++;
390
383
  }
391
384
  else {
392
- if (isalpha((unsigned char)s[i]))
393
- *d++ = tolower((unsigned char)s[i]);
394
- else
395
- *d++ = s[i];
396
- sp = 0;
385
+ sp = 1;
397
386
  }
398
387
  }
399
- if (d > dest) {
400
- if (*(d - 1) == ' ')
401
- --d;
402
- *d = '\0';
388
+ return ni < l ? ni : 0;
389
+ }
390
+
391
+ static long
392
+ shrink_space(char *d, const char *s, long l)
393
+ {
394
+ long i, ni;
395
+ int sp = 0;
396
+ for (i = ni = 0; i < l; ++i) {
397
+ if (!isspace((unsigned char)s[i])) {
398
+ if (sp) d[ni++] = ' ';
399
+ sp = 0;
400
+ d[ni++] = s[i];
401
+ }
402
+ else {
403
+ sp = 1;
404
+ }
403
405
  }
404
- l = d - dest;
405
- s = dest;
406
+ return ni;
407
+ }
408
+
409
+ VALUE
410
+ date_zone_to_diff(VALUE str)
411
+ {
412
+ VALUE offset = Qnil;
413
+ VALUE vbuf = 0;
414
+ long l = RSTRING_LEN(str);
415
+ const char *s = RSTRING_PTR(str);
416
+
406
417
  {
407
- static const char STD[] = " standard time";
408
- static const char DST1[] = " daylight time";
409
- static const char DST2[] = " dst";
410
418
  int dst = 0;
419
+ int w;
411
420
 
412
- if (str_end_with(d, l, STD)) {
413
- l -= sizeof(STD) - 1;
414
- }
415
- else if (str_end_with(d, l, DST1)) {
416
- l -= sizeof(DST1) - 1;
417
- dst = 1;
421
+ if ((w = str_end_with_word(s, l, "time")) > 0) {
422
+ int wtime = w;
423
+ l -= w;
424
+ if ((w = str_end_with_word(s, l, "standard")) > 0) {
425
+ l -= w;
426
+ }
427
+ else if ((w = str_end_with_word(s, l, "daylight")) > 0) {
428
+ l -= w;
429
+ dst = 1;
430
+ }
431
+ else {
432
+ l += wtime;
433
+ }
418
434
  }
419
- else if (str_end_with(d, l, DST2)) {
420
- l -= sizeof(DST2) - 1;
435
+ else if ((w = str_end_with_word(s, l, "dst")) > 0) {
436
+ l -= w;
421
437
  dst = 1;
422
438
  }
423
439
  {
440
+ long sl = shrunk_size(s, l);
441
+ if (sl > 0 && sl <= MAX_WORD_LENGTH) {
442
+ char *d = ALLOCV_N(char, vbuf, sl);
443
+ l = shrink_space(d, s, l);
444
+ s = d;
445
+ }
446
+ }
447
+ if (l > 0 && l <= MAX_WORD_LENGTH) {
424
448
  const struct zone *z = zonetab(s, (unsigned int)l);
425
449
  if (z) {
426
450
  int d = z->offset;
@@ -436,8 +460,8 @@ date_zone_to_diff(VALUE str)
436
460
  long hour = 0, min = 0, sec = 0;
437
461
 
438
462
  if (l > 3 &&
439
- (strncmp(s, "gmt", 3) == 0 ||
440
- strncmp(s, "utc", 3) == 0)) {
463
+ (strncasecmp(s, "gmt", 3) == 0 ||
464
+ strncasecmp(s, "utc", 3) == 0)) {
441
465
  s += 3;
442
466
  l -= 3;
443
467
  }
@@ -730,8 +754,8 @@ check_year_width(VALUE y)
730
754
  l = RSTRING_LEN(y);
731
755
  if (l < 2) return 0;
732
756
  s = RSTRING_PTR(y);
733
- if (!isdigit(s[1])) return 0;
734
- return (l == 2 || !isdigit(s[2]));
757
+ if (!isdigit((unsigned char)s[1])) return 0;
758
+ return (l == 2 || !isdigit((unsigned char)s[2]));
735
759
  }
736
760
 
737
761
  static int
@@ -1212,6 +1236,9 @@ parse_iso2(VALUE str, VALUE hash)
1212
1236
  return 1;
1213
1237
  }
1214
1238
 
1239
+ #define JISX0301_ERA_INITIALS "mtshr"
1240
+ #define JISX0301_DEFAULT_ERA 'H' /* obsolete */
1241
+
1215
1242
  static int
1216
1243
  gengo(int c)
1217
1244
  {
@@ -1222,6 +1249,7 @@ gengo(int c)
1222
1249
  case 'T': case 't': e = 1911; break;
1223
1250
  case 'S': case 's': e = 1925; break;
1224
1251
  case 'H': case 'h': e = 1988; break;
1252
+ case 'R': case 'r': e = 2018; break;
1225
1253
  default: e = 0; break;
1226
1254
  }
1227
1255
  return e;
@@ -1252,11 +1280,11 @@ parse_jis(VALUE str, VALUE hash)
1252
1280
  {
1253
1281
  static const char pat_source[] =
1254
1282
  #ifndef TIGHT_PARSER
1255
- "\\b([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)"
1283
+ "\\b([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
1256
1284
  #else
1257
1285
  BOS
1258
1286
  FPW_COM FPT_COM
1259
- "([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)"
1287
+ "([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
1260
1288
  TEE_FPT COM_FPW
1261
1289
  EOS
1262
1290
  #endif
@@ -1859,30 +1887,26 @@ parse_ddd_cb(VALUE m, VALUE hash)
1859
1887
  set_hash("zone", s5);
1860
1888
 
1861
1889
  if (*cs5 == '[') {
1862
- VALUE vbuf = 0;
1863
- char *buf = ALLOCV_N(char, vbuf, l5 + 1);
1864
- char *s1, *s2, *s3;
1890
+ const char *s1, *s2;
1865
1891
  VALUE zone;
1866
1892
 
1867
- memcpy(buf, cs5, l5);
1868
- buf[l5 - 1] = '\0';
1869
-
1870
- s1 = buf + 1;
1871
- s2 = strchr(buf, ':');
1893
+ l5 -= 2;
1894
+ s1 = cs5 + 1;
1895
+ s2 = memchr(s1, ':', l5);
1872
1896
  if (s2) {
1873
- *s2 = '\0';
1874
1897
  s2++;
1898
+ zone = rb_str_subseq(s5, s2 - cs5, l5 - (s2 - s1));
1899
+ s5 = rb_str_subseq(s5, 1, s2 - s1);
1875
1900
  }
1876
- if (s2)
1877
- s3 = s2;
1878
- else
1879
- s3 = s1;
1880
- zone = rb_str_new2(s3);
1901
+ else {
1902
+ zone = rb_str_subseq(s5, 1, l5);
1903
+ if (isdigit((unsigned char)*s1))
1904
+ s5 = rb_str_append(rb_str_new_cstr("+"), zone);
1905
+ else
1906
+ s5 = zone;
1907
+ }
1881
1908
  set_hash("zone", zone);
1882
- if (isdigit((unsigned char)*s1))
1883
- *--s1 = '+';
1884
- set_hash("offset", date_zone_to_diff(rb_str_new2(s1)));
1885
- ALLOCV_END(vbuf);
1909
+ set_hash("offset", date_zone_to_diff(s5));
1886
1910
  }
1887
1911
  RB_GC_GUARD(s5);
1888
1912
  }
@@ -2175,7 +2199,7 @@ date__parse(VALUE str, VALUE comp)
2175
2199
  #endif
2176
2200
 
2177
2201
  {
2178
- if (RTEST(ref_hash("_bc"))) {
2202
+ if (RTEST(del_hash("_bc"))) {
2179
2203
  VALUE y;
2180
2204
 
2181
2205
  y = ref_hash("cwyear");
@@ -2190,7 +2214,7 @@ date__parse(VALUE str, VALUE comp)
2190
2214
  }
2191
2215
  }
2192
2216
 
2193
- if (RTEST(ref_hash("_comp"))) {
2217
+ if (RTEST(del_hash("_comp"))) {
2194
2218
  VALUE y;
2195
2219
 
2196
2220
  y = ref_hash("cwyear");
@@ -2213,9 +2237,6 @@ date__parse(VALUE str, VALUE comp)
2213
2237
 
2214
2238
  }
2215
2239
 
2216
- del_hash("_bc");
2217
- del_hash("_comp");
2218
-
2219
2240
  {
2220
2241
  VALUE zone = ref_hash("zone");
2221
2242
  if (!NIL_P(zone) && NIL_P(ref_hash("offset")))
@@ -2265,8 +2286,8 @@ iso8601_ext_datetime_cb(VALUE m, VALUE hash)
2265
2286
  s[i] = rb_reg_nth_match(i, m);
2266
2287
  }
2267
2288
 
2268
- if (!NIL_P(s[3])) {
2269
- set_hash("mday", str2num(s[3]));
2289
+ if (!NIL_P(s[1])) {
2290
+ if (!NIL_P(s[3])) set_hash("mday", str2num(s[3]));
2270
2291
  if (strcmp(RSTRING_PTR(s[1]), "-") != 0) {
2271
2292
  y = str2num(s[1]);
2272
2293
  if (RSTRING_LEN(s[1]) < 4)
@@ -2323,7 +2344,7 @@ static int
2323
2344
  iso8601_ext_datetime(VALUE str, VALUE hash)
2324
2345
  {
2325
2346
  static const char pat_source[] =
2326
- "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?-(\\d{2})|"
2347
+ "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?(?:-(\\d{2}))?|"
2327
2348
  "([-+]?\\d{2,})?-(\\d{3})|"
2328
2349
  "(\\d{4}|\\d{2})?-w(\\d{2})-(\\d)|"
2329
2350
  "-w-(\\d))"
@@ -2954,7 +2975,7 @@ jisx0301_cb(VALUE m, VALUE hash)
2954
2975
  s[i] = rb_reg_nth_match(i, m);
2955
2976
  }
2956
2977
 
2957
- ep = gengo(NIL_P(s[1]) ? 'h' : *RSTRING_PTR(s[1]));
2978
+ ep = gengo(NIL_P(s[1]) ? JISX0301_DEFAULT_ERA : *RSTRING_PTR(s[1]));
2958
2979
  set_hash("year", f_add(str2num(s[2]), INT2FIX(ep)));
2959
2980
  set_hash("mon", str2num(s[3]));
2960
2981
  set_hash("mday", str2num(s[4]));
@@ -2979,7 +3000,7 @@ static int
2979
3000
  jisx0301(VALUE str, VALUE hash)
2980
3001
  {
2981
3002
  static const char pat_source[] =
2982
- "\\A\\s*([mtsh])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
3003
+ "\\A\\s*([" JISX0301_ERA_INITIALS "])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
2983
3004
  "(?:t"
2984
3005
  "(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d*))?)?"
2985
3006
  "(z|[-+]\\d{2}(?::?\\d{2})?)?)?)?\\s*\\z";
@@ -669,7 +669,7 @@ date__strptime(const char *str, size_t slen,
669
669
  if (fail_p())
670
670
  return Qnil;
671
671
 
672
- cent = ref_hash("_cent");
672
+ cent = del_hash("_cent");
673
673
  if (!NIL_P(cent)) {
674
674
  VALUE year;
675
675
 
@@ -679,10 +679,9 @@ date__strptime(const char *str, size_t slen,
679
679
  year = ref_hash("year");
680
680
  if (!NIL_P(year))
681
681
  set_hash("year", f_add(year, f_mul(cent, INT2FIX(100))));
682
- del_hash("_cent");
683
682
  }
684
683
 
685
- merid = ref_hash("_merid");
684
+ merid = del_hash("_merid");
686
685
  if (!NIL_P(merid)) {
687
686
  VALUE hour;
688
687
 
@@ -691,7 +690,6 @@ date__strptime(const char *str, size_t slen,
691
690
  hour = f_mod(hour, INT2FIX(12));
692
691
  set_hash("hour", f_add(hour, merid));
693
692
  }
694
- del_hash("_merid");
695
693
  }
696
694
 
697
695
  return hash;
data/ext/date/prereq.mk CHANGED
@@ -1,8 +1,12 @@
1
1
  .SUFFIXES: .list
2
2
 
3
3
  .list.h:
4
- gperf -E -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \
4
+ gperf --ignore-case -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \
5
5
  | sed -f $(top_srcdir)/tool/gperf.sed \
6
6
  > $(@F)
7
7
 
8
8
  zonetab.h: zonetab.list
9
+
10
+ .PHONY: update-zonetab
11
+ update-zonetab:
12
+ $(RUBY) -C $(srcdir) update-abbr.rb