Coverage Report

Created: 2025-06-13 06:43

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