summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/backend/vcc_yacc.cpp1545
1 files changed, 1545 insertions, 0 deletions
diff --git a/library/backend/vcc_yacc.cpp b/library/backend/vcc_yacc.cpp
new file mode 100644
index 0000000..cb24631
--- a/dev/null
+++ b/library/backend/vcc_yacc.cpp
@@ -0,0 +1,1545 @@
1#ifndef lint
2 static char yysccsid[] = "@(#)yaccpar1.9 (Berkeley) 02/21/93";
3#endif
4#define YYBYACC 1
5#define YYMAJOR 1
6#define YYMINOR 9
7#define yyclearin (yychar=(-1))
8#define yyerrok (yyerrflag=0)
9#define YYRECOVERING (yyerrflag!=0)
10#define YYPREFIX "yy"
11#line 1 "vcc.y"
12
13
14/***************************************************************************
15(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
16Business Machines Corporation and Siemens Rolm Communications Inc.
17
18For purposes of this license notice, the term Licensors shall mean,
19collectively, Apple Computer, Inc., AT&T Corp., International
20Business Machines Corporation and Siemens Rolm Communications Inc.
21The term Licensor shall mean any of the Licensors.
22
23Subject to acceptance of the following conditions, permission is hereby
24granted by Licensors without the need for written agreement and without
25license or royalty fees, to use, copy, modify and distribute this
26software for any purpose.
27
28The above copyright notice and the following four paragraphs must be
29reproduced in all copies of this software and any software including
30this software.
31
32THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
33ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
34MODIFICATIONS.
35
36IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
37INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
38OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
39DAMAGE.
40
41EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
42INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
43IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44PURPOSE.
45
46The software is provided with RESTRICTED RIGHTS. Use, duplication, or
47disclosure by the government are subject to restrictions set forth in
48DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
49
50***************************************************************************/
51
52/*
53 * src: vcc.c
54 * doc: Parser for vCard and vCalendar. Note that this code is
55 * generated by a yacc parser generator. Generally it should not
56 * be edited by hand. The real source is vcc.y. The #line directives
57 * can be commented out here to make it easier to trace through
58 * in a debugger. However, if a bug is found it should
59 * be fixed in vcc.y and this file regenerated.
60 */
61
62
63/* debugging utilities */
64#if __DEBUG
65#define DBG_(x) printf x
66#else
67#define DBG_(x)
68#endif
69
70/**** External Functions ****/
71
72/* assign local name to parser variables and functions so that
73 we can use more than one yacc based parser.
74*/
75
76#define yyparse mime_parse
77#define yylex mime_lex
78#define yyerror mime_error
79#define yychar mime_char
80/* #define p_yyval p_mime_val */
81#undef yyval
82#define yyval mime_yyval
83/* #define p_yylval p_mime_lval */
84#undef yylval
85#define yylval mime_yylval
86#define yydebug mime_debug
87#define yynerrs mime_nerrs
88#define yyerrflag mime_errflag
89#define yyss mime_ss
90#define yyssp mime_ssp
91#define yyvs mime_vs
92#define yyvsp mime_vsp
93#define yylhs mime_lhs
94#define yylen mime_len
95#define yydefred mime_defred
96#define yydgoto mime_dgoto
97#define yysindex mime_sindex
98#define yyrindex mime_rindex
99#define yygindex mime_gindex
100#define yytable mime_table
101#define yycheck mime_check
102#define yyname mime_name
103#define yyrule mime_rule
104#ifdef YYPREFIX
105#undef YYPREFIX
106#endif
107#define YYPREFIX "mime_"
108
109
110#ifndef _NO_LINE_FOLDING
111#define _SUPPORT_LINE_FOLDING 1
112#endif
113
114/* undef below if compile with MFC */
115/* #define INCLUDEMFC 1 */
116
117#if defined(WIN32) || defined(_WIN32)
118#ifdef INCLUDEMFC
119#include <afx.h>
120#endif
121#endif
122
123#include <string.h>
124#ifndef __MWERKS__
125#include <stdlib.h>
126#endif
127#include <stdio.h>
128#include <stdlib.h>
129#include <ctype.h>
130
131#ifdef PALMTOPCENTER
132#include <qpe/vobject_p.h>
133#include <qpe/qfiledirect_p.h>
134#else
135#include "vobject_p.h"
136#include "qfiledirect_p.h"
137#endif
138
139/**** Types, Constants ****/
140
141 #define YYDEBUG 0/* 1 to compile in some debugging code */
142 #define MAXTOKEN 256/* maximum token (line) length */
143 #define YYSTACKSIZE 100/* ~unref ?
144*/
145 #define MAXLEVEL 10/* max # of nested objects parseable */
146 /* (includes outermost) */
147
148
149/**** Global Variables ****/
150int mime_lineNum, mime_numErrors; /* yyerror() can use these */
151static VObject* vObjList;
152static VObject *curProp;
153static VObject *curObj;
154static VObject* ObjStack[MAXLEVEL];
155static int ObjStackTop;
156
157
158/* A helpful utility for the rest of the app. */
159#if __CPLUSPLUS__
160extern "C" {
161#endif
162
163 extern void yyerror(char *s);
164
165#if __CPLUSPLUS__
166 };
167#endif
168
169int yyparse();
170
171enum LexMode {
172 L_NORMAL,
173 L_VCARD,
174 L_VCAL,
175 L_VEVENT,
176 L_VTODO,
177 L_VALUES,
178 L_BASE64,
179 L_QUOTED_PRINTABLE
180 };
181
182/**** Private Forward Declarations ****/
183static int pushVObject(const char *prop);
184static VObject* popVObject();
185static void lexPopMode(int top);
186static int lexWithinMode(enum LexMode mode);
187static void lexPushMode(enum LexMode mode);
188static void enterProps(const char *s);
189static void enterAttr(const char *s1, const char *s2);
190static void enterValues(const char *value);
191void mime_error_(char *s);
192
193#line 185 "vcc.y"
194typedef union {
195 char *str;
196 VObject *vobj;
197 } YYSTYPE;
198#line 196 "y.tab.c"
199#define EQ 257
200#define COLON 258
201#define DOT 259
202#define SEMICOLON 260
203#define SPACE 261
204#define HTAB 262
205#define LINESEP 263
206#define NEWLINE 264
207#define BEGIN_VCARD 265
208#define END_VCARD 266
209#define BEGIN_VCAL 267
210#define END_VCAL 268
211#define BEGIN_VEVENT 269
212#define END_VEVENT 270
213#define BEGIN_VTODO 271
214#define END_VTODO 272
215#define ID 273
216#define STRING 274
217#define YYERRCODE 256
218short yylhs[] = { -1,
219 0, 6, 6, 5, 5, 8, 3, 9, 3, 7,
220 7, 13, 10, 10, 15, 11, 11, 14, 14, 16,
221 17, 17, 1, 18, 12, 12, 2, 2, 20, 4,
222 21, 4, 19, 19, 22, 22, 22, 25, 23, 26,
223 23, 27, 24, 28, 24,
224};
225short yylen[] = { 2,
226 1, 2, 1, 1, 1, 0, 4, 0, 3, 2,
227 1, 0, 5, 1, 0, 3, 1, 2, 1, 2,
228 1, 3, 1, 0, 4, 1, 1, 0, 0, 4,
229 0, 3, 2, 1, 1, 1, 1, 0, 4, 0,
230 3, 0, 4, 0, 3,
231};
232short yydefred[] = { 0,
233 0, 0, 0, 4, 5, 3, 0, 0, 0, 0,
234 0, 2, 14, 23, 0, 0, 11, 0, 9, 0,
235 0, 0, 0, 34, 35, 36, 32, 0, 7, 10,
236 12, 0, 0, 0, 0, 30, 33, 0, 0, 19,
237 0, 0, 41, 0, 45, 0, 20, 18, 27, 0,
238 0, 39, 43, 0, 24, 13, 22, 0, 25,
239};
240short yydgoto[] = { 3,
241 15, 50, 4, 5, 6, 7, 22, 8, 9, 17,
242 18, 51, 41, 39, 28, 40, 47, 58, 23, 10,
243 11, 24, 25, 26, 32, 33, 34, 35,
244};
245short yysindex[] = { -262,
246 0, 0, 0, 0, 0, 0, -262, -252, -219, -249,
247 -256, 0, 0, 0, 0, -227, 0, -242, 0, 0,
248 0, -252, -254, 0, 0, 0, 0, -208, 0, 0,
249 0, -252, -228, -252, -213, 0, 0, -212, -208, 0,
250 -214, -233, 0, -224, 0, -195, 0, 0, 0, -197,
251 -199, 0, 0, -212, 0, 0, 0, -214, 0,
252};
253short yyrindex[] = { 0,
254 -222, -238, 0, 0, 0, 0, 65, 0, 0, 0,
255 0, 0, 0, 0, -215, 0, 0, 0, 0, -220,
256 -218, -260, 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0, -192, 0,
258 -250, 0, 0, 0, 0, -202, 0, 0, 0, -196,
259 0, 0, 0, 0, 0, 0, 0, -250, 0,
260};
261short yygindex[] = { 0,
262 3, 0, 0, 0, 61, 0, -7, 0, 0, -16,
263 0, 11, 0, 0, 0, 31, 0, 0, 0, 0,
264 0, 48, 0, 0, 0, 0, 0, 0,
265};
266#define YYTABLESIZE 71
267short yytable[] = { 30,
268 16, 13, 1, 13, 2, 30, 13, 37, 37, 28,
269 37, 27, 28, 36, 20, 31, 21, 29, 14, 20,
270 14, 21, 13, 14, 42, 30, 44, 30, 13, 31,
271 29, 13, 29, 6, 29, 38, 52, 42, 29, 14,
272 46, 43, 17, 8, 15, 14, 19, 53, 14, 40,
273 6, 38, 38, 44, 42, 21, 57, 21, 45, 49,
274 14, 54, 55, 56, 1, 16, 26, 12, 59, 48,
275 37,
276};
277short yycheck[] = { 16,
278 8, 256, 265, 256, 267, 22, 256, 268, 269, 260,
279 271, 268, 263, 268, 269, 258, 271, 256, 273, 269,
280 273, 271, 256, 273, 32, 42, 34, 44, 256, 268,
281 269, 256, 271, 256, 273, 256, 270, 256, 266, 273,
282 38, 270, 258, 266, 260, 273, 266, 272, 273, 270,
283 273, 260, 273, 272, 273, 258, 54, 260, 272, 274,
284 273, 257, 260, 263, 0, 258, 263, 7, 58, 39,
285 23,
286};
287#define YYFINAL 3
288#ifndef YYDEBUG
289#define YYDEBUG 0
290#endif
291#define YYMAXTOKEN 274
292#if YYDEBUG
293char *yyname[] = {
294"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2960,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2970,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2980,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2990,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"EQ","COLON","DOT","SEMICOLON",
301"SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL",
302"END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING",
303};
304char *yyrule[] = {
305"$accept : mime",
306"mime : vobjects",
307"vobjects : vobjects vobject",
308"vobjects : vobject",
309"vobject : vcard",
310"vobject : vcal",
311"$$1 :",
312"vcard : BEGIN_VCARD $$1 items END_VCARD",
313"$$2 :",
314"vcard : BEGIN_VCARD $$2 END_VCARD",
315"items : items item",
316"items : item",
317"$$3 :",
318"item : prop COLON $$3 values LINESEP",
319"item : error",
320"$$4 :",
321"prop : name $$4 attr_params",
322"prop : name",
323"attr_params : attr_params attr_param",
324"attr_params : attr_param",
325"attr_param : SEMICOLON attr",
326"attr : name",
327"attr : name EQ name",
328"name : ID",
329"$$5 :",
330"values : value SEMICOLON $$5 values",
331"values : value",
332"value : STRING",
333"value :",
334"$$6 :",
335"vcal : BEGIN_VCAL $$6 calitems END_VCAL",
336"$$7 :",
337"vcal : BEGIN_VCAL $$7 END_VCAL",
338"calitems : calitems calitem",
339"calitems : calitem",
340"calitem : eventitem",
341"calitem : todoitem",
342"calitem : items",
343"$$8 :",
344"eventitem : BEGIN_VEVENT $$8 items END_VEVENT",
345"$$9 :",
346"eventitem : BEGIN_VEVENT $$9 END_VEVENT",
347"$$10 :",
348"todoitem : BEGIN_VTODO $$10 items END_VTODO",
349"$$11 :",
350"todoitem : BEGIN_VTODO $$11 END_VTODO",
351};
352#endif
353#ifdef YYSTACKSIZE
354#undef YYMAXDEPTH
355#define YYMAXDEPTH YYSTACKSIZE
356#else
357#ifdef YYMAXDEPTH
358#define YYSTACKSIZE YYMAXDEPTH
359#else
360#define YYSTACKSIZE 500
361#define YYMAXDEPTH 500
362#endif
363#endif
364int yydebug;
365int yynerrs;
366int yyerrflag;
367int yychar;
368short *yyssp;
369YYSTYPE *yyvsp;
370YYSTYPE yyval;
371YYSTYPE yylval;
372short yyss[YYSTACKSIZE];
373YYSTYPE yyvs[YYSTACKSIZE];
374#define yystacksize YYSTACKSIZE
375#line 378 "vcc.y"
376
377/*------------------------------------*/
378static int pushVObject(const char *prop)
379 {
380 VObject *newObj;
381 if (ObjStackTop == MAXLEVEL)
382 return FALSE;
383
384 ObjStack[++ObjStackTop] = curObj;
385
386 if (curObj) {
387 newObj = addProp(curObj,prop);
388 curObj = newObj;
389 }
390 else
391 curObj = newVObject(prop);
392
393 return TRUE;
394 }
395
396
397/*---------------------------------------*/
398/* This pops the recently built vCard off the stack and returns it. */
399static VObject* popVObject()
400 {
401 VObject *oldObj;
402 if (ObjStackTop < 0) {
403 yyerror("pop on empty Object Stack\n");
404 return 0;
405 }
406 oldObj = curObj;
407 curObj = ObjStack[ObjStackTop--];
408
409 return oldObj;
410 }
411
412
413static void enterValues(const char *value)
414 {
415 if (fieldedProp && *fieldedProp) {
416 if (value) {
417 addPropValue(curProp,*fieldedProp,value);
418 }
419 /* else this field is empty, advance to next field */
420 fieldedProp++;
421 }
422 else {
423 if (value) {
424 setVObjectStringZValue_(curProp,strdup( value ));
425 }
426 }
427 deleteStr(value);
428 }
429
430static void enterProps(const char *s)
431 {
432 curProp = addGroup(curObj,s);
433 deleteStr(s);
434 }
435
436static void enterAttr(const char *s1, const char *s2)
437 {
438 const char *p1, *p2;
439 p1 = lookupProp_(s1);
440 if (s2) {
441 VObject *a;
442 p2 = lookupProp_(s2);
443 a = addProp(curProp,p1);
444 setVObjectStringZValue(a,p2);
445 }
446 else
447 addProp(curProp,p1);
448 if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0))
449 lexPushMode(L_BASE64);
450 else if (qstricmp(p1,VCQuotedPrintableProp) == 0
451 || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0))
452 lexPushMode(L_QUOTED_PRINTABLE);
453 deleteStr(s1); deleteStr(s2);
454 }
455
456
457#define MAX_LEX_LOOKAHEAD_0 32
458#define MAX_LEX_LOOKAHEAD 64
459#define MAX_LEX_MODE_STACK_SIZE 10
460#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
461
462struct LexBuf {
463 /* input */
464#ifdef INCLUDEMFC
465 CFile *inputFile;
466#else
467 FILE *inputFile;
468#endif
469 char *inputString;
470 unsigned long curPos;
471 unsigned long inputLen;
472 /* lookahead buffer */
473 /* -- lookahead buffer is short instead of char so that EOF
474 / can be represented correctly.
475 */
476 unsigned long len;
477 short buf[MAX_LEX_LOOKAHEAD];
478 unsigned long getPtr;
479 /* context stack */
480 unsigned long lexModeStackTop;
481 enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE];
482 /* token buffer */
483 unsigned long maxToken;
484 char *strs;
485 unsigned long strsLen;
486 } lexBuf;
487
488static void lexPushMode(enum LexMode mode)
489 {
490 if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1))
491 yyerror("lexical context stack overflow");
492 else {
493 lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
494 }
495 }
496
497static void lexPopMode(int top)
498 {
499 /* special case of pop for ease of error recovery -- this
500 version will never underflow */
501 if (top)
502 lexBuf.lexModeStackTop = 0;
503 else
504 if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--;
505 }
506
507static int lexWithinMode(enum LexMode mode) {
508 unsigned long i;
509 for (i=0;i<lexBuf.lexModeStackTop;i++)
510 if (mode == lexBuf.lexModeStack[i]) return 1;
511 return 0;
512 }
513
514static char lexGetc_()
515 {
516 /* get next char from input, no buffering. */
517 if (lexBuf.curPos == lexBuf.inputLen)
518 return EOF;
519 else if (lexBuf.inputString)
520 return *(lexBuf.inputString + lexBuf.curPos++);
521 else {
522#ifdef INCLUDEMFC
523 char result;
524 return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF;
525#else
526 return fgetc(lexBuf.inputFile);
527#endif
528 }
529 }
530
531static int lexGeta()
532 {
533 ++lexBuf.len;
534 return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
535 }
536
537static int lexGeta_(int i)
538 {
539 ++lexBuf.len;
540 return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_());
541 }
542
543static void lexSkipLookahead() {
544 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
545 /* don't skip EOF. */
546 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
547 lexBuf.len--;
548 }
549 }
550
551static int lexLookahead() {
552 int c = (lexBuf.len)?
553 lexBuf.buf[lexBuf.getPtr]:
554 lexGeta();
555 /* do the \r\n -> \n or \r -> \n translation here */
556 if (c == '\r') {
557 int a = (lexBuf.len>1)?
558 lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]:
559 lexGeta_(1);
560 if (a == '\n') {
561 lexSkipLookahead();
562 }
563 lexBuf.buf[lexBuf.getPtr] = c = '\n';
564 }
565 else if (c == '\n') {
566 int a = (lexBuf.len>1)?
567 lexBuf.buf[lexBuf.getPtr+1]:
568 lexGeta_(1);
569 if (a == '\r') {
570 lexSkipLookahead();
571 }
572 lexBuf.buf[lexBuf.getPtr] = '\n';
573 }
574 return c;
575 }
576
577static int lexGetc() {
578 int c = lexLookahead();
579 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
580 /* EOF will remain in lookahead buffer */
581 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
582 lexBuf.len--;
583 }
584 return c;
585 }
586
587static void lexSkipLookaheadWord() {
588 if (lexBuf.strsLen <= lexBuf.len) {
589 lexBuf.len -= lexBuf.strsLen;
590 lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD;
591 }
592 }
593
594static void lexClearToken()
595 {
596 lexBuf.strsLen = 0;
597 }
598
599static void lexAppendc(int c)
600 {
601 lexBuf.strs[lexBuf.strsLen] = c;
602 /* append up to zero termination */
603 if (c == 0) return;
604 lexBuf.strsLen++;
605 if (lexBuf.strsLen > lexBuf.maxToken) {
606 /* double the token string size */
607 lexBuf.maxToken <<= 1;
608 lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken);
609 }
610 }
611
612static char* lexStr() {
613 return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1);
614 }
615
616static void lexSkipWhite() {
617 int c = lexLookahead();
618 while (c == ' ' || c == '\t') {
619 lexSkipLookahead();
620 c = lexLookahead();
621 }
622 }
623
624static char* lexGetWord() {
625 int c;
626 lexSkipWhite();
627 lexClearToken();
628 c = lexLookahead();
629 while (c != EOF && !strchr("\t\n ;:=",c)) {
630 lexAppendc(c);
631 lexSkipLookahead();
632 c = lexLookahead();
633 }
634 lexAppendc(0);
635 return lexStr();
636 }
637
638static void lexPushLookaheadc(int c) {
639 int putptr;
640 /* can't putback EOF, because it never leaves lookahead buffer */
641 if (c == EOF) return;
642 putptr = (int)lexBuf.getPtr - 1;
643 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
644 lexBuf.getPtr = putptr;
645 lexBuf.buf[putptr] = c;
646 lexBuf.len += 1;
647 }
648
649static char* lexLookaheadWord() {
650 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
651 / and thing bigger than that will stop the lookahead and return 0;
652 / leading white spaces are not recoverable.
653 */
654 int c;
655 int len = 0;
656 int curgetptr = 0;
657 lexSkipWhite();
658 lexClearToken();
659 curgetptr = (int)lexBuf.getPtr;// remember!
660 while (len < (MAX_LEX_LOOKAHEAD_0)) {
661 c = lexGetc();
662 len++;
663 if (c == EOF || strchr("\t\n ;:=", c)) {
664 lexAppendc(0);
665 /* restore lookahead buf. */
666 lexBuf.len += len;
667 lexBuf.getPtr = curgetptr;
668 return lexStr();
669 }
670 else
671 lexAppendc(c);
672 }
673 lexBuf.len += len;/* char that has been moved to lookahead buffer */
674 lexBuf.getPtr = curgetptr;
675 return 0;
676 }
677
678#ifdef _SUPPORT_LINE_FOLDING
679static void handleMoreRFC822LineBreak(int c) {
680 /* suport RFC 822 line break in cases like
681 *ADR: foo;
682 * morefoo;
683 * more foo;
684 */
685 if (c == ';') {
686 int a;
687 lexSkipLookahead();
688 /* skip white spaces */
689 a = lexLookahead();
690 while (a == ' ' || a == '\t') {
691 lexSkipLookahead();
692 a = lexLookahead();
693 }
694 if (a == '\n') {
695 lexSkipLookahead();
696 a = lexLookahead();
697 if (a == ' ' || a == '\t') {
698 /* continuation, throw away all the \n and spaces read so
699 * far
700 */
701 lexSkipWhite();
702 lexPushLookaheadc(';');
703 }
704 else {
705 lexPushLookaheadc('\n');
706 lexPushLookaheadc(';');
707 }
708 }
709 else {
710 lexPushLookaheadc(';');
711 }
712 }
713 }
714
715static char* lexGet1Value() {
716 int c;
717 lexSkipWhite();
718 c = lexLookahead();
719 lexClearToken();
720 while (c != EOF && c != ';') {
721 if (c == '\\' ) {
722 int a;
723 lexSkipLookahead();
724 a = lexLookahead();
725 if ( a != ';' ) {
726 lexAppendc('\\');
727 } else {
728 lexAppendc( ';' );
729 lexSkipLookahead();
730 }
731 } else if (c == '\n') {
732 int a;
733 lexSkipLookahead();
734 a = lexLookahead();
735 if (a == ' ' || a == '\t') {
736 lexAppendc(' ');
737 lexSkipLookahead();
738 }
739 else {
740 lexPushLookaheadc('\n');
741 break;
742 }
743 }
744 else {
745 lexAppendc(c);
746 lexSkipLookahead();
747 }
748 c = lexLookahead();
749 }
750 lexAppendc(0);
751 handleMoreRFC822LineBreak(c);
752 return c==EOF?0:lexStr();
753 }
754#endif
755
756static int match_begin_name(int end) {
757 char *n = lexLookaheadWord();
758 int token = ID;
759 if (n) {
760 if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
761 else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
762 else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
763 else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
764 deleteStr(n);
765 return token;
766 }
767 return 0;
768 }
769
770
771#ifdef INCLUDEMFC
772void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
773#else
774void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
775#endif
776 {
777 // initialize lex mode stack
778 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
779
780 // iniatialize lex buffer.
781 lexBuf.inputString = (char*) inputstring;
782 lexBuf.inputLen = inputlen;
783 lexBuf.curPos = 0;
784 lexBuf.inputFile = inputfile;
785
786 lexBuf.len = 0;
787 lexBuf.getPtr = 0;
788
789 lexBuf.maxToken = MAXTOKEN;
790 lexBuf.strs = (char*)malloc(MAXTOKEN);
791 lexBuf.strsLen = 0;
792
793 }
794
795static void finiLex() {
796 free(lexBuf.strs);
797 }
798
799
800/*-----------------------------------*/
801/* This parses and converts the base64 format for binary encoding into
802 * a decoded buffer (allocated with new). See RFC 1521.
803 */
804static char * lexGetDataFromBase64()
805 {
806 unsigned long bytesLen = 0, bytesMax = 0;
807 int quadIx = 0, pad = 0;
808 unsigned long trip = 0;
809 unsigned char b;
810 int c;
811 unsigned char *bytes = NULL;
812 unsigned char *oldBytes = NULL;
813
814 DBG_(("db: lexGetDataFromBase64\n"));
815 while (1) {
816 c = lexGetc();
817 if (c == '\n') {
818 ++mime_lineNum;
819 if (lexLookahead() == '\n') {
820 /* a '\n' character by itself means end of data */
821 break;
822 }
823 else continue; /* ignore '\n' */
824 }
825 else {
826 if ((c >= 'A') && (c <= 'Z'))
827 b = (unsigned char)(c - 'A');
828 else if ((c >= 'a') && (c <= 'z'))
829 b = (unsigned char)(c - 'a') + 26;
830 else if ((c >= '0') && (c <= '9'))
831 b = (unsigned char)(c - '0') + 52;
832 else if (c == '+')
833 b = 62;
834 else if (c == '/')
835 b = 63;
836 else if (c == '=') {
837 b = 0;
838 pad++;
839 } else if ((c == ' ') || (c == '\t')) {
840 continue;
841 } else { /* error condition */
842 if (bytes) free(bytes);
843 else if (oldBytes) free(oldBytes);
844 // error recovery: skip until 2 adjacent newlines.
845 DBG_(("db: invalid character 0x%x '%c'\n", c,c));
846 if (c != EOF) {
847 c = lexGetc();
848 while (c != EOF) {
849 if (c == '\n' && lexLookahead() == '\n') {
850 ++mime_lineNum;
851 break;
852 }
853 c = lexGetc();
854 }
855 }
856 return NULL;
857 }
858 trip = (trip << 6) | b;
859 if (++quadIx == 4) {
860 unsigned char outBytes[3];
861 int numOut;
862 int i;
863 for (i = 0; i < 3; i++) {
864 outBytes[2-i] = (unsigned char)(trip & 0xFF);
865 trip >>= 8;
866 }
867 numOut = 3 - pad;
868 if (bytesLen + numOut > bytesMax) {
869 if (!bytes) {
870 bytesMax = 1024;
871 bytes = (unsigned char*)malloc((size_t)bytesMax);
872 }
873 else {
874 bytesMax <<= 2;
875 oldBytes = bytes;
876 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
877 }
878 if (bytes == 0) {
879 mime_error("out of memory while processing BASE64 data\n");
880 }
881 }
882 if (bytes) {
883 memcpy(bytes + bytesLen, outBytes, numOut);
884 bytesLen += numOut;
885 }
886 trip = 0;
887 quadIx = 0;
888 }
889 }
890 } /* while */
891 DBG_(("db: bytesLen = %d\n", bytesLen));
892 /* kludge: all this won't be necessary if we have tree form
893 representation */
894 if (bytes) {
895 setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
896 free(bytes);
897 }
898 else if (oldBytes) {
899 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
900 free(oldBytes);
901 }
902 return 0;
903 }
904
905static int match_begin_end_name(int end) {
906 int token;
907 lexSkipWhite();
908 if (lexLookahead() != ':') return ID;
909 lexSkipLookahead();
910 lexSkipWhite();
911 token = match_begin_name(end);
912 if (token == ID) {
913 lexPushLookaheadc(':');
914 DBG_(("db: ID '%s'\n", yylval.str));
915 return ID;
916 }
917 else if (token != 0) {
918 lexSkipLookaheadWord();
919 deleteStr(yylval.str);
920 DBG_(("db: begin/end %d\n", token));
921 return token;
922 }
923 return 0;
924 }
925
926static char* lexGetQuotedPrintable()
927 {
928 char cur;
929
930 lexClearToken();
931 do {
932 cur = lexGetc();
933 switch (cur) {
934 case '=': {
935 int c = 0;
936 int next[2];
937 int i;
938 for (i = 0; i < 2; i++) {
939 next[i] = lexGetc();
940 if (next[i] >= '0' && next[i] <= '9')
941 c = c * 16 + next[i] - '0';
942 else if (next[i] >= 'A' && next[i] <= 'F')
943 c = c * 16 + next[i] - 'A' + 10;
944 else
945 break;
946 }
947 if (i == 0) {
948 /* single '=' follow by LINESEP is continuation sign? */
949 if (next[0] == '\n') {
950 ++mime_lineNum;
951 }
952 else {
953 lexPushLookaheadc('=');
954 goto EndString;
955 }
956 }
957 else if (i == 1) {
958 lexPushLookaheadc(next[1]);
959 lexPushLookaheadc(next[0]);
960 lexAppendc('=');
961 } else {
962 lexAppendc(c);
963 }
964 break;
965 } /* '=' */
966 case '\n': {
967 lexPushLookaheadc('\n');
968 goto EndString;
969 }
970 case (char)EOF:
971 break;
972 default:
973 lexAppendc(cur);
974 break;
975 } /* switch */
976 } while (cur != (char)EOF);
977
978EndString:
979 lexAppendc(0);
980 return lexStr();
981 } /* LexQuotedPrintable */
982
983static int yylex() {
984
985 int lexmode = LEXMODE();
986 if (lexmode == L_VALUES) {
987 int c = lexGetc();
988 if (c == ';') {
989 DBG_(("db: SEMICOLON\n"));
990 lexPushLookaheadc(c);
991 handleMoreRFC822LineBreak(c);
992 lexSkipLookahead();
993 return SEMICOLON;
994 }
995 else if (strchr("\n",c)) {
996 ++mime_lineNum;
997 /* consume all line separator(s) adjacent to each other */
998 c = lexLookahead();
999 while (strchr("\n",c)) {
1000 lexSkipLookahead();
1001 c = lexLookahead();
1002 ++mime_lineNum;
1003 }
1004 DBG_(("db: LINESEP\n"));
1005 return LINESEP;
1006 }
1007 else {
1008 char *p = 0;
1009 lexPushLookaheadc(c);
1010 if (lexWithinMode(L_BASE64)) {
1011 /* get each char and convert to bin on the fly... */
1012 p = lexGetDataFromBase64();
1013 yylval.str = p;
1014 return STRING;
1015 }
1016 else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
1017 p = lexGetQuotedPrintable();
1018 }
1019 else {
1020#ifdef _SUPPORT_LINE_FOLDING
1021 p = lexGet1Value();
1022#else
1023 p = lexGetStrUntil(";\n");
1024#endif
1025 }
1026 if (p) {
1027 DBG_(("db: STRING: '%s'\n", p));
1028 yylval.str = p;
1029 return STRING;
1030 }
1031 else return 0;
1032 }
1033 }
1034 else {
1035 /* normal mode */
1036 while (1) {
1037 int c = lexGetc();
1038 switch(c) {
1039 case ':': {
1040 /* consume all line separator(s) adjacent to each other */
1041 /* ignoring linesep immediately after colon. */
1042 c = lexLookahead();
1043 while (strchr("\n",c)) {
1044 lexSkipLookahead();
1045 c = lexLookahead();
1046 ++mime_lineNum;
1047 }
1048 DBG_(("db: COLON\n"));
1049 return COLON;
1050 }
1051 case ';':
1052 DBG_(("db: SEMICOLON\n"));
1053 return SEMICOLON;
1054 case '=':
1055 DBG_(("db: EQ\n"));
1056 return EQ;
1057 /* ignore whitespace in this mode */
1058 case '\t':
1059 case ' ': continue;
1060 case '\n': {
1061 ++mime_lineNum;
1062 continue;
1063 }
1064 case EOF: return 0;
1065 break;
1066 default: {
1067 lexPushLookaheadc(c);
1068 if (isalnum(c)) {
1069 char *t = lexGetWord();
1070 yylval.str = t;
1071 if (!qstricmp(t, "begin")) {
1072 return match_begin_end_name(0);
1073 }
1074 else if (!qstricmp(t,"end")) {
1075 return match_begin_end_name(1);
1076 }
1077 else {
1078 DBG_(("db: ID '%s'\n", t));
1079 return ID;
1080 }
1081 }
1082 else {
1083 /* unknow token */
1084 return 0;
1085 }
1086 break;
1087 }
1088 }
1089 }
1090 }
1091 return 0;
1092 }
1093
1094
1095/***************************************************************************/
1096 /*** Public Functions ****/
1097/***************************************************************************/
1098
1099static VObject* Parse_MIMEHelper()
1100 {
1101 ObjStackTop = -1;
1102 mime_numErrors = 0;
1103 mime_lineNum = 1;
1104 vObjList = 0;
1105 curObj = 0;
1106
1107 if (yyparse() != 0)
1108 return 0;
1109
1110 finiLex();
1111 return vObjList;
1112 }
1113
1114/*--------------------------------------------*/
1115DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len)
1116 {
1117 initLex(input, len, 0);
1118 return Parse_MIMEHelper();
1119 }
1120
1121
1122#if INCLUDEMFC
1123
1124DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file)
1125 {
1126 unsigned long startPos;
1127 VObject *result;
1128
1129 initLex(0,-1,file);
1130 startPos = file->GetPosition();
1131 if (!(result = Parse_MIMEHelper()))
1132 file->Seek(startPos, CFile::begin);
1133 return result;
1134 }
1135
1136#else
1137
1138VObject* Parse_MIME_FromFile(FILE *file)
1139 {
1140 VObject *result;
1141 long startPos;
1142
1143 initLex(0,(unsigned long)-1,file);
1144 startPos = ftell(file);
1145 if (!(result = Parse_MIMEHelper())) {
1146 fseek(file,startPos,SEEK_SET);
1147 }
1148 return result;
1149 }
1150
1151DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname)
1152 {
1153 QFileDirect f( fname );
1154 if ( !f.open( IO_ReadOnly ) ) {
1155 qWarning("Unable to open mime for reading %s", fname);
1156 return 0;
1157 }
1158
1159 return Parse_MIME_FromFile( f.directHandle() );
1160 }
1161
1162#endif
1163
1164/*-------------------------------------*/
1165
1166static MimeErrorHandler mimeErrorHandler;
1167
1168DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me)
1169 {
1170 mimeErrorHandler = me;
1171 }
1172
1173void mime_error(char *s)
1174 {
1175 char msg[256];
1176 if (mimeErrorHandler) {
1177 sprintf(msg,"%s at line %d", s, mime_lineNum);
1178 mimeErrorHandler(msg);
1179 }
1180 }
1181
1182void mime_error_(char *s)
1183 {
1184 if (mimeErrorHandler) {
1185 mimeErrorHandler(s);
1186 }
1187 }
1188
1189#line 1192 "y.tab.c"
1190#define YYABORT goto yyabort
1191#define YYREJECT goto yyabort
1192#define YYACCEPT goto yyaccept
1193#define YYERROR goto yyerrlab
1194int
1195yyparse()
1196{
1197 register int yym, yyn, yystate;
1198#if YYDEBUG
1199 register char *yys;
1200 extern char *getenv();
1201
1202 if (yys = getenv("YYDEBUG"))
1203 {
1204 yyn = *yys;
1205 if (yyn >= '0' && yyn <= '9')
1206 yydebug = yyn - '0';
1207 }
1208#endif
1209
1210 yynerrs = 0;
1211 yyerrflag = 0;
1212 yychar = (-1);
1213
1214 yyssp = yyss;
1215 yyvsp = yyvs;
1216 *yyssp = yystate = 0;
1217
1218yyloop:
1219 if (yyn = yydefred[yystate]) goto yyreduce;
1220 if (yychar < 0)
1221 {
1222 if ((yychar = yylex()) < 0) yychar = 0;
1223#if YYDEBUG
1224 if (yydebug)
1225 {
1226 yys = 0;
1227 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1228 if (!yys) yys = "illegal-symbol";
1229 printf("%sdebug: state %d, reading %d (%s)\n",
1230 YYPREFIX, yystate, yychar, yys);
1231 }
1232#endif
1233 }
1234 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1235 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1236 {
1237#if YYDEBUG
1238 if (yydebug)
1239 printf("%sdebug: state %d, shifting to state %d\n",
1240 YYPREFIX, yystate, yytable[yyn]);
1241#endif
1242 if (yyssp >= yyss + yystacksize - 1)
1243 {
1244 goto yyoverflow;
1245 }
1246 *++yyssp = yystate = yytable[yyn];
1247 *++yyvsp = yylval;
1248 yychar = (-1);
1249 if (yyerrflag > 0) --yyerrflag;
1250 goto yyloop;
1251 }
1252 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1253 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1254 {
1255 yyn = yytable[yyn];
1256 goto yyreduce;
1257 }
1258 if (yyerrflag) goto yyinrecovery;
1259#ifdef lint
1260 goto yynewerror;
1261#endif
1262yynewerror:
1263 yyerror("syntax error");
1264#ifdef lint
1265 goto yyerrlab;
1266#endif
1267yyerrlab:
1268 ++yynerrs;
1269yyinrecovery:
1270 if (yyerrflag < 3)
1271 {
1272 yyerrflag = 3;
1273 for (;;)
1274 {
1275 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1276 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1277 {
1278#if YYDEBUG
1279 if (yydebug)
1280 printf("%sdebug: state %d, error recovery shifting\
1281 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1282#endif
1283 if (yyssp >= yyss + yystacksize - 1)
1284 {
1285 goto yyoverflow;
1286 }
1287 *++yyssp = yystate = yytable[yyn];
1288 *++yyvsp = yylval;
1289 goto yyloop;
1290 }
1291 else
1292 {
1293#if YYDEBUG
1294 if (yydebug)
1295 printf("%sdebug: error recovery discarding state %d\n",
1296 YYPREFIX, *yyssp);
1297#endif
1298 if (yyssp <= yyss) goto yyabort;
1299 --yyssp;
1300 --yyvsp;
1301 }
1302 }
1303 }
1304 else
1305 {
1306 if (yychar == 0) goto yyabort;
1307#if YYDEBUG
1308 if (yydebug)
1309 {
1310 yys = 0;
1311 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1312 if (!yys) yys = "illegal-symbol";
1313 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1314 YYPREFIX, yystate, yychar, yys);
1315 }
1316#endif
1317 yychar = (-1);
1318 goto yyloop;
1319 }
1320yyreduce:
1321#if YYDEBUG
1322 if (yydebug)
1323 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1324 YYPREFIX, yystate, yyn, yyrule[yyn]);
1325#endif
1326 yym = yylen[yyn];
1327 yyval = yyvsp[1-yym];
1328 switch (yyn)
1329 {
1330case 2:
1331#line 217 "vcc.y"
1332{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
1333break;
1334case 3:
1335#line 219 "vcc.y"
1336{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
1337break;
1338case 6:
1339#line 228 "vcc.y"
1340{
1341 lexPushMode(L_VCARD);
1342 if (!pushVObject(VCCardProp)) YYERROR;
1343 }
1344break;
1345case 7:
1346#line 233 "vcc.y"
1347{
1348 lexPopMode(0);
1349 yyval.vobj = popVObject();
1350 }
1351break;
1352case 8:
1353#line 238 "vcc.y"
1354{
1355 lexPushMode(L_VCARD);
1356 if (!pushVObject(VCCardProp)) YYERROR;
1357 }
1358break;
1359case 9:
1360#line 243 "vcc.y"
1361{
1362 lexPopMode(0);
1363 yyval.vobj = popVObject();
1364 }
1365break;
1366case 12:
1367#line 254 "vcc.y"
1368{
1369 lexPushMode(L_VALUES);
1370 }
1371break;
1372case 13:
1373#line 258 "vcc.y"
1374{
1375 if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
1376 lexPopMode(0);
1377 lexPopMode(0);
1378 }
1379break;
1380case 15:
1381#line 267 "vcc.y"
1382{
1383 enterProps(yyvsp[0].str);
1384 }
1385break;
1386case 17:
1387#line 272 "vcc.y"
1388{
1389 enterProps(yyvsp[0].str);
1390 }
1391break;
1392case 21:
1393#line 285 "vcc.y"
1394{
1395 enterAttr(yyvsp[0].str,0);
1396 }
1397break;
1398case 22:
1399#line 289 "vcc.y"
1400{
1401 enterAttr(yyvsp[-2].str,yyvsp[0].str);
1402
1403 }
1404break;
1405case 24:
1406#line 298 "vcc.y"
1407{ enterValues(yyvsp[-1].str); }
1408break;
1409case 26:
1410#line 300 "vcc.y"
1411{ enterValues(yyvsp[0].str); }
1412break;
1413case 28:
1414#line 305 "vcc.y"
1415{ yyval.str = 0; }
1416break;
1417case 29:
1418#line 310 "vcc.y"
1419{ if (!pushVObject(VCCalProp)) YYERROR; }
1420break;
1421case 30:
1422#line 313 "vcc.y"
1423{ yyval.vobj = popVObject(); }
1424break;
1425case 31:
1426#line 315 "vcc.y"
1427{ if (!pushVObject(VCCalProp)) YYERROR; }
1428break;
1429case 32:
1430#line 317 "vcc.y"
1431{ yyval.vobj = popVObject(); }
1432break;
1433case 38:
1434#line 332 "vcc.y"
1435{
1436 lexPushMode(L_VEVENT);
1437 if (!pushVObject(VCEventProp)) YYERROR;
1438 }
1439break;
1440case 39:
1441#line 338 "vcc.y"
1442{
1443 lexPopMode(0);
1444 popVObject();
1445 }
1446break;
1447case 40:
1448#line 343 "vcc.y"
1449{
1450 lexPushMode(L_VEVENT);
1451 if (!pushVObject(VCEventProp)) YYERROR;
1452 }
1453break;
1454case 41:
1455#line 348 "vcc.y"
1456{
1457 lexPopMode(0);
1458 popVObject();
1459 }
1460break;
1461case 42:
1462#line 356 "vcc.y"
1463{
1464 lexPushMode(L_VTODO);
1465 if (!pushVObject(VCTodoProp)) YYERROR;
1466 }
1467break;
1468case 43:
1469#line 362 "vcc.y"
1470{
1471 lexPopMode(0);
1472 popVObject();
1473 }
1474break;
1475case 44:
1476#line 367 "vcc.y"
1477{
1478 lexPushMode(L_VTODO);
1479 if (!pushVObject(VCTodoProp)) YYERROR;
1480 }
1481break;
1482case 45:
1483#line 372 "vcc.y"
1484{
1485 lexPopMode(0);
1486 popVObject();
1487 }
1488break;
1489#line 1492 "y.tab.c"
1490 }
1491 yyssp -= yym;
1492 yystate = *yyssp;
1493 yyvsp -= yym;
1494 yym = yylhs[yyn];
1495 if (yystate == 0 && yym == 0)
1496 {
1497#if YYDEBUG
1498 if (yydebug)
1499 printf("%sdebug: after reduction, shifting from state 0 to\
1500 state %d\n", YYPREFIX, YYFINAL);
1501#endif
1502 yystate = YYFINAL;
1503 *++yyssp = YYFINAL;
1504 *++yyvsp = yyval;
1505 if (yychar < 0)
1506 {
1507 if ((yychar = yylex()) < 0) yychar = 0;
1508#if YYDEBUG
1509 if (yydebug)
1510 {
1511 yys = 0;
1512 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1513 if (!yys) yys = "illegal-symbol";
1514 printf("%sdebug: state %d, reading %d (%s)\n",
1515 YYPREFIX, YYFINAL, yychar, yys);
1516 }
1517#endif
1518 }
1519 if (yychar == 0) goto yyaccept;
1520 goto yyloop;
1521 }
1522 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1523 yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1524 yystate = yytable[yyn];
1525 else
1526 yystate = yydgoto[yym];
1527#if YYDEBUG
1528 if (yydebug)
1529 printf("%sdebug: after reduction, shifting from state %d \
1530to state %d\n", YYPREFIX, *yyssp, yystate);
1531#endif
1532 if (yyssp >= yyss + yystacksize - 1)
1533 {
1534 goto yyoverflow;
1535 }
1536 *++yyssp = yystate;
1537 *++yyvsp = yyval;
1538 goto yyloop;
1539yyoverflow:
1540 yyerror("yacc stack overflow");
1541yyabort:
1542 return (1);
1543yyaccept:
1544 return (0);
1545}