xref: /php-src/ext/date/lib/parse_iso_intervals.c (revision 06d4c70e)
1 /* Generated by re2c 0.15.3 on Wed Sep 14 16:32:05 2022 */
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 #define EOI      257
43 
44 #define TIMELIB_PERIOD  260
45 #define TIMELIB_ISO_DATE 261
46 #define TIMELIB_ERROR   999
47 
48 typedef unsigned char uchar;
49 
50 #define   BSIZE	   8192
51 
52 #define   YYCTYPE      uchar
53 #define   YYCURSOR     cursor
54 #define   YYLIMIT      s->lim
55 #define   YYMARKER     s->ptr
56 #define   YYFILL(n)    return EOI;
57 
58 #define   RET(i)       {s->cur = cursor; return i;}
59 
60 #define timelib_string_free timelib_free
61 
62 #define TIMELIB_INIT  s->cur = cursor; str = timelib_string(s); ptr = str
63 #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 
add_error(Scanner * s,const char * error)91 static void add_error(Scanner *s, const char *error)
92 {
93 	s->errors->error_count++;
94 	s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
95 	s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0;
96 	s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0;
97 	s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error);
98 }
99 
timelib_string(Scanner * s)100 static char *timelib_string(Scanner *s)
101 {
102 	char *tmp = timelib_calloc(1, s->cur - s->tok + 1);
103 	memcpy(tmp, s->tok, s->cur - s->tok);
104 
105 	return tmp;
106 }
107 
timelib_get_nr(const char ** ptr,int max_length)108 static timelib_sll timelib_get_nr(const char **ptr, int max_length)
109 {
110 	const char *begin, *end;
111 	char *str;
112 	timelib_sll tmp_nr = TIMELIB_UNSET;
113 	int len = 0;
114 
115 	while ((**ptr < '0') || (**ptr > '9')) {
116 		if (**ptr == '\0') {
117 			return TIMELIB_UNSET;
118 		}
119 		++*ptr;
120 	}
121 	begin = *ptr;
122 	while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) {
123 		++*ptr;
124 		++len;
125 	}
126 	end = *ptr;
127 	str = timelib_calloc(1, end - begin + 1);
128 	memcpy(str, begin, end - begin);
129 	tmp_nr = strtoll(str, NULL, 10);
130 	timelib_free(str);
131 	return tmp_nr;
132 }
133 
timelib_get_unsigned_nr(const char ** ptr,int max_length)134 static timelib_ull timelib_get_unsigned_nr(const char **ptr, int max_length)
135 {
136 	timelib_ull dir = 1;
137 
138 	while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) {
139 		if (**ptr == '\0') {
140 			return TIMELIB_UNSET;
141 		}
142 		++*ptr;
143 	}
144 
145 	while (**ptr == '+' || **ptr == '-')
146 	{
147 		if (**ptr == '-') {
148 			dir *= -1;
149 		}
150 		++*ptr;
151 	}
152 	return dir * timelib_get_nr(ptr, max_length);
153 }
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
scan(Scanner * s)170 static int scan(Scanner *s)
171 {
172 	uchar *cursor = s->cur;
173 	char *str;
174 	const char *ptr = NULL;
175 
176 std:
177 	s->tok = cursor;
178 	s->len = 0;
179 #line 204 "ext/date/lib/parse_iso_intervals.re"
180 
181 
182 
183 #line 184 "<stdout>"
184 {
185 	YYCTYPE yych;
186 	unsigned int yyaccept = 0;
187 	static const unsigned char yybm[] = {
188 		  0,   0,   0,   0,   0,   0,   0,   0,
189 		  0,   0,   0,   0,   0,   0,   0,   0,
190 		  0,   0,   0,   0,   0,   0,   0,   0,
191 		  0,   0,   0,   0,   0,   0,   0,   0,
192 		  0,   0,   0,   0,   0,   0,   0,   0,
193 		  0,   0,   0,   0,   0,   0,   0,   0,
194 		128, 128, 128, 128, 128, 128, 128, 128,
195 		128, 128,   0,   0,   0,   0,   0,   0,
196 		  0,   0,   0,   0,   0,   0,   0,   0,
197 		  0,   0,   0,   0,   0,   0,   0,   0,
198 		  0,   0,   0,   0,   0,   0,   0,   0,
199 		  0,   0,   0,   0,   0,   0,   0,   0,
200 		  0,   0,   0,   0,   0,   0,   0,   0,
201 		  0,   0,   0,   0,   0,   0,   0,   0,
202 		  0,   0,   0,   0,   0,   0,   0,   0,
203 		  0,   0,   0,   0,   0,   0,   0,   0,
204 		  0,   0,   0,   0,   0,   0,   0,   0,
205 		  0,   0,   0,   0,   0,   0,   0,   0,
206 		  0,   0,   0,   0,   0,   0,   0,   0,
207 		  0,   0,   0,   0,   0,   0,   0,   0,
208 		  0,   0,   0,   0,   0,   0,   0,   0,
209 		  0,   0,   0,   0,   0,   0,   0,   0,
210 		  0,   0,   0,   0,   0,   0,   0,   0,
211 		  0,   0,   0,   0,   0,   0,   0,   0,
212 		  0,   0,   0,   0,   0,   0,   0,   0,
213 		  0,   0,   0,   0,   0,   0,   0,   0,
214 		  0,   0,   0,   0,   0,   0,   0,   0,
215 		  0,   0,   0,   0,   0,   0,   0,   0,
216 		  0,   0,   0,   0,   0,   0,   0,   0,
217 		  0,   0,   0,   0,   0,   0,   0,   0,
218 		  0,   0,   0,   0,   0,   0,   0,   0,
219 		  0,   0,   0,   0,   0,   0,   0,   0,
220 	};
221 	YYDEBUG(0, *YYCURSOR);
222 	if ((YYLIMIT - YYCURSOR) < 20) YYFILL(20);
223 	yych = *YYCURSOR;
224 	if (yych <= ',') {
225 		if (yych <= '\n') {
226 			if (yych <= 0x00) goto yy9;
227 			if (yych <= 0x08) goto yy11;
228 			if (yych <= '\t') goto yy7;
229 			goto yy9;
230 		} else {
231 			if (yych == ' ') goto yy7;
232 			if (yych <= '+') goto yy11;
233 			goto yy7;
234 		}
235 	} else {
236 		if (yych <= 'O') {
237 			if (yych <= '-') goto yy11;
238 			if (yych <= '/') goto yy7;
239 			if (yych <= '9') goto yy4;
240 			goto yy11;
241 		} else {
242 			if (yych <= 'P') goto yy5;
243 			if (yych != 'R') goto yy11;
244 		}
245 	}
246 	YYDEBUG(2, *YYCURSOR);
247 	++YYCURSOR;
248 	if ((yych = *YYCURSOR) <= '/') goto yy3;
249 	if (yych <= '9') goto yy98;
250 yy3:
251 	YYDEBUG(3, *YYCURSOR);
252 #line 317 "ext/date/lib/parse_iso_intervals.re"
253 	{
254 		add_error(s, "Unexpected character");
255 		goto std;
256 	}
257 #line 258 "<stdout>"
258 yy4:
259 	YYDEBUG(4, *YYCURSOR);
260 	yyaccept = 0;
261 	yych = *(YYMARKER = ++YYCURSOR);
262 	if (yych <= '/') goto yy3;
263 	if (yych <= '9') goto yy59;
264 	goto yy3;
265 yy5:
266 	YYDEBUG(5, *YYCURSOR);
267 	yyaccept = 1;
268 	yych = *(YYMARKER = ++YYCURSOR);
269 	if (yych <= '/') goto yy6;
270 	if (yych <= '9') goto yy12;
271 	if (yych == 'T') goto yy14;
272 yy6:
273 	YYDEBUG(6, *YYCURSOR);
274 #line 244 "ext/date/lib/parse_iso_intervals.re"
275 	{
276 		timelib_sll nr;
277 		int         in_time = 0;
278 		DEBUG_OUTPUT("period");
279 		TIMELIB_INIT;
280 		ptr++;
281 		do {
282 			if ( *ptr == 'T' ) {
283 				in_time = 1;
284 				ptr++;
285 			}
286 			if ( *ptr == '\0' ) {
287 				add_error(s, "Missing expected time part");
288 				break;
289 			}
290 
291 			nr = timelib_get_unsigned_nr(&ptr, 12);
292 			switch (*ptr) {
293 				case 'Y': s->period->y = nr; break;
294 				case 'W': s->period->d += nr * 7; break;
295 				case 'D': s->period->d += nr; break;
296 				case 'H': s->period->h = nr; break;
297 				case 'S': s->period->s = nr; break;
298 				case 'M':
299 					if (in_time) {
300 						s->period->i = nr;
301 					} else {
302 						s->period->m = nr;
303 					}
304 					break;
305 				default:
306 					add_error(s, "Undefined period specifier");
307 					break;
308 			}
309 			ptr++;
310 		} while (!s->errors->error_count && *ptr);
311 		s->have_period = 1;
312 		TIMELIB_DEINIT;
313 		return TIMELIB_PERIOD;
314 	}
315 #line 316 "<stdout>"
316 yy7:
317 	YYDEBUG(7, *YYCURSOR);
318 	++YYCURSOR;
319 	YYDEBUG(8, *YYCURSOR);
320 #line 306 "ext/date/lib/parse_iso_intervals.re"
321 	{
322 		goto std;
323 	}
324 #line 325 "<stdout>"
325 yy9:
326 	YYDEBUG(9, *YYCURSOR);
327 	++YYCURSOR;
328 	YYDEBUG(10, *YYCURSOR);
329 #line 311 "ext/date/lib/parse_iso_intervals.re"
330 	{
331 		s->pos = cursor; s->line++;
332 		goto std;
333 	}
334 #line 335 "<stdout>"
335 yy11:
336 	YYDEBUG(11, *YYCURSOR);
337 	yych = *++YYCURSOR;
338 	goto yy3;
339 yy12:
340 	YYDEBUG(12, *YYCURSOR);
341 	yych = *++YYCURSOR;
342 	if (yych <= 'L') {
343 		if (yych <= '9') {
344 			if (yych >= '0') goto yy25;
345 		} else {
346 			if (yych == 'D') goto yy24;
347 		}
348 	} else {
349 		if (yych <= 'W') {
350 			if (yych <= 'M') goto yy27;
351 			if (yych >= 'W') goto yy26;
352 		} else {
353 			if (yych == 'Y') goto yy28;
354 		}
355 	}
356 yy13:
357 	YYDEBUG(13, *YYCURSOR);
358 	YYCURSOR = YYMARKER;
359 	if (yyaccept == 0) {
360 		goto yy3;
361 	} else {
362 		goto yy6;
363 	}
364 yy14:
365 	YYDEBUG(14, *YYCURSOR);
366 	yyaccept = 1;
367 	yych = *(YYMARKER = ++YYCURSOR);
368 	if (yybm[0+yych] & 128) {
369 		goto yy15;
370 	}
371 	goto yy6;
372 yy15:
373 	YYDEBUG(15, *YYCURSOR);
374 	++YYCURSOR;
375 	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
376 	yych = *YYCURSOR;
377 	YYDEBUG(16, *YYCURSOR);
378 	if (yybm[0+yych] & 128) {
379 		goto yy15;
380 	}
381 	if (yych <= 'L') {
382 		if (yych == 'H') goto yy19;
383 		goto yy13;
384 	} else {
385 		if (yych <= 'M') goto yy18;
386 		if (yych != 'S') goto yy13;
387 	}
388 yy17:
389 	YYDEBUG(17, *YYCURSOR);
390 	yych = *++YYCURSOR;
391 	goto yy6;
392 yy18:
393 	YYDEBUG(18, *YYCURSOR);
394 	yyaccept = 1;
395 	yych = *(YYMARKER = ++YYCURSOR);
396 	if (yych <= '/') goto yy6;
397 	if (yych <= '9') goto yy22;
398 	goto yy6;
399 yy19:
400 	YYDEBUG(19, *YYCURSOR);
401 	yyaccept = 1;
402 	yych = *(YYMARKER = ++YYCURSOR);
403 	if (yych <= '/') goto yy6;
404 	if (yych >= ':') goto yy6;
405 yy20:
406 	YYDEBUG(20, *YYCURSOR);
407 	++YYCURSOR;
408 	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
409 	yych = *YYCURSOR;
410 	YYDEBUG(21, *YYCURSOR);
411 	if (yych <= 'L') {
412 		if (yych <= '/') goto yy13;
413 		if (yych <= '9') goto yy20;
414 		goto yy13;
415 	} else {
416 		if (yych <= 'M') goto yy18;
417 		if (yych == 'S') goto yy17;
418 		goto yy13;
419 	}
420 yy22:
421 	YYDEBUG(22, *YYCURSOR);
422 	++YYCURSOR;
423 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
424 	yych = *YYCURSOR;
425 	YYDEBUG(23, *YYCURSOR);
426 	if (yych <= '/') goto yy13;
427 	if (yych <= '9') goto yy22;
428 	if (yych == 'S') goto yy17;
429 	goto yy13;
430 yy24:
431 	YYDEBUG(24, *YYCURSOR);
432 	yych = *++YYCURSOR;
433 	if (yych == 'T') goto yy14;
434 	goto yy6;
435 yy25:
436 	YYDEBUG(25, *YYCURSOR);
437 	yych = *++YYCURSOR;
438 	if (yych <= 'L') {
439 		if (yych <= '9') {
440 			if (yych <= '/') goto yy13;
441 			goto yy35;
442 		} else {
443 			if (yych == 'D') goto yy24;
444 			goto yy13;
445 		}
446 	} else {
447 		if (yych <= 'W') {
448 			if (yych <= 'M') goto yy27;
449 			if (yych <= 'V') goto yy13;
450 		} else {
451 			if (yych == 'Y') goto yy28;
452 			goto yy13;
453 		}
454 	}
455 yy26:
456 	YYDEBUG(26, *YYCURSOR);
457 	yyaccept = 1;
458 	yych = *(YYMARKER = ++YYCURSOR);
459 	if (yych <= '/') goto yy6;
460 	if (yych <= '9') goto yy33;
461 	if (yych == 'T') goto yy14;
462 	goto yy6;
463 yy27:
464 	YYDEBUG(27, *YYCURSOR);
465 	yyaccept = 1;
466 	yych = *(YYMARKER = ++YYCURSOR);
467 	if (yych <= '/') goto yy6;
468 	if (yych <= '9') goto yy31;
469 	if (yych == 'T') goto yy14;
470 	goto yy6;
471 yy28:
472 	YYDEBUG(28, *YYCURSOR);
473 	yyaccept = 1;
474 	yych = *(YYMARKER = ++YYCURSOR);
475 	if (yych <= '/') goto yy6;
476 	if (yych <= '9') goto yy29;
477 	if (yych == 'T') goto yy14;
478 	goto yy6;
479 yy29:
480 	YYDEBUG(29, *YYCURSOR);
481 	++YYCURSOR;
482 	if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
483 	yych = *YYCURSOR;
484 	YYDEBUG(30, *YYCURSOR);
485 	if (yych <= 'D') {
486 		if (yych <= '/') goto yy13;
487 		if (yych <= '9') goto yy29;
488 		if (yych <= 'C') goto yy13;
489 		goto yy24;
490 	} else {
491 		if (yych <= 'M') {
492 			if (yych <= 'L') goto yy13;
493 			goto yy27;
494 		} else {
495 			if (yych == 'W') goto yy26;
496 			goto yy13;
497 		}
498 	}
499 yy31:
500 	YYDEBUG(31, *YYCURSOR);
501 	++YYCURSOR;
502 	if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
503 	yych = *YYCURSOR;
504 	YYDEBUG(32, *YYCURSOR);
505 	if (yych <= 'C') {
506 		if (yych <= '/') goto yy13;
507 		if (yych <= '9') goto yy31;
508 		goto yy13;
509 	} else {
510 		if (yych <= 'D') goto yy24;
511 		if (yych == 'W') goto yy26;
512 		goto yy13;
513 	}
514 yy33:
515 	YYDEBUG(33, *YYCURSOR);
516 	++YYCURSOR;
517 	if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
518 	yych = *YYCURSOR;
519 	YYDEBUG(34, *YYCURSOR);
520 	if (yych <= '/') goto yy13;
521 	if (yych <= '9') goto yy33;
522 	if (yych == 'D') goto yy24;
523 	goto yy13;
524 yy35:
525 	YYDEBUG(35, *YYCURSOR);
526 	yych = *++YYCURSOR;
527 	if (yych <= 'L') {
528 		if (yych <= '9') {
529 			if (yych <= '/') goto yy13;
530 		} else {
531 			if (yych == 'D') goto yy24;
532 			goto yy13;
533 		}
534 	} else {
535 		if (yych <= 'W') {
536 			if (yych <= 'M') goto yy27;
537 			if (yych <= 'V') goto yy13;
538 			goto yy26;
539 		} else {
540 			if (yych == 'Y') goto yy28;
541 			goto yy13;
542 		}
543 	}
544 	YYDEBUG(36, *YYCURSOR);
545 	yych = *++YYCURSOR;
546 	if (yych != '-') goto yy39;
547 	YYDEBUG(37, *YYCURSOR);
548 	yych = *++YYCURSOR;
549 	if (yych <= '/') goto yy13;
550 	if (yych <= '0') goto yy40;
551 	if (yych <= '1') goto yy41;
552 	goto yy13;
553 yy38:
554 	YYDEBUG(38, *YYCURSOR);
555 	++YYCURSOR;
556 	if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
557 	yych = *YYCURSOR;
558 yy39:
559 	YYDEBUG(39, *YYCURSOR);
560 	if (yych <= 'L') {
561 		if (yych <= '9') {
562 			if (yych <= '/') goto yy13;
563 			goto yy38;
564 		} else {
565 			if (yych == 'D') goto yy24;
566 			goto yy13;
567 		}
568 	} else {
569 		if (yych <= 'W') {
570 			if (yych <= 'M') goto yy27;
571 			if (yych <= 'V') goto yy13;
572 			goto yy26;
573 		} else {
574 			if (yych == 'Y') goto yy28;
575 			goto yy13;
576 		}
577 	}
578 yy40:
579 	YYDEBUG(40, *YYCURSOR);
580 	yych = *++YYCURSOR;
581 	if (yych <= '/') goto yy13;
582 	if (yych <= '9') goto yy42;
583 	goto yy13;
584 yy41:
585 	YYDEBUG(41, *YYCURSOR);
586 	yych = *++YYCURSOR;
587 	if (yych <= '/') goto yy13;
588 	if (yych >= '3') goto yy13;
589 yy42:
590 	YYDEBUG(42, *YYCURSOR);
591 	yych = *++YYCURSOR;
592 	if (yych != '-') goto yy13;
593 	YYDEBUG(43, *YYCURSOR);
594 	yych = *++YYCURSOR;
595 	if (yych <= '/') goto yy13;
596 	if (yych <= '0') goto yy44;
597 	if (yych <= '2') goto yy45;
598 	if (yych <= '3') goto yy46;
599 	goto yy13;
600 yy44:
601 	YYDEBUG(44, *YYCURSOR);
602 	yych = *++YYCURSOR;
603 	if (yych <= '/') goto yy13;
604 	if (yych <= '9') goto yy47;
605 	goto yy13;
606 yy45:
607 	YYDEBUG(45, *YYCURSOR);
608 	yych = *++YYCURSOR;
609 	if (yych <= '/') goto yy13;
610 	if (yych <= '9') goto yy47;
611 	goto yy13;
612 yy46:
613 	YYDEBUG(46, *YYCURSOR);
614 	yych = *++YYCURSOR;
615 	if (yych <= '/') goto yy13;
616 	if (yych >= '2') goto yy13;
617 yy47:
618 	YYDEBUG(47, *YYCURSOR);
619 	yych = *++YYCURSOR;
620 	if (yych != 'T') goto yy13;
621 	YYDEBUG(48, *YYCURSOR);
622 	yych = *++YYCURSOR;
623 	if (yych <= '/') goto yy13;
624 	if (yych <= '1') goto yy49;
625 	if (yych <= '2') goto yy50;
626 	goto yy13;
627 yy49:
628 	YYDEBUG(49, *YYCURSOR);
629 	yych = *++YYCURSOR;
630 	if (yych <= '/') goto yy13;
631 	if (yych <= '9') goto yy51;
632 	goto yy13;
633 yy50:
634 	YYDEBUG(50, *YYCURSOR);
635 	yych = *++YYCURSOR;
636 	if (yych <= '/') goto yy13;
637 	if (yych >= '5') goto yy13;
638 yy51:
639 	YYDEBUG(51, *YYCURSOR);
640 	yych = *++YYCURSOR;
641 	if (yych != ':') goto yy13;
642 	YYDEBUG(52, *YYCURSOR);
643 	yych = *++YYCURSOR;
644 	if (yych <= '/') goto yy13;
645 	if (yych >= '6') goto yy13;
646 	YYDEBUG(53, *YYCURSOR);
647 	yych = *++YYCURSOR;
648 	if (yych <= '/') goto yy13;
649 	if (yych >= ':') goto yy13;
650 	YYDEBUG(54, *YYCURSOR);
651 	yych = *++YYCURSOR;
652 	if (yych != ':') goto yy13;
653 	YYDEBUG(55, *YYCURSOR);
654 	yych = *++YYCURSOR;
655 	if (yych <= '/') goto yy13;
656 	if (yych >= '6') goto yy13;
657 	YYDEBUG(56, *YYCURSOR);
658 	yych = *++YYCURSOR;
659 	if (yych <= '/') goto yy13;
660 	if (yych >= ':') goto yy13;
661 	YYDEBUG(57, *YYCURSOR);
662 	++YYCURSOR;
663 	YYDEBUG(58, *YYCURSOR);
664 #line 286 "ext/date/lib/parse_iso_intervals.re"
665 	{
666 		DEBUG_OUTPUT("combinedrep");
667 		TIMELIB_INIT;
668 		s->period->y = timelib_get_unsigned_nr(&ptr, 4);
669 		ptr++;
670 		s->period->m = timelib_get_unsigned_nr(&ptr, 2);
671 		ptr++;
672 		s->period->d = timelib_get_unsigned_nr(&ptr, 2);
673 		ptr++;
674 		s->period->h = timelib_get_unsigned_nr(&ptr, 2);
675 		ptr++;
676 		s->period->i = timelib_get_unsigned_nr(&ptr, 2);
677 		ptr++;
678 		s->period->s = timelib_get_unsigned_nr(&ptr, 2);
679 		s->have_period = 1;
680 		TIMELIB_DEINIT;
681 		return TIMELIB_PERIOD;
682 	}
683 #line 684 "<stdout>"
684 yy59:
685 	YYDEBUG(59, *YYCURSOR);
686 	yych = *++YYCURSOR;
687 	if (yych <= '/') goto yy13;
688 	if (yych >= ':') goto yy13;
689 	YYDEBUG(60, *YYCURSOR);
690 	yych = *++YYCURSOR;
691 	if (yych <= '/') goto yy13;
692 	if (yych >= ':') goto yy13;
693 	YYDEBUG(61, *YYCURSOR);
694 	yych = *++YYCURSOR;
695 	if (yych <= '/') {
696 		if (yych == '-') goto yy64;
697 		goto yy13;
698 	} else {
699 		if (yych <= '0') goto yy62;
700 		if (yych <= '1') goto yy63;
701 		goto yy13;
702 	}
703 yy62:
704 	YYDEBUG(62, *YYCURSOR);
705 	yych = *++YYCURSOR;
706 	if (yych <= '0') goto yy13;
707 	if (yych <= '9') goto yy85;
708 	goto yy13;
709 yy63:
710 	YYDEBUG(63, *YYCURSOR);
711 	yych = *++YYCURSOR;
712 	if (yych <= '/') goto yy13;
713 	if (yych <= '2') goto yy85;
714 	goto yy13;
715 yy64:
716 	YYDEBUG(64, *YYCURSOR);
717 	yych = *++YYCURSOR;
718 	if (yych <= '/') goto yy13;
719 	if (yych <= '0') goto yy65;
720 	if (yych <= '1') goto yy66;
721 	goto yy13;
722 yy65:
723 	YYDEBUG(65, *YYCURSOR);
724 	yych = *++YYCURSOR;
725 	if (yych <= '0') goto yy13;
726 	if (yych <= '9') goto yy67;
727 	goto yy13;
728 yy66:
729 	YYDEBUG(66, *YYCURSOR);
730 	yych = *++YYCURSOR;
731 	if (yych <= '/') goto yy13;
732 	if (yych >= '3') goto yy13;
733 yy67:
734 	YYDEBUG(67, *YYCURSOR);
735 	yych = *++YYCURSOR;
736 	if (yych != '-') goto yy13;
737 	YYDEBUG(68, *YYCURSOR);
738 	yych = *++YYCURSOR;
739 	if (yych <= '/') goto yy13;
740 	if (yych <= '0') goto yy69;
741 	if (yych <= '2') goto yy70;
742 	if (yych <= '3') goto yy71;
743 	goto yy13;
744 yy69:
745 	YYDEBUG(69, *YYCURSOR);
746 	yych = *++YYCURSOR;
747 	if (yych <= '0') goto yy13;
748 	if (yych <= '9') goto yy72;
749 	goto yy13;
750 yy70:
751 	YYDEBUG(70, *YYCURSOR);
752 	yych = *++YYCURSOR;
753 	if (yych <= '/') goto yy13;
754 	if (yych <= '9') goto yy72;
755 	goto yy13;
756 yy71:
757 	YYDEBUG(71, *YYCURSOR);
758 	yych = *++YYCURSOR;
759 	if (yych <= '/') goto yy13;
760 	if (yych >= '2') goto yy13;
761 yy72:
762 	YYDEBUG(72, *YYCURSOR);
763 	yych = *++YYCURSOR;
764 	if (yych != 'T') goto yy13;
765 	YYDEBUG(73, *YYCURSOR);
766 	yych = *++YYCURSOR;
767 	if (yych <= '/') goto yy13;
768 	if (yych <= '1') goto yy74;
769 	if (yych <= '2') goto yy75;
770 	goto yy13;
771 yy74:
772 	YYDEBUG(74, *YYCURSOR);
773 	yych = *++YYCURSOR;
774 	if (yych <= '/') goto yy13;
775 	if (yych <= '9') goto yy76;
776 	goto yy13;
777 yy75:
778 	YYDEBUG(75, *YYCURSOR);
779 	yych = *++YYCURSOR;
780 	if (yych <= '/') goto yy13;
781 	if (yych >= '5') goto yy13;
782 yy76:
783 	YYDEBUG(76, *YYCURSOR);
784 	yych = *++YYCURSOR;
785 	if (yych != ':') goto yy13;
786 	YYDEBUG(77, *YYCURSOR);
787 	yych = *++YYCURSOR;
788 	if (yych <= '/') goto yy13;
789 	if (yych >= '6') goto yy13;
790 	YYDEBUG(78, *YYCURSOR);
791 	yych = *++YYCURSOR;
792 	if (yych <= '/') goto yy13;
793 	if (yych >= ':') goto yy13;
794 	YYDEBUG(79, *YYCURSOR);
795 	yych = *++YYCURSOR;
796 	if (yych != ':') goto yy13;
797 	YYDEBUG(80, *YYCURSOR);
798 	yych = *++YYCURSOR;
799 	if (yych <= '/') goto yy13;
800 	if (yych >= '6') goto yy13;
801 	YYDEBUG(81, *YYCURSOR);
802 	yych = *++YYCURSOR;
803 	if (yych <= '/') goto yy13;
804 	if (yych >= ':') goto yy13;
805 	YYDEBUG(82, *YYCURSOR);
806 	yych = *++YYCURSOR;
807 	if (yych != 'Z') goto yy13;
808 yy83:
809 	YYDEBUG(83, *YYCURSOR);
810 	++YYCURSOR;
811 	YYDEBUG(84, *YYCURSOR);
812 #line 220 "ext/date/lib/parse_iso_intervals.re"
813 	{
814 		timelib_time *current;
815 
816 		if (s->have_date || s->have_period) {
817 			current = s->end;
818 			s->have_end_date = 1;
819 		} else {
820 			current = s->begin;
821 			s->have_begin_date = 1;
822 		}
823 		DEBUG_OUTPUT("datetimebasic | datetimeextended");
824 		TIMELIB_INIT;
825 		current->y = timelib_get_nr(&ptr, 4);
826 		current->m = timelib_get_nr(&ptr, 2);
827 		current->d = timelib_get_nr(&ptr, 2);
828 		current->h = timelib_get_nr(&ptr, 2);
829 		current->i = timelib_get_nr(&ptr, 2);
830 		current->s = timelib_get_nr(&ptr, 2);
831 		s->have_date = 1;
832 		TIMELIB_DEINIT;
833 		return TIMELIB_ISO_DATE;
834 	}
835 #line 836 "<stdout>"
836 yy85:
837 	YYDEBUG(85, *YYCURSOR);
838 	yych = *++YYCURSOR;
839 	if (yych <= '/') goto yy13;
840 	if (yych <= '0') goto yy86;
841 	if (yych <= '2') goto yy87;
842 	if (yych <= '3') goto yy88;
843 	goto yy13;
844 yy86:
845 	YYDEBUG(86, *YYCURSOR);
846 	yych = *++YYCURSOR;
847 	if (yych <= '0') goto yy13;
848 	if (yych <= '9') goto yy89;
849 	goto yy13;
850 yy87:
851 	YYDEBUG(87, *YYCURSOR);
852 	yych = *++YYCURSOR;
853 	if (yych <= '/') goto yy13;
854 	if (yych <= '9') goto yy89;
855 	goto yy13;
856 yy88:
857 	YYDEBUG(88, *YYCURSOR);
858 	yych = *++YYCURSOR;
859 	if (yych <= '/') goto yy13;
860 	if (yych >= '2') goto yy13;
861 yy89:
862 	YYDEBUG(89, *YYCURSOR);
863 	yych = *++YYCURSOR;
864 	if (yych != 'T') goto yy13;
865 	YYDEBUG(90, *YYCURSOR);
866 	yych = *++YYCURSOR;
867 	if (yych <= '/') goto yy13;
868 	if (yych <= '1') goto yy91;
869 	if (yych <= '2') goto yy92;
870 	goto yy13;
871 yy91:
872 	YYDEBUG(91, *YYCURSOR);
873 	yych = *++YYCURSOR;
874 	if (yych <= '/') goto yy13;
875 	if (yych <= '9') goto yy93;
876 	goto yy13;
877 yy92:
878 	YYDEBUG(92, *YYCURSOR);
879 	yych = *++YYCURSOR;
880 	if (yych <= '/') goto yy13;
881 	if (yych >= '5') goto yy13;
882 yy93:
883 	YYDEBUG(93, *YYCURSOR);
884 	yych = *++YYCURSOR;
885 	if (yych <= '/') goto yy13;
886 	if (yych >= '6') goto yy13;
887 	YYDEBUG(94, *YYCURSOR);
888 	yych = *++YYCURSOR;
889 	if (yych <= '/') goto yy13;
890 	if (yych >= ':') goto yy13;
891 	YYDEBUG(95, *YYCURSOR);
892 	yych = *++YYCURSOR;
893 	if (yych <= '/') goto yy13;
894 	if (yych >= '6') goto yy13;
895 	YYDEBUG(96, *YYCURSOR);
896 	yych = *++YYCURSOR;
897 	if (yych <= '/') goto yy13;
898 	if (yych >= ':') goto yy13;
899 	YYDEBUG(97, *YYCURSOR);
900 	yych = *++YYCURSOR;
901 	if (yych == 'Z') goto yy83;
902 	goto yy13;
903 yy98:
904 	YYDEBUG(98, *YYCURSOR);
905 	++YYCURSOR;
906 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
907 	yych = *YYCURSOR;
908 	YYDEBUG(99, *YYCURSOR);
909 	if (yych <= '/') goto yy100;
910 	if (yych <= '9') goto yy98;
911 yy100:
912 	YYDEBUG(100, *YYCURSOR);
913 #line 209 "ext/date/lib/parse_iso_intervals.re"
914 	{
915 		DEBUG_OUTPUT("recurrences");
916 		TIMELIB_INIT;
917 		ptr++;
918 		s->recurrences = timelib_get_unsigned_nr(&ptr, 9);
919 		TIMELIB_DEINIT;
920 		s->have_recurrences = 1;
921 		return TIMELIB_PERIOD;
922 	}
923 #line 924 "<stdout>"
924 }
925 #line 321 "ext/date/lib/parse_iso_intervals.re"
926 
927 }
928 #ifdef PHP_WIN32
929 #pragma optimize( "", on )
930 #endif
931 
932 #define YYMAXFILL 20
933 
timelib_strtointerval(const char * s,size_t len,timelib_time ** begin,timelib_time ** end,timelib_rel_time ** period,int * recurrences,timelib_error_container ** errors)934 void timelib_strtointerval(const char *s, size_t len,
935                            timelib_time **begin, timelib_time **end,
936 						   timelib_rel_time **period, int *recurrences,
937 						   timelib_error_container **errors)
938 {
939 	Scanner in;
940 	int t;
941 	const char *e = s + len - 1;
942 
943 	memset(&in, 0, sizeof(in));
944 	in.errors = timelib_malloc(sizeof(timelib_error_container));
945 	in.errors->warning_count = 0;
946 	in.errors->warning_messages = NULL;
947 	in.errors->error_count = 0;
948 	in.errors->error_messages = NULL;
949 
950 	if (len > 0) {
951 		while (isspace(*s) && s < e) {
952 			s++;
953 		}
954 		while (isspace(*e) && e > s) {
955 			e--;
956 		}
957 	}
958 	if (e - s < 0) {
959 		add_error(&in, "Empty string");
960 		if (errors) {
961 			*errors = in.errors;
962 		} else {
963 			timelib_error_container_dtor(in.errors);
964 		}
965 		return;
966 	}
967 	e++;
968 
969 	/* init cursor */
970 	in.str = timelib_malloc((e - s) + YYMAXFILL);
971 	memset(in.str, 0, (e - s) + YYMAXFILL);
972 	memcpy(in.str, s, (e - s));
973 	in.lim = in.str + (e - s) + YYMAXFILL;
974 	in.cur = in.str;
975 
976 	/* init value containers */
977 	in.begin = timelib_time_ctor();
978 	in.begin->y = TIMELIB_UNSET;
979 	in.begin->d = TIMELIB_UNSET;
980 	in.begin->m = TIMELIB_UNSET;
981 	in.begin->h = TIMELIB_UNSET;
982 	in.begin->i = TIMELIB_UNSET;
983 	in.begin->s = TIMELIB_UNSET;
984 	in.begin->us = 0;
985 	in.begin->z = 0;
986 	in.begin->dst = 0;
987 	in.begin->is_localtime = 0;
988 	in.begin->zone_type = TIMELIB_ZONETYPE_OFFSET;
989 
990 	in.end = timelib_time_ctor();
991 	in.end->y = TIMELIB_UNSET;
992 	in.end->d = TIMELIB_UNSET;
993 	in.end->m = TIMELIB_UNSET;
994 	in.end->h = TIMELIB_UNSET;
995 	in.end->i = TIMELIB_UNSET;
996 	in.end->s = TIMELIB_UNSET;
997 	in.end->us = 0;
998 	in.end->z = 0;
999 	in.end->dst = 0;
1000 	in.end->is_localtime = 0;
1001 	in.end->zone_type = TIMELIB_ZONETYPE_OFFSET;
1002 
1003 	in.period = timelib_rel_time_ctor();
1004 	in.period->y = 0;
1005 	in.period->d = 0;
1006 	in.period->m = 0;
1007 	in.period->h = 0;
1008 	in.period->i = 0;
1009 	in.period->s = 0;
1010 	in.period->weekday = 0;
1011 	in.period->weekday_behavior = 0;
1012 	in.period->first_last_day_of = 0;
1013 	in.period->days = TIMELIB_UNSET;
1014 
1015 	in.recurrences = 1;
1016 
1017 	do {
1018 		t = scan(&in);
1019 #ifdef DEBUG_PARSER
1020 		printf("%d\n", t);
1021 #endif
1022 	} while(t != EOI);
1023 
1024 	timelib_free(in.str);
1025 	if (errors) {
1026 		*errors = in.errors;
1027 	} else {
1028 		timelib_error_container_dtor(in.errors);
1029 	}
1030 	if (in.have_begin_date) {
1031 		*begin = in.begin;
1032 	} else {
1033 		timelib_time_dtor(in.begin);
1034 	}
1035 	if (in.have_end_date) {
1036 		*end   = in.end;
1037 	} else {
1038 		timelib_time_dtor(in.end);
1039 	}
1040 	if (in.have_period) {
1041 		*period = in.period;
1042 	} else {
1043 		timelib_rel_time_dtor(in.period);
1044 	}
1045 	if (in.have_recurrences) {
1046 		*recurrences = in.recurrences;
1047 	}
1048 }
1049 
1050 
1051 /*
1052  * vim: syntax=c
1053  */
1054