Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

vcc_yacc.cpp

Go to the documentation of this file.
00001 #ifndef lint
00002 static char yysccsid[] = "@(#)yaccpar   1.9 (Berkeley) 02/21/93";
00003 #endif
00004 #define YYBYACC 1
00005 #define YYMAJOR 1
00006 #define YYMINOR 9
00007 #define yyclearin (yychar=(-1))
00008 #define yyerrok (yyerrflag=0)
00009 #define YYRECOVERING (yyerrflag!=0)
00010 #define YYPREFIX "yy"
00011 #line 1 "vcc.y"
00012 
00013 
00014 /***************************************************************************
00015 (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
00016 Business Machines Corporation and Siemens Rolm Communications Inc.
00017 
00018 For purposes of this license notice, the term Licensors shall mean,
00019 collectively, Apple Computer, Inc., AT&T Corp., International
00020 Business Machines Corporation and Siemens Rolm Communications Inc.
00021 The term Licensor shall mean any of the Licensors.
00022 
00023 Subject to acceptance of the following conditions, permission is hereby
00024 granted by Licensors without the need for written agreement and without
00025 license or royalty fees, to use, copy, modify and distribute this
00026 software for any purpose.
00027 
00028 The above copyright notice and the following four paragraphs must be
00029 reproduced in all copies of this software and any software including
00030 this software.
00031 
00032 THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
00033 ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
00034 MODIFICATIONS.
00035 
00036 IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
00037 INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
00038 OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00039 DAMAGE.
00040 
00041 EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
00042 INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
00043 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00044 PURPOSE.
00045 
00046 The software is provided with RESTRICTED RIGHTS.  Use, duplication, or
00047 disclosure by the government are subject to restrictions set forth in
00048 DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
00049 
00050 ***************************************************************************/
00051 
00052 /*
00053  * src: vcc.c
00054  * doc: Parser for vCard and vCalendar. Note that this code is
00055  * generated by a yacc parser generator. Generally it should not
00056  * be edited by hand. The real source is vcc.y. The #line directives
00057  * can be commented out here to make it easier to trace through
00058  * in a debugger. However, if a bug is found it should
00059  * be fixed in vcc.y and this file regenerated.
00060  */
00061 
00062 
00063 /* debugging utilities */
00064 #define __DEBUG 1
00065 
00066 #if __DEBUG
00067 #define DBG_(x) printf x
00068 #else
00069 #define DBG_(x)
00070 #endif
00071 
00072 /****  External Functions  ****/
00073 
00074 /* assign local name to parser variables and functions so that
00075    we can use more than one yacc based parser.
00076 */
00077 
00078 #if 0
00079 #define yyparse mime_parse
00080 #define yylex mime_lex
00081 #define yyerror mime_error
00082 #define yychar mime_char
00083 /* #define p_yyval p_mime_val */
00084 #undef yyval
00085 #define yyval mime_yyval
00086 /* #define p_yylval p_mime_lval */
00087 #undef yylval
00088 #define yylval mime_yylval
00089 #define yydebug mime_debug
00090 #define yynerrs mime_nerrs
00091 #define yyerrflag mime_errflag
00092 #define yyss mime_ss
00093 #define yyssp mime_ssp
00094 #define yyvs mime_vs
00095 #define yyvsp mime_vsp
00096 #define yylhs mime_lhs
00097 #define yylen mime_len
00098 #define yydefred mime_defred
00099 #define yydgoto mime_dgoto
00100 #define yysindex mime_sindex
00101 #define yyrindex mime_rindex
00102 #define yygindex mime_gindex
00103 #define yytable mime_table
00104 #define yycheck mime_check
00105 #define yyname mime_name
00106 #define yyrule mime_rule
00107 #ifdef YYPREFIX
00108 #undef YYPREFIX
00109 #endif
00110 #define YYPREFIX "mime_"
00111 #endif
00112 
00113 
00114 #ifndef _NO_LINE_FOLDING
00115 #define _SUPPORT_LINE_FOLDING 1
00116 #endif
00117 
00118 /* undef below if compile with MFC */
00119 /* #define INCLUDEMFC 1 */
00120 
00121 #if defined(WIN32) || defined(_WIN32)
00122 #ifdef INCLUDEMFC
00123 #include <afx.h>
00124 #endif
00125 #endif
00126 
00127 #include <string.h>
00128 #ifndef __MWERKS__
00129 #include <stdlib.h>
00130 #endif
00131 #include <stdio.h>
00132 #include <stdlib.h>
00133 #include <ctype.h>
00134 
00135 /*#ifdef PALMTOPCENTER*/
00136 /*#include <qpe/vobject_p.h>*/
00137 /*#else*/
00138 #include "vobject_p.h"
00139 /*#endif*/
00140 
00141 /****  Types, Constants  ****/
00142 
00143 #define YYDEBUG         0       /* 1 to compile in some debugging code */
00144 #define MAXTOKEN        256     /* maximum token (line) length */
00145 #define YYSTACKSIZE     100     /* ~unref ?*/
00146 #define MAXLEVEL        10      /* max # of nested objects parseable */
00147                                 /* (includes outermost) */
00148 
00149 
00150 /****  Global Variables  ****/
00151 int q_DontDecodeBase64Photo = 0;
00152 int mime_lineNum, mime_numErrors; /* yyerror() can use these */
00153 static VObject* vObjList;
00154 static VObject *curProp;
00155 static VObject *curObj;
00156 static VObject* ObjStack[MAXLEVEL];
00157 static int ObjStackTop;
00158 
00159 
00160 /* A helpful utility for the rest of the app. */
00161 #if __CPLUSPLUS__
00162 extern "C" {
00163 #endif
00164 
00165     extern void yyerror(char *s);
00166 
00167 #if __CPLUSPLUS__
00168     };
00169 #endif
00170 
00171 int yyparse();
00172 
00173 enum LexMode {
00174         L_NORMAL,
00175         L_PARAMWORD,
00176         L_VCARD,
00177         L_VCAL,
00178         L_VEVENT,
00179         L_VTODO,
00180         L_VALUES,
00181         L_BASE64,
00182         L_QUOTED_PRINTABLE
00183         };
00184 
00185 /****  Private Forward Declarations  ****/
00186 static int pushVObject(const char *prop);
00187 static VObject* popVObject();
00188 static void lexPopMode(int top);
00189 static int lexWithinMode(enum LexMode mode);
00190 static void lexPushMode(enum LexMode mode);
00191 static void enterProps(const char *s);
00192 static void enterAttr(const char *s1, const char *s2);
00193 static void enterValues(const char *value);
00194 #define mime_error yyerror
00195 void mime_error(char *s);
00196 void mime_error_(char *s);
00197 
00198 #line 193 "vcc.y"
00199 typedef union {
00200     char *str;
00201     VObject *vobj;
00202     } YYSTYPE;
00203 #line 204 "y.tab.c"
00204 #define EQ 257
00205 #define COLON 258
00206 #define DOT 259
00207 #define SEMICOLON 260
00208 #define SPACE 261
00209 #define HTAB 262
00210 #define LINESEP 263
00211 #define NEWLINE 264
00212 #define BEGIN_VCARD 265
00213 #define END_VCARD 266
00214 #define BEGIN_VCAL 267
00215 #define END_VCAL 268
00216 #define BEGIN_VEVENT 269
00217 #define END_VEVENT 270
00218 #define BEGIN_VTODO 271
00219 #define END_VTODO 272
00220 #define ID 273
00221 #define STRING 274
00222 #define YYERRCODE 256
00223 short yylhs[] = {                                        -1,
00224     0,    6,    6,    5,    5,    8,    3,    9,    3,    7,
00225     7,   13,   10,   10,   15,   11,   11,   14,   14,   16,
00226    17,   18,   17,    1,   19,   12,   12,    2,    2,   21,
00227     4,   22,    4,   20,   20,   23,   23,   23,   26,   24,
00228    27,   24,   28,   25,   29,   25,
00229 };
00230 short yylen[] = {                                         2,
00231     1,    2,    1,    1,    1,    0,    4,    0,    3,    2,
00232     1,    0,    5,    1,    0,    3,    1,    2,    1,    2,
00233     1,    0,    4,    1,    0,    4,    1,    1,    0,    0,
00234     4,    0,    3,    2,    1,    1,    1,    1,    0,    4,
00235     0,    3,    0,    4,    0,    3,
00236 };
00237 short yydefred[] = {                                      0,
00238     0,    0,    0,    4,    5,    3,    0,    0,    0,    0,
00239     0,    2,   14,   24,    0,    0,   11,    0,    9,    0,
00240     0,    0,    0,   35,   36,   37,   33,    0,    7,   10,
00241    12,    0,    0,    0,    0,   31,   34,    0,    0,   19,
00242     0,    0,   42,    0,   46,    0,   20,   18,   28,    0,
00243     0,   40,   44,   22,   25,   13,    0,    0,   23,   26,
00244 };
00245 short yydgoto[] = {                                       3,
00246    15,   50,    4,    5,    6,    7,   22,    8,    9,   17,
00247    18,   51,   41,   39,   28,   40,   47,   57,   58,   23,
00248    10,   11,   24,   25,   26,   32,   33,   34,   35,
00249 };
00250 short yysindex[] = {                                   -255,
00251     0,    0,    0,    0,    0,    0, -255, -215, -257, -234,
00252  -245,    0,    0,    0,    0, -242,    0, -210,    0,    0,
00253     0, -215, -253,    0,    0,    0,    0, -247,    0,    0,
00254     0, -215, -227, -215, -226,    0,    0, -221, -247,    0,
00255  -211, -237,    0, -218,    0, -204,    0,    0,    0, -198,
00256  -199,    0,    0,    0,    0,    0, -221, -211,    0,    0,
00257 };
00258 short yyrindex[] = {                                      0,
00259  -216, -239,    0,    0,    0,    0,   65,    0,    0,    0,
00260     0,    0,    0,    0, -213,    0,    0,    0,    0, -214,
00261  -212, -264,    0,    0,    0,    0,    0,    0,    0,    0,
00262     0,    0,    0,    0,    0,    0,    0,    0, -192,    0,
00263  -252,    0,    0,    0,    0, -209,    0,    0,    0, -196,
00264     0,    0,    0,    0,    0,    0,    0, -252,    0,    0,
00265 };
00266 short yygindex[] = {                                      0,
00267   -36,    0,    0,    0,   61,    0,   -7,    0,    0,  -16,
00268     0,   11,    0,    0,    0,   31,    0,    0,    0,    0,
00269     0,    0,   48,    0,    0,    0,    0,    0,    0,
00270 };
00271 #define YYTABLESIZE 71
00272 short yytable[] = {                                      30,
00273    16,   46,   13,   38,   38,   30,   38,   29,   19,    1,
00274    29,    2,   38,   13,   36,   20,   30,   21,   13,   14,
00275    59,   13,   27,   29,   42,   30,   44,   30,   32,   30,
00276    14,   30,   52,   30,   20,   14,   21,   13,   14,    6,
00277    13,   39,   43,   43,   17,   45,   15,   31,   21,    8,
00278    21,   14,   54,   53,   14,   41,    6,   14,   39,   45,
00279    43,   55,   49,   56,    1,   16,   27,   12,   60,   48,
00280    37,
00281 };
00282 short yycheck[] = {                                      16,
00283     8,   38,  256,  268,  269,   22,  271,  260,  266,  265,
00284   263,  267,  260,  256,  268,  269,  256,  271,  256,  273,
00285    57,  256,  268,  266,   32,   42,   34,   44,  268,  269,
00286   273,  271,  270,  273,  269,  273,  271,  256,  273,  256,
00287   256,  256,  270,  256,  258,  272,  260,  258,  258,  266,
00288   260,  273,  257,  272,  273,  270,  273,  273,  273,  272,
00289   273,  260,  274,  263,    0,  258,  263,    7,   58,   39,
00290    23,
00291 };
00292 #define YYFINAL 3
00293 #ifndef YYDEBUG
00294 #define YYDEBUG 0
00295 #endif
00296 #define YYMAXTOKEN 274
00297 #if YYDEBUG
00298 char *yyname[] = {
00299 "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,
00300 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,0,
00301 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,0,
00302 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,0,
00303 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,0,
00304 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,0,
00305 0,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",
00306 "SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL",
00307 "END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING",
00308 };
00309 char *yyrule[] = {
00310 "$accept : mime",
00311 "mime : vobjects",
00312 "vobjects : vobjects vobject",
00313 "vobjects : vobject",
00314 "vobject : vcard",
00315 "vobject : vcal",
00316 "$$1 :",
00317 "vcard : BEGIN_VCARD $$1 items END_VCARD",
00318 "$$2 :",
00319 "vcard : BEGIN_VCARD $$2 END_VCARD",
00320 "items : items item",
00321 "items : item",
00322 "$$3 :",
00323 "item : prop COLON $$3 values LINESEP",
00324 "item : error",
00325 "$$4 :",
00326 "prop : name $$4 attr_params",
00327 "prop : name",
00328 "attr_params : attr_params attr_param",
00329 "attr_params : attr_param",
00330 "attr_param : SEMICOLON attr",
00331 "attr : name",
00332 "$$5 :",
00333 "attr : name EQ $$5 name",
00334 "name : ID",
00335 "$$6 :",
00336 "values : value SEMICOLON $$6 values",
00337 "values : value",
00338 "value : STRING",
00339 "value :",
00340 "$$7 :",
00341 "vcal : BEGIN_VCAL $$7 calitems END_VCAL",
00342 "$$8 :",
00343 "vcal : BEGIN_VCAL $$8 END_VCAL",
00344 "calitems : calitems calitem",
00345 "calitems : calitem",
00346 "calitem : eventitem",
00347 "calitem : todoitem",
00348 "calitem : items",
00349 "$$9 :",
00350 "eventitem : BEGIN_VEVENT $$9 items END_VEVENT",
00351 "$$10 :",
00352 "eventitem : BEGIN_VEVENT $$10 END_VEVENT",
00353 "$$11 :",
00354 "todoitem : BEGIN_VTODO $$11 items END_VTODO",
00355 "$$12 :",
00356 "todoitem : BEGIN_VTODO $$12 END_VTODO",
00357 };
00358 #endif
00359 #ifdef YYSTACKSIZE
00360 #undef YYMAXDEPTH
00361 #define YYMAXDEPTH YYSTACKSIZE
00362 #else
00363 #ifdef YYMAXDEPTH
00364 #define YYSTACKSIZE YYMAXDEPTH
00365 #else
00366 #define YYSTACKSIZE 500
00367 #define YYMAXDEPTH 500
00368 #endif
00369 #endif
00370 int yydebug;
00371 int yynerrs;
00372 int yyerrflag;
00373 int yychar;
00374 short *yyssp;
00375 YYSTYPE *yyvsp;
00376 YYSTYPE yyval;
00377 YYSTYPE yylval;
00378 short yyss[YYSTACKSIZE];
00379 YYSTYPE yyvs[YYSTACKSIZE];
00380 #define yystacksize YYSTACKSIZE
00381 #line 390 "vcc.y"
00382 
00383 /*------------------------------------*/
00384 static int pushVObject(const char *prop)
00385     {
00386     VObject *newObj;
00387     if (ObjStackTop == MAXLEVEL)
00388         return FALSE;
00389 
00390     ObjStack[++ObjStackTop] = curObj;
00391 
00392     if (curObj) {
00393         newObj = addProp(curObj,prop);
00394         curObj = newObj;
00395         }
00396     else
00397         curObj = newVObject(prop);
00398 
00399     return TRUE;
00400     }
00401 
00402 
00403 /*---------------------------------------*/
00404 /* This pops the recently built vCard off the stack and returns it. */
00405 static VObject* popVObject()
00406     {
00407     VObject *oldObj;
00408     if (ObjStackTop < 0) {
00409         yyerror("pop on empty Object Stack\n");
00410         return 0;
00411         }
00412     oldObj = curObj;
00413     curObj = ObjStack[ObjStackTop--];
00414 
00415     return oldObj;
00416     }
00417 
00418 
00419 static void enterValues(const char *value)
00420     {
00421     if (fieldedProp && *fieldedProp) {
00422         if (value) {
00423             addPropValue(curProp,*fieldedProp,value);
00424             }
00425         /* else this field is empty, advance to next field */
00426         fieldedProp++;
00427         }
00428     else {
00429         if (value) {
00430             setVObjectStringZValue_(curProp,strdup( value ));
00431             }
00432         }
00433     deleteStr(value);
00434     }
00435 
00436 static void enterProps(const char *s)
00437     {
00438     curProp = addGroup(curObj,s);
00439     deleteStr(s);
00440     }
00441 
00442 static void enterAttr(const char *s1, const char *s2)
00443     {
00444     const char *p1, *p2=0;
00445     p1 = lookupProp_(s1);
00446     if (s2) {
00447         VObject *a;
00448         p2 = lookupProp_(s2);
00449         a = addProp(curProp,p1);
00450         setVObjectStringZValue(a,p2);
00451         }
00452     else
00453         addProp(curProp,p1);
00454     /* Lookup strings so we can quickly use pointer comparison */
00455     static const char* base64 = lookupProp_(VCBase64Prop);
00456     static const char* qp = lookupProp_(VCQuotedPrintableProp);
00457     static const char* photo = lookupProp_(VCPhotoProp);
00458     static const char* encoding = lookupProp_(VCEncodingProp);
00459     if ((!q_DontDecodeBase64Photo || vObjectName(curProp) != photo)
00460         && (p1 == base64 || p1 == encoding && p2 == base64))
00461         lexPushMode(L_BASE64);
00462     else if (p1 == qp || p1 == encoding && p2 == qp)
00463         lexPushMode(L_QUOTED_PRINTABLE);
00464     deleteStr(s1); deleteStr(s2);
00465     }
00466 
00467 
00468 #define MAX_LEX_LOOKAHEAD_0 32
00469 #define MAX_LEX_LOOKAHEAD 64
00470 #define MAX_LEX_MODE_STACK_SIZE 10
00471 #define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
00472 
00473 struct LexBuf {
00474         /* input */
00475 #ifdef INCLUDEMFC
00476     CFile *inputFile;
00477 #else
00478     FILE *inputFile;
00479 #endif
00480     char *inputString;
00481     unsigned long curPos;
00482     unsigned long inputLen;
00483         /* lookahead buffer */
00484         /*   -- lookahead buffer is short instead of char so that EOF
00485          /      can be represented correctly.
00486         */
00487     unsigned long len;
00488     short buf[MAX_LEX_LOOKAHEAD];
00489     unsigned long getPtr;
00490         /* context stack */
00491     unsigned long lexModeStackTop;
00492     enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE];
00493         /* token buffer */
00494     unsigned long maxToken;
00495     char *strs;
00496     unsigned long strsLen;
00497     } lexBuf;
00498 
00499 static void lexPushMode(enum LexMode mode)
00500     {
00501     if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1))
00502         yyerror("lexical context stack overflow");
00503     else {
00504         lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
00505         }
00506     }
00507 
00508 static void lexPopMode(int top)
00509     {
00510     /* special case of pop for ease of error recovery -- this
00511         version will never underflow */
00512     if (top)
00513         lexBuf.lexModeStackTop = 0;
00514     else
00515         if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--;
00516     }
00517 
00518 static int lexWithinMode(enum LexMode mode) {
00519     unsigned long i;
00520     for (i=0;i<lexBuf.lexModeStackTop;i++)
00521         if (mode == lexBuf.lexModeStack[i]) return 1;
00522     return 0;
00523     }
00524 
00525 static int lexGetc_()
00526     {
00527     /* get next char from input, no buffering. */
00528     if (lexBuf.curPos == lexBuf.inputLen)
00529         return EOF;
00530     else if (lexBuf.inputString)
00531         return *(lexBuf.inputString + lexBuf.curPos++);
00532     else {
00533 #ifdef INCLUDEMFC
00534         char result;
00535         return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF;
00536 #else
00537         return fgetc(lexBuf.inputFile);
00538 #endif
00539         }
00540     }
00541 
00542 static int lexGeta()
00543     {
00544     ++lexBuf.len;
00545     return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
00546     }
00547 
00548 static int lexGeta_(int i)
00549     {
00550     ++lexBuf.len;
00551     return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_());
00552     }
00553 
00554 static void lexSkipLookahead() {
00555     if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
00556         /* don't skip EOF. */
00557         lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
00558         lexBuf.len--;
00559         }
00560     }
00561 
00562 static int lexLookahead() {
00563     int c = (lexBuf.len)?
00564         lexBuf.buf[lexBuf.getPtr]:
00565         lexGeta();
00566     /* do the \r\n -> \n or \r -> \n translation here */
00567     if (c == '\r') {
00568         int a = (lexBuf.len>1)?
00569             lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]:
00570             lexGeta_(1);
00571         if (a == '\n') {
00572             lexSkipLookahead();
00573             }
00574         lexBuf.buf[lexBuf.getPtr] = c = '\n';
00575         }
00576     else if (c == '\n') {
00577         int a = (lexBuf.len>1)?
00578             lexBuf.buf[lexBuf.getPtr+1]:
00579             lexGeta_(1);
00580         if (a == '\r') {
00581             lexSkipLookahead();
00582             }
00583         lexBuf.buf[lexBuf.getPtr] = '\n';
00584         }
00585     return c;
00586     }
00587 
00588 static int lexGetc() {
00589     int c = lexLookahead();
00590     if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
00591         /* EOF will remain in lookahead buffer */
00592         lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
00593         lexBuf.len--;
00594         }
00595     return c;
00596     }
00597 
00598 static void lexSkipLookaheadWord() {
00599     if (lexBuf.strsLen <= lexBuf.len) {
00600         lexBuf.len -= lexBuf.strsLen;
00601         lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD;
00602         }
00603     }
00604 
00605 static void lexClearToken()
00606     {
00607     lexBuf.strsLen = 0;
00608     }
00609 
00610 static void lexAppendc(int c)
00611     {
00612     lexBuf.strs[lexBuf.strsLen] = c;
00613     /* append up to zero termination */
00614     if (c == 0) return;
00615     lexBuf.strsLen++;
00616     if (lexBuf.strsLen > lexBuf.maxToken) {
00617         /* double the token string size */
00618         lexBuf.maxToken <<= 1;
00619         lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken);
00620         }
00621     }
00622 
00623 static char* lexStr() {
00624     return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1);
00625     }
00626 
00627 static void lexSkipWhite() {
00628     int c = lexLookahead();
00629     while (c == ' ' || c == '\t') {
00630         lexSkipLookahead();
00631         c = lexLookahead();
00632         }
00633     }
00634 
00635 static char* lexGetWord() {
00636     int c;
00637     lexSkipWhite();
00638     lexClearToken();
00639     c = lexLookahead();
00640     while (c != EOF && !strchr("\t\n ;:=",c)) {
00641         lexAppendc(c);
00642         lexSkipLookahead();
00643         c = lexLookahead();
00644         }
00645     lexAppendc(0);
00646     return lexStr();
00647     }
00648 
00649 static char* lexGetParamWord()
00650 {
00651     int c;
00652     lexClearToken();
00653     c = lexLookahead();
00654     while (c >= ' ' && c < 127 && !strchr("[]:=,.;",c)) {
00655         lexAppendc(c);
00656         lexSkipLookahead();
00657         c = lexLookahead();
00658     }
00659     lexAppendc(0);
00660     return lexStr();
00661 }
00662 
00663 static void lexPushLookaheadc(int c) {
00664     int putptr;
00665     /* can't putback EOF, because it never leaves lookahead buffer */
00666     if (c == EOF) return;
00667     putptr = (int)lexBuf.getPtr - 1;
00668     if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
00669     lexBuf.getPtr = putptr;
00670     lexBuf.buf[putptr] = c;
00671     lexBuf.len += 1;
00672     }
00673 
00674 static char* lexLookaheadWord() {
00675     /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
00676      /  and thing bigger than that will stop the lookahead and return 0;
00677      / leading white spaces are not recoverable.
00678      */
00679     int c;
00680     int len = 0;
00681     int curgetptr = 0;
00682     lexSkipWhite();
00683     lexClearToken();
00684     curgetptr = (int)lexBuf.getPtr;     // remember!
00685     while (len < (MAX_LEX_LOOKAHEAD_0)) {
00686         c = lexGetc();
00687         len++;
00688         if (c == EOF || strchr("\t\n ;:=", c)) {
00689             lexAppendc(0);
00690             /* restore lookahead buf. */
00691             lexBuf.len += len;
00692             lexBuf.getPtr = curgetptr;
00693             return lexStr();
00694             }
00695         else
00696             lexAppendc(c);
00697         }
00698     lexBuf.len += len;  /* char that has been moved to lookahead buffer */
00699     lexBuf.getPtr = curgetptr;
00700     return 0;
00701     }
00702 
00703 #ifdef _SUPPORT_LINE_FOLDING
00704 static void handleMoreRFC822LineBreak(int c) {
00705     /* suport RFC 822 line break in cases like
00706      *  ADR: foo;
00707      *    morefoo;
00708      *    more foo;
00709      */
00710     if (c == ';') {
00711         int a;
00712         lexSkipLookahead();
00713         /* skip white spaces */
00714         a = lexLookahead();
00715         while (a == ' ' || a == '\t') {
00716             lexSkipLookahead();
00717             a = lexLookahead();
00718             }
00719         if (a == '\n') {
00720             lexSkipLookahead();
00721             a = lexLookahead();
00722             if (a == ' ' || a == '\t') {
00723                 /* continuation, throw away all the \n and spaces read so
00724                  * far
00725                  */
00726                 lexSkipWhite();
00727                 lexPushLookaheadc(';');
00728                 }
00729             else {
00730                 lexPushLookaheadc('\n');
00731                 lexPushLookaheadc(';');
00732                 }
00733             }
00734         else {
00735             lexPushLookaheadc(';');
00736             }
00737         }
00738     }
00739 
00740 static char* lexGet1Value() {
00741     int c;
00742     lexSkipWhite();
00743     c = lexLookahead();
00744     lexClearToken();
00745     while (c != EOF && (c != ';' || !fieldedProp)) {
00746         if (c == '\\' ) {
00747             int a;
00748             lexSkipLookahead();
00749             a = lexLookahead();
00750             if ( a == ';' ) {
00751                 lexAppendc( ';' );
00752                 lexSkipLookahead();
00753             } else if ( a == '\n' ) {
00754                 lexAppendc( '\n' );
00755                 lexSkipLookahead();
00756             } else if ( a == '\\' ) {
00757                 lexAppendc( '\\' );
00758                 lexSkipLookahead();
00759             } else {
00760                 lexAppendc('\\');
00761             }
00762         } else if (c == '\n') {
00763             int a;
00764             lexSkipLookahead();
00765             a  = lexLookahead();
00766             if (a == ' ' || a == '\t') {
00767                 lexAppendc(' ');
00768                 lexSkipLookahead();
00769                 }
00770             else {
00771                 lexPushLookaheadc('\n');
00772                 break;
00773                 }
00774             }
00775         else {
00776             lexAppendc(c);
00777             lexSkipLookahead();
00778             }
00779         c = lexLookahead();
00780         }
00781     lexAppendc(0);
00782     handleMoreRFC822LineBreak(c);
00783     return c==EOF?0:lexStr();
00784     }
00785 #endif
00786 
00787 static int match_begin_name(int end) {
00788     char *n = lexLookaheadWord();
00789     int token = ID;
00790     if (n) {
00791         if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
00792         else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
00793         else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
00794         else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
00795         deleteStr(n);
00796         return token;
00797         }
00798     return 0;
00799     }
00800 
00801 
00802 #ifdef INCLUDEMFC
00803 void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
00804 #else
00805 void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
00806 #endif
00807     {
00808     // initialize lex mode stack
00809     lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
00810 
00811     // iniatialize lex buffer.
00812     lexBuf.inputString = (char*) inputstring;
00813     lexBuf.inputLen = inputlen;
00814     lexBuf.curPos = 0;
00815     lexBuf.inputFile = inputfile;
00816 
00817     lexBuf.len = 0;
00818     lexBuf.getPtr = 0;
00819 
00820     lexBuf.maxToken = MAXTOKEN;
00821     lexBuf.strs = (char*)malloc(MAXTOKEN);
00822     lexBuf.strsLen = 0;
00823 
00824     }
00825 
00826 static void finiLex() {
00827     free(lexBuf.strs);
00828     }
00829 
00830 
00831 /*-----------------------------------*/
00832 /* This parses and converts the base64 format for binary encoding into
00833  * a decoded buffer (allocated with new).  See RFC 1521.
00834  */
00835 static int lexGetDataFromBase64()
00836     {
00837     unsigned long bytesLen = 0, bytesMax = 0;
00838     int quadIx = 0, pad = 0;
00839     unsigned long trip = 0;
00840     unsigned char b;
00841     int c;
00842     unsigned char *bytes = NULL;
00843     unsigned char *oldBytes = NULL;
00844 
00845     DBG_(("db: lexGetDataFromBase64\n"));
00846     while (1) {
00847         c = lexGetc();
00848         lexSkipWhite();
00849         if (c == '\n') {
00850             ++mime_lineNum;
00851             if (lexLookahead() == '\n') {
00852                 /* a '\n' character by itself means end of data */
00853                 break;
00854                 }
00855             else continue; /* ignore '\n' */
00856             }
00857         else {
00858             if ((c >= 'A') && (c <= 'Z'))
00859                 b = (unsigned char)(c - 'A');
00860             else if ((c >= 'a') && (c <= 'z'))
00861                 b = (unsigned char)(c - 'a') + 26;
00862             else if ((c >= '0') && (c <= '9'))
00863                 b = (unsigned char)(c - '0') + 52;
00864             else if (c == '+')
00865                 b = 62;
00866             else if (c == '/')
00867                 b = 63;
00868             else if (c == '=') {
00869                 b = 0;
00870                 pad++;
00871             } else { /* error condition */
00872                 if (bytes) free(bytes);
00873                 else if (oldBytes) free(oldBytes);
00874                 // error recovery: skip until 2 adjacent newlines.
00875                 DBG_(("db: invalid character 0x%x '%c'\n", c,c));
00876                 if (c != EOF)  {
00877                     c = lexGetc();
00878                     while (c != EOF) {
00879                         if (c == '\n') {
00880                             lexSkipWhite();
00881                             if(lexLookahead() == '\n') {
00882                                 ++mime_lineNum;
00883                                 break;
00884                                 }
00885                             }
00886                         c = lexGetc();
00887                         }
00888                     }
00889                 return c != EOF;
00890                 }
00891             trip = (trip << 6) | b;
00892             if (++quadIx == 4) {
00893                 unsigned char outBytes[3];
00894                 int numOut;
00895                 int i;
00896                 for (i = 0; i < 3; i++) {
00897                     outBytes[2-i] = (unsigned char)(trip & 0xFF);
00898                     trip >>= 8;
00899                     }
00900                 numOut = 3 - pad;
00901                 if (bytesLen + numOut > bytesMax) {
00902                     if (!bytes) {
00903                         bytesMax = 1024;
00904                         bytes = (unsigned char*)malloc((size_t)bytesMax);
00905                         }
00906                     else {
00907                         bytesMax <<= 2;
00908                         oldBytes = bytes;
00909                         bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
00910                         }
00911                     if (bytes == 0) {
00912                         mime_error("out of memory while processing BASE64 data\n");
00913                         }
00914                     }
00915                 if (bytes) {
00916                     memcpy(bytes + bytesLen, outBytes, numOut);
00917                     bytesLen += numOut;
00918                     }
00919                 trip = 0;
00920                 quadIx = 0;
00921                 }
00922             }
00923         } /* while */
00924     DBG_(("db: bytesLen = %d\n",  bytesLen));
00925     /* kludge: all this won't be necessary if we have tree form
00926         representation */
00927     if (bytes) {
00928         setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
00929         free(bytes);
00930         }
00931     else if (oldBytes) {
00932         setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
00933         free(oldBytes);
00934         }
00935     return bytesLen;
00936     }
00937 
00938 static int match_begin_end_name(int end) {
00939     int token;
00940     lexSkipWhite();
00941     if (lexLookahead() != ':') return ID;
00942     lexSkipLookahead();
00943     lexSkipWhite();
00944     token = match_begin_name(end);
00945     if (token == ID) {
00946         lexPushLookaheadc(':');
00947         DBG_(("db: ID '%s'\n", yylval.str));
00948         return ID;
00949         }
00950     else if (token != 0) {
00951         lexSkipLookaheadWord();
00952         deleteStr(yylval.str);
00953         DBG_(("db: begin/end %d\n", token));
00954         return token;
00955         }
00956     return 0;
00957     }
00958 
00959 static char* lexGetQuotedPrintable()
00960 {
00961     int c;
00962     lexSkipWhite();
00963     c = lexLookahead();
00964     lexClearToken();
00965 
00966     while (c != EOF && (c != ';' || !fieldedProp)) {
00967         if (c == '\n') {
00968             // break, leave '\n' on remaining chars.
00969             break;
00970         } else if (c == '=') {
00971             int cur = 0;
00972             int next;
00973 
00974             lexSkipLookahead(); // skip '='
00975             next = lexLookahead();
00976 
00977             if (next == '\n') {
00978                 // skip and only skip the \n
00979                 lexSkipLookahead(); 
00980                 c = lexLookahead();
00981                 ++mime_lineNum; // aid in error reporting
00982                 continue;
00983             } else if (next >= '0' && next <= '9') {
00984                 cur = next - '0';
00985             } else if (next >= 'A' && next <= 'F') {
00986                 cur = next - 'A' + 10;
00987             } else {
00988                 // we have been sent buggy stuff. doesn't matter
00989                 // what we do so long as we keep going.
00990                 // should probably spit an error here
00991                 lexSkipLookahead(); 
00992                 c = lexLookahead();
00993                 continue;
00994             }
00995 
00996             lexSkipLookahead(); // skip A-Z0-9
00997             next = lexLookahead();
00998 
00999             cur = cur * 16;
01000             // this time really just expecting 0-9A-F
01001             if (next >= '0' && next <= '9') {
01002                 cur += next - '0';
01003             } else if (next >= 'A' && next <= 'F') {
01004                 cur += next - 'A' + 10;
01005             } else {
01006                 // we have been sent buggy stuff. doesn't matter
01007                 // what we do so long as we keep going.
01008                 // should probably spit an error here
01009                 lexSkipLookahead(); 
01010                 c = lexLookahead();
01011                 continue;
01012             }
01013 
01014             // got a valid escaped =.  append it.
01015             lexSkipLookahead(); // skip second 0-9A-F
01016             lexAppendc(cur);
01017         } else {
01018             lexSkipLookahead(); // skip whatever we just read.
01019             lexAppendc(c); // and append it.
01020         }
01021         c = lexLookahead();
01022     }
01023     lexAppendc(0);
01024     return c==EOF?0:lexStr();
01025 }
01026 
01027 static int yylex() {
01028 
01029     int lexmode = LEXMODE();
01030     if (lexmode == L_VALUES) {
01031         int c = lexGetc();
01032         int c2;
01033         if (c == ';' && fieldedProp) {
01034             DBG_(("db: SEMICOLON\n"));
01035             lexPushLookaheadc(c);
01036             handleMoreRFC822LineBreak(c);
01037             lexSkipLookahead();
01038             return SEMICOLON;
01039             }
01040         else if (strchr("\n",c) && (c2 = lexLookahead()) != ' ' && c2 != '\t') {
01041             ++mime_lineNum;
01042             /* consume all line separator(s) adjacent to each other */
01043             while (strchr("\n",c2)) {
01044                 lexSkipLookahead();
01045                 c2 = lexLookahead();
01046                 ++mime_lineNum;
01047                 }
01048             DBG_(("db: LINESEP\n"));
01049             return LINESEP;
01050             }
01051         else {
01052             char *p = 0;
01053             lexPushLookaheadc(c);
01054             if (lexWithinMode(L_BASE64)) {
01055                 /* get each char and convert to bin on the fly... */
01056                 yylval.str = NULL;
01057                 return lexGetDataFromBase64() ? STRING : 0;
01058                 }
01059             else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
01060                 p = lexGetQuotedPrintable();
01061                 }
01062             else {
01063 #ifdef _SUPPORT_LINE_FOLDING
01064                 p = lexGet1Value();
01065 #else
01066                 p = lexGetStrUntil(";\n");
01067 #endif
01068                 }
01069             if (p) {
01070                 DBG_(("db: STRING: '%s'\n", p));
01071                 yylval.str = p;
01072                 return STRING;
01073                 }
01074             else return 0;
01075             }
01076     } else if (lexmode == L_PARAMWORD) {
01077         yylval.str = lexGetParamWord();
01078         return ID;
01079     } else {
01080         /* normal mode */
01081         while (1) {
01082             int c = lexGetc();
01083             switch(c) {
01084                 case ':': {
01085                     /* consume all line separator(s) adjacent to each other */
01086                     /* ignoring linesep immediately after colon. */
01087                     /* I don't see this in the spec, and it breaks null values -- WA
01088                     c = lexLookahead();
01089                     while (strchr("\n",c)) {
01090                         lexSkipLookahead();
01091                         c = lexLookahead();
01092                         ++mime_lineNum;
01093                         }
01094                     */
01095                     DBG_(("db: COLON\n"));
01096                     return COLON;
01097                     }
01098                 case ';':
01099                     DBG_(("db: SEMICOLON\n"));
01100                     return SEMICOLON;
01101                 case '=':
01102                     DBG_(("db: EQ\n"));
01103                     return EQ;
01104                 /* ignore whitespace in this mode */
01105                 case '\t':
01106                 case ' ': continue;
01107                 case '\n': {
01108                     ++mime_lineNum;
01109                     continue;
01110                     }
01111                 case EOF: return 0;
01112                     break;
01113                 default: {
01114                     lexPushLookaheadc(c);
01115                     if (isalnum(c)) {
01116                         char *t = lexGetWord();
01117                         yylval.str = t;
01118                         if (!qstricmp(t, "begin")) {
01119                             return match_begin_end_name(0);
01120                             }
01121                         else if (!qstricmp(t,"end")) {
01122                             return match_begin_end_name(1);
01123                             }
01124                         else {
01125                             DBG_(("db: ID '%s'\n", t));
01126                             return ID;
01127                             }
01128                         }
01129                     else {
01130                         /* unknow token */
01131                         return 0;
01132                         }
01133                     break;
01134                     }
01135                 }
01136             }
01137         }
01138     return 0;
01139     }
01140 
01141 
01142 /***************************************************************************/
01143 /***                                                    Public Functions                                                ****/
01144 /***************************************************************************/
01145 
01146 static VObject* Parse_MIMEHelper()
01147     {
01148     ObjStackTop = -1;
01149     mime_numErrors = 0;
01150     mime_lineNum = 1;
01151     vObjList = 0;
01152     curObj = 0;
01153 
01154     if (yyparse() != 0)
01155         return 0;
01156 
01157     finiLex();
01158     return vObjList;
01159     }
01160 
01161 /*--------------------------------------------*/
01162 DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len)
01163     {
01164     initLex(input, len, 0);
01165     return Parse_MIMEHelper();
01166     }
01167 
01168 
01169 #if INCLUDEMFC
01170 
01171 DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file)
01172     {
01173     unsigned long startPos;
01174     VObject *result;    
01175 
01176     initLex(0,-1,file);
01177     startPos = file->GetPosition();
01178     if (!(result = Parse_MIMEHelper()))
01179         file->Seek(startPos, CFile::begin);
01180     return result;
01181     }
01182 
01183 #else
01184 
01185 VObject* Parse_MIME_FromFile(FILE *file)
01186     {
01187     VObject *result;    
01188     long startPos;
01189 
01190     initLex(0,(unsigned long)-1,file);
01191     startPos = ftell(file);
01192     if (!(result = Parse_MIMEHelper())) {
01193         fseek(file,startPos,SEEK_SET);
01194         }
01195     return result;
01196     }
01197 
01198 DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname)
01199     {
01200     FILE *fp = fopen(fname,"r");
01201     if (fp) {
01202         VObject* o = Parse_MIME_FromFile(fp);
01203         fclose(fp);
01204         return o;
01205         }
01206     else {
01207         char msg[80];
01208         sprintf(msg, "can't open file '%s' for reading\n", fname);
01209         mime_error_(msg);
01210         return 0;
01211         }
01212     }
01213 
01214 #endif
01215 
01216 /*-------------------------------------*/
01217 
01218 static MimeErrorHandler mimeErrorHandler;
01219 
01220 DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me)
01221     {
01222     mimeErrorHandler = me;
01223     }
01224 
01225 void mime_error(char *s)
01226     {
01227     char msg[256];
01228     if (mimeErrorHandler) {
01229         sprintf(msg,"%s at line %d", s, mime_lineNum);
01230         mimeErrorHandler(msg);
01231         }
01232     }
01233 
01234 void mime_error_(char *s)
01235     {
01236     if (mimeErrorHandler) {
01237         mimeErrorHandler(s);
01238         }
01239     }
01240 
01241 #line 1242 "y.tab.c"
01242 #define YYABORT goto yyabort
01243 #define YYREJECT goto yyabort
01244 #define YYACCEPT goto yyaccept
01245 #define YYERROR goto yyerrlab
01246 int
01247 yyparse()
01248 {
01249     register int yym, yyn, yystate;
01250 #if YYDEBUG
01251     register char *yys;
01252     extern char *getenv();
01253 
01254     if (yys = getenv("YYDEBUG"))
01255     {
01256         yyn = *yys;
01257         if (yyn >= '0' && yyn <= '9')
01258             yydebug = yyn - '0';
01259     }
01260 #endif
01261 
01262     yynerrs = 0;
01263     yyerrflag = 0;
01264     yychar = (-1);
01265 
01266     yyssp = yyss;
01267     yyvsp = yyvs;
01268     *yyssp = yystate = 0;
01269 
01270 yyloop:
01271     if (yyn = yydefred[yystate]) goto yyreduce;
01272     if (yychar < 0)
01273     {
01274         if ((yychar = yylex()) < 0) yychar = 0;
01275 #if YYDEBUG
01276         if (yydebug)
01277         {
01278             yys = 0;
01279             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
01280             if (!yys) yys = "illegal-symbol";
01281             printf("%sdebug: state %d, reading %d (%s)\n",
01282                     YYPREFIX, yystate, yychar, yys);
01283         }
01284 #endif
01285     }
01286     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
01287             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
01288     {
01289 #if YYDEBUG
01290         if (yydebug)
01291             printf("%sdebug: state %d, shifting to state %d\n",
01292                     YYPREFIX, yystate, yytable[yyn]);
01293 #endif
01294         if (yyssp >= yyss + yystacksize - 1)
01295         {
01296             goto yyoverflow;
01297         }
01298         *++yyssp = yystate = yytable[yyn];
01299         *++yyvsp = yylval;
01300         yychar = (-1);
01301         if (yyerrflag > 0)  --yyerrflag;
01302         goto yyloop;
01303     }
01304     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
01305             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
01306     {
01307         yyn = yytable[yyn];
01308         goto yyreduce;
01309     }
01310     if (yyerrflag) goto yyinrecovery;
01311 #ifdef lint
01312     goto yynewerror;
01313 #endif
01314 yynewerror:
01315     yyerror("syntax error");
01316 #ifdef lint
01317     goto yyerrlab;
01318 #endif
01319 yyerrlab:
01320     ++yynerrs;
01321 yyinrecovery:
01322     if (yyerrflag < 3)
01323     {
01324         yyerrflag = 3;
01325         for (;;)
01326         {
01327             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
01328                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
01329             {
01330 #if YYDEBUG
01331                 if (yydebug)
01332                     printf("%sdebug: state %d, error recovery shifting\
01333  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
01334 #endif
01335                 if (yyssp >= yyss + yystacksize - 1)
01336                 {
01337                     goto yyoverflow;
01338                 }
01339                 *++yyssp = yystate = yytable[yyn];
01340                 *++yyvsp = yylval;
01341                 goto yyloop;
01342             }
01343             else
01344             {
01345 #if YYDEBUG
01346                 if (yydebug)
01347                     printf("%sdebug: error recovery discarding state %d\n",
01348                             YYPREFIX, *yyssp);
01349 #endif
01350                 if (yyssp <= yyss) goto yyabort;
01351                 --yyssp;
01352                 --yyvsp;
01353             }
01354         }
01355     }
01356     else
01357     {
01358         if (yychar == 0) goto yyabort;
01359 #if YYDEBUG
01360         if (yydebug)
01361         {
01362             yys = 0;
01363             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
01364             if (!yys) yys = "illegal-symbol";
01365             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
01366                     YYPREFIX, yystate, yychar, yys);
01367         }
01368 #endif
01369         yychar = (-1);
01370         goto yyloop;
01371     }
01372 yyreduce:
01373 #if YYDEBUG
01374     if (yydebug)
01375         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
01376                 YYPREFIX, yystate, yyn, yyrule[yyn]);
01377 #endif
01378     yym = yylen[yyn];
01379     yyval = yyvsp[1-yym];
01380     switch (yyn)
01381     {
01382 case 2:
01383 #line 225 "vcc.y"
01384 { addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
01385 break;
01386 case 3:
01387 #line 227 "vcc.y"
01388 { addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
01389 break;
01390 case 6:
01391 #line 236 "vcc.y"
01392 {
01393         lexPushMode(L_VCARD);
01394         if (!pushVObject(VCCardProp)) YYERROR;
01395         }
01396 break;
01397 case 7:
01398 #line 241 "vcc.y"
01399 {
01400         lexPopMode(0);
01401         yyval.vobj = popVObject();
01402         }
01403 break;
01404 case 8:
01405 #line 246 "vcc.y"
01406 {
01407         lexPushMode(L_VCARD);
01408         if (!pushVObject(VCCardProp)) YYERROR;
01409         }
01410 break;
01411 case 9:
01412 #line 251 "vcc.y"
01413 {
01414         lexPopMode(0);
01415         yyval.vobj = popVObject();
01416         }
01417 break;
01418 case 12:
01419 #line 262 "vcc.y"
01420 {
01421         lexPushMode(L_VALUES);
01422         }
01423 break;
01424 case 13:
01425 #line 266 "vcc.y"
01426 {
01427         if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
01428            lexPopMode(0);
01429         lexPopMode(0);
01430         }
01431 break;
01432 case 15:
01433 #line 275 "vcc.y"
01434 {
01435         enterProps(yyvsp[0].str);
01436         }
01437 break;
01438 case 17:
01439 #line 280 "vcc.y"
01440 {
01441         enterProps(yyvsp[0].str);
01442         }
01443 break;
01444 case 21:
01445 #line 293 "vcc.y"
01446 {
01447         enterAttr(yyvsp[0].str,0);
01448         }
01449 break;
01450 case 22:
01451 #line 297 "vcc.y"
01452 {
01453         lexPushMode(L_PARAMWORD);
01454         }
01455 break;
01456 case 23:
01457 #line 301 "vcc.y"
01458 {
01459         lexPopMode(0);
01460         enterAttr(yyvsp[-3].str,yyvsp[0].str);
01461         }
01462 break;
01463 case 25:
01464 #line 310 "vcc.y"
01465 { enterValues(yyvsp[-1].str); }
01466 break;
01467 case 27:
01468 #line 312 "vcc.y"
01469 { enterValues(yyvsp[0].str); }
01470 break;
01471 case 29:
01472 #line 317 "vcc.y"
01473 { yyval.str = 0; }
01474 break;
01475 case 30:
01476 #line 322 "vcc.y"
01477 { if (!pushVObject(VCCalProp)) YYERROR; }
01478 break;
01479 case 31:
01480 #line 325 "vcc.y"
01481 { yyval.vobj = popVObject(); }
01482 break;
01483 case 32:
01484 #line 327 "vcc.y"
01485 { if (!pushVObject(VCCalProp)) YYERROR; }
01486 break;
01487 case 33:
01488 #line 329 "vcc.y"
01489 { yyval.vobj = popVObject(); }
01490 break;
01491 case 39:
01492 #line 344 "vcc.y"
01493 {
01494         lexPushMode(L_VEVENT);
01495         if (!pushVObject(VCEventProp)) YYERROR;
01496         }
01497 break;
01498 case 40:
01499 #line 350 "vcc.y"
01500 {
01501         lexPopMode(0);
01502         popVObject();
01503         }
01504 break;
01505 case 41:
01506 #line 355 "vcc.y"
01507 {
01508         lexPushMode(L_VEVENT);
01509         if (!pushVObject(VCEventProp)) YYERROR;
01510         }
01511 break;
01512 case 42:
01513 #line 360 "vcc.y"
01514 {
01515         lexPopMode(0);
01516         popVObject();
01517         }
01518 break;
01519 case 43:
01520 #line 368 "vcc.y"
01521 {
01522         lexPushMode(L_VTODO);
01523         if (!pushVObject(VCTodoProp)) YYERROR;
01524         }
01525 break;
01526 case 44:
01527 #line 374 "vcc.y"
01528 {
01529         lexPopMode(0);
01530         popVObject();
01531         }
01532 break;
01533 case 45:
01534 #line 379 "vcc.y"
01535 {
01536         lexPushMode(L_VTODO);
01537         if (!pushVObject(VCTodoProp)) YYERROR;
01538         }
01539 break;
01540 case 46:
01541 #line 384 "vcc.y"
01542 {
01543         lexPopMode(0);
01544         popVObject();
01545         }
01546 break;
01547 #line 1548 "y.tab.c"
01548     }
01549     yyssp -= yym;
01550     yystate = *yyssp;
01551     yyvsp -= yym;
01552     yym = yylhs[yyn];
01553     if (yystate == 0 && yym == 0)
01554     {
01555 #if YYDEBUG
01556         if (yydebug)
01557             printf("%sdebug: after reduction, shifting from state 0 to\
01558  state %d\n", YYPREFIX, YYFINAL);
01559 #endif
01560         yystate = YYFINAL;
01561         *++yyssp = YYFINAL;
01562         *++yyvsp = yyval;
01563         if (yychar < 0)
01564         {
01565             if ((yychar = yylex()) < 0) yychar = 0;
01566 #if YYDEBUG
01567             if (yydebug)
01568             {
01569                 yys = 0;
01570                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
01571                 if (!yys) yys = "illegal-symbol";
01572                 printf("%sdebug: state %d, reading %d (%s)\n",
01573                         YYPREFIX, YYFINAL, yychar, yys);
01574             }
01575 #endif
01576         }
01577         if (yychar == 0) goto yyaccept;
01578         goto yyloop;
01579     }
01580     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
01581             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
01582         yystate = yytable[yyn];
01583     else
01584         yystate = yydgoto[yym];
01585 #if YYDEBUG
01586     if (yydebug)
01587         printf("%sdebug: after reduction, shifting from state %d \
01588 to state %d\n", YYPREFIX, *yyssp, yystate);
01589 #endif
01590     if (yyssp >= yyss + yystacksize - 1)
01591     {
01592         goto yyoverflow;
01593     }
01594     *++yyssp = yystate;
01595     *++yyvsp = yyval;
01596     goto yyloop;
01597 yyoverflow:
01598     yyerror("yacc stack overflow");
01599 yyabort:
01600     return (1);
01601 yyaccept:
01602     return (0);
01603 }

Generated on Sat Nov 5 16:16:33 2005 for OPIE by  doxygen 1.4.2