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