date 2.0.3 → 3.0.0

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.
@@ -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(s[l - n - 1])) return 0;
368
+ if (strncasecmp(&s[l - n], w, n)) return 0;
369
+ do ++n; while (l > n && isspace(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(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(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
  }
@@ -1863,30 +1887,26 @@ parse_ddd_cb(VALUE m, VALUE hash)
1863
1887
  set_hash("zone", s5);
1864
1888
 
1865
1889
  if (*cs5 == '[') {
1866
- VALUE vbuf = 0;
1867
- char *buf = ALLOCV_N(char, vbuf, l5 + 1);
1868
- char *s1, *s2, *s3;
1890
+ const char *s1, *s2;
1869
1891
  VALUE zone;
1870
1892
 
1871
- memcpy(buf, cs5, l5);
1872
- buf[l5 - 1] = '\0';
1873
-
1874
- s1 = buf + 1;
1875
- s2 = strchr(buf, ':');
1893
+ l5 -= 2;
1894
+ s1 = cs5 + 1;
1895
+ s2 = memchr(s1, ':', l5);
1876
1896
  if (s2) {
1877
- *s2 = '\0';
1878
1897
  s2++;
1898
+ zone = rb_str_subseq(s5, s2 - cs5, l5 - (s2 - s1));
1899
+ s5 = rb_str_subseq(s5, 1, s2 - s1);
1879
1900
  }
1880
- if (s2)
1881
- s3 = s2;
1882
- else
1883
- s3 = s1;
1884
- 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
+ }
1885
1908
  set_hash("zone", zone);
1886
- if (isdigit((unsigned char)*s1))
1887
- *--s1 = '+';
1888
- set_hash("offset", date_zone_to_diff(rb_str_new2(s1)));
1889
- ALLOCV_END(vbuf);
1909
+ set_hash("offset", date_zone_to_diff(s5));
1890
1910
  }
1891
1911
  RB_GC_GUARD(s5);
1892
1912
  }
@@ -2179,7 +2199,7 @@ date__parse(VALUE str, VALUE comp)
2179
2199
  #endif
2180
2200
 
2181
2201
  {
2182
- if (RTEST(ref_hash("_bc"))) {
2202
+ if (RTEST(del_hash("_bc"))) {
2183
2203
  VALUE y;
2184
2204
 
2185
2205
  y = ref_hash("cwyear");
@@ -2194,7 +2214,7 @@ date__parse(VALUE str, VALUE comp)
2194
2214
  }
2195
2215
  }
2196
2216
 
2197
- if (RTEST(ref_hash("_comp"))) {
2217
+ if (RTEST(del_hash("_comp"))) {
2198
2218
  VALUE y;
2199
2219
 
2200
2220
  y = ref_hash("cwyear");
@@ -2217,9 +2237,6 @@ date__parse(VALUE str, VALUE comp)
2217
2237
 
2218
2238
  }
2219
2239
 
2220
- del_hash("_bc");
2221
- del_hash("_comp");
2222
-
2223
2240
  {
2224
2241
  VALUE zone = ref_hash("zone");
2225
2242
  if (!NIL_P(zone) && NIL_P(ref_hash("offset")))
@@ -2269,8 +2286,8 @@ iso8601_ext_datetime_cb(VALUE m, VALUE hash)
2269
2286
  s[i] = rb_reg_nth_match(i, m);
2270
2287
  }
2271
2288
 
2272
- if (!NIL_P(s[3])) {
2273
- set_hash("mday", str2num(s[3]));
2289
+ if (!NIL_P(s[1])) {
2290
+ if (!NIL_P(s[3])) set_hash("mday", str2num(s[3]));
2274
2291
  if (strcmp(RSTRING_PTR(s[1]), "-") != 0) {
2275
2292
  y = str2num(s[1]);
2276
2293
  if (RSTRING_LEN(s[1]) < 4)
@@ -2327,7 +2344,7 @@ static int
2327
2344
  iso8601_ext_datetime(VALUE str, VALUE hash)
2328
2345
  {
2329
2346
  static const char pat_source[] =
2330
- "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?-(\\d{2})|"
2347
+ "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?(?:-(\\d{2}))?|"
2331
2348
  "([-+]?\\d{2,})?-(\\d{3})|"
2332
2349
  "(\\d{4}|\\d{2})?-w(\\d{2})-(\\d)|"
2333
2350
  "-w-(\\d))"
@@ -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