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