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