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