Coverage Report

Created: 2025-09-27 06:26

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