Coverage Report

Created: 2026-09-14 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/date/lib/parse_iso_intervals.c
Line
Count
Source
1
/* Generated by re2c 1.0.3 on Wed Aug  5 11:34:39 2026 */
2
#line 1 "ext/date/lib/parse_iso_intervals.re"
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2015-2019 Derick Rethans
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26
27
#include "timelib.h"
28
#include "timelib_private.h"
29
30
#include <ctype.h>
31
32
204
#define EOI      257
33
34
58
#define TIMELIB_PERIOD  260
35
0
#define TIMELIB_ISO_DATE 261
36
#define TIMELIB_ERROR   999
37
38
typedef unsigned char uchar;
39
40
#define   BSIZE    8192
41
42
1.96k
#define   YYCTYPE      uchar
43
8.71k
#define   YYCURSOR     cursor
44
2.13k
#define   YYLIMIT      s->lim
45
1.37k
#define   YYMARKER     s->ptr
46
73
#define   YYFILL(n)    return EOI;
47
48
#define   RET(i)       {s->cur = cursor; return i;}
49
50
58
#define timelib_string_free timelib_free
51
52
58
#define TIMELIB_INIT  s->cur = cursor; str = timelib_string(s); ptr = str
53
58
#define TIMELIB_DEINIT timelib_string_free(str)
54
55
#ifdef DEBUG_PARSER
56
#define DEBUG_OUTPUT(s) printf("%s\n", s);
57
#define YYDEBUG(s,c) { if (s != -1) { printf("state: %d ", s); printf("[%c]\n", c); } }
58
#else
59
#define DEBUG_OUTPUT(s)
60
#define YYDEBUG(s,c)
61
#endif
62
63
typedef struct _Scanner {
64
  int           fd;
65
  uchar        *lim, *str, *ptr, *cur, *tok, *pos;
66
  unsigned int  line, len;
67
  timelib_error_container *errors;
68
69
  timelib_time     *begin;
70
  timelib_time     *end;
71
  timelib_rel_time *period;
72
  int               recurrences;
73
74
  int have_period;
75
  int have_recurrences;
76
  int have_date;
77
  int have_begin_date;
78
  int have_end_date;
79
} Scanner;
80
81
static void add_error(Scanner *s, const char *error)
82
1.54k
{
83
1.54k
  s->errors->error_count++;
84
1.54k
  s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
85
1.54k
  s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0;
86
1.54k
  s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0;
87
1.54k
  s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error);
88
1.54k
}
89
90
static char *timelib_string(Scanner *s)
91
58
{
92
58
  char *tmp = timelib_calloc(1, s->cur - s->tok + 1);
93
58
  memcpy(tmp, s->tok, s->cur - s->tok);
94
95
58
  return tmp;
96
58
}
97
98
static timelib_sll timelib_get_nr(const char **ptr, int max_length)
99
41
{
100
41
  const char *begin, *end;
101
41
  char *str;
102
41
  timelib_sll tmp_nr = TIMELIB_UNSET;
103
41
  int len = 0;
104
105
41
  while ((**ptr < '0') || (**ptr > '9')) {
106
0
    if (**ptr == '\0') {
107
0
      return TIMELIB_UNSET;
108
0
    }
109
0
    ++*ptr;
110
0
  }
111
41
  begin = *ptr;
112
86
  while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) {
113
45
    ++*ptr;
114
45
    ++len;
115
45
  }
116
41
  end = *ptr;
117
41
  str = timelib_calloc(1, end - begin + 1);
118
41
  memcpy(str, begin, end - begin);
119
41
  tmp_nr = strtoll(str, NULL, 10);
120
41
  timelib_free(str);
121
41
  return tmp_nr;
122
41
}
123
124
static timelib_ull timelib_get_unsigned_nr(const char **ptr, int max_length)
125
41
{
126
41
  timelib_ull dir = 1;
127
128
41
  while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) {
129
0
    if (**ptr == '\0') {
130
0
      return TIMELIB_UNSET;
131
0
    }
132
0
    ++*ptr;
133
0
  }
134
135
41
  while (**ptr == '+' || **ptr == '-')
136
0
  {
137
0
    if (**ptr == '-') {
138
0
      dir *= -1;
139
0
    }
140
0
    ++*ptr;
141
0
  }
142
41
  return dir * timelib_get_nr(ptr, max_length);
143
41
}
144
145
#define timelib_split_free(arg) {       \
146
  int i;                         \
147
  for (i = 0; i < arg.c; i++) {  \
148
    timelib_free(arg.v[i]);    \
149
  }                              \
150
  if (arg.v) {                   \
151
    timelib_free(arg.v);       \
152
  }                              \
153
}
154
155
/* date parser's scan function too large for VC6 - VC7.x
156
   drop the optimization solves the problem */
