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