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