157
#ifdef PHP_WIN32
158
#pragma optimize( "", off )
159
#endif
160
static int scan(Scanner *s)
161
131
{
162
131
  uchar *cursor = s->cur;
163
131
  char *str;
164
131
  const char *ptr = NULL;
165
166
1.96k
std:
167
1.96k
  s->tok = cursor;
168
1.96k
  s->len = 0;
169
1.96k
#line 194 "ext/date/lib/parse_iso_intervals.re"
170
171
172
173
1.96k
#line 174 "ext/date/lib/parse_iso_intervals.c"
174
1.96k
{
175
1.96k
  YYCTYPE yych;
176
1.96k
  unsigned int yyaccept = 0;
177
1.96k
  static const unsigned char yybm[] = {
178
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
179
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
180
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
181
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
182
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
183
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
184
1.96k
    128, 128, 128, 128, 128, 128, 128, 128, 
185
1.96k
    128, 128,   0,   0,   0,   0,   0,   0, 
186
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
187
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
188
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
189
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
190
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
191
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
192
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
193
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
194
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
195
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
196
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
197
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
198
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
199
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
200
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
201
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
202
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
203
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
204
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
205
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
206
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
207
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
208
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
209
1.96k
      0,   0,   0,   0,   0,   0,   0,   0, 
210
1.96k
  };
211
1.96k
  YYDEBUG(0, *YYCURSOR);
212
1.96k
  if ((YYLIMIT - YYCURSOR) < 20) YYFILL(20);
213
1.89k
  yych = *YYCURSOR;
214
1.89k
  if (yych <= ',') {
215
418
    if (yych <= '\n') {
216
262
      if (yych <= 0x00) goto yy2;
217
41
      if (yych <= 0x08) goto yy4;
218
22
      if (yych <= '\t') goto yy6;
219
156
    } else {
220
156
      if (yych == ' ') goto yy6;
221
98
      if (yych <= '+') goto yy4;
222
0
      goto yy6;
223
98
    }
224
1.47k
  } else {
225
1.47k
    if (yych <= 'O') {
226
804
      if (yych <= '-') goto yy4;
227
784
      if (yych <= '/') goto yy6;
228
784
      if (yych <= '9') goto yy8;
229
105
      goto yy4;
230
784
    } else {
231
669
      if (yych <= 'P') goto yy9;
232
611
      if (yych == 'R') goto yy11;
233
605
      goto yy4;
234
611
    }
235
1.47k
  }
236
243
yy2:
237
243
  YYDEBUG(2, *YYCURSOR);
238
243
  ++YYCURSOR;
239
243
  YYDEBUG(3, *YYCURSOR);
240
243
#line 301 "ext/date/lib/parse_iso_intervals.re"
241
243
  {
242
243
    s->pos = cursor; s->line++;
243
243
    goto std;
244
1.89k
  }
245
0
#line 246 "ext/date/lib/parse_iso_intervals.c"
246
847
yy4:
247
847
  YYDEBUG(4, *YYCURSOR);
248
847
  ++YYCURSOR;
249
1.53k
yy5:
250
1.53k
  YYDEBUG(5, *YYCURSOR);
251
1.53k
#line 307 "ext/date/lib/parse_iso_intervals.re"
252
1.53k
  {
253
1.53k
    add_error(s, "Unexpected character");
254
1.53k
    goto std;
255
847
  }
256
0
#line 257 "ext/date/lib/parse_iso_intervals.c"
257
58
yy6:
258
58
  YYDEBUG(6, *YYCURSOR);
259
58
  ++YYCURSOR;
260
58
  YYDEBUG(7, *YYCURSOR);
261
58
#line 296 "ext/date/lib/parse_iso_intervals.re"
262
58
  {
263
58
    goto std;
264
847
  }
265
0
#line 266 "ext/date/lib/parse_iso_intervals.c"
266
679
yy8:
267
679
  YYDEBUG(8, *YYCURSOR);
268
679
  yyaccept = 0;
269
679
  yych = *(YYMARKER = ++YYCURSOR);
270
679
  if (yych <= '/') goto yy5;
271
635
  if (yych <= '9') goto yy12;
272
65
  goto yy5;
273
65
yy9:
274
58
  YYDEBUG(9, *YYCURSOR);
275
58
  yyaccept = 1;
276
58
  yych = *(YYMARKER = ++YYCURSOR);
277
58
  if (yych <= '/') goto yy10;
278
58
  if (yych <= '9') goto yy14;
279
46
  if (yych == 'T') goto yy15;
280
58
yy10:
281
58
  YYDEBUG(10, *YYCURSOR);
282
58
#line 234 "ext/date/lib/parse_iso_intervals.re"
283
58
  {
284
58
    timelib_sll nr;
285
58
    int         in_time = 0;
286
58
    DEBUG_OUTPUT("period");
287
58
    TIMELIB_INIT;
288
58
    ptr++;
289
58
    do {
290
58
      if ( *ptr == 'T' ) {
291
46
        in_time = 1;
292
46
        ptr++;
293
46
      }
294
58
      if ( *ptr == '\0' ) {
295
17
        add_error(s, "Missing expected time part");
296
17
        break;
297
17
      }
298
299
41
      nr = timelib_get_unsigned_nr(&ptr, 12);
300
41
      switch (*ptr) {
301
0
        case 'Y': s->period->y = nr; break;
302
0
        case 'W': s->period->d += nr * 7; break;
303
12
        case 'D': s->period->d += nr; break;
304
0
        case 'H': s->period->h = nr; break;
305
29
        case 'S': s->period->s = nr; break;
306
0
        case 'M':
307
0
          if (in_time) {
308
0
            s->period->i = nr;
309
0
          } else {
310
0
            s->period->m = nr;
311
0
          }
312
0
          break;
313
0
        default:
314
0
          add_error(s, "Undefined period specifier");
315
0
          break;
316
41
      }
317
41
      ptr++;
318
41
    } while (!s->errors->error_count && *ptr);
319
58
    s->have_period = 1;
320
58
    TIMELIB_DEINIT;
321
58
    return TIMELIB_PERIOD;
322
58
  }
323
0
#line 324 "ext/date/lib/parse_iso_intervals.c"
324
6
yy11:
325
6
  YYDEBUG(11, *YYCURSOR);
326
6
  yych = *++YYCURSOR;
327
6
  if (yybm[0+yych] & 128) {
328
0
    goto yy16;
329
0
  }
330
6
  goto yy5;
331
570
yy12:
332
570
  YYDEBUG(12, *YYCURSOR);
333
570
  yych = *++YYCURSOR;
334
570
  if (yych <= '/') goto yy13;
335
536
  if (yych <= '9') goto yy19;
336
587
yy13:
337
587
  YYDEBUG(13, *YYCURSOR);
338
587
  YYCURSOR = YYMARKER;
339
587
  if (yyaccept == 0) {
340
570
    goto yy5;
341
570
  } else {
342
17
    goto yy10;
343
17
  }
344
12
yy14:
345
12
  YYDEBUG(14, *YYCURSOR);
346
12
  yych = *++YYCURSOR;
347
12
  if (yych <= 'L') {
348
12
    if (yych <= '9') {
349
0
      if (yych <= '/') goto yy13;
350
0
      goto yy20;
351
12
    } else {
352
12
      if (yych == 'D') goto yy21;
353
0
      goto yy13;
354
12
    }
355
12
  } else {
356
0
    if (yych <= 'W') {
357
0
      if (yych <= 'M') goto yy22;
358
0
      if (yych <= 'V') goto yy13;
359
0
      goto yy23;
360
0
    } else {
361
0
      if (yych == 'Y') goto yy24;
362
0
      goto yy13;
363
0
    }
364
0
  }
365
46
yy15:
366
46
  YYDEBUG(15, *YYCURSOR);
367
46
  yyaccept = 1;
368
46
  yych = *(YYMARKER = ++YYCURSOR);
369
46
  if (yych <= '/') goto yy10;
370
46
  if (yych <= '9') goto yy25;
371
0
  goto yy10;
372
0
yy16:
373
0
  YYDEBUG(16, *YYCURSOR);
374
0
  ++YYCURSOR;
375
0
  if (YYLIMIT <= YYCURSOR) YYFILL(1);
376
0
  yych = *YYCURSOR;
377
0
  YYDEBUG(17, *YYCURSOR);
378
0
  if (yybm[0+yych] & 128) {
379
0
    goto yy16;
380
0
  }
381
0
  YYDEBUG(18, *YYCURSOR);
382
0
#line 199 "ext/date/lib/parse_iso_intervals.re"
383
0
  {
384
0
    DEBUG_OUTPUT("recurrences");
385
0
    TIMELIB_INIT;
386
0
    ptr++;
387
0
    s->recurrences = timelib_get_unsigned_nr(&ptr, 9);
388
0
    TIMELIB_DEINIT;
389
0
    s->have_recurrences = 1;
390
0
    return TIMELIB_PERIOD;
391
0
  }
392
0
#line 393 "ext/date/lib/parse_iso_intervals.c"
393
502
yy19:
394
502
  YYDEBUG(19, *YYCURSOR);
395
502
  yych = *++YYCURSOR;
396
502
  if (yych <= '/') goto yy13;
397
468
  if (yych <= '9') goto yy27;
398
34
  goto yy13;
399
34
yy20:
400
0
  YYDEBUG(20, *YYCURSOR);
401
0
  yych = *++YYCURSOR;
402
0
  if (yych <= 'L') {
403
0
    if (yych <= '9') {
404
0
      if (yych <= '/') goto yy13;
405
0
      goto yy28;
406
0
    } else {
407
0
      if (yych != 'D') goto yy13;
408
0
    }
409
0
  } else {
410
0
    if (yych <= 'W') {
411
0
      if (yych <= 'M') goto yy22;
412
0
      if (yych <= 'V') goto yy13;
413
0
      goto yy23;
414
0
    } else {
415
0
      if (yych == 'Y') goto yy24;
416
0
      goto yy13;
417
0
    }
418
0
  }
419
12
yy21:
420
12
  YYDEBUG(21, *YYCURSOR);
421
12
  yych = *++YYCURSOR;
422
12
  if (yych == 'T') goto yy15;
423
12
  goto yy10;
424
12
yy22:
425
0
  YYDEBUG(22, *YYCURSOR);
426
0
  yyaccept = 1;
427
0
  yych = *(YYMARKER = ++YYCURSOR);
428
0
  if (yych <= '/') goto yy10;
429
0
  if (yych <= '9') goto yy29;
430
0
  if (yych == 'T') goto yy15;
431
0
  goto yy10;
432
0
yy23:
433
0
  YYDEBUG(23, *YYCURSOR);
434
0
  yyaccept = 1;
435
0
  yych = *(YYMARKER = ++YYCURSOR);
436
0
  if (yych <= '/') goto yy10;
437
0
  if (yych <= '9') goto yy31;
438
0
  if (yych == 'T') goto yy15;
439
0
  goto yy10;
440
0
yy24:
441
0
  YYDEBUG(24, *YYCURSOR);
442
0
  yyaccept = 1;
443
0
  yych = *(YYMARKER = ++YYCURSOR);
444
0
  if (yych <= '/') goto yy10;
445
0
  if (yych <= '9') goto yy33;
446
0
  if (yych == 'T') goto yy15;
447
0
  goto yy10;
448
170
yy25:
449
170
  YYDEBUG(25, *YYCURSOR);
450
170
  ++YYCURSOR;
451
170
  if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
452
170
  yych = *YYCURSOR;
453
170
  YYDEBUG(26, *YYCURSOR);
454
170
  if (yych <= 'H') {
455
136
    if (yych <= '/') goto yy13;
456
134
    if (yych <= '9') goto yy25;
457
10
    if (yych <= 'G') goto yy13;
458
0
    goto yy35;
459
34
  } else {
460
34
    if (yych <= 'M') {
461
0
      if (yych <= 'L') goto yy13;
462
0
      goto yy36;
463
34
    } else {
464
34
      if (yych == 'S') goto yy37;
465
5
      goto yy13;
466
34
    }
467
34
  }
468
434
yy27:
469
434
  YYDEBUG(27, *YYCURSOR);
470
434
  yych = *++YYCURSOR;
471
434
  if (yych <= '/') {
472
32
    if (yych == '-') goto yy38;
473
24
    goto yy13;
474
402
  } else {
475
402
    if (yych <= '0') goto yy39;
476
318
    if (yych <= '1') goto yy40;
477
274
    goto yy13;
478
318
  }
479
0
yy28:
480
0
  YYDEBUG(28, *YYCURSOR);
481
0
  yych = *++YYCURSOR;
482
0
  if (yych <= 'L') {
483
0
    if (yych <= '9') {
484
0
      if (yych <= '/') goto yy13;
485
0
      goto yy41;
486
0
    } else {
487
0
      if (yych == 'D') goto yy21;
488
0
      goto yy13;
489
0
    }
490
0
  } else {
491
0
    if (yych <= 'W') {
492
0
      if (yych <= 'M') goto yy22;
493
0
      if (yych <= 'V') goto yy13;
494
0
      goto yy23;
495
0
    } else {
496
0
      if (yych == 'Y') goto yy24;
497
0
      goto yy13;
498
0
    }
499
0
  }
500
0
yy29:
501
0
  YYDEBUG(29, *YYCURSOR);
502
0
  ++YYCURSOR;
503
0
  if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
504
0
  yych = *YYCURSOR;
505
0
  YYDEBUG(30, *YYCURSOR);
506
0
  if (yych <= 'C') {
507
0
    if (yych <= '/') goto yy13;
508
0
    if (yych <= '9') goto yy29;
509
0
    goto yy13;
510
0
  } else {
511
0
    if (yych <= 'D') goto yy21;
512
0
    if (yych == 'W') goto yy23;
513
0
    goto yy13;
514
0
  }
515
0
yy31:
516
0
  YYDEBUG(31, *YYCURSOR);
517
0
  ++YYCURSOR;
518
0
  if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
519
0
  yych = *YYCURSOR;
520
0
  YYDEBUG(32, *YYCURSOR);
521
0
  if (yych <= '/') goto yy13;
522
0
  if (yych <= '9') goto yy31;
523
0
  if (yych == 'D') goto yy21;
524
0
  goto yy13;
525
0
yy33:
526
0
  YYDEBUG(33, *YYCURSOR);
527
0
  ++YYCURSOR;
528
0
  if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
529
0
  yych = *YYCURSOR;
530
0
  YYDEBUG(34, *YYCURSOR);
531
0
  if (yych <= 'D') {
532
0
    if (yych <= '/') goto yy13;
533
0
    if (yych <= '9') goto yy33;
534
0
    if (yych <= 'C') goto yy13;
535
0
    goto yy21;
536
0
  } else {
537
0
    if (yych <= 'M') {
538
0
      if (yych <= 'L') goto yy13;
539
0
      goto yy22;
540
0
    } else {
541
0
      if (yych == 'W') goto yy23;
542
0
      goto yy13;
543
0
    }
544
0
  }
545
0
yy35:
546
0
  YYDEBUG(35, *YYCURSOR);
547
0
  yyaccept = 1;
548
0
  yych = *(YYMARKER = ++YYCURSOR);
549
0
  if (yych <= '/') goto yy10;
550
0
  if (yych <= '9') goto yy42;
551
0
  goto yy10;
552
0
yy36:
553
0
  YYDEBUG(36, *YYCURSOR);
554
0
  yyaccept = 1;
555
0
  yych = *(YYMARKER = ++YYCURSOR);
556
0
  if (yych <= '/') goto yy10;
557
0
  if (yych <= '9') goto yy44;
558
0
  goto yy10;
559
29
yy37:
560
29
  YYDEBUG(37, *YYCURSOR);
561
29
  ++YYCURSOR;
562
29
  goto yy10;
563
8
yy38:
564
8
  YYDEBUG(38, *YYCURSOR);
565
8
  yych = *++YYCURSOR;
566
8
  if (yych <= '/') goto yy13;
567
6
  if (yych <= '0') goto yy46;
568
6
  if (yych <= '1') goto yy47;
569
6
  goto yy13;
570
84
yy39:
571
84
  YYDEBUG(39, *YYCURSOR);
572
84
  yych = *++YYCURSOR;
573
84
  if (yych <= '0') goto yy13;
574
54
  if (yych <= '9') goto yy48;
575
18
  goto yy13;
576
44
yy40:
577
44
  YYDEBUG(40, *YYCURSOR);
578
44
  yych = *++YYCURSOR;
579
44
  if (yych <= '/') goto yy13;
580
44
  if (yych <= '2') goto yy48;
581
12
  goto yy13;
582
12
yy41:
583
0
  YYDEBUG(41, *YYCURSOR);
584
0
  yych = *++YYCURSOR;
585
0
  if (yych == '-') goto yy49;
586
0
  goto yy51;
587
0
yy42:
588
0
  YYDEBUG(42, *YYCURSOR);
589
0
  ++YYCURSOR;
590
0
  if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
591
0
  yych = *YYCURSOR;
592
0
  YYDEBUG(43, *YYCURSOR);
593
0
  if (yych <= 'L') {
594
0
    if (yych <= '/') goto yy13;
595
0
    if (yych <= '9') goto yy42;
596
0
    goto yy13;
597
0
  } else {
598
0
    if (yych <= 'M') goto yy36;
599
0
    if (yych == 'S') goto yy37;
600
0
    goto yy13;
601
0
  }
602
0
yy44:
603
0
  YYDEBUG(44, *YYCURSOR);
604
0
  ++YYCURSOR;
605
0
  if (YYLIMIT <= YYCURSOR) YYFILL(1);
606
0
  yych = *YYCURSOR;
607
0
  YYDEBUG(45, *YYCURSOR);
608
0
  if (yych <= '/') goto yy13;
609
0
  if (yych <= '9') goto yy44;
610
0
  if (yych == 'S') goto yy37;
611
0
  goto yy13;
612
0
yy46:
613
0
  YYDEBUG(46, *YYCURSOR);
614
0
  yych = *++YYCURSOR;
615
0
  if (yych <= '0') goto yy13;
616
0
  if (yych <= '9') goto yy52;
617
0
  goto yy13;
618
0
yy47:
619
0
  YYDEBUG(47, *YYCURSOR);
620
0
  yych = *++YYCURSOR;
621
0
  if (yych <= '/') goto yy13;
622
0
  if (yych <= '2') goto yy52;
623
0
  goto yy13;
624
68
yy48:
625
68
  YYDEBUG(48, *YYCURSOR);
626
68
  yych = *++YYCURSOR;
627
68
  if (yych <= '/') goto yy13;
628
68
  if (yych <= '0') goto yy53;
629
64
  if (yych <= '2') goto yy54;
630
42
  if (yych <= '3') goto yy55;
631
28
  goto yy13;
632
28
yy49:
633
0
  YYDEBUG(49, *YYCURSOR);
634
0
  yych = *++YYCURSOR;
635
0
  if (yych <= '/') goto yy13;
636
0
  if (yych <= '0') goto yy56;
637
0
  if (yych <= '1') goto yy57;
638
0
  goto yy13;
639
0
yy50:
640
0
  YYDEBUG(50, *YYCURSOR);
641
0
  ++YYCURSOR;
642
0
  if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
643
0
  yych = *YYCURSOR;
644
0
yy51:
645
0
  YYDEBUG(51, *YYCURSOR);
646
0
  if (yych <= 'L') {
647
0
    if (yych <= '9') {
648
0
      if (yych <= '/') goto yy13;
649
0
      goto yy50;
650
0
    } else {
651
0
      if (yych == 'D') goto yy21;
652
0
      goto yy13;
653
0
    }
654
0
  } else {
655
0
    if (yych <= 'W') {
656
0
      if (yych <= 'M') goto yy22;
657
0
      if (yych <= 'V') goto yy13;
658
0
      goto yy23;
659
0
    } else {
660
0
      if (yych == 'Y') goto yy24;
661
0
      goto yy13;
662
0
    }
663
0
  }
664
0
yy52:
665
0
  YYDEBUG(52, *YYCURSOR);
666
0
  yych = *++YYCURSOR;
667
0
  if (yych == '-') goto yy58;
668
0
  goto yy13;
669
4
yy53:
670
4
  YYDEBUG(53, *YYCURSOR);
671
4
  yych = *++YYCURSOR;
672
4
  if (yych <= '0') goto yy13;
673
0
  if (yych <= '9') goto yy59;
674
0
  goto yy13;
675
22
yy54:
676
22
  YYDEBUG(54, *YYCURSOR);
677
22
  yych = *++YYCURSOR;
678
22
  if (yych <= '/') goto yy13;
679
22
  if (yych <= '9') goto yy59;
680
0
  goto yy13;
681
14
yy55:
682
14
  YYDEBUG(55, *YYCURSOR);
683
14
  yych = *++YYCURSOR;
684
14
  if (yych <= '/') goto yy13;
685
2
  if (yych <= '1') goto yy59;
686
2
  goto yy13;
687
2
yy56:
688
0
  YYDEBUG(56, *YYCURSOR);
689
0
  yych = *++YYCURSOR;
690
0
  if (yych <= '/') goto yy13;
691
0
  if (yych <= '9') goto yy60;
692
0
  goto yy13;
693
0
yy57:
694
0
  YYDEBUG(57, *YYCURSOR);
695
0
  yych = *++YYCURSOR;
696
0
  if (yych <= '/') goto yy13;
697
0
  if (yych <= '2') goto yy60;
698
0
  goto yy13;
699
0
yy58:
700
0
  YYDEBUG(58, *YYCURSOR);
701
0
  yych = *++YYCURSOR;
702
0
  if (yych <= '/') goto yy13;
703
0
  if (yych <= '0') goto yy61;
704
0
  if (yych <= '2') goto yy62;
705
0
  if (yych <= '3') goto yy63;
706
0
  goto yy13;
707
22
yy59:
708
22
  YYDEBUG(59, *YYCURSOR);
709
22
  yych = *++YYCURSOR;
710
22
  if (yych == 'T') goto yy64;
711
22
  goto yy13;
712
22
yy60:
713
0
  YYDEBUG(60, *YYCURSOR);
714
0
  yych = *++YYCURSOR;
715
0
  if (yych == '-') goto yy65;
716
0
  goto yy13;
717
0
yy61:
718
0
  YYDEBUG(61, *YYCURSOR);
719
0
  yych = *++YYCURSOR;
720
0
  if (yych <= '0') goto yy13;
721
0
  if (yych <= '9') goto yy66;
722
0
  goto yy13;
723
0
yy62:
724
0
  YYDEBUG(62, *YYCURSOR);
725
0
  yych = *++YYCURSOR;
726
0
  if (yych <= '/') goto yy13;
727
0
  if (yych <= '9') goto yy66;
728
0
  goto yy13;
729
0
yy63:
730
0
  YYDEBUG(63, *YYCURSOR);
731
0
  yych = *++YYCURSOR;
732
0
  if (yych <= '/') goto yy13;
733
0
  if (yych <= '1') goto yy66;
734
0
  goto yy13;
735
0
yy64:
736
0
  YYDEBUG(64, *YYCURSOR);
737
0
  yych = *++YYCURSOR;
738
0
  if (yych <= '/') goto yy13;
739
0
  if (yych <= '1') goto yy67;
740
0
  if (yych <= '2') goto yy68;
741
0
  goto yy13;
742
0
yy65:
743
0
  YYDEBUG(65, *YYCURSOR);
744
0
  yych = *++YYCURSOR;
745
0
  if (yych <= '/') goto yy13;
746
0
  if (yych <= '2') goto yy69;
747
0
  if (yych <= '3') goto yy70;
748
0
  goto yy13;
749
0
yy66:
750
0
  YYDEBUG(66, *YYCURSOR);
751
0
  yych = *++YYCURSOR;
752
0
  if (yych == 'T') goto yy71;
753
0
  goto yy13;
754
0
yy67:
755
0
  YYDEBUG(67, *YYCURSOR);
756
0
  yych = *++YYCURSOR;
757
0
  if (yych <= '/') goto yy13;
758
0
  if (yych <= '9') goto yy72;
759
0
  goto yy13;
760
0
yy68:
761
0
  YYDEBUG(68, *YYCURSOR);
762
0
  yych = *++YYCURSOR;
763
0
  if (yych <= '/') goto yy13;
764
0
  if (yych <= '4') goto yy72;
765
0
  goto yy13;
766
0
yy69:
767
0
  YYDEBUG(69, *YYCURSOR);
768
0
  yych = *++YYCURSOR;
769
0
  if (yych <= '/') goto yy13;
770
0
  if (yych <= '9') goto yy73;
771
0
  goto yy13;
772
0
yy70:
773
0
  YYDEBUG(70, *YYCURSOR);
774
0
  yych = *++YYCURSOR;
775
0
  if (yych <= '/') goto yy13;
776
0
  if (yych <= '1') goto yy73;
777
0
  goto yy13;
778
0
yy71:
779
0
  YYDEBUG(71, *YYCURSOR);
780
0
  yych = *++YYCURSOR;
781
0
  if (yych <= '/') goto yy13;
782
0
  if (yych <= '1') goto yy74;
783
0
  if (yych <= '2') goto yy75;
784
0
  goto yy13;
785
0
yy72:
786
0
  YYDEBUG(72, *YYCURSOR);
787
0
  yych = *++YYCURSOR;
788
0
  if (yych <= '/') goto yy13;
789
0
  if (yych <= '5') goto yy76;
790
0
  goto yy13;
791
0
yy73:
792
0
  YYDEBUG(73, *YYCURSOR);
793
0
  yych = *++YYCURSOR;
794
0
  if (yych == 'T') goto yy77;
795
0
  goto yy13;
796
0
yy74:
797
0
  YYDEBUG(74, *YYCURSOR);
798
0
  yych = *++YYCURSOR;
799
0
  if (yych <= '/') goto yy13;
800
0
  if (yych <= '9') goto yy78;
801
0
  goto yy13;
802
0
yy75:
803
0
  YYDEBUG(75, *YYCURSOR);
804
0
  yych = *++YYCURSOR;
805
0
  if (yych <= '/') goto yy13;
806
0
  if (yych <= '4') goto yy78;
807
0
  goto yy13;
808
0
yy76:
809
0
  YYDEBUG(76, *YYCURSOR);
810
0
  yych = *++YYCURSOR;
811
0
  if (yych <= '/') goto yy13;
812
0
  if (yych <= '9') goto yy79;
813
0
  goto yy13;
814
0
yy77:
815
0
  YYDEBUG(77, *YYCURSOR);
816
0
  yych = *++YYCURSOR;
817
0
  if (yych <= '/') goto yy13;
818
0
  if (yych <= '1') goto yy80;
819
0
  if (yych <= '2') goto yy81;
820
0
  goto yy13;
821
0
yy78:
822
0
  YYDEBUG(78, *YYCURSOR);
823
0
  yych = *++YYCURSOR;
824
0
  if (yych == ':') goto yy82;
825
0
  goto yy13;
826
0
yy79:
827
0
  YYDEBUG(79, *YYCURSOR);
828
0
  yych = *++YYCURSOR;
829
0
  if (yych <= '/') goto yy13;
830
0
  if (yych <= '5') goto yy83;
831
0
  goto yy13;
832
0
yy80:
833
0
  YYDEBUG(80, *YYCURSOR);
834
0
  yych = *++YYCURSOR;
835
0
  if (yych <= '/') goto yy13;
836
0
  if (yych <= '9') goto yy84;
837
0
  goto yy13;
838
0
yy81:
839
0
  YYDEBUG(81, *YYCURSOR);
840
0
  yych = *++YYCURSOR;
841
0
  if (yych <= '/') goto yy13;
842
0
  if (yych <= '4') goto yy84;
843
0
  goto yy13;
844
0
yy82:
845
0
  YYDEBUG(82, *YYCURSOR);
846
0
  yych = *++YYCURSOR;
847
0
  if (yych <= '/') goto yy13;
848
0
  if (yych <= '5') goto yy85;
849
0
  goto yy13;
850
0
yy83:
851
0
  YYDEBUG(83, *YYCURSOR);
852
0
  yych = *++YYCURSOR;
853
0
  if (yych <= '/') goto yy13;
854
0
  if (yych <= '9') goto yy86;
855
0
  goto yy13;
856
0
yy84:
857
0
  YYDEBUG(84, *YYCURSOR);
858
0
  yych = *++YYCURSOR;
859
0
  if (yych == ':') goto yy87;
860
0
  goto yy13;
861
0
yy85:
862
0
  YYDEBUG(85, *YYCURSOR);
863
0
  yych = *++YYCURSOR;
864
0
  if (yych <= '/') goto yy13;
865
0
  if (yych <= '9') goto yy88;
866
0
  goto yy13;
867
0
yy86:
868
0
  YYDEBUG(86, *YYCURSOR);
869
0
  yych = *++YYCURSOR;
870
0
  if (yych == 'Z') goto yy89;
871
0
  goto yy13;
872
0
yy87:
873
0
  YYDEBUG(87, *YYCURSOR);
874
0
  yych = *++YYCURSOR;
875
0
  if (yych <= '/') goto yy13;
876
0
  if (yych <= '5') goto yy91;
877
0
  goto yy13;
878
0
yy88:
879
0
  YYDEBUG(88, *YYCURSOR);
880
0
  yych = *++YYCURSOR;
881
0
  if (yych == ':') goto yy79;
882
0
  goto yy13;
883
0
yy89:
884
0
  YYDEBUG(89, *YYCURSOR);
885
0
  ++YYCURSOR;
886
0
  YYDEBUG(90, *YYCURSOR);
887
0
#line 210 "ext/date/lib/parse_iso_intervals.re"
888
0
  {
889
0
    timelib_time *current;
890
891
0
    if (s->have_date || s->have_period) {
892
0
      current = s->end;
893
0
      s->have_end_date = 1;
894
0
    } else {
895
0
      current = s->begin;
896
0
      s->have_begin_date = 1;
897
0
    }
898
0
    DEBUG_OUTPUT("datetimebasic | datetimeextended");
899
0
    TIMELIB_INIT;
900
0
    current->y = timelib_get_nr(&ptr, 4);
901
0
    current->m = timelib_get_nr(&ptr, 2);
902
0
    current->d = timelib_get_nr(&ptr, 2);
903
0
    current->h = timelib_get_nr(&ptr, 2);
904
0
    current->i = timelib_get_nr(&ptr, 2);
905
0
    current->s = timelib_get_nr(&ptr, 2);
906
0
    s->have_date = 1;
907
0
    TIMELIB_DEINIT;
908
0
    return TIMELIB_ISO_DATE;
909
0
  }
910
0
#line 911 "ext/date/lib/parse_iso_intervals.c"
911
0
yy91:
912
0
  YYDEBUG(91, *YYCURSOR);
913
0
  yych = *++YYCURSOR;
914
0
  if (yych <= '/') goto yy13;
915
0
  if (yych >= ':') goto yy13;
916
0
  YYDEBUG(92, *YYCURSOR);
917
0
  yych = *++YYCURSOR;
918
0
  if (yych != ':') goto yy13;
919
0
  YYDEBUG(93, *YYCURSOR);
920
0
  yych = *++YYCURSOR;
921
0
  if (yych <= '/') goto yy13;
922
0
  if (yych >= '6') goto yy13;
923
0
  YYDEBUG(94, *YYCURSOR);
924
0
  yych = *++YYCURSOR;
925
0
  if (yych <= '/') goto yy13;
926
0
  if (yych >= ':') goto yy13;
927
0
  YYDEBUG(95, *YYCURSOR);
928
0
  ++YYCURSOR;
929
0
  YYDEBUG(96, *YYCURSOR);
930
0
#line 276 "ext/date/lib/parse_iso_intervals.re"
931
0
  {
932
0
    DEBUG_OUTPUT("combinedrep");
933
0
    TIMELIB_INIT;
934
0
    s->period->y = timelib_get_unsigned_nr(&ptr, 4);
935
0
    ptr++;
936
0
    s->period->m = timelib_get_unsigned_nr(&ptr, 2);
937
0
    ptr++;
938
0
    s->period->d = timelib_get_unsigned_nr(&ptr, 2);
939
0
    ptr++;
940
0
    s->period->h = timelib_get_unsigned_nr(&ptr, 2);
941
0
    ptr++;
942
0
    s->period->i = timelib_get_unsigned_nr(&ptr, 2);
943
0
    ptr++;
944
0
    s->period->s = timelib_get_unsigned_nr(&ptr, 2);
945
0
    s->have_period = 1;
946
0
    TIMELIB_DEINIT;
947
0
    return TIMELIB_PERIOD;
948
0
  }
949
0
#line 950 "ext/date/lib/parse_iso_intervals.c"
950
0
}
951
0
#line 311 "ext/date/lib/parse_iso_intervals.re"
952
953
0
}
954
#ifdef PHP_WIN32
955
#pragma optimize( "", on )
956
#endif
957
958
146
#define YYMAXFILL 20
959
960
961
void timelib_strtointerval(const char *s, size_t len,
962
                           timelib_time **begin, timelib_time **end,
963
               timelib_rel_time **period, int *recurrences,
964
               timelib_error_container **errors)
