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