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