Coverage Report

Created: 2026-02-09 07:07

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