965
73
{
966
73
  Scanner in;
967
73
  int t;
968
73
  const char *e = s + len - 1;
969
970
73
  memset(&in, 0, sizeof(in));
971
73
  in.errors = timelib_malloc(sizeof(timelib_error_container));
972
73
  in.errors->warning_count = 0;
973
73
  in.errors->warning_messages = NULL;
974
73
  in.errors->error_count = 0;
975
73
  in.errors->error_messages = NULL;
976
977
73
  if (len > 0) {
978
77
    while (isspace((unsigned char)*s) && s < e) {
979
4
      s++;
980
4
    }
981
73
    while (isspace((unsigned char)*e) && e > s) {
982
0
      e--;
983
0
    }
984
73
  }
985
73
  if (e - s < 0) {
986
0
    add_error(&in, "Empty string");
987
0
    if (errors) {
988
0
      *errors = in.errors;
989
0
    } else {
990
0
      timelib_error_container_dtor(in.errors);
991
0
    }
992
0
    return;
993
0
  }
994
73
  e++;
995
996
  /* init cursor */
997
73
  in.str = timelib_malloc((e - s) + YYMAXFILL);
998
73
  memset(in.str, 0, (e - s) + YYMAXFILL);
999
73
  memcpy(in.str, s, (e - s));
1000
73
  in.lim = in.str + (e - s) + YYMAXFILL;
1001
73
  in.cur = in.str;
1002
1003
  /* init value containers */
1004
73
  in.begin = timelib_time_ctor();
1005
73
  in.begin->y = TIMELIB_UNSET;
1006
73
  in.begin->d = TIMELIB_UNSET;
1007
73
  in.begin->m = TIMELIB_UNSET;
1008
73
  in.begin->h = TIMELIB_UNSET;
1009
73
  in.begin->i = TIMELIB_UNSET;
1010
73
  in.begin->s = TIMELIB_UNSET;
1011
73
  in.begin->us = 0;
1012
73
  in.begin->z = 0;
1013
73
  in.begin->dst = 0;
1014
73
  in.begin->is_localtime = 0;
1015
73
  in.begin->zone_type = TIMELIB_ZONETYPE_OFFSET;
1016
1017
73
  in.end = timelib_time_ctor();
1018
73
  in.end->y = TIMELIB_UNSET;
1019
73
  in.end->d = TIMELIB_UNSET;
1020
73
  in.end->m = TIMELIB_UNSET;
1021
73
  in.end->h = TIMELIB_UNSET;
1022
73
  in.end->i = TIMELIB_UNSET;
1023
73
  in.end->s = TIMELIB_UNSET;
1024
73
  in.end->us = 0;
1025
73
  in.end->z = 0;
1026
73
  in.end->dst = 0;
1027
73
  in.end->is_localtime = 0;
1028
73
  in.end->zone_type = TIMELIB_ZONETYPE_OFFSET;
1029
1030
73
  in.period = timelib_rel_time_ctor();
1031
73
  in.period->y = 0;
1032
73
  in.period->d = 0;
1033
73
  in.period->m = 0;
1034
73
  in.period->h = 0;
1035
73
  in.period->i = 0;
1036
73
  in.period->s = 0;
1037
73
  in.period->weekday = 0;
1038
73
  in.period->weekday_behavior = 0;
1039
73
  in.period->first_last_day_of = 0;
1040
73
  in.period->days = TIMELIB_UNSET;
1041
1042
73
  in.recurrences = 1;
1043
1044
131
  do {
1045
131
    t = scan(&in);
1046
#ifdef DEBUG_PARSER
1047
    printf("%d\n", t);
1048
#endif
1049
131
  } while(t != EOI);
1050
1051
73
  timelib_free(in.str);
1052
73
  if (errors) {
1053
73
    *errors = in.errors;
1054
73
  } else {
1055
0
    timelib_error_container_dtor(in.errors);
1056
0
  }
1057
73
  if (in.have_begin_date) {
1058
0
    *begin = in.begin;
1059
73
  } else {
1060
73
    timelib_time_dtor(in.begin);
1061
73
  }
1062
73
  if (in.have_end_date) {
1063
0
    *end   = in.end;
1064
73
  } else {
1065
73
    timelib_time_dtor(in.end);
1066
73
  }
1067
73
  if (in.have_period) {
1068
58
    *period = in.period;
1069
58
  } else {
1070
15
    timelib_rel_time_dtor(in.period);
1071
15
  }
1072
73
  if (in.have_recurrences) {
1073
0
    *recurrences = in.recurrences;
1074
0
  }
1075
73
}
1076
1077
1078
/*
1079
 * vim: syntax=c
1080
 */