Coverage Report

Created: 2026-04-01 06:49

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