Coverage Report

Created: 2025-12-31 07:28

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