summaryrefslogtreecommitdiffabout
path: root/libkcal/versit
authorzautrix <zautrix>2004-06-26 19:01:18 (UTC)
committer zautrix <zautrix>2004-06-26 19:01:18 (UTC)
commitb9aad1f15dc600e4dbe4c62d3fcced6363188ba3 (patch) (unidiff)
tree2c3d4004fb21c72cba65793859f9bcd8ffd3a49c /libkcal/versit
downloadkdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.zip
kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.gz
kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.bz2
Initial revision
Diffstat (limited to 'libkcal/versit') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/versit/port.h75
-rw-r--r--libkcal/versit/vcc.c2162
-rw-r--r--libkcal/versit/vcc.h76
-rw-r--r--libkcal/versit/versit.pro15
-rw-r--r--libkcal/versit/versit.pro.back15
-rw-r--r--libkcal/versit/vobject.c1433
-rw-r--r--libkcal/versit/vobject.h384
7 files changed, 4160 insertions, 0 deletions
diff --git a/libkcal/versit/port.h b/libkcal/versit/port.h
new file mode 100644
index 0000000..afc16dd
--- a/dev/null
+++ b/libkcal/versit/port.h
@@ -0,0 +1,75 @@
1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc.
4
5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors.
9
10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose.
14
15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including
17this software.
18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS.
22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE.
27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE.
32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36
37***************************************************************************/
38
39#ifndef __PORT_H__
40#define __PORT_H__ 1
41
42#if defined(__CPLUSPLUS__) || defined(__cplusplus)
43extern "C" {
44#endif
45
46#define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard"
47#define vCalendarClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCalendar"
48
49/* The above strings vCardClipboardFormat and vCalendarClipboardFormat
50are globally unique IDs which can be used to generate clipboard format
51ID's as per the requirements of a specific platform. For example, in
52Windows they are used as the parameter in a call to RegisterClipboardFormat.
53For example:
54
55 CLIPFORMAT foo = RegisterClipboardFormat(vCardClipboardFormat);
56
57*/
58
59#define vCardMimeType "text/x-vCard"
60#define vCalendarMimeType "text/x-vCalendar"
61
62#ifndef FALSE
63#define FALSE 0
64#endif
65#ifndef TRUE
66#define TRUE 1
67#endif
68
69#define Parse_Debug(t)
70
71#if defined(__CPLUSPLUS__) || defined(__cplusplus)
72}
73#endif
74
75#endif /* __PORT_H__ */
diff --git a/libkcal/versit/vcc.c b/libkcal/versit/vcc.c
new file mode 100644
index 0000000..350cac3
--- a/dev/null
+++ b/libkcal/versit/vcc.c
@@ -0,0 +1,2162 @@
1
2/* A Bison parser, made from ./vcc.y
3 by GNU Bison version 1.28 */
4
5#define YYBISON 1 /* Identify Bison output. */
6
7#ifdef _WIN32_
8#define strcasecmp _stricmp
9#endif
10
11 #define EQ257
12 #define COLON258
13 #define DOT259
14 #define SEMICOLON260
15 #define SPACE261
16 #define HTAB262
17 #define LINESEP263
18 #define NEWLINE264
19 #define BEGIN_VCARD265
20 #define END_VCARD266
21 #define BEGIN_VCAL267
22 #define END_VCAL268
23 #define BEGIN_VEVENT269
24 #define END_VEVENT270
25 #define BEGIN_VTODO271
26 #define END_VTODO272
27 #define ID273
28 #define STRING274
29
30#line 1 "./vcc.y"
31
32
33/***************************************************************************
34(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
35Business Machines Corporation and Siemens Rolm Communications Inc.
36
37For purposes of this license notice, the term Licensors shall mean,
38collectively, Apple Computer, Inc., AT&T Corp., International
39Business Machines Corporation and Siemens Rolm Communications Inc.
40The term Licensor shall mean any of the Licensors.
41
42Subject to acceptance of the following conditions, permission is hereby
43granted by Licensors without the need for written agreement and without
44license or royalty fees, to use, copy, modify and distribute this
45software for any purpose.
46
47The above copyright notice and the following four paragraphs must be
48reproduced in all copies of this software and any software including
49this software.
50
51THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
52ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
53MODIFICATIONS.
54
55IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
56INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
57OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58DAMAGE.
59
60EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
61INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
62IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63PURPOSE.
64
65The software is provided with RESTRICTED RIGHTS. Use, duplication, or
66disclosure by the government are subject to restrictions set forth in
67DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
68
69***************************************************************************/
70
71/*
72 * src: vcc.c
73 * doc: Parser for vCard and vCalendar. Note that this code is
74 * generated by a yacc parser generator. Generally it should not
75 * be edited by hand. The real source is vcc.y. The #line directives
76 * can be commented out here to make it easier to trace through
77 * in a debugger. However, if a bug is found it should
78 * be fixed in vcc.y and this file regenerated.
79 */
80
81
82/* debugging utilities */
83#if __DEBUG
84#define DBG_(x) printf x
85#else
86#define DBG_(x)
87#endif
88
89/**** External Functions ****/
90
91/* assign local name to parser variables and functions so that
92 we can use more than one yacc based parser.
93*/
94
95#define yyparse mime_parse
96#define yylex mime_lex
97#define yyerror mime_error
98#define yychar mime_char
99/* #define p_yyval p_mime_val */
100#undef yyval
101#define yyval mime_yyval
102/* #define p_yylval p_mime_lval */
103#undef yylval
104#define yylval mime_yylval
105#define yydebug mime_debug
106#define yynerrs mime_nerrs
107#define yyerrflag mime_errflag
108#define yyss mime_ss
109#define yyssp mime_ssp
110#define yyvs mime_vs
111#define yyvsp mime_vsp
112#define yylhs mime_lhs
113#define yylen mime_len
114#define yydefred mime_defred
115#define yydgoto mime_dgoto
116#define yysindex mime_sindex
117#define yyrindex mime_rindex
118#define yygindex mime_gindex
119#define yytable mime_table
120#define yycheck mime_check
121#define yyname mime_name
122#define yyrule mime_rule
123#undef YYPREFIX
124#define YYPREFIX "mime_"
125
126
127#ifndef _NO_LINE_FOLDING
128#define _SUPPORT_LINE_FOLDING 1
129#endif
130
131#include <string.h>
132#ifndef __FreeBSD__
133#include <malloc.h>
134#endif
135#include <stdio.h>
136#include <stdlib.h>
137#include <ctype.h>
138#include "vcc.h"
139
140/* The following is a hack that I hope will get things compiling
141 * on SunOS 4.1.x systems
142 */
143#ifndef SEEK_SET
144#define SEEK_SET 0 /* Seek from beginning of file. */
145#define SEEK_CUR 1 /* Seek from current position. */
146#define SEEK_END 2 /* Seek from end of file. */
147#endif
148
149/**** Types, Constants ****/
150
151 #define YYDEBUG 0/* 1 to compile in some debugging code */
152 #define MAXTOKEN 256/* maximum token (line) length */
153 #define YYSTACKSIZE 1000/* ~unref ? */
154 #define MAXLEVEL 10/* max # of nested objects parseable */
155 /* (includes outermost) */
156
157
158/**** Global Variables ****/
159int mime_lineNum, mime_numErrors; /* yyerror() can use these */
160static VObject* vObjList;
161static VObject *curProp;
162static VObject *curObj;
163static VObject* ObjStack[MAXLEVEL];
164static int ObjStackTop;
165
166
167/* A helpful utility for the rest of the app. */
168#if __CPLUSPLUS__
169extern "C" {
170#endif
171
172 /* static void Parse_Debug(const char *s);*/
173 static void yyerror(char *s);
174
175#if __CPLUSPLUS__
176 };
177#endif
178
179int yyparse();
180static int yylex();
181enum LexMode {
182 L_NORMAL,
183 L_VCARD,
184 L_VCAL,
185 L_VEVENT,
186 L_VTODO,
187 L_VALUES,
188 L_BASE64,
189 L_QUOTED_PRINTABLE
190 };
191
192/**** Private Forward Declarations ****/
193static int pushVObject(const char *prop);
194static VObject* popVObject();
195char* lexDataFromBase64();
196static void lexPopMode(int top);
197static int lexWithinMode(enum LexMode mode);
198static void lexPushMode(enum LexMode mode);
199static void enterProps(const char *s);
200static void enterAttr(const char *s1, const char *s2);
201/* static void enterValues(const char *value); */
202static void appendValue(const char *value);
203static void mime_error_(char *s);
204
205
206#line 181 "./vcc.y"
207typedef union {
208 char *str;
209 VObject *vobj;
210 } YYSTYPE;
211#include <stdio.h>
212
213#ifndef __cplusplus
214#ifndef __STDC__
215#define const
216#endif
217#endif
218
219
220
221 #define YYFINAL 62
222 #define YYFLAG -32768
223 #define YYNTBASE21
224
225#define YYTRANSLATE(x) ((unsigned)(x) <= 274 ? yytranslate[x] : 51)
226
227static const char yytranslate[] = { 0,
228 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
229 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
230 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
231 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
232 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
233 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
234 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
235 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
236 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
237 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
238 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
239 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
240 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
241 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
242 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
243 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
244 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
245 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
246 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
247 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
248 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
249 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
250 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
251 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
252 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
253 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
254 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
255 17, 18, 19, 20
256};
257
258#if YYDEBUG != 0
259static const short yyprhs[] = { 0,
260 0, 2, 3, 7, 9, 11, 13, 14, 19, 20,
261 24, 27, 29, 30, 36, 38, 39, 43, 45, 48,
262 50, 53, 55, 59, 61, 62, 67, 69, 71, 72,
263 73, 78, 79, 83, 86, 88, 90, 92, 94, 95,
264 100, 101, 105, 106, 111, 112
265};
266
267static const short yyrhs[] = { 22,
268 0, 0, 24, 23, 22, 0, 24, 0, 25, 0,
269 40, 0, 0, 11, 26, 28, 12, 0, 0, 11,
270 27, 12, 0, 29, 28, 0, 29, 0, 0, 31,
271 4, 30, 37, 9, 0, 1, 0, 0, 36, 32,
272 33, 0, 36, 0, 34, 33, 0, 34, 0, 6,
273 35, 0, 36, 0, 36, 3, 36, 0, 19, 0,
274 0, 39, 6, 38, 37, 0, 39, 0, 20, 0,
275 0, 0, 13, 41, 43, 14, 0, 0, 13, 42,
276 14, 0, 44, 43, 0, 44, 0, 45, 0, 48,
277 0, 28, 0, 0, 15, 46, 28, 16, 0, 0,
278 15, 47, 16, 0, 0, 17, 49, 28, 18, 0,
279 0, 17, 50, 18, 0
280};
281
282#endif
283
284#if YYDEBUG != 0
285static const short yyrline[] = { 0,
286 209, 212, 215, 215, 219, 220, 223, 229, 234, 240,
287 246, 247, 250, 254, 260, 263, 268, 268, 274, 275,
288 278, 281, 285, 292, 295, 296, 296, 300, 301, 305,
289 309, 311, 314, 317, 318, 321, 323, 324, 327, 334,
290 339, 345, 351, 358, 363, 369
291};
292#endif
293
294
295#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
296
297static const char * const yytname[] = { "$","error","$undefined.","EQ","COLON",
298"DOT","SEMICOLON","SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD",
299"BEGIN_VCAL","END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO",
300"ID","STRING","mime","vobjects","@1","vobject","vcard","@2","@3","items","item",
301"@4","prop","@5","attr_params","attr_param","attr","name","values","@6","value",
302"vcal","@7","@8","calitems","calitem","eventitem","@9","@10","todoitem","@11",
303"@12", NULL
304};
305#endif
306
307static const short yyr1[] = { 0,
308 21, 23, 22, 22, 24, 24, 26, 25, 27, 25,
309 28, 28, 30, 29, 29, 32, 31, 31, 33, 33,
310 34, 35, 35, 36, 38, 37, 37, 39, 39, 41,
311 40, 42, 40, 43, 43, 44, 44, 44, 46, 45,
312 47, 45, 49, 48, 50, 48
313};
314
315static const short yyr2[] = { 0,
316 1, 0, 3, 1, 1, 1, 0, 4, 0, 3,
317 2, 1, 0, 5, 1, 0, 3, 1, 2, 1,
318 2, 1, 3, 1, 0, 4, 1, 1, 0, 0,
319 4, 0, 3, 2, 1, 1, 1, 1, 0, 4,
320 0, 3, 0, 4, 0, 3
321};
322
323static const short yydefact[] = { 0,
324 7, 30, 1, 2, 5, 6, 0, 0, 0, 0,
325 0, 15, 24, 0, 0, 0, 16, 10, 39, 43,
326 38, 0, 0, 36, 37, 33, 3, 8, 11, 13,
327 0, 0, 0, 0, 0, 31, 34, 29, 0, 17,
328 20, 0, 42, 0, 46, 28, 0, 27, 21, 22,
329 19, 40, 44, 14, 25, 0, 29, 23, 26, 0,
330 0, 0
331};
332
333static const short yydefgoto[] = { 60,
334 3, 11, 4, 5, 7, 8, 21, 15, 38, 16,
335 31, 40, 41, 49, 17, 47, 57, 48, 6, 9,
336 10, 22, 23, 24, 32, 33, 25, 34, 35
337};
338
339static const short yypact[] = { -9,
340 -6, -5,-32768, 7,-32768,-32768, 2, -1, 19, 15,
341 -9,-32768,-32768, 1, 0, 26, 27,-32768, 16, 17,
342-32768, 23, 9,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
343 33, 2, 24, 2, 25,-32768,-32768, 13, 22,-32768,
344 33, 28,-32768, 29,-32768,-32768, 36, 40,-32768, 39,
345-32768,-32768,-32768,-32768,-32768, 22, 13,-32768,-32768, 48,
346 49,-32768
347};
348
349static const short yypgoto[] = {-32768,
350 41,-32768,-32768,-32768,-32768,-32768, -7,-32768,-32768,-32768,
351-32768, 10,-32768,-32768, -34, -4,-32768,-32768,-32768,-32768,
352-32768, 31,-32768,-32768,-32768,-32768,-32768,-32768,-32768
353};
354
355
356 #define YYLAST 54
357
358
359static const short yytable[] = { 14,
360 12, 1, 12, 2, 50, -9, -4, 29, -32, 12,
361 18, -12, 28, -12, -12, -12, -12, -12, 13, 12,
362 13, 58, -35, 19, 42, 20, 44, 13, 26, 30,
363 -18, -41, 46, 19, -45, 20, 36, 13, 39, 43,
364 13, 56, 45, 52, 54, 55, 53, 61, 62, 0,
365 51, 27, 59, 37
366};
367
368static const short yycheck[] = { 7,
369 1, 11, 1, 13, 39, 12, 0, 15, 14, 1,
370 12, 12, 12, 14, 15, 16, 17, 18, 19, 1,
371 19, 56, 14, 15, 32, 17, 34, 19, 14, 4,
372 4, 16, 20, 15, 18, 17, 14, 19, 6, 16,
373 19, 3, 18, 16, 9, 6, 18, 0, 0, -1,
374 41, 11, 57, 23
375};
376/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
377#line 3 "/usr/share/bison.simple"
378/* This file comes from bison-1.28. */
379
380/* Skeleton output parser for bison,
381 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
382
383 This program is free software; you can redistribute it and/or modify
384 it under the terms of the GNU General Public License as published by
385 the Free Software Foundation; either version 2, or (at your option)
386 any later version.
387
388 This program is distributed in the hope that it will be useful,
389 but WITHOUT ANY WARRANTY; without even the implied warranty of
390 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
391 GNU General Public License for more details.
392
393 You should have received a copy of the GNU General Public License
394 along with this program; if not, write to the Free Software
395 Foundation, Inc., 59 Temple Place - Suite 330,
396 Boston, MA 02111-1307, USA. */
397
398/* As a special exception, when this file is copied by Bison into a
399 Bison output file, you may use that output file without restriction.
400 This special exception was added by the Free Software Foundation
401 in version 1.24 of Bison. */
402
403/* This is the parser code that is written into each bison parser
404 when the %semantic_parser declaration is not specified in the grammar.
405 It was written by Richard Stallman by simplifying the hairy parser
406 used when %semantic_parser is specified. */
407
408#ifndef YYSTACK_USE_ALLOCA
409#ifdef alloca
410#define YYSTACK_USE_ALLOCA
411#else /* alloca not defined */
412#ifdef __GNUC__
413#define YYSTACK_USE_ALLOCA
414#define alloca __builtin_alloca
415#else /* not GNU C. */
416#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
417#define YYSTACK_USE_ALLOCA
418#include <alloca.h>
419#else /* not sparc */
420/* We think this test detects Watcom and Microsoft C. */
421/* This used to test MSDOS, but that is a bad idea
422 since that symbol is in the user namespace. */
423#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
424#if 0 /* No need for malloc.h, which pollutes the namespace;
425 instead, just don't use alloca. */
426#include <malloc.h>
427#endif
428#else /* not MSDOS, or __TURBOC__ */
429#if defined(_AIX)
430/* I don't know what this was needed for, but it pollutes the namespace.
431 So I turned it off. rms, 2 May 1997. */
432/* #include <malloc.h> */
433 #pragma alloca
434#define YYSTACK_USE_ALLOCA
435#else /* not MSDOS, or __TURBOC__, or _AIX */
436#if 0
437#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
438 and on HPUX 10. Eventually we can turn this on. */
439#define YYSTACK_USE_ALLOCA
440#define alloca __builtin_alloca
441#endif /* __hpux */
442#endif
443#endif /* not _AIX */
444#endif /* not MSDOS, or __TURBOC__ */
445#endif /* not sparc */
446#endif /* not GNU C */
447#endif /* alloca not defined */
448#endif /* YYSTACK_USE_ALLOCA not defined */
449
450#ifdef YYSTACK_USE_ALLOCA
451#define YYSTACK_ALLOC alloca
452#else
453#define YYSTACK_ALLOC malloc
454#endif
455
456/* Note: there must be only one dollar sign in this file.
457 It is replaced by the list of actions, each action
458 as one case of the switch. */
459
460 #define yyerrok (yyerrstatus = 0)
461 #define yyclearin(yychar = YYEMPTY)
462 #define YYEMPTY -2
463 #define YYEOF 0
464 #define YYACCEPTgoto yyacceptlab
465 #define YYABORT goto yyabortlab
466 #define YYERROR goto yyerrlab1
467/* Like YYERROR except do call yyerror.
468 This remains here temporarily to ease the
469 transition to the new meaning of YYERROR, for GCC.
470 Once GCC version 2 has supplanted version 1, this can go. */
471 #define YYFAIL goto yyerrlab
472#define YYRECOVERING() (!!yyerrstatus)
473#define YYBACKUP(token, value) \
474 do \
475 if (yychar == YYEMPTY && yylen == 1) \
476 { yychar = (token), yylval = (value); \
477 yychar1 = YYTRANSLATE (yychar); \
478 YYPOPSTACK; \
479 goto yybackup; \
480 } \
481 else \
482 { yyerror ("syntax error: cannot back up"); YYERROR; }\
483while (0)
484
485 #define YYTERROR1
486 #define YYERRCODE256
487
488#ifndef YYPURE
489 #define YYLEX yylex()
490#endif
491
492#ifdef YYPURE
493#ifdef YYLSP_NEEDED
494#ifdef YYLEX_PARAM
495 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
496#else
497 #define YYLEX yylex(&yylval, &yylloc)
498#endif
499#else /* not YYLSP_NEEDED */
500#ifdef YYLEX_PARAM
501 #define YYLEX yylex(&yylval, YYLEX_PARAM)
502#else
503 #define YYLEX yylex(&yylval)
504#endif
505#endif /* not YYLSP_NEEDED */
506#endif
507
508/* If nonreentrant, generate the variables here */
509
510#ifndef YYPURE
511
512 int yychar; /* the lookahead symbol */
513 YYSTYPE yylval; /* the semantic value of the */
514 /* lookahead symbol */
515
516#ifdef YYLSP_NEEDED
517 YYLTYPE yylloc; /* location data for the lookahead*/
518 /* symbol */
519#endif
520
521 int yynerrs; /* number of parse errors so far */
522#endif /* not YYPURE */
523
524#if YYDEBUG != 0
525 int yydebug; /* nonzero means print parse trace*/
526/* Since this is uninitialized, it does not stop multiple parsers
527 from coexisting. */
528#endif
529
530 /* YYINITDEPTH indicates the initial size of the parser's stacks*/
531
532 #ifndefYYINITDEPTH
533#define YYINITDEPTH 200
534#endif
535
536/* YYMAXDEPTH is the maximum size the stacks can grow to
537 (effective only if the built-in stack extension method is used). */
538
539#if YYMAXDEPTH == 0
540#undef YYMAXDEPTH
541#endif
542
543#ifndef YYMAXDEPTH
544#define YYMAXDEPTH 10000
545#endif
546
547/* Define __yy_memcpy. Note that the size argument
548 should be passed with type unsigned int, because that is what the non-GCC
549 definitions require. With GCC, __builtin_memcpy takes an arg
550 of type size_t, but it can handle unsigned int. */
551
552 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
553 #define __yy_memcpy(TO,FROM,COUNT)__builtin_memcpy(TO,FROM,COUNT)
554 #else /* not GNU C or C++ */
555#ifndef __cplusplus
556
557/* This is the most reliable way to avoid incompatibilities
558 in available built-in functions on various systems. */
559static void
560__yy_memcpy (to, from, count)
561 char *to;
562 char *from;
563 unsigned int count;
564{
565 register char *f = from;
566 register char *t = to;
567 register int i = count;
568
569 while (i-- > 0)
570 *t++ = *f++;
571}
572
573#else /* __cplusplus */
574
575/* This is the most reliable way to avoid incompatibilities
576 in available built-in functions on various systems. */
577static void
578__yy_memcpy (char *to, char *from, unsigned int count)
579{
580 register char *t = to;
581 register char *f = from;
582 register int i = count;
583
584 while (i-- > 0)
585 *t++ = *f++;
586}
587
588#endif
589#endif
590
591#line 217 "/usr/share/bison.simple"
592
593/* The user can define YYPARSE_PARAM as the name of an argument to be passed
594 into yyparse. The argument should have type void *.
595 It should actually point to an object.
596 Grammar actions can access the variable by casting it
597 to the proper pointer type. */
598
599#ifdef YYPARSE_PARAM
600#ifdef __cplusplus
601#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
602#define YYPARSE_PARAM_DECL
603#else /* not __cplusplus */
604#define YYPARSE_PARAM_ARG YYPARSE_PARAM
605#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
606#endif /* not __cplusplus */
607#else /* not YYPARSE_PARAM */
608#define YYPARSE_PARAM_ARG
609#define YYPARSE_PARAM_DECL
610#endif /* not YYPARSE_PARAM */
611
612/* Prevent warning if -Wstrict-prototypes. */
613#if defined (__GNUC__) && ! defined (__cplusplus)
614#ifdef YYPARSE_PARAM
615int yyparse (void *);
616#else
617int yyparse (void);
618#endif
619#endif
620
621int
622yyparse(YYPARSE_PARAM_ARG)
623 YYPARSE_PARAM_DECL
624{
625 register int yystate;
626 register int yyn;
627 register short *yyssp;
628 register YYSTYPE *yyvsp;
629 int yyerrstatus;/* number of tokens to shift before error messages enabled */
630 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
631
632 short yyssa[YYINITDEPTH]; /* the state stack */
633 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
634
635 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
636 YYSTYPE *yyvs = yyvsa;/* to allow yyoverflow to reallocate them elsewhere */
637
638#ifdef YYLSP_NEEDED
639 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
640 YYLTYPE *yyls = yylsa;
641 YYLTYPE *yylsp;
642
643#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
644#else
645#define YYPOPSTACK (yyvsp--, yyssp--)
646#endif
647
648 int yystacksize = YYINITDEPTH;
649 int yyfree_stacks = 0;
650
651#ifdef YYPURE
652 int yychar;
653 YYSTYPE yylval;
654 int yynerrs;
655#ifdef YYLSP_NEEDED
656 YYLTYPE yylloc;
657#endif
658#endif
659
660 YYSTYPE yyval; /* the variable used to return */
661 /* semantic values from the action*/
662 /* routines */
663
664 int yylen;
665
666#if YYDEBUG != 0
667 if (yydebug)
668 fprintf(stderr, "Starting parse\n");
669#endif
670
671 yystate = 0;
672 yyerrstatus = 0;
673 yynerrs = 0;
674 yychar = YYEMPTY; /* Cause a token to be read. */
675
676 /* Initialize stack pointers.
677 Waste one element of value and location stack
678 so that they stay on the same level as the state stack.
679 The wasted elements are never initialized. */
680
681 yyssp = yyss - 1;
682 yyvsp = yyvs;
683#ifdef YYLSP_NEEDED
684 yylsp = yyls;
685#endif
686
687/* Push a new state, which is found in yystate . */
688/* In all cases, when you get here, the value and location stacks
689 have just been pushed. so pushing a state here evens the stacks. */
690yynewstate:
691
692 *++yyssp = yystate;
693
694 if (yyssp >= yyss + yystacksize - 1)
695 {
696 /* Give user a chance to reallocate the stack */
697 /* Use copies of these so that the &'s don't force the real ones into memory. */
698 YYSTYPE *yyvs1 = yyvs;
699 short *yyss1 = yyss;
700#ifdef YYLSP_NEEDED
701 YYLTYPE *yyls1 = yyls;
702#endif
703
704 /* Get the current used size of the three stacks, in elements. */
705 int size = yyssp - yyss + 1;
706
707#ifdef yyoverflow
708 /* Each stack pointer address is followed by the size of
709 the data in use in that stack, in bytes. */
710#ifdef YYLSP_NEEDED
711 /* This used to be a conditional around just the two extra args,
712 but that might be undefined if yyoverflow is a macro. */
713 yyoverflow("parser stack overflow",
714 &yyss1, size * sizeof (*yyssp),
715 &yyvs1, size * sizeof (*yyvsp),
716 &yyls1, size * sizeof (*yylsp),
717 &yystacksize);
718#else
719 yyoverflow("parser stack overflow",
720 &yyss1, size * sizeof (*yyssp),
721 &yyvs1, size * sizeof (*yyvsp),
722 &yystacksize);
723#endif
724
725 yyss = yyss1; yyvs = yyvs1;
726#ifdef YYLSP_NEEDED
727 yyls = yyls1;
728#endif
729#else /* no yyoverflow */
730 /* Extend the stack our own way. */
731 if (yystacksize >= YYMAXDEPTH)
732 {
733 yyerror("parser stack overflow");
734 if (yyfree_stacks)
735 {
736 free (yyss);
737 free (yyvs);
738#ifdef YYLSP_NEEDED
739 free (yyls);
740#endif
741 }
742 return 2;
743 }
744 yystacksize *= 2;
745 if (yystacksize > YYMAXDEPTH)
746 yystacksize = YYMAXDEPTH;
747#ifndef YYSTACK_USE_ALLOCA
748 yyfree_stacks = 1;
749#endif
750 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
751 __yy_memcpy ((char *)yyss, (char *)yyss1,
752 size * (unsigned int) sizeof (*yyssp));
753 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
754 __yy_memcpy ((char *)yyvs, (char *)yyvs1,
755 size * (unsigned int) sizeof (*yyvsp));
756#ifdef YYLSP_NEEDED
757 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
758 __yy_memcpy ((char *)yyls, (char *)yyls1,
759 size * (unsigned int) sizeof (*yylsp));
760#endif
761#endif /* no yyoverflow */
762
763 yyssp = yyss + size - 1;
764 yyvsp = yyvs + size - 1;
765#ifdef YYLSP_NEEDED
766 yylsp = yyls + size - 1;
767#endif
768
769#if YYDEBUG != 0
770 if (yydebug)
771 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
772#endif
773
774 if (yyssp >= yyss + yystacksize - 1)
775 YYABORT;
776 }
777
778#if YYDEBUG != 0
779 if (yydebug)
780 fprintf(stderr, "Entering state %d\n", yystate);
781#endif
782
783 goto yybackup;
784 yybackup:
785
786/* Do appropriate processing given the current state. */
787/* Read a lookahead token if we need one and don't already have one. */
788/* yyresume: */
789
790 /* First try to decide what to do without reference to lookahead token. */
791
792 yyn = yypact[yystate];
793 if (yyn == YYFLAG)
794 goto yydefault;
795
796 /* Not known => get a lookahead token if don't already have one. */
797
798 /* yychar is either YYEMPTY or YYEOF
799 or a valid token in external form. */
800
801 if (yychar == YYEMPTY)
802 {
803#if YYDEBUG != 0
804 if (yydebug)
805 fprintf(stderr, "Reading a token: ");
806#endif
807 yychar = YYLEX;
808 }
809
810 /* Convert token to internal form (in yychar1) for indexing tables with */
811
812 if (yychar <= 0) /* This means end of input. */
813 {
814 yychar1 = 0;
815 yychar = YYEOF; /* Don't call YYLEX any more */
816
817#if YYDEBUG != 0
818 if (yydebug)
819 fprintf(stderr, "Now at end of input.\n");
820#endif
821 }
822 else
823 {
824 yychar1 = YYTRANSLATE(yychar);
825
826#if YYDEBUG != 0
827 if (yydebug)
828 {
829 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
830 /* Give the individual parser a way to print the precise meaning
831 of a token, for further debugging info. */
832#ifdef YYPRINT
833 YYPRINT (stderr, yychar, yylval);
834#endif
835 fprintf (stderr, ")\n");
836 }
837#endif
838 }
839
840 yyn += yychar1;
841 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
842 goto yydefault;
843
844 yyn = yytable[yyn];
845
846 /* yyn is what to do for this token type in this state.
847 Negative => reduce, -yyn is rule number.
848 Positive => shift, yyn is new state.
849 New state is final state => don't bother to shift,
850 just return success.
851 0, or most negative number => error. */
852
853 if (yyn < 0)
854 {
855 if (yyn == YYFLAG)
856 goto yyerrlab;
857 yyn = -yyn;
858 goto yyreduce;
859 }
860 else if (yyn == 0)
861 goto yyerrlab;
862
863 if (yyn == YYFINAL)
864 YYACCEPT;
865
866 /* Shift the lookahead token. */
867
868#if YYDEBUG != 0
869 if (yydebug)
870 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
871#endif
872
873 /* Discard the token being shifted unless it is eof. */
874 if (yychar != YYEOF)
875 yychar = YYEMPTY;
876
877 *++yyvsp = yylval;
878#ifdef YYLSP_NEEDED
879 *++yylsp = yylloc;
880#endif
881
882 /* count tokens shifted since error; after three, turn off error status. */
883 if (yyerrstatus) yyerrstatus--;
884
885 yystate = yyn;
886 goto yynewstate;
887
888/* Do the default action for the current state. */
889yydefault:
890
891 yyn = yydefact[yystate];
892 if (yyn == 0)
893 goto yyerrlab;
894
895/* Do a reduction. yyn is the number of a rule to reduce with. */
896yyreduce:
897 yylen = yyr2[yyn];
898 if (yylen > 0)
899 yyval = yyvsp[1-yylen]; /* implement default value of the action */
900
901#if YYDEBUG != 0
902 if (yydebug)
903 {
904 int i;
905
906 fprintf (stderr, "Reducing via rule %d (line %d), ",
907 yyn, yyrline[yyn]);
908
909 /* Print the symbols being reduced, and their result. */
910 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
911 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
912 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
913 }
914#endif
915
916
917 switch (yyn) {
918
919case 2:
920#line 213 "./vcc.y"
921{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; ;
922 break;}
923case 4:
924#line 216 "./vcc.y"
925{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; ;
926 break;}
927case 7:
928#line 225 "./vcc.y"
929{
930 lexPushMode(L_VCARD);
931 if (!pushVObject(VCCardProp)) YYERROR;
932 ;
933 break;}
934case 8:
935#line 230 "./vcc.y"
936{
937 lexPopMode(0);
938 yyval.vobj = popVObject();
939 ;
940 break;}
941case 9:
942#line 235 "./vcc.y"
943{
944 lexPushMode(L_VCARD);
945 if (!pushVObject(VCCardProp)) YYERROR;
946 ;
947 break;}
948case 10:
949#line 240 "./vcc.y"
950{
951 lexPopMode(0);
952 yyval.vobj = popVObject();
953 ;
954 break;}
955case 13:
956#line 251 "./vcc.y"
957{
958 lexPushMode(L_VALUES);
959 ;
960 break;}
961case 14:
962#line 255 "./vcc.y"
963{
964 if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
965 lexPopMode(0);
966 lexPopMode(0);
967 ;
968 break;}
969case 16:
970#line 264 "./vcc.y"
971{
972 enterProps(yyvsp[0].str);
973 ;
974 break;}
975case 18:
976#line 269 "./vcc.y"
977{
978 enterProps(yyvsp[0].str);
979 ;
980 break;}
981case 22:
982#line 282 "./vcc.y"
983{
984 enterAttr(yyvsp[0].str,0);
985 ;
986 break;}
987case 23:
988#line 286 "./vcc.y"
989{
990 enterAttr(yyvsp[-2].str,yyvsp[0].str);
991
992 ;
993 break;}
994case 25:
995#line 295 "./vcc.y"
996{ appendValue(yyvsp[-1].str); ;
997 break;}
998case 27:
999#line 297 "./vcc.y"
1000{ appendValue(yyvsp[0].str); ;
1001 break;}
1002case 29:
1003#line 302 "./vcc.y"
1004{ yyval.str = 0; ;
1005 break;}
1006case 30:
1007#line 307 "./vcc.y"
1008{ if (!pushVObject(VCCalProp)) YYERROR; ;
1009 break;}
1010case 31:
1011#line 310 "./vcc.y"
1012{ yyval.vobj = popVObject(); ;
1013 break;}
1014case 32:
1015#line 312 "./vcc.y"
1016{ if (!pushVObject(VCCalProp)) YYERROR; ;
1017 break;}
1018case 33:
1019#line 314 "./vcc.y"
1020{ yyval.vobj = popVObject(); ;
1021 break;}
1022case 39:
1023#line 329 "./vcc.y"
1024{
1025 lexPushMode(L_VEVENT);
1026 if (!pushVObject(VCEventProp)) YYERROR;
1027 ;
1028 break;}
1029case 40:
1030#line 335 "./vcc.y"
1031{
1032 lexPopMode(0);
1033 popVObject();
1034 ;
1035 break;}
1036case 41:
1037#line 340 "./vcc.y"
1038{
1039 lexPushMode(L_VEVENT);
1040 if (!pushVObject(VCEventProp)) YYERROR;
1041 ;
1042 break;}
1043case 42:
1044#line 345 "./vcc.y"
1045{
1046 lexPopMode(0);
1047 popVObject();
1048 ;
1049 break;}
1050case 43:
1051#line 353 "./vcc.y"
1052{
1053 lexPushMode(L_VTODO);
1054 if (!pushVObject(VCTodoProp)) YYERROR;
1055 ;
1056 break;}
1057case 44:
1058#line 359 "./vcc.y"
1059{
1060 lexPopMode(0);
1061 popVObject();
1062 ;
1063 break;}
1064case 45:
1065#line 364 "./vcc.y"
1066{
1067 lexPushMode(L_VTODO);
1068 if (!pushVObject(VCTodoProp)) YYERROR;
1069 ;
1070 break;}
1071case 46:
1072#line 369 "./vcc.y"
1073{
1074 lexPopMode(0);
1075 popVObject();
1076 ;
1077 break;}
1078}
1079 /* the action file gets copied in in place of this dollarsign */
1080#line 543 "/usr/share/bison.simple"
1081
1082 yyvsp -= yylen;
1083 yyssp -= yylen;
1084#ifdef YYLSP_NEEDED
1085 yylsp -= yylen;
1086#endif
1087
1088#if YYDEBUG != 0
1089 if (yydebug)
1090 {
1091 short *ssp1 = yyss - 1;
1092 fprintf (stderr, "state stack now");
1093 while (ssp1 != yyssp)
1094 fprintf (stderr, " %d", *++ssp1);
1095 fprintf (stderr, "\n");
1096 }
1097#endif
1098
1099 *++yyvsp = yyval;
1100
1101#ifdef YYLSP_NEEDED
1102 yylsp++;
1103 if (yylen == 0)
1104 {
1105 yylsp->first_line = yylloc.first_line;
1106 yylsp->first_column = yylloc.first_column;
1107 yylsp->last_line = (yylsp-1)->last_line;
1108 yylsp->last_column = (yylsp-1)->last_column;
1109 yylsp->text = 0;
1110 }
1111 else
1112 {
1113 yylsp->last_line = (yylsp+yylen-1)->last_line;
1114 yylsp->last_column = (yylsp+yylen-1)->last_column;
1115 }
1116#endif
1117
1118 /* Now "shift" the result of the reduction.
1119 Determine what state that goes to,
1120 based on the state we popped back to
1121 and the rule number reduced by. */
1122
1123 yyn = yyr1[yyn];
1124
1125 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1126 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1127 yystate = yytable[yystate];
1128 else
1129 yystate = yydefgoto[yyn - YYNTBASE];
1130
1131 goto yynewstate;
1132
1133yyerrlab: /* here on detecting error */
1134
1135 if (! yyerrstatus)
1136 /* If not already recovering from an error, report this error. */
1137 {
1138 ++yynerrs;
1139
1140#ifdef YYERROR_VERBOSE
1141 yyn = yypact[yystate];
1142
1143 if (yyn > YYFLAG && yyn < YYLAST)
1144 {
1145 int size = 0;
1146 char *msg;
1147 int x, count;
1148
1149 count = 0;
1150 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1151 for (x = (yyn < 0 ? -yyn : 0);
1152 x < (sizeof(yytname) / sizeof(char *)); x++)
1153 if (yycheck[x + yyn] == x)
1154 size += strlen(yytname[x]) + 15, count++;
1155 msg = (char *) malloc(size + 15);
1156 if (msg != 0)
1157 {
1158 strcpy(msg, "parse error");
1159
1160 if (count < 5)
1161 {
1162 count = 0;
1163 for (x = (yyn < 0 ? -yyn : 0);
1164 x < (sizeof(yytname) / sizeof(char *)); x++)
1165 if (yycheck[x + yyn] == x)
1166 {
1167 strcat(msg, count == 0 ? ", expecting `" : " or `");
1168 strcat(msg, yytname[x]);
1169 strcat(msg, "'");
1170 count++;
1171 }
1172 }
1173 yyerror(msg);
1174 free(msg);
1175 }
1176 else
1177 yyerror ("parse error; also virtual memory exceeded");
1178 }
1179 else
1180#endif /* YYERROR_VERBOSE */
1181 yyerror("parse error");
1182 }
1183
1184 goto yyerrlab1;
1185yyerrlab1: /* here on error raised explicitly by an action */
1186
1187 if (yyerrstatus == 3)
1188 {
1189 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1190
1191 /* return failure if at end of input */
1192 if (yychar == YYEOF)
1193 YYABORT;
1194
1195#if YYDEBUG != 0
1196 if (yydebug)
1197 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1198#endif
1199
1200 yychar = YYEMPTY;
1201 }
1202
1203 /* Else will try to reuse lookahead token
1204 after shifting the error token. */
1205
1206 yyerrstatus = 3; /* Each real token shifted decrements this */
1207
1208 goto yyerrhandle;
1209
1210yyerrdefault: /* current state does not do anything special for the error token. */
1211
1212#if 0
1213 /* This is wrong; only states that explicitly want error tokens
1214 should shift them. */
1215 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1216 if (yyn) goto yydefault;
1217#endif
1218
1219yyerrpop: /* pop the current state because it cannot handle the error token */
1220
1221 if (yyssp == yyss) YYABORT;
1222 yyvsp--;
1223 yystate = *--yyssp;
1224#ifdef YYLSP_NEEDED
1225 yylsp--;
1226#endif
1227
1228#if YYDEBUG != 0
1229 if (yydebug)
1230 {
1231 short *ssp1 = yyss - 1;
1232 fprintf (stderr, "Error: state stack now");
1233 while (ssp1 != yyssp)
1234 fprintf (stderr, " %d", *++ssp1);
1235 fprintf (stderr, "\n");
1236 }
1237#endif
1238
1239yyerrhandle:
1240
1241 yyn = yypact[yystate];
1242 if (yyn == YYFLAG)
1243 goto yyerrdefault;
1244
1245 yyn += YYTERROR;
1246 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1247 goto yyerrdefault;
1248
1249 yyn = yytable[yyn];
1250 if (yyn < 0)
1251 {
1252 if (yyn == YYFLAG)
1253 goto yyerrpop;
1254 yyn = -yyn;
1255 goto yyreduce;
1256 }
1257 else if (yyn == 0)
1258 goto yyerrpop;
1259
1260 if (yyn == YYFINAL)
1261 YYACCEPT;
1262
1263#if YYDEBUG != 0
1264 if (yydebug)
1265 fprintf(stderr, "Shifting error token, ");
1266#endif
1267
1268 *++yyvsp = yylval;
1269#ifdef YYLSP_NEEDED
1270 *++yylsp = yylloc;
1271#endif
1272
1273 yystate = yyn;
1274 goto yynewstate;
1275
1276 yyacceptlab:
1277 /* YYACCEPT comes here. */
1278 if (yyfree_stacks)
1279 {
1280 free (yyss);
1281 free (yyvs);
1282#ifdef YYLSP_NEEDED
1283 free (yyls);
1284#endif
1285 }
1286 return 0;
1287
1288 yyabortlab:
1289 /* YYABORT comes here. */
1290 if (yyfree_stacks)
1291 {
1292 free (yyss);
1293 free (yyvs);
1294#ifdef YYLSP_NEEDED
1295 free (yyls);
1296#endif
1297 }
1298 return 1;
1299}
1300#line 375 "./vcc.y"
1301
1302/****************************************************************************/
1303static int pushVObject(const char *prop)
1304 {
1305 VObject *newObj;
1306 if (ObjStackTop == MAXLEVEL)
1307 return FALSE;
1308
1309 ObjStack[++ObjStackTop] = curObj;
1310
1311 if (curObj) {
1312 newObj = addProp(curObj,prop);
1313 curObj = newObj;
1314 }
1315 else
1316 curObj = newVObject(prop);
1317
1318 return TRUE;
1319 }
1320
1321
1322/****************************************************************************/
1323/* This pops the recently built vCard off the stack and returns it. */
1324static VObject* popVObject()
1325 {
1326 VObject *oldObj;
1327 if (ObjStackTop < 0) {
1328 yyerror("pop on empty Object Stack\n");
1329 return 0;
1330 }
1331 oldObj = curObj;
1332 curObj = ObjStack[ObjStackTop--];
1333
1334 return oldObj;
1335 }
1336
1337
1338/* static void enterValues(const char *value) */
1339/* { */
1340/* if (fieldedProp && *fieldedProp) { */
1341 /* if (value) { */
1342 /* addPropValue(curProp,*fieldedProp,value); */
1343 /* } */
1344 /* else this field is empty, advance to next field */
1345 /* fieldedProp++; */
1346 /* } */
1347/* else { */
1348 /* if (value) { */
1349 /* setVObjectUStringZValue_(curProp,fakeUnicode(value,0)); */
1350 /* } */
1351 /* } */
1352/* deleteStr(value); */
1353/* } */
1354
1355static void appendValue(const char *value)
1356{
1357 char *p1, *p2;
1358 wchar_t *p3;
1359 int i;
1360
1361 if (fieldedProp && *fieldedProp) {
1362 if (value) {
1363 addPropValue(curProp, *fieldedProp, value);
1364 }
1365 /* else this field is empty, advance to next field */
1366 fieldedProp++;
1367 } else {
1368 if (value) {
1369 if (vObjectUStringZValue(curProp)) {
1370 p1 = fakeCString(vObjectUStringZValue(curProp));
1371 p2 = malloc(sizeof(char *) * (strlen(p1)+strlen(value)+1));
1372 strcpy(p2, p1);
1373 deleteStr(p1);
1374
1375 i = strlen(p2);
1376 p2[i] = ',';
1377 p2[i+1] = '\0';
1378 p2 = strcat(p2, value);
1379 p3 = (wchar_t *) vObjectUStringZValue(curProp);
1380 free(p3);
1381 setVObjectUStringZValue_(curProp,fakeUnicode(p2,0));
1382 deleteStr(p2);
1383 } else {
1384 setVObjectUStringZValue_(curProp,fakeUnicode(value,0));
1385 }
1386 }
1387 }
1388 deleteStr(value);
1389}
1390
1391
1392static void enterProps(const char *s)
1393 {
1394 curProp = addGroup(curObj,s);
1395 deleteStr(s);
1396 }
1397
1398static void enterAttr(const char *s1, const char *s2)
1399 {
1400 const char *p1=0L, *p2=0L;
1401 p1 = lookupProp_(s1);
1402 if (s2) {
1403 VObject *a;
1404 p2 = lookupProp_(s2);
1405 a = addProp(curProp,p1);
1406 setVObjectStringZValue(a,p2);
1407 }
1408 else
1409 addProp(curProp,p1);
1410 if (strcasecmp(p1,VCBase64Prop) == 0 || (s2 && strcasecmp(p2,VCBase64Prop)==0))
1411 lexPushMode(L_BASE64);
1412 else if (strcasecmp(p1,VCQuotedPrintableProp) == 0
1413 || (s2 && strcasecmp(p2,VCQuotedPrintableProp)==0))
1414 lexPushMode(L_QUOTED_PRINTABLE);
1415 deleteStr(s1); deleteStr(s2);
1416 }
1417
1418
1419#define MAX_LEX_LOOKAHEAD_0 32
1420#define MAX_LEX_LOOKAHEAD 64
1421#define MAX_LEX_MODE_STACK_SIZE 10
1422#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
1423
1424struct LexBuf {
1425 /* input */
1426 FILE *inputFile;
1427 char *inputString;
1428 unsigned long curPos;
1429 unsigned long inputLen;
1430 /* lookahead buffer */
1431 /* -- lookahead buffer is short instead of char so that EOF
1432 / can be represented correctly.
1433 */
1434 unsigned long len;
1435 short buf[MAX_LEX_LOOKAHEAD];
1436 unsigned long getPtr;
1437 /* context stack */
1438 unsigned long lexModeStackTop;
1439 enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE];
1440 /* token buffer */
1441 unsigned long maxToken;
1442 char *strs;
1443 unsigned long strsLen;
1444 } lexBuf;
1445
1446static void lexPushMode(enum LexMode mode)
1447 {
1448 if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1))
1449 yyerror("lexical context stack overflow");
1450 else {
1451 lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
1452 }
1453 }
1454
1455static void lexPopMode(int top)
1456 {
1457 /* special case of pop for ease of error recovery -- this
1458 version will never underflow */
1459 if (top)
1460 lexBuf.lexModeStackTop = 0;
1461 else
1462 if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--;
1463 }
1464
1465static int lexWithinMode(enum LexMode mode) {
1466 unsigned long i;
1467 for (i=0;i<lexBuf.lexModeStackTop;i++)
1468 if (mode == lexBuf.lexModeStack[i]) return 1;
1469 return 0;
1470 }
1471
1472static int lexGetc_()
1473 {
1474 /* get next char from input, no buffering. */
1475 if (lexBuf.curPos == lexBuf.inputLen)
1476 return EOF;
1477 else if (lexBuf.inputString)
1478 return *(lexBuf.inputString + lexBuf.curPos++);
1479 else {
1480 if (!feof(lexBuf.inputFile))
1481 return fgetc(lexBuf.inputFile);
1482 else
1483 return EOF;
1484 }
1485 }
1486
1487static int lexGeta()
1488 {
1489 ++lexBuf.len;
1490 return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
1491 }
1492
1493static int lexGeta_(int i)
1494 {
1495 ++lexBuf.len;
1496 return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_());
1497 }
1498
1499static void lexSkipLookahead() {
1500 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
1501 /* don't skip EOF. */
1502 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
1503 lexBuf.len--;
1504 }
1505 }
1506
1507static int lexLookahead() {
1508 int c = (lexBuf.len)?
1509 lexBuf.buf[lexBuf.getPtr]:
1510 lexGeta();
1511 /* do the \r\n -> \n or \r -> \n translation here */
1512 if (c == '\r') {
1513 int a = (lexBuf.len>1)?
1514 lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]:
1515 lexGeta_(1);
1516 if (a == '\n') {
1517 lexSkipLookahead();
1518 }
1519 lexBuf.buf[lexBuf.getPtr] = c = '\n';
1520 }
1521 else if (c == '\n') {
1522 int a;
1523 if (lexBuf.len > 1)
1524 a = lexBuf.buf[lexBuf.getPtr];
1525 else
1526 a = lexGeta_(1);
1527 if (a == '\r') {
1528 lexSkipLookahead();
1529 }
1530 lexBuf.buf[lexBuf.getPtr] = '\n';
1531 }
1532 return c;
1533 }
1534
1535static int lexGetc() {
1536 int c = lexLookahead();
1537 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
1538 /* EOF will remain in lookahead buffer */
1539 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
1540 lexBuf.len--;
1541 }
1542 return c;
1543 }
1544
1545static void lexSkipLookaheadWord() {
1546 if (lexBuf.strsLen <= lexBuf.len) {
1547 lexBuf.len -= lexBuf.strsLen;
1548 lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD;
1549 }
1550 }
1551
1552static void lexClearToken()
1553 {
1554 lexBuf.strsLen = 0;
1555 }
1556
1557static void lexAppendc(int c)
1558 {
1559 /* not sure if I am doing this right to fix purify report -- PGB */
1560 lexBuf.strs = (char *) realloc(lexBuf.strs, (size_t) lexBuf.strsLen + 1);
1561 lexBuf.strs[lexBuf.strsLen] = c;
1562 /* append up to zero termination */
1563 if (c == 0) return;
1564 lexBuf.strsLen++;
1565 if (lexBuf.strsLen > lexBuf.maxToken) {
1566 /* double the token string size */
1567 lexBuf.maxToken <<= 1;
1568 lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken);
1569 }
1570 }
1571
1572static char* lexStr() {
1573 return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1);
1574 }
1575
1576static void lexSkipWhite() {
1577 int c = lexLookahead();
1578 while (c == ' ' || c == '\t') {
1579 lexSkipLookahead();
1580 c = lexLookahead();
1581 }
1582 }
1583
1584static char* lexGetWord() {
1585 int c;
1586 lexSkipWhite();
1587 lexClearToken();
1588 c = lexLookahead();
1589 /* some "words" have a space in them, like "NEEDS ACTION".
1590 this may be an oversight of the spec, but it is true nevertheless.
1591 while (c != EOF && !strchr("\t\n ;:=",c)) { */
1592 while (c != EOF && !strchr("\n;:=",c)) {
1593 lexAppendc(c);
1594 lexSkipLookahead();
1595 c = lexLookahead();
1596 }
1597 lexAppendc(0);
1598 return lexStr();
1599 }
1600
1601void lexPushLookahead(char *s, int len) {
1602 int putptr;
1603 if (len == 0) len = strlen(s);
1604 putptr = (int)lexBuf.getPtr - len;
1605 /* this function assumes that length of word to push back
1606 / is not greater than MAX_LEX_LOOKAHEAD.
1607 */
1608 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
1609 lexBuf.getPtr = putptr;
1610 while (*s) {
1611 lexBuf.buf[putptr] = *s++;
1612 putptr = (putptr + 1) % MAX_LEX_LOOKAHEAD;
1613 }
1614 lexBuf.len += len;
1615 }
1616
1617static void lexPushLookaheadc(int c) {
1618 int putptr;
1619 /* can't putback EOF, because it never leaves lookahead buffer */
1620 if (c == EOF) return;
1621 putptr = (int)lexBuf.getPtr - 1;
1622 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
1623 lexBuf.getPtr = putptr;
1624 lexBuf.buf[putptr] = c;
1625 lexBuf.len += 1;
1626 }
1627
1628static char* lexLookaheadWord() {
1629 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
1630 / and thing bigger than that will stop the lookahead and return 0;
1631 / leading white spaces are not recoverable.
1632 */
1633 int c;
1634 int len = 0;
1635 int curgetptr = 0;
1636 lexSkipWhite();
1637 lexClearToken();
1638 curgetptr = (int)lexBuf.getPtr;/* remember! */
1639 while (len < (MAX_LEX_LOOKAHEAD_0)) {
1640 c = lexGetc();
1641 len++;
1642 if (c == EOF || strchr("\t\n ;:=", c)) {
1643 lexAppendc(0);
1644 /* restore lookahead buf. */
1645 lexBuf.len += len;
1646 lexBuf.getPtr = curgetptr;
1647 return lexStr();
1648 }
1649 else
1650 lexAppendc(c);
1651 }
1652 lexBuf.len += len;/* char that has been moved to lookahead buffer */
1653 lexBuf.getPtr = curgetptr;
1654 return 0;
1655 }
1656
1657#ifdef _SUPPORT_LINE_FOLDING
1658static void handleMoreRFC822LineBreak(int c) {
1659 /* suport RFC 822 line break in cases like
1660 *ADR: foo;
1661 * morefoo;
1662 * more foo;
1663 */
1664 if (c == ';') {
1665 int a;
1666 lexSkipLookahead();
1667 /* skip white spaces */
1668 a = lexLookahead();
1669 while (a == ' ' || a == '\t') {
1670 lexSkipLookahead();
1671 a = lexLookahead();
1672 }
1673 if (a == '\n') {
1674 lexSkipLookahead();
1675 a = lexLookahead();
1676 if (a == ' ' || a == '\t') {
1677 /* continuation, throw away all the \n and spaces read so
1678 * far
1679 */
1680 lexSkipWhite();
1681 lexPushLookaheadc(';');
1682 }
1683 else {
1684 lexPushLookaheadc('\n');
1685 lexPushLookaheadc(';');
1686 }
1687 }
1688 else {
1689 lexPushLookaheadc(';');
1690 }
1691 }
1692 }
1693
1694static char* lexGet1Value() {
1695 int c;
1696 lexSkipWhite();
1697 c = lexLookahead();
1698 lexClearToken();
1699 while (c != EOF && c != ';') {
1700 if (c == '\n') {
1701 int a;
1702 lexSkipLookahead();
1703 a = lexLookahead();
1704 if (a == ' ' || a == '\t') {
1705 lexAppendc(' ');
1706 lexSkipLookahead();
1707 }
1708 else {
1709 lexPushLookaheadc('\n');
1710 break;
1711 }
1712 }
1713 else {
1714 lexAppendc(c);
1715 lexSkipLookahead();
1716 }
1717 c = lexLookahead();
1718 }
1719 lexAppendc(0);
1720 handleMoreRFC822LineBreak(c);
1721 return c==EOF?0:lexStr();
1722 }
1723#endif
1724
1725char* lexGetStrUntil(char *termset) {
1726 int c = lexLookahead();
1727 lexClearToken();
1728 while (c != EOF && !strchr(termset,c)) {
1729 lexAppendc(c);
1730 lexSkipLookahead();
1731 c = lexLookahead();
1732 }
1733 lexAppendc(0);
1734 return c==EOF?0:lexStr();
1735 }
1736
1737static int match_begin_name(int end) {
1738 char *n = lexLookaheadWord();
1739 int token = ID;
1740 if (n) {
1741 if (!strcasecmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
1742 else if (!strcasecmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
1743 else if (!strcasecmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
1744 else if (!strcasecmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
1745 deleteStr(n);
1746 return token;
1747 }
1748 return 0;
1749 }
1750
1751
1752void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
1753 {
1754 /* initialize lex mode stack */
1755 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
1756
1757 /* iniatialize lex buffer. */
1758 lexBuf.inputString = (char*) inputstring;
1759 lexBuf.inputLen = inputlen;
1760 lexBuf.curPos = 0;
1761 lexBuf.inputFile = inputfile;
1762
1763 lexBuf.len = 0;
1764 lexBuf.getPtr = 0;
1765
1766 lexBuf.maxToken = MAXTOKEN;
1767 lexBuf.strs = (char*)malloc(MAXTOKEN);
1768 lexBuf.strsLen = 0;
1769
1770 }
1771
1772static void finiLex() {
1773 free(lexBuf.strs);
1774 }
1775
1776
1777/****************************************************************************/
1778/* This parses and converts the base64 format for binary encoding into
1779 * a decoded buffer (allocated with new). See RFC 1521.
1780 */
1781static char * lexGetDataFromBase64()
1782 {
1783 unsigned long bytesLen = 0, bytesMax = 0;
1784 int quadIx = 0, pad = 0;
1785 unsigned long trip = 0;
1786 unsigned char b;
1787 int c;
1788 unsigned char *bytes = NULL;
1789 unsigned char *oldBytes = NULL;
1790
1791 DBG_(("db: lexGetDataFromBase64\n"));
1792 while (1) {
1793 c = lexGetc();
1794 if (c == '\n') {
1795 ++mime_lineNum;
1796 if (lexLookahead() == '\n') {
1797 /* a '\n' character by itself means end of data */
1798 break;
1799 }
1800 else continue; /* ignore '\n' */
1801 }
1802 else {
1803 if ((c >= 'A') && (c <= 'Z'))
1804 b = (unsigned char)(c - 'A');
1805 else if ((c >= 'a') && (c <= 'z'))
1806 b = (unsigned char)(c - 'a') + 26;
1807 else if ((c >= '0') && (c <= '9'))
1808 b = (unsigned char)(c - '0') + 52;
1809 else if (c == '+')
1810 b = 62;
1811 else if (c == '/')
1812 b = 63;
1813 else if (c == '=') {
1814 b = 0;
1815 pad++;
1816 } else if ((c == ' ') || (c == '\t')) {
1817 continue;
1818 } else { /* error condition */
1819 if (bytes) free(bytes);
1820 else if (oldBytes) free(oldBytes);
1821 /* error recovery: skip until 2 adjacent newlines. */
1822 DBG_(("db: invalid character 0x%x '%c'\n", c,c));
1823 if (c != EOF) {
1824 c = lexGetc();
1825 while (c != EOF) {
1826 if (c == '\n' && lexLookahead() == '\n') {
1827 ++mime_lineNum;
1828 break;
1829 }
1830 c = lexGetc();
1831 }
1832 }
1833 return NULL;
1834 }
1835 trip = (trip << 6) | b;
1836 if (++quadIx == 4) {
1837 unsigned char outBytes[3];
1838 int numOut;
1839 int i;
1840 for (i = 0; i < 3; i++) {
1841 outBytes[2-i] = (unsigned char)(trip & 0xFF);
1842 trip >>= 8;
1843 }
1844 numOut = 3 - pad;
1845 if (bytesLen + numOut > bytesMax) {
1846 if (!bytes) {
1847 bytesMax = 1024;
1848 bytes = (unsigned char*)malloc((size_t)bytesMax);
1849 }
1850 else {
1851 bytesMax <<= 2;
1852 oldBytes = bytes;
1853 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
1854 }
1855 if (bytes == 0) {
1856 mime_error("out of memory while processing BASE64 data\n");
1857 }
1858 }
1859 if (bytes) {
1860 memcpy(bytes + bytesLen, outBytes, numOut);
1861 bytesLen += numOut;
1862 }
1863 trip = 0;
1864 quadIx = 0;
1865 }
1866 }
1867 } /* while */
1868 DBG_(("db: bytesLen = %d\n", bytesLen));
1869 /* kludge: all this won't be necessary if we have tree form
1870 representation */
1871 if (bytes) {
1872 setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
1873 free(bytes);
1874 }
1875 else if (oldBytes) {
1876 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
1877 free(oldBytes);
1878 }
1879 return 0;
1880 }
1881
1882static int match_begin_end_name(int end) {
1883 int token;
1884 lexSkipWhite();
1885 if (lexLookahead() != ':') return ID;
1886 lexSkipLookahead();
1887 lexSkipWhite();
1888 token = match_begin_name(end);
1889 if (token == ID) {
1890 lexPushLookaheadc(':');
1891 DBG_(("db: ID '%s'\n", yylval.str));
1892 return ID;
1893 }
1894 else if (token != 0) {
1895 lexSkipLookaheadWord();
1896 deleteStr(yylval.str);
1897 DBG_(("db: begin/end %d\n", token));
1898 return token;
1899 }
1900 return 0;
1901 }
1902
1903static char* lexGetQuotedPrintable()
1904 {
1905 char cur;
1906
1907 lexClearToken();
1908 do {
1909 cur = lexGetc();
1910 switch (cur) {
1911 case '=': {
1912 int c = 0;
1913 int next[2];
1914 int i;
1915 for (i = 0; i < 2; i++) {
1916 next[i] = lexGetc();
1917 if (next[i] >= '0' && next[i] <= '9')
1918 c = c * 16 + next[i] - '0';
1919 else if (next[i] >= 'A' && next[i] <= 'F')
1920 c = c * 16 + next[i] - 'A' + 10;
1921 else
1922 break;
1923 }
1924 if (i == 0) {
1925 /* single '=' follow by LINESEP is continuation sign? */
1926 if (next[0] == '\n') {
1927 ++mime_lineNum;
1928 }
1929 else {
1930 lexPushLookaheadc('=');
1931 goto EndString;
1932 }
1933 }
1934 else if (i == 1) {
1935 lexPushLookaheadc(next[1]);
1936 lexPushLookaheadc(next[0]);
1937 lexAppendc('=');
1938 } else {
1939 lexAppendc(c);
1940 }
1941 break;
1942 } /* '=' */
1943 case '\n': {
1944 lexPushLookaheadc('\n');
1945 goto EndString;
1946 }
1947 case (char)EOF:
1948 break;
1949 default:
1950 lexAppendc(cur);
1951 break;
1952 } /* switch */
1953 } while (cur != (char)EOF);
1954
1955EndString:
1956 lexAppendc(0);
1957 return lexStr();
1958 } /* LexQuotedPrintable */
1959
1960static int yylex() {
1961
1962 int lexmode = LEXMODE();
1963 if (lexmode == L_VALUES) {
1964 int c = lexGetc();
1965 if (c == ';') {
1966 DBG_(("db: SEMICOLON\n"));
1967 lexPushLookaheadc(c);
1968 handleMoreRFC822LineBreak(c);
1969 lexSkipLookahead();
1970 return SEMICOLON;
1971 }
1972 else if (strchr("\n",c)) {
1973 ++mime_lineNum;
1974 /* consume all line separator(s) adjacent to each other */
1975 c = lexLookahead();
1976 while (strchr("\n",c)) {
1977 lexSkipLookahead();
1978 c = lexLookahead();
1979 ++mime_lineNum;
1980 }
1981 DBG_(("db: LINESEP\n"));
1982 return LINESEP;
1983 }
1984 else {
1985 char *p = 0;
1986 lexPushLookaheadc(c);
1987 if (lexWithinMode(L_BASE64)) {
1988 /* get each char and convert to bin on the fly... */
1989 p = lexGetDataFromBase64();
1990 yylval.str = p;
1991 return STRING;
1992 }
1993 else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
1994 p = lexGetQuotedPrintable();
1995 }
1996 else {
1997#ifdef _SUPPORT_LINE_FOLDING
1998 p = lexGet1Value();
1999#else
2000 p = lexGetStrUntil(";\n");
2001#endif
2002 }
2003 if (p) {
2004 DBG_(("db: STRING: '%s'\n", p));
2005 yylval.str = p;
2006 return STRING;
2007 }
2008 else return 0;
2009 }
2010 }
2011
2012 else {
2013 /* normal mode */
2014 while (1) {
2015 int c = lexGetc();
2016 switch(c) {
2017 case ':': {
2018 /* consume all line separator(s) adjacent to each other */
2019 /* ignoring linesep immediately after colon. */
2020 c = lexLookahead();
2021 while (strchr("\n",c)) {
2022 lexSkipLookahead();
2023 c = lexLookahead();
2024 ++mime_lineNum;
2025 }
2026 DBG_(("db: COLON\n"));
2027 return COLON;
2028 }
2029 case ';':
2030 DBG_(("db: SEMICOLON\n"));
2031 return SEMICOLON;
2032 case '=':
2033 DBG_(("db: EQ\n"));
2034 return EQ;
2035 /* ignore tabs/newlines in this mode. We can't ignore
2036 * spaces, because values like NEEDS ACTION have a space. */
2037 case '\t': continue;
2038 case '\n': {
2039 ++mime_lineNum;
2040 continue;
2041 }
2042 case EOF: return 0;
2043 break;
2044 default: {
2045 lexPushLookaheadc(c);
2046 /* pending lutz : why linker error with isalpha(c)? */
2047 /*if ( isalpha(c) || c == ' ') { */
2048 if ( ( c >= 'A' && c <= 'Z') || ( c >= 'a' && c <= 'z') || c == ' ') {
2049
2050 char *t = lexGetWord();
2051 yylval.str = t;
2052 if (!strcasecmp(t, "begin")) {
2053 return match_begin_end_name(0);
2054 }
2055 else if (!strcasecmp(t,"end")) {
2056 return match_begin_end_name(1);
2057 }
2058 else {
2059 DBG_(("db: ID '%s'\n", t));
2060 return ID;
2061 }
2062 }
2063 else {
2064 /* unknown token */
2065 return 0;
2066 }
2067 break;
2068 }
2069 }
2070 }
2071 }
2072
2073 return 0;
2074 }
2075
2076
2077/***************************************************************************/
2078 /*** Public Functions ****/
2079/***************************************************************************/
2080
2081static VObject* Parse_MIMEHelper()
2082 {
2083 ObjStackTop = -1;
2084 mime_numErrors = 0;
2085 mime_lineNum = 1;
2086 vObjList = 0;
2087 curObj = 0;
2088
2089 if (yyparse() != 0)
2090 return 0;
2091
2092 finiLex();
2093 return vObjList;
2094 }
2095
2096/****************************************************************************/
2097VObject* Parse_MIME(const char *input, unsigned long len)
2098 {
2099 initLex(input, len, 0);
2100 return Parse_MIMEHelper();
2101 }
2102
2103
2104VObject* Parse_MIME_FromFile(FILE *file)
2105 {
2106 VObject *result;
2107 long startPos;
2108
2109 initLex(0,(unsigned long)-1,file);
2110 startPos = ftell(file);
2111 if (!(result = Parse_MIMEHelper())) {
2112 fseek(file,startPos,SEEK_SET);
2113 }
2114 return result;
2115 }
2116
2117VObject* Parse_MIME_FromFileName(const char *fname)
2118 {
2119 FILE *fp = fopen(fname,"r");
2120 if (fp) {
2121 VObject* o = Parse_MIME_FromFile(fp);
2122 fclose(fp);
2123 return o;
2124 }
2125 else {
2126 char msg[255];
2127 sprintf(msg, "can't open file '%s' for reading\n", fname);
2128 mime_error_(msg);
2129 return 0;
2130 }
2131 }
2132
2133/****************************************************************************/
2134void YYDebug(const char *s)
2135{
2136 Parse_Debug(s);
2137}
2138
2139
2140static MimeErrorHandler mimeErrorHandler;
2141
2142void registerMimeErrorHandler(MimeErrorHandler me)
2143 {
2144 mimeErrorHandler = me;
2145 }
2146
2147static void mime_error(char *s)
2148 {
2149 char msg[256];
2150 if (mimeErrorHandler) {
2151 sprintf(msg,"%s at line %d", s, mime_lineNum);
2152 mimeErrorHandler(msg);
2153 }
2154 }
2155
2156static void mime_error_(char *s)
2157 {
2158 if (mimeErrorHandler) {
2159 mimeErrorHandler(s);
2160 }
2161 }
2162
diff --git a/libkcal/versit/vcc.h b/libkcal/versit/vcc.h
new file mode 100644
index 0000000..03886d1
--- a/dev/null
+++ b/libkcal/versit/vcc.h
@@ -0,0 +1,76 @@
1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc.
4
5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors.
9
10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose.
14
15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including
17this software.
18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS.
22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE.
27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE.
32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36
37***************************************************************************/
38
39#ifndef __VCC_H__
40#define __VCC_H__ 1
41
42#include "vobject.h"
43
44
45#if defined(__CPLUSPLUS__) || defined(__cplusplus)
46extern "C" {
47#endif
48
49typedef void (*MimeErrorHandler)(char *);
50
51extern void registerMimeErrorHandler(MimeErrorHandler);
52
53extern VObject* Parse_MIME(const char *input, unsigned long len);
54extern VObject* Parse_MIME_FromFileName(const char* fname);
55
56
57/* NOTE regarding Parse_MIME_FromFile
58The function below, Parse_MIME_FromFile, come in two flavors,
59neither of which is exported from the DLL. Each version takes
60a CFile or FILE* as a parameter, neither of which can be
61passed across a DLL interface (at least that is my experience).
62If you are linking this code into your build directly then
63you may find them a more convenient API that the other flavors
64that take a file name. If you use them with the DLL LIB you
65will get a link error.
66*/
67
68
69extern VObject* Parse_MIME_FromFile(FILE *file);
70
71#if defined(__CPLUSPLUS__) || defined(__cplusplus)
72}
73#endif
74
75#endif /* __VCC_H__ */
76
diff --git a/libkcal/versit/versit.pro b/libkcal/versit/versit.pro
new file mode 100644
index 0000000..915c25c
--- a/dev/null
+++ b/libkcal/versit/versit.pro
@@ -0,0 +1,15 @@
1 TEMPLATE= lib
2 CONFIG = qt warn_on release
3 TARGET = versit
4INTERFACES = \
5
6HEADERS = \
7 port.h \
8 vcc.h \
9 vobject.h \
10
11SOURCES = \
12 \ \
13 vcc.c \
14 vobject.c \
15
diff --git a/libkcal/versit/versit.pro.back b/libkcal/versit/versit.pro.back
new file mode 100644
index 0000000..915c25c
--- a/dev/null
+++ b/libkcal/versit/versit.pro.back
@@ -0,0 +1,15 @@
1 TEMPLATE= lib
2 CONFIG = qt warn_on release
3 TARGET = versit
4INTERFACES = \
5
6HEADERS = \
7 port.h \
8 vcc.h \
9 vobject.h \
10
11SOURCES = \
12 \ \
13 vcc.c \
14 vobject.c \
15
diff --git a/libkcal/versit/vobject.c b/libkcal/versit/vobject.c
new file mode 100644
index 0000000..637efb2
--- a/dev/null
+++ b/libkcal/versit/vobject.c
@@ -0,0 +1,1433 @@
1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc.
4
5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors.
9
10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose.
14
15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including
17this software.
18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS.
22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE.
27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE.
32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36
37***************************************************************************/
38
39/*
40 * src: vobject.c
41 * doc: vobject and APIs to construct vobject, APIs pretty print
42 * vobject, and convert a vobject into its textual representation.
43 */
44
45#include <stdlib.h>
46
47#include "vobject.h"
48#include <string.h>
49#include <stdio.h>
50#ifdef _WIN32_
51
52 #define strcasecmp _stricmp
53
54#endif
55
56 #define NAME_OF(o) o->id
57 #define VALUE_TYPE(o) o->valType
58 #define STRINGZ_VALUE_OF(o) o->val.strs
59 #define USTRINGZ_VALUE_OF(o)o->val.ustrs
60 #define INTEGER_VALUE_OF(o) o->val.i
61 #define LONG_VALUE_OF(o) o->val.l
62 #define ANY_VALUE_OF(o) o->val.any
63 #define VOBJECT_VALUE_OF(o) o->val.vobj
64
65const char** fieldedProp;
66
67
68
69/*----------------------------------------------------------------------
70 The following functions involve with memory allocation:
71 newVObject
72 deleteVObject
73 dupStr
74 deleteStr
75 newStrItem
76 deleteStrItem
77 ----------------------------------------------------------------------*/
78
79VObject* newVObject_(const char *id)
80{
81 VObject *p = (VObject*)malloc(sizeof(VObject));
82 p->next = 0;
83 p->id = id;
84 p->prop = 0;
85 VALUE_TYPE(p) = 0;
86 ANY_VALUE_OF(p) = 0;
87 return p;
88}
89
90VObject* newVObject(const char *id)
91{
92 return newVObject_(lookupStr(id));
93}
94
95void deleteVObject(VObject *p)
96{
97 if (p->id)
98 unUseStr(p->id);
99 if (p)
100 free(p);
101 p = NULL;
102}
103
104char* dupStr(const char *s, unsigned int size)
105{
106 char *t;
107 if (size == 0) {
108 size = strlen(s);
109 }
110 t = (char*)malloc(size+1);
111 if (t) {
112 memcpy(t,s,size);
113 t[size] = 0;
114 return t;
115 }
116 else {
117 return (char*)0;
118 }
119}
120
121void deleteStr(const char *p)
122{
123 if (p)
124 free((void*)p);
125 p = NULL;
126}
127
128
129static StrItem* newStrItem(const char *s, StrItem *next)
130{
131 StrItem *p = (StrItem*)malloc(sizeof(StrItem));
132 p->next = next;
133 p->s = s;
134 p->refCnt = 1;
135 return p;
136}
137
138static void deleteStrItem(StrItem *p)
139{
140 if (p)
141 free((void*)p);
142 p = NULL;
143}
144
145
146/*----------------------------------------------------------------------
147 The following function provide accesses to VObject's value.
148 ----------------------------------------------------------------------*/
149
150const char* vObjectName(VObject *o)
151{
152 return NAME_OF(o);
153}
154
155void setVObjectName(VObject *o, const char* id)
156{
157 NAME_OF(o) = id;
158}
159
160const char* vObjectStringZValue(VObject *o)
161{
162 return STRINGZ_VALUE_OF(o);
163}
164
165void setVObjectStringZValue(VObject *o, const char *s)
166{
167 STRINGZ_VALUE_OF(o) = dupStr(s,0);
168 VALUE_TYPE(o) = VCVT_STRINGZ;
169}
170
171void setVObjectStringZValue_(VObject *o, const char *s)
172{
173 STRINGZ_VALUE_OF(o) = s;
174 VALUE_TYPE(o) = VCVT_STRINGZ;
175}
176
177const wchar_t* vObjectUStringZValue(VObject *o)
178{
179 return USTRINGZ_VALUE_OF(o);
180}
181
182void setVObjectUStringZValue(VObject *o, const wchar_t *s)
183{
184 USTRINGZ_VALUE_OF(o) = (wchar_t*) dupStr((char*)s,(uStrLen(s)+1)*2);
185 VALUE_TYPE(o) = VCVT_USTRINGZ;
186}
187
188void setVObjectUStringZValue_(VObject *o, const wchar_t *s)
189{
190 USTRINGZ_VALUE_OF(o) = s;
191 VALUE_TYPE(o) = VCVT_USTRINGZ;
192}
193
194unsigned int vObjectIntegerValue(VObject *o)
195{
196 return INTEGER_VALUE_OF(o);
197}
198
199void setVObjectIntegerValue(VObject *o, unsigned int i)
200{
201 INTEGER_VALUE_OF(o) = i;
202 VALUE_TYPE(o) = VCVT_UINT;
203}
204
205unsigned long vObjectLongValue(VObject *o)
206{
207 return LONG_VALUE_OF(o);
208}
209
210void setVObjectLongValue(VObject *o, unsigned long l)
211{
212 LONG_VALUE_OF(o) = l;
213 VALUE_TYPE(o) = VCVT_ULONG;
214}
215
216void* vObjectAnyValue(VObject *o)
217{
218 return ANY_VALUE_OF(o);
219}
220
221void setVObjectAnyValue(VObject *o, void *t)
222{
223 ANY_VALUE_OF(o) = t;
224 VALUE_TYPE(o) = VCVT_RAW;
225}
226
227VObject* vObjectVObjectValue(VObject *o)
228{
229 return VOBJECT_VALUE_OF(o);
230}
231
232void setVObjectVObjectValue(VObject *o, VObject *p)
233{
234 VOBJECT_VALUE_OF(o) = p;
235 VALUE_TYPE(o) = VCVT_VOBJECT;
236}
237
238int vObjectValueType(VObject *o)
239{
240 return VALUE_TYPE(o);
241}
242
243
244/*----------------------------------------------------------------------
245 The following functions can be used to build VObject.
246 ----------------------------------------------------------------------*/
247
248VObject* addVObjectProp(VObject *o, VObject *p)
249{
250 /* circular link list pointed to tail */
251 /*
252 o {next,id,prop,val}
253 V
254 pn {next,id,prop,val}
255 V
256 ...
257 p1 {next,id,prop,val}
258 V
259 pn
260 -->
261 o {next,id,prop,val}
262 V
263 pn {next,id,prop,val}
264 V
265 p {next,id,prop,val}
266 ...
267 p1 {next,id,prop,val}
268 V
269 pn
270 */
271
272 VObject *tail = o->prop;
273 if (tail) {
274 p->next = tail->next;
275 o->prop = tail->next = p;
276 }
277 else {
278 o->prop = p->next = p;
279 }
280 return p;
281}
282
283VObject* addProp(VObject *o, const char *id)
284{
285 return addVObjectProp(o,newVObject(id));
286}
287
288VObject* addProp_(VObject *o, const char *id)
289{
290 return addVObjectProp(o,newVObject_(id));
291}
292
293void addList(VObject **o, VObject *p)
294{
295 p->next = 0;
296 if (*o == 0) {
297 *o = p;
298 }
299 else {
300 VObject *t = *o;
301 while (t->next) {
302 t = t->next;
303 }
304 t->next = p;
305 }
306}
307
308VObject* nextVObjectInList(VObject *o)
309{
310 return o->next;
311}
312
313VObject* setValueWithSize_(VObject *prop, void *val, unsigned int size)
314{
315 VObject *sizeProp;
316 setVObjectAnyValue(prop, val);
317 sizeProp = addProp(prop,VCDataSizeProp);
318 setVObjectLongValue(sizeProp, size);
319 return prop;
320}
321
322VObject* setValueWithSize(VObject *prop, void *val, unsigned int size)
323{
324 void *p = dupStr(val,size);
325 return setValueWithSize_(prop,p,p?size:0);
326}
327
328void initPropIterator(VObjectIterator *i, VObject *o)
329{
330 i->start = o->prop;
331 i->next = 0;
332}
333
334void initVObjectIterator(VObjectIterator *i, VObject *o)
335{
336 i->start = o->next;
337 i->next = 0;
338}
339
340int moreIteration(VObjectIterator *i)
341{
342 return (i->start && (i->next==0 || i->next!=i->start));
343}
344
345VObject* nextVObject(VObjectIterator *i)
346{
347 if (i->start && i->next != i->start) {
348 if (i->next == 0) {
349 i->next = i->start->next;
350 return i->next;
351 }
352 else {
353 i->next = i->next->next;
354 return i->next;
355 }
356 }
357 else return (VObject*)0;
358}
359
360VObject* isAPropertyOf(VObject *o, const char *id)
361{
362 VObjectIterator i;
363 initPropIterator(&i,o);
364 while (moreIteration(&i)) {
365 VObject *each = nextVObject(&i);
366 if (!strcasecmp(id,each->id))
367 return each;
368 }
369 return (VObject*)0;
370}
371
372VObject* addGroup(VObject *o, const char *g)
373{
374 /*
375 a.b.c
376 -->
377 prop(c)
378 prop(VCGrouping=b)
379 prop(VCGrouping=a)
380 */
381 char *dot = strrchr(g,'.');
382 if (dot) {
383 VObject *p, *t;
384 char *gs, *n = dot+1;
385 gs = dupStr(g,0);/* so we can write to it. */
386 /* used to be
387 * t = p = addProp_(o,lookupProp_(n));
388 */
389 t = p = addProp_(o,lookupProp(n));
390 dot = strrchr(gs,'.');
391 *dot = 0;
392 do {
393 dot = strrchr(gs,'.');
394 if (dot) {
395 n = dot+1;
396 *dot=0;
397 }
398 else
399 n = gs;
400 /* property(VCGroupingProp=n);
401 *and the value may have VCGrouping property
402 */
403 t = addProp(t,VCGroupingProp);
404 setVObjectStringZValue(t,lookupProp_(n));
405 } while (n != gs);
406 deleteStr(gs);
407 return p;
408 }
409 else
410 return addProp_(o,lookupProp(g));
411}
412
413VObject* addPropValue(VObject *o, const char *p, const char *v)
414{
415 VObject *prop;
416 prop = addProp(o,p);
417 setVObjectUStringZValue_(prop, fakeUnicode(v,0));
418 return prop;
419}
420
421VObject* addPropSizedValue_(VObject *o, const char *p, const char *v,
422 unsigned int size)
423{
424 VObject *prop;
425 prop = addProp(o,p);
426 setValueWithSize_(prop, (void*)v, size);
427 return prop;
428}
429
430VObject* addPropSizedValue(VObject *o, const char *p, const char *v,
431 unsigned int size)
432{
433 return addPropSizedValue_(o,p,dupStr(v,size),size);
434}
435
436
437
438/*----------------------------------------------------------------------
439 The following pretty print a VObject
440 ----------------------------------------------------------------------*/
441
442static void printVObject_(FILE *fp, VObject *o, int level);
443
444static void indent(FILE *fp, int level)
445{
446 int i;
447 for (i=0;i<level*4;i++) {
448 fputc(' ', fp);
449 }
450}
451
452static void printValue(FILE *fp, VObject *o, int level)
453{
454 switch (VALUE_TYPE(o)) {
455 case VCVT_USTRINGZ: {
456 char c;
457 char *t,*s;
458 s = t = fakeCString(USTRINGZ_VALUE_OF(o));
459 fputc('"',fp);
460 while (c=*t,c) {
461 fputc(c,fp);
462 if (c == '\n') indent(fp,level+2);
463 t++;
464 }
465 fputc('"',fp);
466 deleteStr(s);
467 break;
468 }
469 case VCVT_STRINGZ: {
470 char c;
471 const char *s = STRINGZ_VALUE_OF(o);
472 fputc('"',fp);
473 while (c=*s,c) {
474 fputc(c,fp);
475 if (c == '\n') indent(fp,level+2);
476 s++;
477 }
478 fputc('"',fp);
479 break;
480 }
481 case VCVT_UINT:
482 fprintf(fp,"%d", INTEGER_VALUE_OF(o)); break;
483 case VCVT_ULONG:
484 fprintf(fp,"%ld", LONG_VALUE_OF(o)); break;
485 case VCVT_RAW:
486 fprintf(fp,"[raw data]"); break;
487 case VCVT_VOBJECT:
488 fprintf(fp,"[vobject]\n");
489 printVObject_(fp,VOBJECT_VALUE_OF(o),level+1);
490 break;
491 case 0:
492 fprintf(fp,"[none]"); break;
493 default:
494 fprintf(fp,"[unknown]"); break;
495 }
496}
497
498static void printNameValue(FILE *fp,VObject *o, int level)
499{
500 indent(fp,level);
501 if (NAME_OF(o)) {
502 fprintf(fp,"%s", NAME_OF(o));
503 }
504 if (VALUE_TYPE(o)) {
505 fputc('=',fp);
506 printValue(fp,o, level);
507 }
508 fprintf(fp,"\n");
509}
510
511static void printVObject_(FILE *fp, VObject *o, int level)
512 {
513 VObjectIterator t;
514 if (o == 0) {
515 fprintf(fp,"[NULL]\n");
516 return;
517 }
518 printNameValue(fp,o,level);
519 initPropIterator(&t,o);
520 while (moreIteration(&t)) {
521 VObject *eachProp = nextVObject(&t);
522 printVObject_(fp,eachProp,level+1);
523 }
524 }
525
526void printVObject(FILE *fp,VObject *o)
527{
528 printVObject_(fp,o,0);
529}
530
531void printVObjectToFile(char *fname,VObject *o)
532{
533 FILE *fp = fopen(fname,"w");
534 if (fp) {
535 printVObject(fp,o);
536 fclose(fp);
537 }
538}
539
540void printVObjectsToFile(char *fname,VObject *list)
541{
542 FILE *fp = fopen(fname,"w");
543 if (fp) {
544 while (list) {
545 printVObject(fp,list);
546 list = nextVObjectInList(list);
547 }
548 fclose(fp);
549 }
550}
551
552void cleanVObject(VObject *o)
553{
554 if (o == 0) return;
555 if (o->prop) {
556 /* destroy time: cannot use the iterator here.
557 Have to break the cycle in the circular link
558 list and turns it into regular NULL-terminated
559 list -- since at some point of destruction,
560 the reference entry for the iterator to work
561 will not longer be valid.
562 */
563 VObject *p;
564 p = o->prop->next;
565 o->prop->next = 0;
566 do {
567 VObject *t = p->next;
568 cleanVObject(p);
569 p = t;
570 } while (p);
571 }
572 switch (VALUE_TYPE(o)) {
573 case VCVT_USTRINGZ:
574 case VCVT_STRINGZ:
575 case VCVT_RAW:
576 /* assume they are all allocated by malloc. */
577 free((char*)STRINGZ_VALUE_OF(o));
578 break;
579 case VCVT_VOBJECT:
580 cleanVObject(VOBJECT_VALUE_OF(o));
581 break;
582 }
583 deleteVObject(o);
584}
585
586void cleanVObjects(VObject *list)
587{
588 while (list) {
589 VObject *t = list;
590 list = nextVObjectInList(list);
591 cleanVObject(t);
592 }
593}
594
595/*----------------------------------------------------------------------
596 The following is a String Table Facilities.
597 ----------------------------------------------------------------------*/
598
599#define STRTBLSIZE 255
600
601static StrItem *strTbl[STRTBLSIZE];
602
603static unsigned int hashStr(const char *s)
604{
605 unsigned int h = 0;
606 int i;
607 for (i=0;s[i];i++) {
608 h += s[i]*i;
609 }
610 return h % STRTBLSIZE;
611}
612
613const char* lookupStr(const char *s)
614{
615 char *newS;
616
617 StrItem *t;
618 unsigned int h = hashStr(s);
619 if ((t = strTbl[h]) != 0) {
620 do {
621 if (strcasecmp(t->s,s) == 0) {
622 t->refCnt++;
623 return t->s;
624 }
625 t = t->next;
626 } while (t);
627 }
628 newS = dupStr(s,0);
629 strTbl[h] = newStrItem(newS,strTbl[h]);
630 return newS;
631}
632
633void unUseStr(const char *s)
634{
635 StrItem *cur, *prev;
636
637 unsigned int h = hashStr(s);
638 cur = strTbl[h];
639 prev = cur;
640 while (cur != 0) {
641 if (strcasecmp(cur->s,s) == 0) {
642 cur->refCnt--;
643 /* if that was the last reference to this string, kill it. */
644 if (cur->refCnt == 0) {
645 if (cur == strTbl[h]) {
646 strTbl[h] = cur->next;
647 deleteStr(prev->s);
648 deleteStrItem(prev);
649 } else {
650 prev->next = cur->next;
651 deleteStr(cur->s);
652 deleteStrItem(cur);
653 }
654 return;
655 }
656 }
657 prev = cur;
658 cur = cur->next;
659 }
660}
661
662void cleanStrTbl()
663{
664 int i;
665 for (i=0; i<STRTBLSIZE;i++) {
666 StrItem *t = strTbl[i];
667 while (t) {
668 StrItem *p;
669 deleteStr(t->s);
670 p = t;
671 t = t->next;
672 deleteStrItem(p);
673 }
674 strTbl[i] = 0;
675 }
676}
677
678
679struct PreDefProp {
680 const char *name;
681 const char *alias;
682 const char** fields;
683 unsigned int flags;
684 };
685
686/* flags in PreDefProp */
687 #define PD_BEGIN0x1
688 #define PD_INTERNAL0x2
689
690static const char *adrFields[] = {
691 VCPostalBoxProp,
692 VCExtAddressProp,
693 VCStreetAddressProp,
694 VCCityProp,
695 VCRegionProp,
696 VCPostalCodeProp,
697 VCCountryNameProp,
698 0
699};
700
701static const char *nameFields[] = {
702 VCFamilyNameProp,
703 VCGivenNameProp,
704 VCAdditionalNamesProp,
705 VCNamePrefixesProp,
706 VCNameSuffixesProp,
707 NULL
708 };
709
710static const char *orgFields[] = {
711 VCOrgNameProp,
712 VCOrgUnitProp,
713 VCOrgUnit2Prop,
714 VCOrgUnit3Prop,
715 VCOrgUnit4Prop,
716 NULL
717 };
718
719static const char *AAlarmFields[] = {
720 VCRunTimeProp,
721 VCSnoozeTimeProp,
722 VCRepeatCountProp,
723 VCAudioContentProp,
724 0
725 };
726
727/* ExDate -- has unamed fields */
728/* RDate -- has unamed fields */
729
730static const char *DAlarmFields[] = {
731 VCRunTimeProp,
732 VCSnoozeTimeProp,
733 VCRepeatCountProp,
734 VCDisplayStringProp,
735 0
736 };
737
738static const char *MAlarmFields[] = {
739 VCRunTimeProp,
740 VCSnoozeTimeProp,
741 VCRepeatCountProp,
742 VCEmailAddressProp,
743 VCNoteProp,
744 0
745 };
746
747static const char *PAlarmFields[] = {
748 VCRunTimeProp,
749 VCSnoozeTimeProp,
750 VCRepeatCountProp,
751 VCProcedureNameProp,
752 0
753 };
754
755static struct PreDefProp propNames[] = {
756 { VC7bitProp, 0, 0, 0 },
757 { VC8bitProp, 0, 0, 0 },
758 { VCAAlarmProp, 0, AAlarmFields, 0 },
759 { VCAdditionalNamesProp, 0, 0, 0 },
760 { VCAdrProp, 0, adrFields, 0 },
761 { VCAgentProp, 0, 0, 0 },
762 { VCAIFFProp, 0, 0, 0 },
763 { VCAOLProp, 0, 0, 0 },
764 { VCAppleLinkProp, 0, 0, 0 },
765 { VCAttachProp, 0, 0, 0 },
766 { VCAttendeeProp, 0, 0, 0 },
767 { VCATTMailProp, 0, 0, 0 },
768 { VCAudioContentProp, 0, 0, 0 },
769 { VCAVIProp, 0, 0, 0 },
770 { VCBase64Prop, 0, 0, 0 },
771 { VCBBSProp, 0, 0, 0 },
772 { VCBirthDateProp, 0, 0, 0 },
773 { VCBMPProp, 0, 0, 0 },
774 { VCBodyProp, 0, 0, 0 },
775 { VCBusinessRoleProp, 0, 0, 0 },
776 { VCCalProp, 0, 0, PD_BEGIN },
777 { VCCaptionProp, 0, 0, 0 },
778 { VCCardProp, 0, 0, PD_BEGIN },
779 { VCCarProp, 0, 0, 0 },
780 { VCCategoriesProp, 0, 0, 0 },
781 { VCCellularProp, 0, 0, 0 },
782 { VCCGMProp, 0, 0, 0 },
783 { VCCharSetProp, 0, 0, 0 },
784 { VCCIDProp, VCContentIDProp, 0, 0 },
785 { VCCISProp, 0, 0, 0 },
786 { VCCityProp, 0, 0, 0 },
787 { VCClassProp, 0, 0, 0 },
788 { VCCommentProp, 0, 0, 0 },
789 { VCCompletedProp, 0, 0, 0 },
790 { VCContentIDProp, 0, 0, 0 },
791 { VCCountryNameProp, 0, 0, 0 },
792 { VCDAlarmProp, 0, DAlarmFields, 0 },
793 { VCDataSizeProp, 0, 0, PD_INTERNAL },
794 { VCDayLightProp, 0, 0, 0 },
795 { VCDCreatedProp, 0, 0, 0 },
796 { VCDeliveryLabelProp, 0, 0, 0 },
797 { VCDescriptionProp, 0, 0, 0 },
798 { VCDIBProp, 0, 0, 0 },
799 { VCDisplayStringProp, 0, 0, 0 },
800 { VCDomesticProp, 0, 0, 0 },
801 { VCDTendProp, 0, 0, 0 },
802 { VCDTstartProp, 0, 0, 0 },
803 { VCDueProp, 0, 0, 0 },
804 { VCEmailAddressProp, 0, 0, 0 },
805 { VCEncodingProp, 0, 0, 0 },
806 { VCEndProp, 0, 0, 0 },
807 { VCEventProp, 0, 0, PD_BEGIN },
808 { VCEWorldProp, 0, 0, 0 },
809 { VCExNumProp, 0, 0, 0 },
810 { VCExDateProp, 0, 0, 0 },
811 { VCExpectProp, 0, 0, 0 },
812 { VCExtAddressProp, 0, 0, 0 },
813 { VCFamilyNameProp, 0, 0, 0 },
814 { VCFaxProp, 0, 0, 0 },
815 { VCFullNameProp, 0, 0, 0 },
816 { VCGeoLocationProp, 0, 0, 0 },
817 { VCGeoProp, 0, 0, 0 },
818 { VCGIFProp, 0, 0, 0 },
819 { VCGivenNameProp, 0, 0, 0 },
820 { VCGroupingProp, 0, 0, 0 },
821 { VCHomeProp, 0, 0, 0 },
822 { VCIBMMailProp, 0, 0, 0 },
823 { VCInlineProp, 0, 0, 0 },
824 { VCInternationalProp, 0, 0, 0 },
825 { VCInternetProp, 0, 0, 0 },
826 { VCISDNProp, 0, 0, 0 },
827 { VCJPEGProp, 0, 0, 0 },
828 { VCLanguageProp, 0, 0, 0 },
829 { VCLastModifiedProp, 0, 0, 0 },
830 { VCLastRevisedProp, 0, 0, 0 },
831 { VCLocationProp, 0, 0, 0 },
832 { VCLogoProp, 0, 0, 0 },
833 { VCMailerProp, 0, 0, 0 },
834 { VCMAlarmProp, 0, MAlarmFields, 0 },
835 { VCMCIMailProp, 0, 0, 0 },
836 { VCMessageProp, 0, 0, 0 },
837 { VCMETProp, 0, 0, 0 },
838 { VCModemProp, 0, 0, 0 },
839 { VCMPEG2Prop, 0, 0, 0 },
840 { VCMPEGProp, 0, 0, 0 },
841 { VCMSNProp, 0, 0, 0 },
842 { VCNamePrefixesProp, 0, 0, 0 },
843 { VCNameProp, 0, nameFields, 0 },
844 { VCNameSuffixesProp, 0, 0, 0 },
845 { VCNoteProp, 0, 0, 0 },
846 { VCOrgNameProp, 0, 0, 0 },
847 { VCOrgProp, 0, orgFields, 0 },
848 { VCOrgUnit2Prop, 0, 0, 0 },
849 { VCOrgUnit3Prop, 0, 0, 0 },
850 { VCOrgUnit4Prop, 0, 0, 0 },
851 { VCOrgUnitProp, 0, 0, 0 },
852 { VCPagerProp, 0, 0, 0 },
853 { VCPAlarmProp, 0, PAlarmFields, 0 },
854 { VCParcelProp, 0, 0, 0 },
855 { VCPartProp, 0, 0, 0 },
856 { VCPCMProp, 0, 0, 0 },
857 { VCPDFProp, 0, 0, 0 },
858 { VCPGPProp, 0, 0, 0 },
859 { VCPhotoProp, 0, 0, 0 },
860 { VCPICTProp, 0, 0, 0 },
861 { VCPMBProp, 0, 0, 0 },
862 { VCPostalBoxProp, 0, 0, 0 },
863 { VCPostalCodeProp, 0, 0, 0 },
864 { VCPostalProp, 0, 0, 0 },
865 { VCPowerShareProp, 0, 0, 0 },
866 { VCPreferredProp, 0, 0, 0 },
867 { VCPriorityProp, 0, 0, 0 },
868 { VCProcedureNameProp, 0, 0, 0 },
869 { VCProdIdProp, 0, 0, 0 },
870 { VCProdigyProp, 0, 0, 0 },
871 { VCPronunciationProp, 0, 0, 0 },
872 { VCPSProp, 0, 0, 0 },
873 { VCPublicKeyProp, 0, 0, 0 },
874 { VCQPProp, VCQuotedPrintableProp, 0, 0 },
875 { VCQuickTimeProp, 0, 0, 0 },
876 { VCQuotedPrintableProp, 0, 0, 0 },
877 { VCRDateProp, 0, 0, 0 },
878 { VCRegionProp, 0, 0, 0 },
879 { VCRelatedToProp, 0, 0, 0 },
880 { VCRepeatCountProp, 0, 0, 0 },
881 { VCResourcesProp, 0, 0, 0 },
882 { VCRNumProp, 0, 0, 0 },
883 { VCRoleProp, 0, 0, 0 },
884 { VCRRuleProp, 0, 0, 0 },
885 { VCRSVPProp, 0, 0, 0 },
886 { VCRunTimeProp, 0, 0, 0 },
887 { VCSequenceProp, 0, 0, 0 },
888 { VCSnoozeTimeProp, 0, 0, 0 },
889 { VCStartProp, 0, 0, 0 },
890 { VCStatusProp, 0, 0, 0 },
891 { VCStreetAddressProp, 0, 0, 0 },
892 { VCSubTypeProp, 0, 0, 0 },
893 { VCSummaryProp, 0, 0, 0 },
894 { VCTelephoneProp, 0, 0, 0 },
895 { VCTIFFProp, 0, 0, 0 },
896 { VCTimeZoneProp, 0, 0, 0 },
897 { VCTitleProp, 0, 0, 0 },
898 { VCTLXProp, 0, 0, 0 },
899 { VCTodoProp, 0, 0, PD_BEGIN },
900 { VCTranspProp, 0, 0, 0 },
901 { VCUniqueStringProp, 0, 0, 0 },
902 { VCURLProp, 0, 0, 0 },
903 { VCURLValueProp, 0, 0, 0 },
904 { VCValueProp, 0, 0, 0 },
905 { VCVersionProp, 0, 0, 0 },
906 { VCVideoProp, 0, 0, 0 },
907 { VCVoiceProp, 0, 0, 0 },
908 { VCWAVEProp, 0, 0, 0 },
909 { VCWMFProp, 0, 0, 0 },
910 { VCWorkProp, 0, 0, 0 },
911 { VCX400Prop, 0, 0, 0 },
912 { VCX509Prop, 0, 0, 0 },
913 { VCXRuleProp, 0, 0, 0 },
914 { 0,0,0,0 }
915 };
916
917
918static struct PreDefProp* lookupPropInfo(const char* str)
919{
920 /* brute force for now, could use a hash table here. */
921 int i;
922
923 for (i = 0; propNames[i].name; i++)
924 if (strcasecmp(str, propNames[i].name) == 0) {
925 return &propNames[i];
926 }
927
928 return 0;
929}
930
931
932const char* lookupProp_(const char* str)
933{
934 int i;
935
936 for (i = 0; propNames[i].name; i++)
937 if (strcasecmp(str, propNames[i].name) == 0) {
938 const char* s;
939 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
940 return lookupStr(s);
941 }
942 return lookupStr(str);
943}
944
945
946const char* lookupProp(const char* str)
947{
948 int i;
949
950 for (i = 0; propNames[i].name; i++)
951 if (strcasecmp(str, propNames[i].name) == 0) {
952 const char *s;
953 fieldedProp = propNames[i].fields;
954 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
955 return lookupStr(s);
956 }
957 fieldedProp = 0;
958 return lookupStr(str);
959}
960
961
962/*----------------------------------------------------------------------
963 APIs to Output text form.
964 ----------------------------------------------------------------------*/
965#define OFILE_REALLOC_SIZE 256
966typedef struct OFile {
967 FILE *fp;
968 char *s;
969 int len;
970 int limit;
971 int alloc:1;
972 int fail:1;
973 } OFile;
974
975
976/* vCalendar files need crlf linebreaks. The disabled functions didn't provide
977 that. */
978#if 0
979
980static void appendsOFile(OFile *fp, const char *s)
981{
982 int slen;
983 if (fp->fail) return;
984 slen = strlen(s);
985 if (fp->fp) {
986 fwrite(s,1,slen,fp->fp);
987 }
988 else {
989stuff:
990 if (fp->len + slen < fp->limit) {
991 memcpy(fp->s+fp->len,s,slen);
992 fp->len += slen;
993 return;
994 }
995 else if (fp->alloc) {
996 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
997 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen;
998 if (fp->s)
999 fp->s = realloc(fp->s,fp->limit);
1000 else
1001 fp->s = malloc(fp->limit);
1002 if (fp->s) goto stuff;
1003 }
1004 if (fp->alloc)
1005 free(fp->s);
1006 fp->s = 0;
1007 fp->fail = 1;
1008 }
1009}
1010
1011static void appendcOFile(OFile *fp, char c)
1012{
1013 if (fp->fail) return;
1014 if (fp->fp) {
1015 fputc(c,fp->fp);
1016 }
1017 else {
1018stuff:
1019 if (fp->len+1 < fp->limit) {
1020 fp->s[fp->len] = c;
1021 fp->len++;
1022 return;
1023 }
1024 else if (fp->alloc) {
1025 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
1026 fp->s = realloc(fp->s,fp->limit);
1027 if (fp->s) goto stuff;
1028 }
1029 if (fp->alloc)
1030 free(fp->s);
1031 fp->s = 0;
1032 fp->fail = 1;
1033 }
1034}
1035
1036#else
1037
1038static void appendcOFile_(OFile *fp, char c)
1039{
1040 if (fp->fail) return;
1041 if (fp->fp) {
1042 fputc(c,fp->fp);
1043 }
1044 else {
1045stuff:
1046 if (fp->len+1 < fp->limit) {
1047 fp->s[fp->len] = c;
1048 fp->len++;
1049 return;
1050 }
1051 else if (fp->alloc) {
1052 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
1053 fp->s = realloc(fp->s,fp->limit);
1054 if (fp->s) goto stuff;
1055 }
1056 if (fp->alloc)
1057 free(fp->s);
1058 fp->s = 0;
1059 fp->fail = 1;
1060 }
1061}
1062
1063static void appendcOFile(OFile *fp, char c)
1064{
1065 if (c == '\n') {
1066 /* write out as <CR><LF> */
1067 appendcOFile_(fp,0xd);
1068 appendcOFile_(fp,0xa);
1069 }
1070 else
1071 appendcOFile_(fp,c);
1072}
1073
1074static void appendsOFile(OFile *fp, const char *s)
1075{
1076 int i, slen;
1077 slen = strlen(s);
1078 for (i=0; i<slen; i++) {
1079 appendcOFile(fp,s[i]);
1080 }
1081}
1082
1083#endif
1084
1085static void initOFile(OFile *fp, FILE *ofp)
1086{
1087 fp->fp = ofp;
1088 fp->s = 0;
1089 fp->len = 0;
1090 fp->limit = 0;
1091 fp->alloc = 0;
1092 fp->fail = 0;
1093}
1094
1095static void initMemOFile(OFile *fp, char *s, int len)
1096{
1097 fp->fp = 0;
1098 fp->s = s;
1099 fp->len = 0;
1100 fp->limit = s?len:0;
1101 fp->alloc = s?0:1;
1102 fp->fail = 0;
1103}
1104
1105
1106static int writeBase64(OFile *fp, unsigned char *s, long len)
1107{
1108 long cur = 0;
1109 int i, numQuads = 0;
1110 unsigned long trip;
1111 unsigned char b;
1112 char quad[5];
1113#define MAXQUADS 16
1114
1115 quad[4] = 0;
1116
1117 while (cur < len) {
1118 /* collect the triplet of bytes into 'trip' */
1119 trip = 0;
1120 for (i = 0; i < 3; i++) {
1121 b = (cur < len) ? *(s + cur) : 0;
1122 cur++;
1123 trip = trip << 8 | b;
1124 }
1125 /* fill in 'quad' with the appropriate four characters */
1126 for (i = 3; i >= 0; i--) {
1127 b = (unsigned char)(trip & 0x3F);
1128 trip = trip >> 6;
1129 if ((3 - i) < (cur - len))
1130 quad[i] = '='; /* pad char */
1131 else if (b < 26) quad[i] = (char)b + 'A';
1132 else if (b < 52) quad[i] = (char)(b - 26) + 'a';
1133 else if (b < 62) quad[i] = (char)(b - 52) + '0';
1134 else if (b == 62) quad[i] = '+';
1135 else quad[i] = '/';
1136 }
1137 /* now output 'quad' with appropriate whitespace and line ending */
1138 appendsOFile(fp, (numQuads == 0 ? " " : ""));
1139 appendsOFile(fp, quad);
1140 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : "")));
1141 numQuads = (numQuads + 1) % MAXQUADS;
1142 }
1143 appendcOFile(fp,'\n');
1144
1145 return 1;
1146}
1147
1148/* this function really sucks. Too basic. */
1149static void writeQPString(OFile *fp, const char *s, int qp)
1150{
1151 const char *p = s;
1152 while (*p) {
1153 if (*p == '\n') {
1154 if (p[1]) appendsOFile(fp,"=0A=");
1155 }
1156 if (*p == '=' && qp)
1157 appendsOFile(fp,"=3D");
1158 else
1159 appendcOFile(fp,*p);
1160 p++;
1161 }
1162}
1163
1164static void writeVObject_(OFile *fp, VObject *o);
1165
1166static void writeValue(OFile *fp, VObject *o, unsigned long size)
1167{
1168 if (o == 0) return;
1169 switch (VALUE_TYPE(o)) {
1170 case VCVT_USTRINGZ: {
1171 char *s = fakeCString(USTRINGZ_VALUE_OF(o));
1172 if (isAPropertyOf(o, VCQuotedPrintableProp))
1173 writeQPString(fp, s, 1);
1174 else
1175 writeQPString(fp, s, 0);
1176 deleteStr(s);
1177 break;
1178 }
1179 case VCVT_STRINGZ: {
1180 if (isAPropertyOf(o, VCQuotedPrintableProp))
1181 writeQPString(fp, STRINGZ_VALUE_OF(o), 1);
1182 else
1183 writeQPString(fp, STRINGZ_VALUE_OF(o), 0);
1184 break;
1185 }
1186 case VCVT_UINT: {
1187 char buf[16];
1188 sprintf(buf,"%u", INTEGER_VALUE_OF(o));
1189 appendsOFile(fp,buf);
1190 break;
1191 }
1192 case VCVT_ULONG: {
1193 char buf[16];
1194 sprintf(buf,"%lu", LONG_VALUE_OF(o));
1195 appendsOFile(fp,buf);
1196 break;
1197 }
1198 case VCVT_RAW: {
1199 appendcOFile(fp,'\n');
1200 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size);
1201 break;
1202 }
1203 case VCVT_VOBJECT:
1204 appendcOFile(fp,'\n');
1205 writeVObject_(fp,VOBJECT_VALUE_OF(o));
1206 break;
1207 }
1208}
1209
1210static void writeAttrValue(OFile *fp, VObject *o)
1211{
1212 if (NAME_OF(o)) {
1213 struct PreDefProp *pi;
1214 pi = lookupPropInfo(NAME_OF(o));
1215 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
1216 appendcOFile(fp,';');
1217 appendsOFile(fp,NAME_OF(o));
1218 }
1219 else
1220 appendcOFile(fp,';');
1221 if (VALUE_TYPE(o)) {
1222 appendcOFile(fp,'=');
1223 writeValue(fp,o,0);
1224 }
1225}
1226
1227static void writeGroup(OFile *fp, VObject *o)
1228{
1229 char buf1[256];
1230 char buf2[256];
1231 strcpy(buf1,NAME_OF(o));
1232 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
1233 strncpy(buf2,STRINGZ_VALUE_OF(o),sizeof(buf2));
1234 buf2[sizeof(buf2)] = '\0';
1235 strncat(buf2,".",sizeof(buf2)-strlen(buf2)-1);
1236 strncat(buf2,buf1,sizeof(buf2)-strlen(buf2)-1);
1237 strcpy(buf1,buf2);
1238 }
1239 appendsOFile(fp,buf1);
1240}
1241
1242static int inList(const char **list, const char *s)
1243{
1244 if (list == 0) return 0;
1245 while (*list) {
1246 if (strcasecmp(*list,s) == 0) return 1;
1247 list++;
1248 }
1249 return 0;
1250}
1251
1252static void writeProp(OFile *fp, VObject *o)
1253{
1254 if (NAME_OF(o)) {
1255 struct PreDefProp *pi;
1256 VObjectIterator t;
1257 const char **fields_ = 0;
1258 pi = lookupPropInfo(NAME_OF(o));
1259 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1260 writeVObject_(fp,o);
1261 return;
1262 }
1263 if (isAPropertyOf(o,VCGroupingProp))
1264 writeGroup(fp,o);
1265 else
1266 appendsOFile(fp,NAME_OF(o));
1267 if (pi) fields_ = pi->fields;
1268 initPropIterator(&t,o);
1269 while (moreIteration(&t)) {
1270 const char *s;
1271 VObject *eachProp = nextVObject(&t);
1272 s = NAME_OF(eachProp);
1273 if (strcasecmp(VCGroupingProp,s) && !inList(fields_,s))
1274 writeAttrValue(fp,eachProp);
1275 }
1276 if (fields_) {
1277 int i = 0, n = 0;
1278 const char** fields = fields_;
1279 /* output prop as fields */
1280 appendcOFile(fp,':');
1281 while (*fields) {
1282 VObject *tl = isAPropertyOf(o,*fields);
1283 i++;
1284 if (tl) n = i;
1285 fields++;
1286 }
1287 fields = fields_;
1288 for (i=0;i<n;i++) {
1289 writeValue(fp,isAPropertyOf(o,*fields),0);
1290 fields++;
1291 if (i<(n-1)) appendcOFile(fp,';');
1292 }
1293 }
1294 }
1295
1296 if (VALUE_TYPE(o)) {
1297 unsigned long size = 0;
1298 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1299 if (p) size = LONG_VALUE_OF(p);
1300 appendcOFile(fp,':');
1301 writeValue(fp,o,size);
1302 }
1303
1304 appendcOFile(fp,'\n');
1305}
1306
1307static void writeVObject_(OFile *fp, VObject *o)
1308{
1309 if (NAME_OF(o)) {
1310 struct PreDefProp *pi;
1311 pi = lookupPropInfo(NAME_OF(o));
1312
1313 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1314 VObjectIterator t;
1315 const char *begin = NAME_OF(o);
1316 appendsOFile(fp,"BEGIN:");
1317 appendsOFile(fp,begin);
1318 appendcOFile(fp,'\n');
1319 initPropIterator(&t,o);
1320 while (moreIteration(&t)) {
1321 VObject *eachProp = nextVObject(&t);
1322 writeProp(fp, eachProp);
1323 }
1324 appendsOFile(fp,"END:");
1325 appendsOFile(fp,begin);
1326 appendsOFile(fp,"\n\n");
1327 }
1328 }
1329}
1330
1331void writeVObject(FILE *fp, VObject *o)
1332{
1333 OFile ofp;
1334 initOFile(&ofp,fp);
1335 writeVObject_(&ofp,o);
1336}
1337
1338void writeVObjectToFile(char *fname, VObject *o)
1339{
1340 FILE *fp = fopen(fname,"w");
1341 if (fp) {
1342 writeVObject(fp,o);
1343 fclose(fp);
1344 }
1345}
1346
1347void writeVObjectsToFile(char *fname, VObject *list)
1348{
1349 FILE *fp = fopen(fname,"w");
1350 if (fp) {
1351 while (list) {
1352 writeVObject(fp,list);
1353 list = nextVObjectInList(list);
1354 }
1355 fclose(fp);
1356 }
1357}
1358
1359char* writeMemVObject(char *s, int *len, VObject *o)
1360{
1361 OFile ofp;
1362 initMemOFile(&ofp,s,len?*len:0);
1363 writeVObject_(&ofp,o);
1364 if (len) *len = ofp.len;
1365 appendcOFile(&ofp,0);
1366 return ofp.s;
1367}
1368
1369char* writeMemVObjects(char *s, int *len, VObject *list)
1370{
1371 OFile ofp;
1372 initMemOFile(&ofp,s,len?*len:0);
1373 while (list) {
1374 writeVObject_(&ofp,list);
1375 list = nextVObjectInList(list);
1376 }
1377 if (len) *len = ofp.len;
1378 appendcOFile(&ofp,0);
1379 return ofp.s;
1380}
1381
1382/*----------------------------------------------------------------------
1383 APIs to do fake Unicode stuff.
1384 ----------------------------------------------------------------------*/
1385wchar_t* fakeUnicode(const char *ps, int *bytes)
1386{
1387 wchar_t *r, *pw;
1388 int len = strlen(ps)+1;
1389
1390 pw = r = (wchar_t*)malloc(sizeof(wchar_t)*len);
1391 if (bytes)
1392 *bytes = len * sizeof(wchar_t);
1393
1394 while (*ps) {
1395 if (*ps == '\n')
1396 *pw = (wchar_t)0x2028;
1397 else if (*ps == '\r')
1398 *pw = (wchar_t)0x2029;
1399 else
1400 *pw = (wchar_t)(unsigned char)*ps;
1401 ps++; pw++;
1402 }
1403 *pw = (wchar_t)0;
1404
1405 return r;
1406}
1407
1408int uStrLen(const wchar_t *u)
1409{
1410 int i = 0;
1411 while (*u != (wchar_t)0) { u++; i++; }
1412 return i;
1413}
1414
1415char* fakeCString(const wchar_t *u)
1416{
1417 char *s, *t;
1418 int len = uStrLen(u) + 1;
1419 t = s = (char*)malloc(len+1);
1420 while (*u) {
1421 if (*u == (wchar_t)0x2028)
1422 *t = '\n';
1423 else if (*u == (wchar_t)0x2029)
1424 *t = '\r';
1425 else
1426 *t = (char)*u;
1427 u++; t++;
1428 }
1429 *t = 0;
1430 return s;
1431}
1432
1433/* end of source file vobject.c */
diff --git a/libkcal/versit/vobject.h b/libkcal/versit/vobject.h
new file mode 100644
index 0000000..0ec8b31
--- a/dev/null
+++ b/libkcal/versit/vobject.h
@@ -0,0 +1,384 @@
1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc.
4
5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors.
9
10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose.
14
15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including
17this software.
18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS.
22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE.
27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE.
32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36
37***************************************************************************/
38
39/*
40
41The vCard/vCalendar C interface is implemented in the set
42of files as follows:
43
44vcc.y, yacc source, and vcc.c, the yacc output you will use
45implements the core parser
46
47vobject.c implements an API that insulates the caller from
48the parser and changes in the vCard/vCalendar BNF
49
50port.h defines compilation environment dependent stuff
51
52vcc.h and vobject.h are header files for their .c counterparts
53
54vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions
55which you may find useful.
56
57test.c is a standalone test driver that exercises some of
58the features of the APIs provided. Invoke test.exe on a
59VCARD/VCALENDAR input text file and you will see the pretty
60print output of the internal representation (this pretty print
61output should give you a good idea of how the internal
62representation looks like -- there is one such output in the
63following too). Also, a file with the .out suffix is generated
64to show that the internal representation can be written back
65in the original text format.
66
67For more information on this API see the readme.txt file
68which accompanied this distribution.
69
70 Also visit:
71
72 http://www.versit.com
73 http://www.ralden.com
74
75*/
76
77
78#ifndef __VOBJECT_H__
79#define __VOBJECT_H__ 1
80
81
82#include "port.h"
83#include <stdlib.h>
84#include <stdio.h>
85
86#if defined(__CPLUSPLUS__) || defined(__cplusplus)
87extern "C" {
88#endif
89
90
91 #define VC7bitProp "7BIT"
92 #define VC8bitProp "8BIT"
93 #define VCAAlarmProp "AALARM"
94 #define VCAdditionalNamesProp"ADDN"
95 #define VCAdrProp "ADR"
96 #define VCAgentProp "AGENT"
97 #define VCAIFFProp "AIFF"
98 #define VCAOLProp "AOL"
99 #define VCAppleLinkProp "APPLELINK"
100 #define VCAttachProp "ATTACH"
101 #define VCAttendeeProp "ATTENDEE"
102 #define VCATTMailProp "ATTMAIL"
103 #define VCAudioContentProp "AUDIOCONTENT"
104 #define VCAVIProp "AVI"
105 #define VCBase64Prop "BASE64"
106 #define VCBBSProp "BBS"
107 #define VCBirthDateProp "BDAY"
108 #define VCBMPProp "BMP"
109 #define VCBodyProp "BODY"
110 #define VCBusinessRoleProp "ROLE"
111 #define VCCalProp "VCALENDAR"
112 #define VCCaptionProp "CAP"
113 #define VCCardProp "VCARD"
114 #define VCCarProp "CAR"
115 #define VCCategoriesProp "CATEGORIES"
116 #define VCCellularProp "CELL"
117 #define VCCGMProp "CGM"
118 #define VCCharSetProp "CS"
119 #define VCCIDProp "CID"
120 #define VCCISProp "CIS"
121 #define VCCityProp "L"
122 #define VCClassProp "CLASS"
123 #define VCCommentProp "NOTE"
124 #define VCCompletedProp "COMPLETED"
125 #define VCContentIDProp "CONTENT-ID"
126 #define VCCountryNameProp "C"
127 #define VCDAlarmProp "DALARM"
128 #define VCDataSizeProp "DATASIZE"
129 #define VCDayLightProp "DAYLIGHT"
130 #define VCDCreatedProp "DCREATED"
131#define VCDeliveryLabelProp "LABEL"
132 #define VCDescriptionProp "DESCRIPTION"
133 #define VCDIBProp "DIB"
134 #define VCDisplayStringProp "DISPLAYSTRING"
135 #define VCDomesticProp "DOM"
136 #define VCDTendProp "DTEND"
137 #define VCDTstartProp "DTSTART"
138 #define VCDueProp "DUE"
139 #define VCEmailAddressProp "EMAIL"
140 #define VCEncodingProp "ENCODING"
141 #define VCEndProp "END"
142 #define VCEventProp "VEVENT"
143 #define VCEWorldProp "EWORLD"
144 #define VCExNumProp "EXNUM"
145 #define VCExDateProp "EXDATE"
146 #define VCExpectProp "EXPECT"
147 #define VCExtAddressProp "EXT ADD"
148 #define VCFamilyNameProp "F"
149 #define VCFaxProp "FAX"
150 #define VCFullNameProp "FN"
151 #define VCGeoProp "GEO"
152 #define VCGeoLocationProp "GEO"
153 #define VCGIFProp "GIF"
154 #define VCGivenNameProp "G"
155 #define VCGroupingProp "Grouping"
156 #define VCHomeProp "HOME"
157 #define VCIBMMailProp "IBMMail"
158 #define VCInlineProp "INLINE"
159 #define VCInternationalProp "INTL"
160 #define VCInternetProp "INTERNET"
161 #define VCISDNProp "ISDN"
162 #define VCJPEGProp "JPEG"
163 #define VCLanguageProp "LANG"
164 #define VCLastModifiedProp "LAST-MODIFIED"
165 #define VCLastRevisedProp "REV"
166 #define VCLocationProp "LOCATION"
167 #define VCLogoProp "LOGO"
168 #define VCMailerProp "MAILER"
169 #define VCMAlarmProp "MALARM"
170 #define VCMCIMailProp "MCIMAIL"
171 #define VCMessageProp "MSG"
172 #define VCMETProp "MET"
173 #define VCModemProp "MODEM"
174 #define VCMPEG2Prop "MPEG2"
175 #define VCMPEGProp "MPEG"
176 #define VCMSNProp "MSN"
177 #define VCNamePrefixesProp "NPRE"
178 #define VCNameProp "N"
179 #define VCNameSuffixesProp "NSUF"
180 #define VCNoteProp "NOTE"
181 #define VCOrgNameProp "ORGNAME"
182 #define VCOrgProp "ORG"
183 #define VCOrgUnit2Prop "OUN2"
184 #define VCOrgUnit3Prop "OUN3"
185 #define VCOrgUnit4Prop "OUN4"
186 #define VCOrgUnitProp "OUN"
187 #define VCPagerProp "PAGER"
188 #define VCPAlarmProp "PALARM"
189 #define VCParcelProp "PARCEL"
190 #define VCPartProp "PART"
191 #define VCPCMProp "PCM"
192 #define VCPDFProp "PDF"
193 #define VCPGPProp "PGP"
194 #define VCPhotoProp "PHOTO"
195 #define VCPICTProp "PICT"
196 #define VCPMBProp "PMB"
197 #define VCPostalBoxProp "BOX"
198 #define VCPostalCodeProp "PC"
199 #define VCPostalProp "POSTAL"
200 #define VCPowerShareProp "POWERSHARE"
201 #define VCPreferredProp "PREF"
202 #define VCPriorityProp "PRIORITY"
203 #define VCProcedureNameProp "PROCEDURENAME"
204 #define VCProdIdProp "PRODID"
205 #define VCProdigyProp "PRODIGY"
206 #define VCPronunciationProp "SOUND"
207 #define VCPSProp "PS"
208 #define VCPublicKeyProp "KEY"
209 #define VCQPProp "QP"
210 #define VCQuickTimeProp "QTIME"
211 #define VCQuotedPrintableProp"QUOTED-PRINTABLE"
212 #define VCRDateProp "RDATE"
213 #define VCRegionProp "R"
214 #define VCRelatedToProp "RELATED-TO"
215 #define VCRepeatCountProp "REPEATCOUNT"
216 #define VCResourcesProp "RESOURCES"
217 #define VCRNumProp "RNUM"
218 #define VCRoleProp "ROLE"
219 #define VCRRuleProp "RRULE"
220 #define VCRSVPProp "RSVP"
221 #define VCRunTimeProp "RUNTIME"
222 #define VCSequenceProp "SEQUENCE"
223 #define VCSnoozeTimeProp "SNOOZETIME"
224 #define VCStartProp "START"
225 #define VCStatusProp "STATUS"
226 #define VCStreetAddressProp "STREET"
227 #define VCSubTypeProp "SUBTYPE"
228 #define VCSummaryProp "SUMMARY"
229 #define VCTelephoneProp "TEL"
230 #define VCTIFFProp "TIFF"
231 #define VCTimeZoneProp "TZ"
232 #define VCTitleProp "TITLE"
233 #define VCTLXProp "TLX"
234 #define VCTodoProp "VTODO"
235 #define VCTranspProp "TRANSP"
236 #define VCUniqueStringProp "UID"
237 #define VCURLProp "URL"
238 #define VCURLValueProp "URLVAL"
239 #define VCValueProp "VALUE"
240 #define VCVersionProp "VERSION"
241 #define VCVideoProp "VIDEO"
242 #define VCVoiceProp "VOICE"
243 #define VCWAVEProp "WAVE"
244 #define VCWMFProp "WMF"
245 #define VCWorkProp "WORK"
246 #define VCX400Prop "X400"
247 #define VCX509Prop "X509"
248 #define VCXRuleProp "XRULE"
249
250/* extensions for KOrganizer / KPilot */
251#define KPilotIdProp "X-PILOTID"
252#define KPilotStatusProp "X-PILOTSTAT"
253
254/* extensions for iMIP / iTIP */
255#define ICOrganizerProp "X-ORGANIZER"
256#define ICMethodProp "X-METHOD"
257#define ICRequestStatusProp "X-REQUEST-STATUS"
258
259typedef struct VObject VObject;
260
261typedef union ValueItem {
262 const char *strs;
263 const wchar_t *ustrs;
264 unsigned int i;
265 unsigned long l;
266 void *any;
267 VObject *vobj;
268 } ValueItem;
269
270struct VObject {
271 VObject *next;
272 const char *id;
273 VObject *prop;
274 unsigned short valType;
275 ValueItem val;
276 };
277
278typedef struct StrItem StrItem;
279
280struct StrItem {
281 StrItem *next;
282 const char *s;
283 unsigned int refCnt;
284 };
285
286typedef struct VObjectIterator {
287 VObject* start;
288 VObject* next;
289 } VObjectIterator;
290
291extern VObject* newVObject(const char *id);
292extern void deleteVObject(VObject *p);
293extern char* dupStr(const char *s, unsigned int size);
294extern void deleteStr(const char *p);
295extern void unUseStr(const char *s);
296
297extern void setVObjectName(VObject *o, const char* id);
298extern void setVObjectStringZValue(VObject *o, const char *s);
299extern void setVObjectStringZValue_(VObject *o, const char *s);
300extern void setVObjectUStringZValue(VObject *o, const wchar_t *s);
301extern void setVObjectUStringZValue_(VObject *o, const wchar_t *s);
302extern void setVObjectIntegerValue(VObject *o, unsigned int i);
303extern void setVObjectLongValue(VObject *o, unsigned long l);
304extern void setVObjectAnyValue(VObject *o, void *t);
305extern VObject* setValueWithSize(VObject *prop, void *val, unsigned int size);
306extern VObject* setValueWithSize_(VObject *prop, void *val, unsigned int size);
307
308extern const char* vObjectName(VObject *o);
309extern const char* vObjectStringZValue(VObject *o);
310extern const wchar_t* vObjectUStringZValue(VObject *o);
311extern unsigned int vObjectIntegerValue(VObject *o);
312extern unsigned long vObjectLongValue(VObject *o);
313extern void* vObjectAnyValue(VObject *o);
314extern VObject* vObjectVObjectValue(VObject *o);
315extern void setVObjectVObjectValue(VObject *o, VObject *p);
316
317extern VObject* addVObjectProp(VObject *o, VObject *p);
318extern VObject* addProp(VObject *o, const char *id);
319extern VObject* addProp_(VObject *o, const char *id);
320extern VObject* addPropValue(VObject *o, const char *p, const char *v);
321extern VObject* addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size);
322extern VObject* addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size);
323extern VObject* addGroup(VObject *o, const char *g);
324extern void addList(VObject **o, VObject *p);
325
326extern VObject* isAPropertyOf(VObject *o, const char *id);
327
328extern VObject* nextVObjectInList(VObject *o);
329extern void initPropIterator(VObjectIterator *i, VObject *o);
330extern int moreIteration(VObjectIterator *i);
331extern VObject* nextVObject(VObjectIterator *i);
332
333extern char* writeMemVObject(char *s, int *len, VObject *o);
334extern char* writeMemVObjects(char *s, int *len, VObject *list);
335
336extern const char* lookupStr(const char *s);
337extern void cleanStrTbl();
338
339extern void cleanVObject(VObject *o);
340extern void cleanVObjects(VObject *list);
341
342extern const char* lookupProp(const char* str);
343extern const char* lookupProp_(const char* str);
344
345extern wchar_t* fakeUnicode(const char *ps, int *bytes);
346extern int uStrLen(const wchar_t *u);
347extern char* fakeCString(const wchar_t *u);
348
349extern void printVObjectToFile(char *fname,VObject *o);
350extern void printVObjectsToFile(char *fname,VObject *list);
351extern void writeVObjectToFile(char *fname, VObject *o);
352extern void writeVObjectsToFile(char *fname, VObject *list);
353
354extern int vObjectValueType(VObject *o);
355
356/* return type of vObjectValueType: */
357 #define VCVT_NOVALUE0
358 /* if the VObject has no value associated with it. */
359 #define VCVT_STRINGZ1
360 /* if the VObject has value set by setVObjectStringZValue. */
361 #define VCVT_USTRINGZ2
362 /* if the VObject has value set by setVObjectUStringZValue. */
363 #define VCVT_UINT 3
364 /* if the VObject has value set by setVObjectIntegerValue. */
365 #define VCVT_ULONG 4
366 /* if the VObject has value set by setVObjectLongValue. */
367 #define VCVT_RAW 5
368 /* if the VObject has value set by setVObjectAnyValue. */
369 #define VCVT_VOBJECT6
370 /* if the VObject has value set by setVObjectVObjectValue. */
371
372extern const char** fieldedProp;
373
374extern void printVObject(FILE *fp,VObject *o);
375extern void writeVObject(FILE *fp, VObject *o);
376
377
378#if defined(__CPLUSPLUS__) || defined(__cplusplus)
379}
380#endif
381
382#endif /* __VOBJECT_H__ */
383
384