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