Coverage Report

Created: 2026-07-25 06:39

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
253
#define EOI      257
43
44
75
#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
2.12k
#define   YYCTYPE      uchar
53
9.48k
#define   YYCURSOR     cursor
54
2.30k
#define   YYLIMIT      s->lim
55
1.57k
#define   YYMARKER     s->ptr
56
89
#define   YYFILL(n)    return EOI;
57
58
#define   RET(i)       {s->cur = cursor; return i;}
59
60
75
#define timelib_string_free timelib_free
61
62
75
#define TIMELIB_INIT  s->cur = cursor; str = timelib_string(s); ptr = str
63
75
#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
1.70k
{
93
1.70k
  s->errors->error_count++;
94
1.70k
  s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
95
1.70k
  s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0;
96
1.70k
  s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0;
97
1.70k
  s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error);
98
1.70k
}
99
100
static char *timelib_string(Scanner *s)
101
75
{
102
75
  char *tmp = timelib_calloc(1, s->cur - s->tok + 1);
103
75
  memcpy(tmp, s->tok, s->cur - s->tok);
104
105
75
  return tmp;
106
75
}
107
108
static timelib_sll timelib_get_nr(const char **ptr, int max_length)
109
50
{
110
50
  const char *begin, *end;
111
50
  char *str;
112
50
  timelib_sll tmp_nr = TIMELIB_UNSET;
113
50
  int len = 0;
114
115
50
  while ((**ptr < '0') || (**ptr > '9')) {
116
0
    if (**ptr == '\0') {
117
0
      return TIMELIB_UNSET;
118
0
    }
119
0
    ++*ptr;
120
0
  }
121
50
  begin = *ptr;
122
100
  while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) {
123
50
    ++*ptr;
124
50
    ++len;
125
50
  }
126
50
  end = *ptr;
127
50
  str = timelib_calloc(1, end - begin + 1);
128
50
  memcpy(str, begin, end - begin);
129
50
  tmp_nr = strtoll(str, NULL, 10);
130
50
  timelib_free(str);
131
50
  return tmp_nr;
