Coverage Report

Created: 2026-06-13 07:01

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