132
50
}
133
134
static timelib_ull timelib_get_unsigned_nr(const char **ptr, int max_length)
135
50
{
136
50
  timelib_ull dir = 1;
137
138
50
  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
50
  while (**ptr == '+' || **ptr == '-')
146
0
  {
147
0
    if (**ptr == '-') {
148
0
      dir *= -1;
149
0
    }
150
0
    ++*ptr;
151
0
  }
152
50
  return dir * timelib_get_nr(ptr, max_length);
153
50
}
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
164
{
172
164
  uchar *cursor = s->cur;
173
164
  char *str;
174
164
  const char *ptr = NULL;
175
176
2.12k
std:
177
2.12k
  s->tok = cursor;
178
2.12k
  s->len = 0;
179
2.12k
#line 204 "ext/date/lib/parse_iso_intervals.re"
180
181
182
183
2.12k
#line 184 "ext/date/lib/parse_iso_intervals.c"
184
2.12k
{
185
2.12k
  YYCTYPE yych;
186
2.12k
  unsigned int yyaccept = 0;
187
2.12k
  static const unsigned char yybm[] = {
188
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
189
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
190
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
191
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
192
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
193
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
194
2.12k
    128, 128, 128, 128, 128, 128, 128, 128, 
195
2.12k
    128, 128,   0,   0,   0,   0,   0,   0, 
196
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
197
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
198
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
199
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
200
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
201
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
202
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
203
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
204
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
205
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
206
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
207
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
208
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
209
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
210
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
211
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
212
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
213
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
214
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
215
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
216
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
217
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
218
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
219
2.12k
      0,   0,   0,   0,   0,   0,   0,   0, 
220
2.12k
  };
221
2.12k
  YYDEBUG(0, *YYCURSOR);
222
2.12k
  if ((YYLIMIT - YYCURSOR) < 20) YYFILL(20);
223
2.04k
  yych = *YYCURSOR;
224
2.04k
  if (yych <= ',') {
225
317
    if (yych <= '\n') {
226
228
      if (yych <= 0x00) goto yy2;
227
46
      if (yych <= 0x08) goto yy4;
228
24
      if (yych <= '\t') goto yy6;
229
89
    } else {
230
89
      if (yych == ' ') goto yy6;
231
15
      if (yych <= '+') goto yy4;
232
2
      goto yy6;
233
15
    }
234
1.72k
  } else {
235
1.72k
    if (yych <= 'O') {
236
936
      if (yych <= '-') goto yy4;
237
908
      if (yych <= '/') goto yy6;
238
908
      if (yych <= '9') goto yy8;
239
130
      goto yy4;
240
908
    } else {
241
787
      if (yych <= 'P') goto yy9;
242
712
      if (yych == 'R') goto yy11;
243
706
      goto yy4;
244
712
    }
245
1.72k
  }
246
206
yy2:
247
206
  YYDEBUG(2, *YYCURSOR);
248
206
  ++YYCURSOR;
249
206
  YYDEBUG(3, *YYCURSOR);
250
206
#line 311 "ext/date/lib/parse_iso_intervals.re"
251
206
  {
252
206
    s->pos = cursor; s->line++;
253
206
    goto std;
254
2.04k
  }
255
0
#line 256 "ext/date/lib/parse_iso_intervals.c"
256
899
yy4:
257
899
  YYDEBUG(4, *YYCURSOR);
258
899
  ++YYCURSOR;
259
1.68k
yy5:
260
1.68k
  YYDEBUG(5, *YYCURSOR);
261
1.68k
#line 317 "ext/date/lib/parse_iso_intervals.re"
262
1.68k
  {
263
1.68k
    add_error(s, "Unexpected character");
264
1.68k
    goto std;
265
899
  }
266
0
#line 267 "ext/date/lib/parse_iso_intervals.c"
267
76
yy6:
268
76
  YYDEBUG(6, *YYCURSOR);
269
76
  ++YYCURSOR;
270
76
  YYDEBUG(7, *YYCURSOR);
271
76
#line 306 "ext/date/lib/parse_iso_intervals.re"
272
76
  {
273
76
    goto std;
274
899
  }
275
0
#line 276 "ext/date/lib/parse_iso_intervals.c"
276
778
yy8:
277
778
  YYDEBUG(8, *YYCURSOR);
278
778
  yyaccept = 0;
279
778
  yych = *(YYMARKER = ++YYCURSOR);
280
778
  if (yych <= '/') goto yy5;
281
720
  if (yych <= '9') goto yy12;
282
84
  goto yy5;
283
84
yy9:
284
75
  YYDEBUG(9, *YYCURSOR);
285
75
  yyaccept = 1;
286
75
  yych = *(YYMARKER = ++YYCURSOR);
287
75
  if (yych <= '/') goto yy10;
288
73
  if (yych <= '9') goto yy14;
289
60
  if (yych == 'T') goto yy15;
290
75
yy10:
291
75
  YYDEBUG(10, *YYCURSOR);
292
75
#line 244 "ext/date/lib/parse_iso_intervals.re"
293
75
  {
294
75
    timelib_sll nr;
295
75
    int         in_time = 0;
296
75
    DEBUG_OUTPUT("period");
297
75
    TIMELIB_INIT;
298
75
    ptr++;
299
75
    do {
300
75
      if ( *ptr == 'T' ) {
301
60
        in_time = 1;
302
60
        ptr++;
303
60
      }
304
75
      if ( *ptr == '\0' ) {
305
25
        add_error(s, "Missing expected time part");
306
25
        break;
307
25
      }
308
309
50
      nr = timelib_get_unsigned_nr(&ptr, 12);
310
50
      switch (*ptr) {
311
0
        case 'Y': s->period->y = nr; break;
312
0
        case 'W': s->period->d += nr * 7; break;
313
13
        case 'D': s->period->d += nr; break;
314
0
        case 'H': s->period->h = nr; break;
315
37
        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
50
      }
327
50
      ptr++;
328
50
    } while (!s->errors->error_count && *ptr);
329
75
    s->have_period = 1;
330
75
    TIMELIB_DEINIT;
331
75
    return TIMELIB_PERIOD;
332
75
  }
333
0
#line 334 "ext/date/lib/parse_iso_intervals.c"
334
6
yy11:
335
6
  YYDEBUG(11, *YYCURSOR);
336
6
  yych = *++YYCURSOR;
337
6
  if (yybm[0+yych] & 128) {
338
0
    goto yy16;
339
0
  }
340
6
  goto yy5;
341
636
yy12:
342
636
  YYDEBUG(12, *YYCURSOR);
343
636
  yych = *++YYCURSOR;
344
636
  if (yych <= '/') goto yy13;
345
590
  if (yych <= '9') goto yy19;
346
659
yy13:
347
659
  YYDEBUG(13, *YYCURSOR);
348
659
  YYCURSOR = YYMARKER;
349
659
  if (yyaccept == 0) {
350
636
    goto yy5;
351
636
  } else {
352
23
    goto yy10;
353
23
  }
354
13
yy14:
355
13
  YYDEBUG(14, *YYCURSOR);
356
13
  yych = *++YYCURSOR;
357
13
  if (yych <= 'L') {
358
13
    if (yych <= '9') {
359
0
      if (yych <= '/') goto yy13;
360
0
      goto yy20;
361
13
    } else {
362
13
      if (yych == 'D') goto yy21;
363
0
      goto yy13;
364
13
    }
365
13
  } 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
60
yy15:
376
60
  YYDEBUG(15, *YYCURSOR);
377
60
  yyaccept = 1;
378
60
  yych = *(YYMARKER = ++YYCURSOR);
379
60
  if (yych <= '/') goto yy10;
380
60
  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
549
yy19:
404
549
  YYDEBUG(19, *YYCURSOR);
405
549
  yych = *++YYCURSOR;
406
549
  if (yych <= '/') goto yy13;
407
503
  if (yych <= '9') goto yy27;
408
41
  goto yy13;
409
41
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
13
yy21:
430
13
  YYDEBUG(21, *YYCURSOR);
431
13
  yych = *++YYCURSOR;
432
13
  if (yych == 'T') goto yy15;
433
13
  goto yy10;
434
13
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
180
yy25:
459
180
  YYDEBUG(25, *YYCURSOR);
460
180
  ++YYCURSOR;
461
180
  if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
462
180
  yych = *YYCURSOR;
463
180
  YYDEBUG(26, *YYCURSOR);
464
180
  if (yych <= 'H') {
465
138
    if (yych <= '/') goto yy13;
466
136
    if (yych <= '9') goto yy25;
467
16
    if (yych <= 'G') goto yy13;
468
0
    goto yy35;
469
42
  } else {
470
42
    if (yych <= 'M') {
471
0
      if (yych <= 'L') goto yy13;
472
0
      goto yy36;
473
42
    } else {
474
42
      if (yych == 'S') goto yy37;
475
5
      goto yy13;
476
42
    }
477
42
  }
478
462
yy27:
479
462
  YYDEBUG(27, *YYCURSOR);
480
462
  yych = *++YYCURSOR;
481
462
  if (yych <= '/') {
482
44
    if (yych == '-') goto yy38;
483
32
    goto yy13;
484
418
  } else {
485
418
    if (yych <= '0') goto yy39;
486
302
    if (yych <= '1') goto yy40;
487
261
    goto yy13;
488
302
  }
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
37
yy37:
570
37
  YYDEBUG(37, *YYCURSOR);
571
37
  ++YYCURSOR;
572
37
  goto yy10;
573
12
yy38:
574
12
  YYDEBUG(38, *YYCURSOR);
575
12
  yych = *++YYCURSOR;
576
12
  if (yych <= '/') goto yy13;
577
10
  if (yych <= '0') goto yy46;
578
10
  if (yych <= '1') goto yy47;
579
10
  goto yy13;
580
116
yy39:
581
116
  YYDEBUG(39, *YYCURSOR);
582
116
  yych = *++YYCURSOR;
583
116
  if (yych <= '0') goto yy13;
584
66
  if (yych <= '9') goto yy48;
585
22
  goto yy13;
586
41
yy40:
587
41
  YYDEBUG(40, *YYCURSOR);
588
41
  yych = *++YYCURSOR;
589
41
  if (yych <= '/') goto yy13;
590
41
  if (yych <= '2') goto yy48;
591
11
  goto yy13;
592
11
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
74
yy48:
635
74
  YYDEBUG(48, *YYCURSOR);
636
74
  yych = *++YYCURSOR;
637
74
  if (yych <= '/') goto yy13;
638
74
  if (yych <= '0') goto yy53;
639
70
  if (yych <= '2') goto yy54;
640
49
  if (yych <= '3') goto yy55;
641
31
  goto yy13;
642
31
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
4
yy53:
680
4
  YYDEBUG(53, *YYCURSOR);
681
4
  yych = *++YYCURSOR;
682
4
  if (yych <= '0') goto yy13;
683
0
  if (yych <= '9') goto yy59;
684
0
  goto yy13;
685
21
yy54:
686
21
  YYDEBUG(54, *YYCURSOR);
687
21
  yych = *++YYCURSOR;
688
21
  if (yych <= '/') goto yy13;
689
21
  if (yych <= '9') goto yy59;
690
0
  goto yy13;
691
18
yy55:
692
18
  YYDEBUG(55, *YYCURSOR);
693
18
  yych = *++YYCURSOR;
694
18
  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
21
yy59:
718
21
  YYDEBUG(59, *YYCURSOR);
719
21
  yych = *++YYCURSOR;
720
21
  if (yych == 'T') goto yy64;
721
21
  goto yy13;
722
21
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
178
#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
89
{
976
89
  Scanner in;
977
89
  int t;
978
89
  const char *e = s + len - 1;
979
980
89
  memset(&in, 0, sizeof(in));
981
89
  in.errors = timelib_malloc(sizeof(timelib_error_container));
982
89
  in.errors->warning_count = 0;
983
89
  in.errors->warning_messages = NULL;
984
89
  in.errors->error_count = 0;
985
89
  in.errors->error_messages = NULL;
986
987
89
  if (len > 0) {
988
97
    while (isspace((unsigned char)*s) && s < e) {
989
8
      s++;
990
8
    }
991
89
    while (isspace((unsigned char)*e) && e > s) {
992
0
      e--;
993
0
    }
994
89
  }
995
89
  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
89
  e++;
1005
1006
  /* init cursor */
1007
89
  in.str = timelib_malloc((e - s) + YYMAXFILL);
1008
89
  memset(in.str, 0, (e - s) + YYMAXFILL);
1009
89
  memcpy(in.str, s, (e - s));
1010
89
  in.lim = in.str + (e - s) + YYMAXFILL;
1011
89
  in.cur = in.str;
1012
1013
  /* init value containers */
1014
89
  in.begin = timelib_time_ctor();
1015
89
  in.begin->y = TIMELIB_UNSET;
1016
89
  in.begin->d = TIMELIB_UNSET;
1017
89
  in.begin->m = TIMELIB_UNSET;
1018
89
  in.begin->h = TIMELIB_UNSET;
1019
89
  in.begin->i = TIMELIB_UNSET;
1020
89
  in.begin->s = TIMELIB_UNSET;
1021
89
  in.begin->us = 0;
1022
89
  in.begin->z = 0;
1023
89
  in.begin->dst = 0;
1024
89
  in.begin->is_localtime = 0;
1025
89
  in.begin->zone_type = TIMELIB_ZONETYPE_OFFSET;
1026
1027
89
  in.end = timelib_time_ctor();
1028
89
  in.end->y = TIMELIB_UNSET;
1029
89
  in.end->d = TIMELIB_UNSET;
1030
89
  in.end->m = TIMELIB_UNSET;
1031
89
  in.end->h = TIMELIB_UNSET;
1032
89
  in.end->i = TIMELIB_UNSET;
1033
89
  in.end->s = TIMELIB_UNSET;
1034
89
  in.end->us = 0;
1035
89
  in.end->z = 0;
1036
89
  in.end->dst = 0;
1037
89
  in.end->is_localtime = 0;
1038
89
  in.end->zone_type = TIMELIB_ZONETYPE_OFFSET;
1039
1040
89
  in.period = timelib_rel_time_ctor();
1041
89
  in.period->y = 0;
1042
89
  in.period->d = 0;
1043
89
  in.period->m = 0;
1044
89
  in.period->h = 0;
1045
89
  in.period->i = 0;
1046
89
  in.period->s = 0;
1047
89
  in.period->weekday = 0;
1048
89
  in.period->weekday_behavior = 0;
1049
89
  in.period->first_last_day_of = 0;
1050
89
  in.period->days = TIMELIB_UNSET;
1051
1052
89
  in.recurrences = 1;
1053
1054
164
  do {
1055
164
    t = scan(&in);
1056
#ifdef DEBUG_PARSER
1057
    printf("%d\n", t);
1058
#endif
1059
164
  } while(t != EOI);
1060
1061
89
  timelib_free(in.str);
1062
89
  if (errors) {
1063
89
    *errors = in.errors;
1064
89
  } else {
1065
0
    timelib_error_container_dtor(in.errors);
1066
0
  }
1067
89
  if (in.have_begin_date) {
1068
0
    *begin = in.begin;
1069
89
  } else {
1070
89
    timelib_time_dtor(in.begin);
1071
89
  }
1072
89
  if (in.have_end_date) {
1073
0
    *end   = in.end;
1074
89
  } else {
1075
89
    timelib_time_dtor(in.end);
1076
89
  }
1077
89
  if (in.have_period) {
1078
75
    *period = in.period;
1079
75
  } else {
1080
14
    timelib_rel_time_dtor(in.period);
1081
14
  }
1082
89
  if (in.have_recurrences) {
1083
0
    *recurrences = in.recurrences;
1084
0
  }
1085
89
}
1086
1087
1088
/*
1089
 * vim: syntax=c
1090
 */