summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--library/backend/vcc.y53
-rw-r--r--library/backend/vcc_yacc.cpp328
-rw-r--r--library/backend/vobject.cpp11
3 files changed, 212 insertions, 180 deletions
diff --git a/library/backend/vcc.y b/library/backend/vcc.y
index eca7c32..00e8fed 100644
--- a/library/backend/vcc.y
+++ b/library/backend/vcc.y
@@ -41,24 +41,26 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
41/* 41/*
42 * src: vcc.c 42 * src: vcc.c
43 * doc: Parser for vCard and vCalendar. Note that this code is 43 * doc: Parser for vCard and vCalendar. Note that this code is
44 * generated by a yacc parser generator. Generally it should not 44 * generated by a yacc parser generator. Generally it should not
45 * be edited by hand. The real source is vcc.y. The #line directives 45 * be edited by hand. The real source is vcc.y. The #line directives
46 * can be commented out here to make it easier to trace through 46 * can be commented out here to make it easier to trace through
47 * in a debugger. However, if a bug is found it should 47 * in a debugger. However, if a bug is found it should
48 * be fixed in vcc.y and this file regenerated. 48 * be fixed in vcc.y and this file regenerated.
49 */ 49 */
50 50
51 51
52/* debugging utilities */ 52/* debugging utilities */
53#define __DEBUG 1
54
53#if __DEBUG 55#if __DEBUG
54#define DBG_(x) printf x 56#define DBG_(x) printf x
55#else 57#else
56#define DBG_(x) 58#define DBG_(x)
57#endif 59#endif
58 60
59/**** External Functions ****/ 61/**** External Functions ****/
60 62
61/* assign local name to parser variables and functions so that 63/* assign local name to parser variables and functions so that
62 we can use more than one yacc based parser. 64 we can use more than one yacc based parser.
63*/ 65*/
64 66
@@ -126,47 +128,49 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
126//#endif 128//#endif
127 129
128/**** Types, Constants ****/ 130/**** Types, Constants ****/
129 131
130 #define YYDEBUG 0/* 1 to compile in some debugging code */ 132 #define YYDEBUG 0/* 1 to compile in some debugging code */
131 #define MAXTOKEN 256/* maximum token (line) length */ 133 #define MAXTOKEN 256/* maximum token (line) length */
132 #define YYSTACKSIZE 100// ~unref ? 134 #define YYSTACKSIZE 100// ~unref ?
133 #define MAXLEVEL 10/* max # of nested objects parseable */ 135 #define MAXLEVEL 10/* max # of nested objects parseable */
134 /* (includes outermost) */ 136 /* (includes outermost) */
135 137
136 138
137/**** Global Variables ****/ 139/**** Global Variables ****/
140int q_DontDecodeBase64Photo = 0;
138int mime_lineNum, mime_numErrors; /* yyerror() can use these */ 141int mime_lineNum, mime_numErrors; /* yyerror() can use these */
139static VObject* vObjList; 142static VObject* vObjList;
140static VObject *curProp; 143static VObject *curProp;
141static VObject *curObj; 144static VObject *curObj;
142static VObject* ObjStack[MAXLEVEL]; 145static VObject* ObjStack[MAXLEVEL];
143static int ObjStackTop; 146static int ObjStackTop;
144 147
145 148
146/* A helpful utility for the rest of the app. */ 149/* A helpful utility for the rest of the app. */
147#if __CPLUSPLUS__ 150#if __CPLUSPLUS__
148extern "C" { 151extern "C" {
149#endif 152#endif
150 153
151 extern void yyerror(char *s); 154 extern void yyerror(char *s);
152 155
153#if __CPLUSPLUS__ 156#if __CPLUSPLUS__
154 }; 157 };
155#endif 158#endif
156 159
157int yyparse(); 160int yyparse();
158 161
159enum LexMode { 162enum LexMode {
160 L_NORMAL, 163 L_NORMAL,
164 L_PARAMWORD,
161 L_VCARD, 165 L_VCARD,
162 L_VCAL, 166 L_VCAL,
163 L_VEVENT, 167 L_VEVENT,
164 L_VTODO, 168 L_VTODO,
165 L_VALUES, 169 L_VALUES,
166 L_BASE64, 170 L_BASE64,
167 L_QUOTED_PRINTABLE 171 L_QUOTED_PRINTABLE
168 }; 172 };
169 173
170/**** Private Forward Declarations ****/ 174/**** Private Forward Declarations ****/
171static int pushVObject(const char *prop); 175static int pushVObject(const char *prop);
172static VObject* popVObject(); 176static VObject* popVObject();
@@ -280,28 +284,32 @@ prop: name
280 284
281attr_params: attr_params attr_param 285attr_params: attr_params attr_param
282 | attr_param 286 | attr_param
283 ; 287 ;
284 288
285attr_param: SEMICOLON attr 289attr_param: SEMICOLON attr
286 ; 290 ;
287 291
288attr: name 292attr: name
289 { 293 {
290 enterAttr($1,0); 294 enterAttr($1,0);
291 } 295 }
292 | name EQ name 296 | name EQ
293 { 297 {
294 enterAttr($1,$3); 298 lexPushMode(L_PARAMWORD);
295 299 }
300 name
301 {
302 lexPopMode(0);
303 enterAttr($1,$4);
296 } 304 }
297 ; 305 ;
298 306
299name: ID 307name: ID
300 ; 308 ;
301 309
302values: value SEMICOLON { enterValues($1); } values 310values: value SEMICOLON { enterValues($1); } values
303 | value 311 | value
304 { enterValues($1); } 312 { enterValues($1); }
305 ; 313 ;
306 314
307value: STRING 315value: STRING
@@ -442,28 +450,33 @@ static void enterProps(const char *s)
442static void enterAttr(const char *s1, const char *s2) 450static void enterAttr(const char *s1, const char *s2)
443 { 451 {
444 const char *p1, *p2=0; 452 const char *p1, *p2=0;
445 p1 = lookupProp_(s1); 453 p1 = lookupProp_(s1);
446 if (s2) { 454 if (s2) {
447 VObject *a; 455 VObject *a;
448 p2 = lookupProp_(s2); 456 p2 = lookupProp_(s2);
449 a = addProp(curProp,p1); 457 a = addProp(curProp,p1);
450 setVObjectStringZValue(a,p2); 458 setVObjectStringZValue(a,p2);
451 } 459 }
452 else 460 else
453 addProp(curProp,p1); 461 addProp(curProp,p1);
454 if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0)) 462 /* Lookup strings so we can quickly use pointer comparison */
463 static const char* base64 = lookupProp_(VCBase64Prop);
464 static const char* qp = lookupProp_(VCQuotedPrintableProp);
465 static const char* photo = lookupProp_(VCPhotoProp);
466 static const char* encoding = lookupProp_(VCEncodingProp);
467 if ((!q_DontDecodeBase64Photo || vObjectName(curProp) != photo)
468 && (p1 == base64 || p1 == encoding && p2 == base64))
455 lexPushMode(L_BASE64); 469 lexPushMode(L_BASE64);
456 else if (qstricmp(p1,VCQuotedPrintableProp) == 0 470 else if (p1 == qp || p1 == encoding && p2 == qp)
457 || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0))
458 lexPushMode(L_QUOTED_PRINTABLE); 471 lexPushMode(L_QUOTED_PRINTABLE);
459 deleteStr(s1); deleteStr(s2); 472 deleteStr(s1); deleteStr(s2);
460 } 473 }
461 474
462 475
463#define MAX_LEX_LOOKAHEAD_0 32 476#define MAX_LEX_LOOKAHEAD_0 32
464#define MAX_LEX_LOOKAHEAD 64 477#define MAX_LEX_LOOKAHEAD 64
465#define MAX_LEX_MODE_STACK_SIZE 10 478#define MAX_LEX_MODE_STACK_SIZE 10
466#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) 479#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
467 480
468struct LexBuf { 481struct LexBuf {
469 /* input */ 482 /* input */
@@ -632,24 +645,38 @@ static char* lexGetWord() {
632 lexSkipWhite(); 645 lexSkipWhite();
633 lexClearToken(); 646 lexClearToken();
634 c = lexLookahead(); 647 c = lexLookahead();
635 while (c != EOF && !strchr("\t\n ;:=",c)) { 648 while (c != EOF && !strchr("\t\n ;:=",c)) {
636 lexAppendc(c); 649 lexAppendc(c);
637 lexSkipLookahead(); 650 lexSkipLookahead();
638 c = lexLookahead(); 651 c = lexLookahead();
639 } 652 }
640 lexAppendc(0); 653 lexAppendc(0);
641 return lexStr(); 654 return lexStr();
642 } 655 }
643 656
657static char* lexGetParamWord()
658{
659 int c;
660 lexClearToken();
661 c = lexLookahead();
662 while (c >= ' ' && c < 127 && !strchr("[]:=,.;",c)) {
663 lexAppendc(c);
664 lexSkipLookahead();
665 c = lexLookahead();
666 }
667 lexAppendc(0);
668 return lexStr();
669}
670
644static void lexPushLookaheadc(int c) { 671static void lexPushLookaheadc(int c) {
645 int putptr; 672 int putptr;
646 /* can't putback EOF, because it never leaves lookahead buffer */ 673 /* can't putback EOF, because it never leaves lookahead buffer */
647 if (c == EOF) return; 674 if (c == EOF) return;
648 putptr = (int)lexBuf.getPtr - 1; 675 putptr = (int)lexBuf.getPtr - 1;
649 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; 676 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
650 lexBuf.getPtr = putptr; 677 lexBuf.getPtr = putptr;
651 lexBuf.buf[putptr] = c; 678 lexBuf.buf[putptr] = c;
652 lexBuf.len += 1; 679 lexBuf.len += 1;
653 } 680 }
654 681
655static char* lexLookaheadWord() { 682static char* lexLookaheadWord() {
@@ -1001,38 +1028,38 @@ static char* lexGetQuotedPrintable()
1001 } 1028 }
1002 c = lexLookahead(); 1029 c = lexLookahead();
1003 } 1030 }
1004 lexAppendc(0); 1031 lexAppendc(0);
1005 return c==EOF?0:lexStr(); 1032 return c==EOF?0:lexStr();
1006} 1033}
1007 1034
1008static int yylex() { 1035static int yylex() {
1009 1036
1010 int lexmode = LEXMODE(); 1037 int lexmode = LEXMODE();
1011 if (lexmode == L_VALUES) { 1038 if (lexmode == L_VALUES) {
1012 int c = lexGetc(); 1039 int c = lexGetc();
1040 int c2;
1013 if (c == ';' && fieldedProp) { 1041 if (c == ';' && fieldedProp) {
1014 DBG_(("db: SEMICOLON\n")); 1042 DBG_(("db: SEMICOLON\n"));
1015 lexPushLookaheadc(c); 1043 lexPushLookaheadc(c);
1016 handleMoreRFC822LineBreak(c); 1044 handleMoreRFC822LineBreak(c);
1017 lexSkipLookahead(); 1045 lexSkipLookahead();
1018 return SEMICOLON; 1046 return SEMICOLON;
1019 } 1047 }
1020 else if (strchr("\n",c)) { 1048 else if (strchr("\n",c) && (c2 = lexLookahead()) != ' ' && c2 != '\t') {
1021 ++mime_lineNum; 1049 ++mime_lineNum;
1022 /* consume all line separator(s) adjacent to each other */ 1050 /* consume all line separator(s) adjacent to each other */
1023 c = lexLookahead(); 1051 while (strchr("\n",c2)) {
1024 while (strchr("\n",c)) {
1025 lexSkipLookahead(); 1052 lexSkipLookahead();
1026 c = lexLookahead(); 1053 c2 = lexLookahead();
1027 ++mime_lineNum; 1054 ++mime_lineNum;
1028 } 1055 }
1029 DBG_(("db: LINESEP\n")); 1056 DBG_(("db: LINESEP\n"));
1030 return LINESEP; 1057 return LINESEP;
1031 } 1058 }
1032 else { 1059 else {
1033 char *p = 0; 1060 char *p = 0;
1034 lexPushLookaheadc(c); 1061 lexPushLookaheadc(c);
1035 if (lexWithinMode(L_BASE64)) { 1062 if (lexWithinMode(L_BASE64)) {
1036 /* get each char and convert to bin on the fly... */ 1063 /* get each char and convert to bin on the fly... */
1037 yylval.str = NULL; 1064 yylval.str = NULL;
1038 return lexGetDataFromBase64() ? STRING : 0; 1065 return lexGetDataFromBase64() ? STRING : 0;
@@ -1045,26 +1072,28 @@ static int yylex() {
1045 p = lexGet1Value(); 1072 p = lexGet1Value();
1046#else 1073#else
1047 p = lexGetStrUntil(";\n"); 1074 p = lexGetStrUntil(";\n");
1048#endif 1075#endif
1049 } 1076 }
1050 if (p) { 1077 if (p) {
1051 DBG_(("db: STRING: '%s'\n", p)); 1078 DBG_(("db: STRING: '%s'\n", p));
1052 yylval.str = p; 1079 yylval.str = p;
1053 return STRING; 1080 return STRING;
1054 } 1081 }
1055 else return 0; 1082 else return 0;
1056 } 1083 }
1057 } 1084 } else if (lexmode == L_PARAMWORD) {
1058 else { 1085 yylval.str = lexGetParamWord();
1086 return ID;
1087 } else {
1059 /* normal mode */ 1088 /* normal mode */
1060 while (1) { 1089 while (1) {
1061 int c = lexGetc(); 1090 int c = lexGetc();
1062 switch(c) { 1091 switch(c) {
1063 case ':': { 1092 case ':': {
1064 /* consume all line separator(s) adjacent to each other */ 1093 /* consume all line separator(s) adjacent to each other */
1065 /* ignoring linesep immediately after colon. */ 1094 /* ignoring linesep immediately after colon. */
1066 /* I don't see this in the spec, and it breaks null values -- WA 1095 /* I don't see this in the spec, and it breaks null values -- WA
1067 c = lexLookahead(); 1096 c = lexLookahead();
1068 while (strchr("\n",c)) { 1097 while (strchr("\n",c)) {
1069 lexSkipLookahead(); 1098 lexSkipLookahead();
1070 c = lexLookahead(); 1099 c = lexLookahead();
diff --git a/library/backend/vcc_yacc.cpp b/library/backend/vcc_yacc.cpp
index bc05f87..68f11b5 100644
--- a/library/backend/vcc_yacc.cpp
+++ b/library/backend/vcc_yacc.cpp
@@ -1,48 +1,23 @@
1#ifndef lint 1#ifndef lint
2 /*static char yysccsid[] = "from: @(#)yaccpar1.9 (Berkeley) 02/21/93";*/ 2 static char yysccsid[] = "@(#)yaccpar1.9 (Berkeley) 02/21/93";
3static char yyrcsid[] = "$Id$";
4#endif 3#endif
5#define YYBYACC 1 4#define YYBYACC 1
6#define YYMAJOR 1 5#define YYMAJOR 1
7#define YYMINOR 9 6#define YYMINOR 9
8#define yyclearin (yychar=(-1)) 7#define yyclearin (yychar=(-1))
9#define yyerrok (yyerrflag=0) 8#define yyerrok (yyerrflag=0)
10#define YYRECOVERING (yyerrflag!=0) 9#define YYRECOVERING (yyerrflag!=0)
11#define yyparse vccparse 10#define YYPREFIX "yy"
12#define yylex vcclex 11#line 1 "vcc.y"
13#define yyerror vccerror
14#define yychar vccchar
15#define yyval vccval
16#define yylval vcclval
17#define yydebug vccdebug
18#define yynerrs vccnerrs
19#define yyerrflag vccerrflag
20#define yyss vccss
21#define yyssp vccssp
22#define yyvs vccvs
23#define yyvsp vccvsp
24#define yylhs vcclhs
25#define yylen vcclen
26#define yydefred vccdefred
27#define yydgoto vccdgoto
28#define yysindex vccsindex
29#define yyrindex vccrindex
30#define yygindex vccgindex
31#define yytable vcctable
32#define yycheck vcccheck
33#define yyname vccname
34#define yyrule vccrule
35#define YYPREFIX "vcc"
36#line 1 "backend/vcc.y"
37 12
38 13
39/*************************************************************************** 14/***************************************************************************
40(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 15(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
41Business Machines Corporation and Siemens Rolm Communications Inc. 16Business Machines Corporation and Siemens Rolm Communications Inc.
42 17
43For purposes of this license notice, the term Licensors shall mean, 18For purposes of this license notice, the term Licensors shall mean,
44collectively, Apple Computer, Inc., AT&T Corp., International 19collectively, Apple Computer, Inc., AT&T Corp., International
45Business Machines Corporation and Siemens Rolm Communications Inc. 20Business Machines Corporation and Siemens Rolm Communications Inc.
46The term Licensor shall mean any of the Licensors. 21The term Licensor shall mean any of the Licensors.
47 22
48Subject to acceptance of the following conditions, permission is hereby 23Subject to acceptance of the following conditions, permission is hereby
@@ -77,24 +52,26 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
77/* 52/*
78 * src: vcc.c 53 * src: vcc.c
79 * doc: Parser for vCard and vCalendar. Note that this code is 54 * doc: Parser for vCard and vCalendar. Note that this code is
80 * generated by a yacc parser generator. Generally it should not 55 * generated by a yacc parser generator. Generally it should not
81 * be edited by hand. The real source is vcc.y. The #line directives 56 * be edited by hand. The real source is vcc.y. The #line directives
82 * can be commented out here to make it easier to trace through 57 * can be commented out here to make it easier to trace through
83 * in a debugger. However, if a bug is found it should 58 * in a debugger. However, if a bug is found it should
84 * be fixed in vcc.y and this file regenerated. 59 * be fixed in vcc.y and this file regenerated.
85 */ 60 */
86 61
87 62
88/* debugging utilities */ 63/* debugging utilities */
64#define __DEBUG 1
65
89#if __DEBUG 66#if __DEBUG
90#define DBG_(x) printf x 67#define DBG_(x) printf x
91#else 68#else
92#define DBG_(x) 69#define DBG_(x)
93#endif 70#endif
94 71
95/**** External Functions ****/ 72/**** External Functions ****/
96 73
97/* assign local name to parser variables and functions so that 74/* assign local name to parser variables and functions so that
98 we can use more than one yacc based parser. 75 we can use more than one yacc based parser.
99*/ 76*/
100 77
@@ -146,273 +123,271 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
146#include <afx.h> 123#include <afx.h>
147#endif 124#endif
148#endif 125#endif
149 126
150#include <string.h> 127#include <string.h>
151#ifndef __MWERKS__ 128#ifndef __MWERKS__
152#include <stdlib.h> 129#include <stdlib.h>
153#endif 130#endif
154#include <stdio.h> 131#include <stdio.h>
155#include <stdlib.h> 132#include <stdlib.h>
156#include <ctype.h> 133#include <ctype.h>
157 134
158/*#ifdef PALMTOPCENTER 135/*#ifdef PALMTOPCENTER */
159*/ 136/*#include <qpe/vobject_p.h> */
160/*#include <qpe/vobject_p.h> 137/*#else */
161*/
162/*#else
163*/
164#include "vobject_p.h" 138#include "vobject_p.h"
165/*#endif 139/*#endif */
166*/
167 140
168/**** Types, Constants ****/ 141/**** Types, Constants ****/
169 142
170 #define YYDEBUG 0/* 1 to compile in some debugging code */ 143 #define YYDEBUG 0/* 1 to compile in some debugging code */
171 #define MAXTOKEN 256/* maximum token (line) length */ 144 #define MAXTOKEN 256/* maximum token (line) length */
172 #define YYSTACKSIZE 100/* ~unref ? 145 #define YYSTACKSIZE 100/* ~unref ? */
173*/
174 #define MAXLEVEL 10/* max # of nested objects parseable */ 146 #define MAXLEVEL 10/* max # of nested objects parseable */
175 /* (includes outermost) */ 147 /* (includes outermost) */
176 148
177 149
178/**** Global Variables ****/ 150/**** Global Variables ****/
151int q_DontDecodeBase64Photo = 0;
179int mime_lineNum, mime_numErrors; /* yyerror() can use these */ 152int mime_lineNum, mime_numErrors; /* yyerror() can use these */
180static VObject* vObjList; 153static VObject* vObjList;
181static VObject *curProp; 154static VObject *curProp;
182static VObject *curObj; 155static VObject *curObj;
183static VObject* ObjStack[MAXLEVEL]; 156static VObject* ObjStack[MAXLEVEL];
184static int ObjStackTop; 157static int ObjStackTop;
185 158
186 159
187/* A helpful utility for the rest of the app. */ 160/* A helpful utility for the rest of the app. */
188#if __CPLUSPLUS__ 161#if __CPLUSPLUS__
189extern "C" { 162extern "C" {
190#endif 163#endif
191 164
192 extern void yyerror(char *s); 165 extern void yyerror(char *s);
193 166
194#if __CPLUSPLUS__ 167#if __CPLUSPLUS__
195 }; 168 };
196#endif 169#endif
197 170
198int yyparse(); 171int yyparse();
199 172
200enum LexMode { 173enum LexMode {
201 L_NORMAL, 174 L_NORMAL,
175 L_PARAMWORD,
202 L_VCARD, 176 L_VCARD,
203 L_VCAL, 177 L_VCAL,
204 L_VEVENT, 178 L_VEVENT,
205 L_VTODO, 179 L_VTODO,
206 L_VALUES, 180 L_VALUES,
207 L_BASE64, 181 L_BASE64,
208 L_QUOTED_PRINTABLE 182 L_QUOTED_PRINTABLE
209 }; 183 };
210 184
211/**** Private Forward Declarations ****/ 185/**** Private Forward Declarations ****/
212static int pushVObject(const char *prop); 186static int pushVObject(const char *prop);
213static VObject* popVObject(); 187static VObject* popVObject();
214static void lexPopMode(int top); 188static void lexPopMode(int top);
215static int lexWithinMode(enum LexMode mode); 189static int lexWithinMode(enum LexMode mode);
216static void lexPushMode(enum LexMode mode); 190static void lexPushMode(enum LexMode mode);
217static void enterProps(const char *s); 191static void enterProps(const char *s);
218static void enterAttr(const char *s1, const char *s2); 192static void enterAttr(const char *s1, const char *s2);
219static void enterValues(const char *value); 193static void enterValues(const char *value);
220#define mime_error yyerror 194#define mime_error yyerror
221void mime_error(char *s); 195void mime_error(char *s);
222void mime_error_(char *s); 196void mime_error_(char *s);
223 197
224#line 189 "backend/vcc.y" 198#line 193 "vcc.y"
225typedef union { 199typedef union {
226 char *str; 200 char *str;
227 VObject *vobj; 201 VObject *vobj;
228 } YYSTYPE; 202 } YYSTYPE;
229#line 225 "y.tab.c" 203#line 204 "y.tab.c"
230#define EQ 257 204#define EQ 257
231#define COLON 258 205#define COLON 258
232#define DOT 259 206#define DOT 259
233#define SEMICOLON 260 207#define SEMICOLON 260
234#define SPACE 261 208#define SPACE 261
235#define HTAB 262 209#define HTAB 262
236#define LINESEP 263 210#define LINESEP 263
237#define NEWLINE 264 211#define NEWLINE 264
238#define BEGIN_VCARD 265 212#define BEGIN_VCARD 265
239#define END_VCARD 266 213#define END_VCARD 266
240#define BEGIN_VCAL 267 214#define BEGIN_VCAL 267
241#define END_VCAL 268 215#define END_VCAL 268
242#define BEGIN_VEVENT 269 216#define BEGIN_VEVENT 269
243#define END_VEVENT 270 217#define END_VEVENT 270
244#define BEGIN_VTODO 271 218#define BEGIN_VTODO 271
245#define END_VTODO 272 219#define END_VTODO 272
246#define ID 273 220#define ID 273
247#define STRING 274 221#define STRING 274
248#define YYERRCODE 256 222#define YYERRCODE 256
249short vcclhs[] = { -1, 223short yylhs[] = { -1,
250 0, 6, 6, 5, 5, 8, 3, 9, 3, 7, 224 0, 6, 6, 5, 5, 8, 3, 9, 3, 7,
251 7, 13, 10, 10, 15, 11, 11, 14, 14, 16, 225 7, 13, 10, 10, 15, 11, 11, 14, 14, 16,
252 17, 17, 1, 18, 12, 12, 2, 2, 20, 4, 226 17, 18, 17, 1, 19, 12, 12, 2, 2, 21,
253 21, 4, 19, 19, 22, 22, 22, 25, 23, 26, 227 4, 22, 4, 20, 20, 23, 23, 23, 26, 24,
254 23, 27, 24, 28, 24, 228 27, 24, 28, 25, 29, 25,
255}; 229};
256short vcclen[] = { 2, 230short yylen[] = { 2,
257 1, 2, 1, 1, 1, 0, 4, 0, 3, 2, 231 1, 2, 1, 1, 1, 0, 4, 0, 3, 2,
258 1, 0, 5, 1, 0, 3, 1, 2, 1, 2, 232 1, 0, 5, 1, 0, 3, 1, 2, 1, 2,
259 1, 3, 1, 0, 4, 1, 1, 0, 0, 4, 233 1, 0, 4, 1, 0, 4, 1, 1, 0, 0,
260 0, 3, 2, 1, 1, 1, 1, 0, 4, 0, 234 4, 0, 3, 2, 1, 1, 1, 1, 0, 4,
261 3, 0, 4, 0, 3, 235 0, 3, 0, 4, 0, 3,
262}; 236};
263short vccdefred[] = { 0, 237short yydefred[] = { 0,
264 0, 0, 0, 4, 5, 3, 0, 0, 0, 0, 238 0, 0, 0, 4, 5, 3, 0, 0, 0, 0,
265 0, 2, 14, 23, 0, 0, 11, 0, 9, 0, 239 0, 2, 14, 24, 0, 0, 11, 0, 9, 0,
266 0, 0, 0, 34, 35, 36, 32, 0, 7, 10, 240 0, 0, 0, 35, 36, 37, 33, 0, 7, 10,
267 12, 0, 0, 0, 0, 30, 33, 0, 0, 19, 241 12, 0, 0, 0, 0, 31, 34, 0, 0, 19,
268 0, 0, 41, 0, 45, 0, 20, 18, 27, 0, 242 0, 0, 42, 0, 46, 0, 20, 18, 28, 0,
269 0, 39, 43, 0, 24, 13, 22, 0, 25, 243 0, 40, 44, 22, 25, 13, 0, 0, 23, 26,
270}; 244};
271short vccdgoto[] = { 3, 245short yydgoto[] = { 3,
272 15, 50, 4, 5, 6, 7, 22, 8, 9, 17, 246 15, 50, 4, 5, 6, 7, 22, 8, 9, 17,
273 18, 51, 41, 39, 28, 40, 47, 58, 23, 10, 247 18, 51, 41, 39, 28, 40, 47, 57, 58, 23,
274 11, 24, 25, 26, 32, 33, 34, 35, 248 10, 11, 24, 25, 26, 32, 33, 34, 35,
275}; 249};
276short vccsindex[] = { -262, 250short yysindex[] = { -255,
277 0, 0, 0, 0, 0, 0, -262, -252, -219, -249, 251 0, 0, 0, 0, 0, 0, -255, -215, -257, -234,
278 -256, 0, 0, 0, 0, -227, 0, -242, 0, 0, 252 -245, 0, 0, 0, 0, -242, 0, -210, 0, 0,
279 0, -252, -254, 0, 0, 0, 0, -208, 0, 0, 253 0, -215, -253, 0, 0, 0, 0, -247, 0, 0,
280 0, -252, -228, -252, -213, 0, 0, -212, -208, 0, 254 0, -215, -227, -215, -226, 0, 0, -221, -247, 0,
281 -214, -233, 0, -224, 0, -195, 0, 0, 0, -197, 255 -211, -237, 0, -218, 0, -204, 0, 0, 0, -198,
282 -199, 0, 0, -212, 0, 0, 0, -214, 0, 256 -199, 0, 0, 0, 0, 0, -221, -211, 0, 0,
283}; 257};
284short vccrindex[] = { 0, 258short yyrindex[] = { 0,
285 -222, -238, 0, 0, 0, 0, 65, 0, 0, 0, 259 -216, -239, 0, 0, 0, 0, 65, 0, 0, 0,
286 0, 0, 0, 0, -215, 0, 0, 0, 0, -220, 260 0, 0, 0, 0, -213, 0, 0, 0, 0, -214,
287 -218, -260, 0, 0, 0, 0, 0, 0, 0, 0, 261 -212, -264, 0, 0, 0, 0, 0, 0, 0, 0,
288 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 262 0, 0, 0, 0, 0, 0, 0, 0, -192, 0,
289 -250, 0, 0, 0, 0, -202, 0, 0, 0, -196, 263 -252, 0, 0, 0, 0, -209, 0, 0, 0, -196,
290 0, 0, 0, 0, 0, 0, 0, -250, 0, 264 0, 0, 0, 0, 0, 0, 0, -252, 0, 0,
291}; 265};
292short vccgindex[] = { 0, 266short yygindex[] = { 0,
293 3, 0, 0, 0, 61, 0, -7, 0, 0, -16, 267 -36, 0, 0, 0, 61, 0, -7, 0, 0, -16,
294 0, 11, 0, 0, 0, 31, 0, 0, 0, 0, 268 0, 11, 0, 0, 0, 31, 0, 0, 0, 0,
295 0, 48, 0, 0, 0, 0, 0, 0, 269 0, 0, 48, 0, 0, 0, 0, 0, 0,
296}; 270};
297#define YYTABLESIZE 71 271#define YYTABLESIZE 71
298short vcctable[] = { 30, 272short yytable[] = { 30,
299 16, 13, 1, 13, 2, 30, 13, 37, 37, 28, 273 16, 46, 13, 38, 38, 30, 38, 29, 19, 1,
300 37, 27, 28, 36, 20, 31, 21, 29, 14, 20, 274 29, 2, 38, 13, 36, 20, 30, 21, 13, 14,
301 14, 21, 13, 14, 42, 30, 44, 30, 13, 31, 275 59, 13, 27, 29, 42, 30, 44, 30, 32, 30,
302 29, 13, 29, 6, 29, 38, 52, 42, 29, 14, 276 14, 30, 52, 30, 20, 14, 21, 13, 14, 6,
303 46, 43, 17, 8, 15, 14, 19, 53, 14, 40, 277 13, 39, 43, 43, 17, 45, 15, 31, 21, 8,
304 6, 38, 38, 44, 42, 21, 57, 21, 45, 49, 278 21, 14, 54, 53, 14, 41, 6, 14, 39, 45,
305 14, 54, 55, 56, 1, 16, 26, 12, 59, 48, 279 43, 55, 49, 56, 1, 16, 27, 12, 60, 48,
306 37, 280 37,
307}; 281};
308short vcccheck[] = { 16, 282short yycheck[] = { 16,
309 8, 256, 265, 256, 267, 22, 256, 268, 269, 260, 283 8, 38, 256, 268, 269, 22, 271, 260, 266, 265,
310 271, 268, 263, 268, 269, 258, 271, 256, 273, 269, 284 263, 267, 260, 256, 268, 269, 256, 271, 256, 273,
311 273, 271, 256, 273, 32, 42, 34, 44, 256, 268, 285 57, 256, 268, 266, 32, 42, 34, 44, 268, 269,
312 269, 256, 271, 256, 273, 256, 270, 256, 266, 273, 286 273, 271, 270, 273, 269, 273, 271, 256, 273, 256,
313 38, 270, 258, 266, 260, 273, 266, 272, 273, 270, 287 256, 256, 270, 256, 258, 272, 260, 258, 258, 266,
314 273, 260, 273, 272, 273, 258, 54, 260, 272, 274, 288 260, 273, 257, 272, 273, 270, 273, 273, 273, 272,
315 273, 257, 260, 263, 0, 258, 263, 7, 58, 39, 289 273, 260, 274, 263, 0, 258, 263, 7, 58, 39,
316 23, 290 23,
317}; 291};
318#define YYFINAL 3 292#define YYFINAL 3
319#ifndef YYDEBUG 293#ifndef YYDEBUG
320#define YYDEBUG 0 294#define YYDEBUG 0
321#endif 295#endif
322#define YYMAXTOKEN 274 296#define YYMAXTOKEN 274
323#if YYDEBUG 297#if YYDEBUG
324char *vccname[] = { 298char *yyname[] = {
325"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 299"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3280,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3020,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3290,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3040,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3310,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"EQ","COLON","DOT","SEMICOLON", 3050,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"EQ","COLON","DOT","SEMICOLON",
332"SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL", 306"SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL",
333"END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING", 307"END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING",
334}; 308};
335char *vccrule[] = { 309char *yyrule[] = {
336"$accept : mime", 310"$accept : mime",
337"mime : vobjects", 311"mime : vobjects",
338"vobjects : vobjects vobject", 312"vobjects : vobjects vobject",
339"vobjects : vobject", 313"vobjects : vobject",
340"vobject : vcard", 314"vobject : vcard",
341"vobject : vcal", 315"vobject : vcal",
342"$$1 :", 316"$$1 :",
343"vcard : BEGIN_VCARD $$1 items END_VCARD", 317"vcard : BEGIN_VCARD $$1 items END_VCARD",
344"$$2 :", 318"$$2 :",
345"vcard : BEGIN_VCARD $$2 END_VCARD", 319"vcard : BEGIN_VCARD $$2 END_VCARD",
346"items : items item", 320"items : items item",
347"items : item", 321"items : item",
348"$$3 :", 322"$$3 :",
349"item : prop COLON $$3 values LINESEP", 323"item : prop COLON $$3 values LINESEP",
350"item : error", 324"item : error",
351"$$4 :", 325"$$4 :",
352"prop : name $$4 attr_params", 326"prop : name $$4 attr_params",
353"prop : name", 327"prop : name",
354"attr_params : attr_params attr_param", 328"attr_params : attr_params attr_param",
355"attr_params : attr_param", 329"attr_params : attr_param",
356"attr_param : SEMICOLON attr", 330"attr_param : SEMICOLON attr",
357"attr : name", 331"attr : name",
358"attr : name EQ name",
359"name : ID",
360"$$5 :", 332"$$5 :",
361"values : value SEMICOLON $$5 values", 333"attr : name EQ $$5 name",
334"name : ID",
335"$$6 :",
336"values : value SEMICOLON $$6 values",
362"values : value", 337"values : value",
363"value : STRING", 338"value : STRING",
364"value :", 339"value :",
365"$$6 :",
366"vcal : BEGIN_VCAL $$6 calitems END_VCAL",
367"$$7 :", 340"$$7 :",
368"vcal : BEGIN_VCAL $$7 END_VCAL", 341"vcal : BEGIN_VCAL $$7 calitems END_VCAL",
342"$$8 :",
343"vcal : BEGIN_VCAL $$8 END_VCAL",
369"calitems : calitems calitem", 344"calitems : calitems calitem",
370"calitems : calitem", 345"calitems : calitem",
371"calitem : eventitem", 346"calitem : eventitem",
372"calitem : todoitem", 347"calitem : todoitem",
373"calitem : items", 348"calitem : items",
374"$$8 :",
375"eventitem : BEGIN_VEVENT $$8 items END_VEVENT",
376"$$9 :", 349"$$9 :",
377"eventitem : BEGIN_VEVENT $$9 END_VEVENT", 350"eventitem : BEGIN_VEVENT $$9 items END_VEVENT",
378"$$10 :", 351"$$10 :",
379"todoitem : BEGIN_VTODO $$10 items END_VTODO", 352"eventitem : BEGIN_VEVENT $$10 END_VEVENT",
380"$$11 :", 353"$$11 :",
381"todoitem : BEGIN_VTODO $$11 END_VTODO", 354"todoitem : BEGIN_VTODO $$11 items END_VTODO",
355"$$12 :",
356"todoitem : BEGIN_VTODO $$12 END_VTODO",
382}; 357};
383#endif 358#endif
384#ifdef YYSTACKSIZE 359#ifdef YYSTACKSIZE
385#undef YYMAXDEPTH 360#undef YYMAXDEPTH
386#define YYMAXDEPTH YYSTACKSIZE 361#define YYMAXDEPTH YYSTACKSIZE
387#else 362#else
388#ifdef YYMAXDEPTH 363#ifdef YYMAXDEPTH
389#define YYSTACKSIZE YYMAXDEPTH 364#define YYSTACKSIZE YYMAXDEPTH
390#else 365#else
391#define YYSTACKSIZE 500 366#define YYSTACKSIZE 500
392#define YYMAXDEPTH 500 367#define YYMAXDEPTH 500
393#endif 368#endif
394#endif 369#endif
395int yydebug; 370int yydebug;
396int yynerrs; 371int yynerrs;
397int yyerrflag; 372int yyerrflag;
398int yychar; 373int yychar;
399short *yyssp; 374short *yyssp;
400YYSTYPE *yyvsp; 375YYSTYPE *yyvsp;
401YYSTYPE yyval; 376YYSTYPE yyval;
402YYSTYPE yylval; 377YYSTYPE yylval;
403short yyss[YYSTACKSIZE]; 378short yyss[YYSTACKSIZE];
404YYSTYPE yyvs[YYSTACKSIZE]; 379YYSTYPE yyvs[YYSTACKSIZE];
405#define yystacksize YYSTACKSIZE 380#define yystacksize YYSTACKSIZE
406#line 382 "backend/vcc.y" 381#line 390 "vcc.y"
407 382
408/*------------------------------------*/ 383/*------------------------------------*/
409static int pushVObject(const char *prop) 384static int pushVObject(const char *prop)
410 { 385 {
411 VObject *newObj; 386 VObject *newObj;
412 if (ObjStackTop == MAXLEVEL) 387 if (ObjStackTop == MAXLEVEL)
413 return FALSE; 388 return FALSE;
414 389
415 ObjStack[++ObjStackTop] = curObj; 390 ObjStack[++ObjStackTop] = curObj;
416 391
417 if (curObj) { 392 if (curObj) {
418 newObj = addProp(curObj,prop); 393 newObj = addProp(curObj,prop);
@@ -467,28 +442,33 @@ static void enterProps(const char *s)
467static void enterAttr(const char *s1, const char *s2) 442static void enterAttr(const char *s1, const char *s2)
468 { 443 {
469 const char *p1, *p2=0; 444 const char *p1, *p2=0;
470 p1 = lookupProp_(s1); 445 p1 = lookupProp_(s1);
471 if (s2) { 446 if (s2) {
472 VObject *a; 447 VObject *a;
473 p2 = lookupProp_(s2); 448 p2 = lookupProp_(s2);
474 a = addProp(curProp,p1); 449 a = addProp(curProp,p1);
475 setVObjectStringZValue(a,p2); 450 setVObjectStringZValue(a,p2);
476 } 451 }
477 else 452 else
478 addProp(curProp,p1); 453 addProp(curProp,p1);
479 if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0)) 454 /* Lookup strings so we can quickly use pointer comparison */
455 static const char* base64 = lookupProp_(VCBase64Prop);
456 static const char* qp = lookupProp_(VCQuotedPrintableProp);
457 static const char* photo = lookupProp_(VCPhotoProp);
458 static const char* encoding = lookupProp_(VCEncodingProp);
459 if ((!q_DontDecodeBase64Photo || vObjectName(curProp) != photo)
460 && (p1 == base64 || p1 == encoding && p2 == base64))
480 lexPushMode(L_BASE64); 461 lexPushMode(L_BASE64);
481 else if (qstricmp(p1,VCQuotedPrintableProp) == 0 462 else if (p1 == qp || p1 == encoding && p2 == qp)
482 || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0))
483 lexPushMode(L_QUOTED_PRINTABLE); 463 lexPushMode(L_QUOTED_PRINTABLE);
484 deleteStr(s1); deleteStr(s2); 464 deleteStr(s1); deleteStr(s2);
485 } 465 }
486 466
487 467
488#define MAX_LEX_LOOKAHEAD_0 32 468#define MAX_LEX_LOOKAHEAD_0 32
489#define MAX_LEX_LOOKAHEAD 64 469#define MAX_LEX_LOOKAHEAD 64
490#define MAX_LEX_MODE_STACK_SIZE 10 470#define MAX_LEX_MODE_STACK_SIZE 10
491#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) 471#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
492 472
493struct LexBuf { 473struct LexBuf {
494 /* input */ 474 /* input */
@@ -657,24 +637,38 @@ static char* lexGetWord() {
657 lexSkipWhite(); 637 lexSkipWhite();
658 lexClearToken(); 638 lexClearToken();
659 c = lexLookahead(); 639 c = lexLookahead();
660 while (c != EOF && !strchr("\t\n ;:=",c)) { 640 while (c != EOF && !strchr("\t\n ;:=",c)) {
661 lexAppendc(c); 641 lexAppendc(c);
662 lexSkipLookahead(); 642 lexSkipLookahead();
663 c = lexLookahead(); 643 c = lexLookahead();
664 } 644 }
665 lexAppendc(0); 645 lexAppendc(0);
666 return lexStr(); 646 return lexStr();
667 } 647 }
668 648
649static char* lexGetParamWord()
650{
651 int c;
652 lexClearToken();
653 c = lexLookahead();
654 while (c >= ' ' && c < 127 && !strchr("[]:=,.;",c)) {
655 lexAppendc(c);
656 lexSkipLookahead();
657 c = lexLookahead();
658 }
659 lexAppendc(0);
660 return lexStr();
661}
662
669static void lexPushLookaheadc(int c) { 663static void lexPushLookaheadc(int c) {
670 int putptr; 664 int putptr;
671 /* can't putback EOF, because it never leaves lookahead buffer */ 665 /* can't putback EOF, because it never leaves lookahead buffer */
672 if (c == EOF) return; 666 if (c == EOF) return;
673 putptr = (int)lexBuf.getPtr - 1; 667 putptr = (int)lexBuf.getPtr - 1;
674 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; 668 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
675 lexBuf.getPtr = putptr; 669 lexBuf.getPtr = putptr;
676 lexBuf.buf[putptr] = c; 670 lexBuf.buf[putptr] = c;
677 lexBuf.len += 1; 671 lexBuf.len += 1;
678 } 672 }
679 673
680static char* lexLookaheadWord() { 674static char* lexLookaheadWord() {
@@ -1026,38 +1020,38 @@ static char* lexGetQuotedPrintable()
1026 } 1020 }
1027 c = lexLookahead(); 1021 c = lexLookahead();
1028 } 1022 }
1029 lexAppendc(0); 1023 lexAppendc(0);
1030 return c==EOF?0:lexStr(); 1024 return c==EOF?0:lexStr();
1031} 1025}
1032 1026
1033static int yylex() { 1027static int yylex() {
1034 1028
1035 int lexmode = LEXMODE(); 1029 int lexmode = LEXMODE();
1036 if (lexmode == L_VALUES) { 1030 if (lexmode == L_VALUES) {
1037 int c = lexGetc(); 1031 int c = lexGetc();
1032 int c2;
1038 if (c == ';' && fieldedProp) { 1033 if (c == ';' && fieldedProp) {
1039 DBG_(("db: SEMICOLON\n")); 1034 DBG_(("db: SEMICOLON\n"));
1040 lexPushLookaheadc(c); 1035 lexPushLookaheadc(c);
1041 handleMoreRFC822LineBreak(c); 1036 handleMoreRFC822LineBreak(c);
1042 lexSkipLookahead(); 1037 lexSkipLookahead();
1043 return SEMICOLON; 1038 return SEMICOLON;
1044 } 1039 }
1045 else if (strchr("\n",c)) { 1040 else if (strchr("\n",c) && (c2 = lexLookahead()) != ' ' && c2 != '\t') {
1046 ++mime_lineNum; 1041 ++mime_lineNum;
1047 /* consume all line separator(s) adjacent to each other */ 1042 /* consume all line separator(s) adjacent to each other */
1048 c = lexLookahead(); 1043 while (strchr("\n",c2)) {
1049 while (strchr("\n",c)) {
1050 lexSkipLookahead(); 1044 lexSkipLookahead();
1051 c = lexLookahead(); 1045 c2 = lexLookahead();
1052 ++mime_lineNum; 1046 ++mime_lineNum;
1053 } 1047 }
1054 DBG_(("db: LINESEP\n")); 1048 DBG_(("db: LINESEP\n"));
1055 return LINESEP; 1049 return LINESEP;
1056 } 1050 }
1057 else { 1051 else {
1058 char *p = 0; 1052 char *p = 0;
1059 lexPushLookaheadc(c); 1053 lexPushLookaheadc(c);
1060 if (lexWithinMode(L_BASE64)) { 1054 if (lexWithinMode(L_BASE64)) {
1061 /* get each char and convert to bin on the fly... */ 1055 /* get each char and convert to bin on the fly... */
1062 yylval.str = NULL; 1056 yylval.str = NULL;
1063 return lexGetDataFromBase64() ? STRING : 0; 1057 return lexGetDataFromBase64() ? STRING : 0;
@@ -1070,26 +1064,28 @@ static int yylex() {
1070 p = lexGet1Value(); 1064 p = lexGet1Value();
1071#else 1065#else
1072 p = lexGetStrUntil(";\n"); 1066 p = lexGetStrUntil(";\n");
1073#endif 1067#endif
1074 } 1068 }
1075 if (p) { 1069 if (p) {
1076 DBG_(("db: STRING: '%s'\n", p)); 1070 DBG_(("db: STRING: '%s'\n", p));
1077 yylval.str = p; 1071 yylval.str = p;
1078 return STRING; 1072 return STRING;
1079 } 1073 }
1080 else return 0; 1074 else return 0;
1081 } 1075 }
1082 } 1076 } else if (lexmode == L_PARAMWORD) {
1083 else { 1077 yylval.str = lexGetParamWord();
1078 return ID;
1079 } else {
1084 /* normal mode */ 1080 /* normal mode */
1085 while (1) { 1081 while (1) {
1086 int c = lexGetc(); 1082 int c = lexGetc();
1087 switch(c) { 1083 switch(c) {
1088 case ':': { 1084 case ':': {
1089 /* consume all line separator(s) adjacent to each other */ 1085 /* consume all line separator(s) adjacent to each other */
1090 /* ignoring linesep immediately after colon. */ 1086 /* ignoring linesep immediately after colon. */
1091 /* I don't see this in the spec, and it breaks null values -- WA 1087 /* I don't see this in the spec, and it breaks null values -- WA
1092 c = lexLookahead(); 1088 c = lexLookahead();
1093 while (strchr("\n",c)) { 1089 while (strchr("\n",c)) {
1094 lexSkipLookahead(); 1090 lexSkipLookahead();
1095 c = lexLookahead(); 1091 c = lexLookahead();
@@ -1233,59 +1229,55 @@ void mime_error(char *s)
1233 sprintf(msg,"%s at line %d", s, mime_lineNum); 1229 sprintf(msg,"%s at line %d", s, mime_lineNum);
1234 mimeErrorHandler(msg); 1230 mimeErrorHandler(msg);
1235 } 1231 }
1236 } 1232 }
1237 1233
1238void mime_error_(char *s) 1234void mime_error_(char *s)
1239 { 1235 {
1240 if (mimeErrorHandler) { 1236 if (mimeErrorHandler) {
1241 mimeErrorHandler(s); 1237 mimeErrorHandler(s);
1242 } 1238 }
1243 } 1239 }
1244 1240
1245#line 1241 "y.tab.c" 1241#line 1242 "y.tab.c"
1246#define YYABORT goto yyabort 1242#define YYABORT goto yyabort
1247#define YYREJECT goto yyabort 1243#define YYREJECT goto yyabort
1248#define YYACCEPT goto yyaccept 1244#define YYACCEPT goto yyaccept
1249#define YYERROR goto yyerrlab 1245#define YYERROR goto yyerrlab
1250int 1246int
1251#if defined(__STDC__)
1252yyparse(void)
1253#else
1254yyparse() 1247yyparse()
1255#endif
1256{ 1248{
1257 register int yym, yyn, yystate; 1249 register int yym, yyn, yystate;
1258#if YYDEBUG 1250#if YYDEBUG
1259 register char *yys; 1251 register char *yys;
1260 extern char *getenv(); 1252 extern char *getenv();
1261 1253
1262 if (yys = getenv("YYDEBUG")) 1254 if (yys = getenv("YYDEBUG"))
1263 { 1255 {
1264 yyn = *yys; 1256 yyn = *yys;
1265 if (yyn >= '0' && yyn <= '9') 1257 if (yyn >= '0' && yyn <= '9')
1266 yydebug = yyn - '0'; 1258 yydebug = yyn - '0';
1267 } 1259 }
1268#endif 1260#endif
1269 1261
1270 yynerrs = 0; 1262 yynerrs = 0;
1271 yyerrflag = 0; 1263 yyerrflag = 0;
1272 yychar = (-1); 1264 yychar = (-1);
1273 1265
1274 yyssp = yyss; 1266 yyssp = yyss;
1275 yyvsp = yyvs; 1267 yyvsp = yyvs;
1276 *yyssp = yystate = 0; 1268 *yyssp = yystate = 0;
1277 1269
1278yyloop: 1270yyloop:
1279 if ((yyn = yydefred[yystate]) != 0) goto yyreduce; 1271 if (yyn = yydefred[yystate]) goto yyreduce;
1280 if (yychar < 0) 1272 if (yychar < 0)
1281 { 1273 {
1282 if ((yychar = yylex()) < 0) yychar = 0; 1274 if ((yychar = yylex()) < 0) yychar = 0;
1283#if YYDEBUG 1275#if YYDEBUG
1284 if (yydebug) 1276 if (yydebug)
1285 { 1277 {
1286 yys = 0; 1278 yys = 0;
1287 if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; 1279 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1288 if (!yys) yys = "illegal-symbol"; 1280 if (!yys) yys = "illegal-symbol";
1289 printf("%sdebug: state %d, reading %d (%s)\n", 1281 printf("%sdebug: state %d, reading %d (%s)\n",
1290 YYPREFIX, yystate, yychar, yys); 1282 YYPREFIX, yystate, yychar, yys);
1291 } 1283 }
@@ -1307,24 +1299,28 @@ yyloop:
1307 *++yyvsp = yylval; 1299 *++yyvsp = yylval;
1308 yychar = (-1); 1300 yychar = (-1);
1309 if (yyerrflag > 0) --yyerrflag; 1301 if (yyerrflag > 0) --yyerrflag;
1310 goto yyloop; 1302 goto yyloop;
1311 } 1303 }
1312 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && 1304 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1313 yyn <= YYTABLESIZE && yycheck[yyn] == yychar) 1305 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1314 { 1306 {
1315 yyn = yytable[yyn]; 1307 yyn = yytable[yyn];
1316 goto yyreduce; 1308 goto yyreduce;
1317 } 1309 }
1318 if (yyerrflag) goto yyinrecovery; 1310 if (yyerrflag) goto yyinrecovery;
1311#ifdef lint
1312 goto yynewerror;
1313#endif
1314yynewerror:
1319 yyerror("syntax error"); 1315 yyerror("syntax error");
1320#ifdef lint 1316#ifdef lint
1321 goto yyerrlab; 1317 goto yyerrlab;
1322#endif 1318#endif
1323yyerrlab: 1319yyerrlab:
1324 ++yynerrs; 1320 ++yynerrs;
1325yyinrecovery: 1321yyinrecovery:
1326 if (yyerrflag < 3) 1322 if (yyerrflag < 3)
1327 { 1323 {
1328 yyerrflag = 3; 1324 yyerrflag = 3;
1329 for (;;) 1325 for (;;)
1330 { 1326 {
@@ -1375,183 +1371,189 @@ yyinrecovery:
1375 } 1371 }
1376yyreduce: 1372yyreduce:
1377#if YYDEBUG 1373#if YYDEBUG
1378 if (yydebug) 1374 if (yydebug)
1379 printf("%sdebug: state %d, reducing by rule %d (%s)\n", 1375 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1380 YYPREFIX, yystate, yyn, yyrule[yyn]); 1376 YYPREFIX, yystate, yyn, yyrule[yyn]);
1381#endif 1377#endif
1382 yym = yylen[yyn]; 1378 yym = yylen[yyn];
1383 yyval = yyvsp[1-yym]; 1379 yyval = yyvsp[1-yym];
1384 switch (yyn) 1380 switch (yyn)
1385 { 1381 {
1386case 2: 1382case 2:
1387#line 221 "backend/vcc.y" 1383#line 225 "vcc.y"
1388{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; } 1384{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
1389break; 1385break;
1390case 3: 1386case 3:
1391#line 223 "backend/vcc.y" 1387#line 227 "vcc.y"
1392{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; } 1388{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
1393break; 1389break;
1394case 6: 1390case 6:
1395#line 232 "backend/vcc.y" 1391#line 236 "vcc.y"
1396{ 1392{
1397 lexPushMode(L_VCARD); 1393 lexPushMode(L_VCARD);
1398 if (!pushVObject(VCCardProp)) YYERROR; 1394 if (!pushVObject(VCCardProp)) YYERROR;
1399 } 1395 }
1400break; 1396break;
1401case 7: 1397case 7:
1402#line 237 "backend/vcc.y" 1398#line 241 "vcc.y"
1403{ 1399{
1404 lexPopMode(0); 1400 lexPopMode(0);
1405 yyval.vobj = popVObject(); 1401 yyval.vobj = popVObject();
1406 } 1402 }
1407break; 1403break;
1408case 8: 1404case 8:
1409#line 242 "backend/vcc.y" 1405#line 246 "vcc.y"
1410{ 1406{
1411 lexPushMode(L_VCARD); 1407 lexPushMode(L_VCARD);
1412 if (!pushVObject(VCCardProp)) YYERROR; 1408 if (!pushVObject(VCCardProp)) YYERROR;
1413 } 1409 }
1414break; 1410break;
1415case 9: 1411case 9:
1416#line 247 "backend/vcc.y" 1412#line 251 "vcc.y"
1417{ 1413{
1418 lexPopMode(0); 1414 lexPopMode(0);
1419 yyval.vobj = popVObject(); 1415 yyval.vobj = popVObject();
1420 } 1416 }
1421break; 1417break;
1422case 12: 1418case 12:
1423#line 258 "backend/vcc.y" 1419#line 262 "vcc.y"
1424{ 1420{
1425 lexPushMode(L_VALUES); 1421 lexPushMode(L_VALUES);
1426 } 1422 }
1427break; 1423break;
1428case 13: 1424case 13:
1429#line 262 "backend/vcc.y" 1425#line 266 "vcc.y"
1430{ 1426{
1431 if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) 1427 if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
1432 lexPopMode(0); 1428 lexPopMode(0);
1433 lexPopMode(0); 1429 lexPopMode(0);
1434 } 1430 }
1435break; 1431break;
1436case 15: 1432case 15:
1437#line 271 "backend/vcc.y" 1433#line 275 "vcc.y"
1438{ 1434{
1439 enterProps(yyvsp[0].str); 1435 enterProps(yyvsp[0].str);
1440 } 1436 }
1441break; 1437break;
1442case 17: 1438case 17:
1443#line 276 "backend/vcc.y" 1439#line 280 "vcc.y"
1444{ 1440{
1445 enterProps(yyvsp[0].str); 1441 enterProps(yyvsp[0].str);
1446 } 1442 }
1447break; 1443break;
1448case 21: 1444case 21:
1449#line 289 "backend/vcc.y" 1445#line 293 "vcc.y"
1450{ 1446{
1451 enterAttr(yyvsp[0].str,0); 1447 enterAttr(yyvsp[0].str,0);
1452 } 1448 }
1453break; 1449break;
1454case 22: 1450case 22:
1455#line 293 "backend/vcc.y" 1451#line 297 "vcc.y"
1456{ 1452{
1457 enterAttr(yyvsp[-2].str,yyvsp[0].str); 1453 lexPushMode(L_PARAMWORD);
1458 1454 }
1455break;
1456case 23:
1457#line 301 "vcc.y"
1458{
1459 lexPopMode(0);
1460 enterAttr(yyvsp[-3].str,yyvsp[0].str);
1459 } 1461 }
1460break; 1462break;
1461case 24: 1463case 25:
1462#line 302 "backend/vcc.y" 1464#line 310 "vcc.y"
1463{ enterValues(yyvsp[-1].str); } 1465{ enterValues(yyvsp[-1].str); }
1464break; 1466break;
1465case 26: 1467case 27:
1466#line 304 "backend/vcc.y" 1468#line 312 "vcc.y"
1467{ enterValues(yyvsp[0].str); } 1469{ enterValues(yyvsp[0].str); }
1468break; 1470break;
1469case 28: 1471case 29:
1470#line 309 "backend/vcc.y" 1472#line 317 "vcc.y"
1471{ yyval.str = 0; } 1473{ yyval.str = 0; }
1472break; 1474break;
1473case 29: 1475case 30:
1474#line 314 "backend/vcc.y" 1476#line 322 "vcc.y"
1475{ if (!pushVObject(VCCalProp)) YYERROR; } 1477{ if (!pushVObject(VCCalProp)) YYERROR; }
1476break; 1478break;
1477case 30: 1479case 31:
1478#line 317 "backend/vcc.y" 1480#line 325 "vcc.y"
1479{ yyval.vobj = popVObject(); } 1481{ yyval.vobj = popVObject(); }
1480break; 1482break;
1481case 31: 1483case 32:
1482#line 319 "backend/vcc.y" 1484#line 327 "vcc.y"
1483{ if (!pushVObject(VCCalProp)) YYERROR; } 1485{ if (!pushVObject(VCCalProp)) YYERROR; }
1484break; 1486break;
1485case 32: 1487case 33:
1486#line 321 "backend/vcc.y" 1488#line 329 "vcc.y"
1487{ yyval.vobj = popVObject(); } 1489{ yyval.vobj = popVObject(); }
1488break; 1490break;
1489case 38: 1491case 39:
1490#line 336 "backend/vcc.y" 1492#line 344 "vcc.y"
1491{ 1493{
1492 lexPushMode(L_VEVENT); 1494 lexPushMode(L_VEVENT);
1493 if (!pushVObject(VCEventProp)) YYERROR; 1495 if (!pushVObject(VCEventProp)) YYERROR;
1494 } 1496 }
1495break; 1497break;
1496case 39: 1498case 40:
1497#line 342 "backend/vcc.y" 1499#line 350 "vcc.y"
1498{ 1500{
1499 lexPopMode(0); 1501 lexPopMode(0);
1500 popVObject(); 1502 popVObject();
1501 } 1503 }
1502break; 1504break;
1503case 40: 1505case 41:
1504#line 347 "backend/vcc.y" 1506#line 355 "vcc.y"
1505{ 1507{
1506 lexPushMode(L_VEVENT); 1508 lexPushMode(L_VEVENT);
1507 if (!pushVObject(VCEventProp)) YYERROR; 1509 if (!pushVObject(VCEventProp)) YYERROR;
1508 } 1510 }
1509break; 1511break;
1510case 41: 1512case 42:
1511#line 352 "backend/vcc.y" 1513#line 360 "vcc.y"
1512{ 1514{
1513 lexPopMode(0); 1515 lexPopMode(0);
1514 popVObject(); 1516 popVObject();
1515 } 1517 }
1516break; 1518break;
1517case 42: 1519case 43:
1518#line 360 "backend/vcc.y" 1520#line 368 "vcc.y"
1519{ 1521{
1520 lexPushMode(L_VTODO); 1522 lexPushMode(L_VTODO);
1521 if (!pushVObject(VCTodoProp)) YYERROR; 1523 if (!pushVObject(VCTodoProp)) YYERROR;
1522 } 1524 }
1523break; 1525break;
1524case 43: 1526case 44:
1525#line 366 "backend/vcc.y" 1527#line 374 "vcc.y"
1526{ 1528{
1527 lexPopMode(0); 1529 lexPopMode(0);
1528 popVObject(); 1530 popVObject();
1529 } 1531 }
1530break; 1532break;
1531case 44: 1533case 45:
1532#line 371 "backend/vcc.y" 1534#line 379 "vcc.y"
1533{ 1535{
1534 lexPushMode(L_VTODO); 1536 lexPushMode(L_VTODO);
1535 if (!pushVObject(VCTodoProp)) YYERROR; 1537 if (!pushVObject(VCTodoProp)) YYERROR;
1536 } 1538 }
1537break; 1539break;
1538case 45: 1540case 46:
1539#line 376 "backend/vcc.y" 1541#line 384 "vcc.y"
1540{ 1542{
1541 lexPopMode(0); 1543 lexPopMode(0);
1542 popVObject(); 1544 popVObject();
1543 } 1545 }
1544break; 1546break;
1545#line 1541 "y.tab.c" 1547#line 1548 "y.tab.c"
1546 } 1548 }
1547 yyssp -= yym; 1549 yyssp -= yym;
1548 yystate = *yyssp; 1550 yystate = *yyssp;
1549 yyvsp -= yym; 1551 yyvsp -= yym;
1550 yym = yylhs[yyn]; 1552 yym = yylhs[yyn];
1551 if (yystate == 0 && yym == 0) 1553 if (yystate == 0 && yym == 0)
1552 { 1554 {
1553#if YYDEBUG 1555#if YYDEBUG
1554 if (yydebug) 1556 if (yydebug)
1555 printf("%sdebug: after reduction, shifting from state 0 to\ 1557 printf("%sdebug: after reduction, shifting from state 0 to\
1556 state %d\n", YYPREFIX, YYFINAL); 1558 state %d\n", YYPREFIX, YYFINAL);
1557#endif 1559#endif
diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp
index 9263c3a..592d116 100644
--- a/library/backend/vobject.cpp
+++ b/library/backend/vobject.cpp
@@ -1094,33 +1094,34 @@ static void writeEncString(OFile *fp, const char *s, bool nosemi)
1094 appendcOFile(fp, *p); 1094 appendcOFile(fp, *p);
1095 } else 1095 } else
1096 appendcOFile(fp, *p); 1096 appendcOFile(fp, *p);
1097 p++; 1097 p++;
1098 } 1098 }
1099 break; 1099 break;
1100 case Base64: 1100 case Base64:
1101 writeBase64(fp, (unsigned char*)p, strlen(p)); 1101 writeBase64(fp, (unsigned char*)p, strlen(p));
1102 break; 1102 break;
1103 } 1103 }
1104} 1104}
1105 1105
1106static bool includesUnprintable(VObject *o) 1106static bool includesUnprintable(VObject *o, bool nosemi)
1107{ 1107{
1108 if (o) { 1108 if (o) {
1109 if (VALUE_TYPE(o) == VCVT_STRINGZ) { 1109 if (VALUE_TYPE(o) == VCVT_STRINGZ) {
1110 const char *p = STRINGZ_VALUE_OF(o); 1110 const char *p = STRINGZ_VALUE_OF(o);
1111 if (p) { 1111 if (p) {
1112 while (*p) { 1112 while (*p) {
1113 if (*p==' ' && (!p[1] || p[1]=='\n') // RFC 1521: spaces at ends need quoting 1113 if (*p==' ' && (!p[1] || p[1]=='\n') // RFC 1521: spaces at ends need quoting
1114 || qpReplaceChar(*p) ) 1114 || qpReplaceChar(*p)
1115 || *p==';' && nosemi )
1115 return TRUE; 1116 return TRUE;
1116 p++; 1117 p++;
1117 } 1118 }
1118 } 1119 }
1119 } 1120 }
1120 } 1121 }
1121 return FALSE; 1122 return FALSE;
1122} 1123}
1123 1124
1124static void writeVObject_(OFile *fp, VObject *o); 1125static void writeVObject_(OFile *fp, VObject *o);
1125 1126
1126static void writeValue(OFile *fp, VObject *o, unsigned long size, bool nosemi) 1127static void writeValue(OFile *fp, VObject *o, unsigned long size, bool nosemi)
@@ -1152,25 +1153,25 @@ static void writeValue(OFile *fp, VObject *o, unsigned long size, bool nosemi)
1152 appendcOFile(fp,'\n'); 1153 appendcOFile(fp,'\n');
1153 writeVObject_(fp,VOBJECT_VALUE_OF(o)); 1154 writeVObject_(fp,VOBJECT_VALUE_OF(o));
1154 break; 1155 break;
1155 } 1156 }
1156} 1157}
1157 1158
1158static void writeAttrValue(OFile *fp, VObject *o) 1159static void writeAttrValue(OFile *fp, VObject *o)
1159{ 1160{
1160 if (NAME_OF(o)) { 1161 if (NAME_OF(o)) {
1161 struct PreDefProp *pi; 1162 struct PreDefProp *pi;
1162 pi = lookupPropInfo(NAME_OF(o)); 1163 pi = lookupPropInfo(NAME_OF(o));
1163 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; 1164 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
1164 if ( includesUnprintable(o) ) 1165 if ( includesUnprintable(o,TRUE) )
1165 appendsOFileEncCs(fp); 1166 appendsOFileEncCs(fp);
1166 appendcOFile(fp,';'); 1167 appendcOFile(fp,';');
1167 appendsOFile(fp,NAME_OF(o)); 1168 appendsOFile(fp,NAME_OF(o));
1168 } else { 1169 } else {
1169 appendcOFile(fp,';'); 1170 appendcOFile(fp,';');
1170 } 1171 }
1171 if (VALUE_TYPE(o)) { 1172 if (VALUE_TYPE(o)) {
1172 appendcOFile(fp,'='); 1173 appendcOFile(fp,'=');
1173 writeValue(fp,o,0,TRUE); 1174 writeValue(fp,o,0,TRUE);
1174 } 1175 }
1175} 1176}
1176 1177
@@ -1220,50 +1221,50 @@ static void writeProp(OFile *fp, VObject *o)
1220 VObject *eachProp = nextVObject(&t); 1221 VObject *eachProp = nextVObject(&t);
1221 s = NAME_OF(eachProp); 1222 s = NAME_OF(eachProp);
1222 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) 1223 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s))
1223 writeAttrValue(fp,eachProp); 1224 writeAttrValue(fp,eachProp);
1224 } 1225 }
1225 if (fields_) { 1226 if (fields_) {
1226 int i = 0, n = 0; 1227 int i = 0, n = 0;
1227 const char** fields = fields_; 1228 const char** fields = fields_;
1228 /* output prop as fields */ 1229 /* output prop as fields */
1229 bool printable = TRUE; 1230 bool printable = TRUE;
1230 while (*fields && printable) { 1231 while (*fields && printable) {
1231 VObject *t = isAPropertyOf(o,*fields); 1232 VObject *t = isAPropertyOf(o,*fields);
1232 if (includesUnprintable(t)) 1233 if (includesUnprintable(t,TRUE))
1233 printable = FALSE; 1234 printable = FALSE;
1234 fields++; 1235 fields++;
1235 } 1236 }
1236 fields = fields_; 1237 fields = fields_;
1237 if (!printable) 1238 if (!printable)
1238 appendsOFileEncCs(fp); 1239 appendsOFileEncCs(fp);
1239 appendcOFile(fp,':'); 1240 appendcOFile(fp,':');
1240 while (*fields) { 1241 while (*fields) {
1241 VObject *t = isAPropertyOf(o,*fields); 1242 VObject *t = isAPropertyOf(o,*fields);
1242 i++; 1243 i++;
1243 if (t) n = i; 1244 if (t) n = i;
1244 fields++; 1245 fields++;
1245 } 1246 }
1246 fields = fields_; 1247 fields = fields_;
1247 for (i=0;i<n;i++) { 1248 for (i=0;i<n;i++) {
1248 writeValue(fp,isAPropertyOf(o,*fields),0,TRUE); 1249 writeValue(fp,isAPropertyOf(o,*fields),0,TRUE);
1249 fields++; 1250 fields++;
1250 if (i<(n-1)) appendcOFile(fp,';'); 1251 if (i<(n-1)) appendcOFile(fp,';');
1251 } 1252 }
1252 } 1253 }
1253 } 1254 }
1254 1255
1255 1256
1256 if (VALUE_TYPE(o)) { 1257 if (VALUE_TYPE(o)) {
1257 if ( includesUnprintable(o) ) 1258 if ( includesUnprintable(o,FALSE) )
1258 appendsOFileEncCs(fp); 1259 appendsOFileEncCs(fp);
1259 unsigned long size = 0; 1260 unsigned long size = 0;
1260 VObject *p = isAPropertyOf(o,VCDataSizeProp); 1261 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1261 if (p) size = LONG_VALUE_OF(p); 1262 if (p) size = LONG_VALUE_OF(p);
1262 appendcOFile(fp,':'); 1263 appendcOFile(fp,':');
1263 writeValue(fp,o,size,FALSE); 1264 writeValue(fp,o,size,FALSE);
1264 } 1265 }
1265 1266
1266 appendcOFile(fp,'\n'); 1267 appendcOFile(fp,'\n');
1267} 1268}
1268 1269
1269static void writeVObject_(OFile *fp, VObject *o) 1270static void writeVObject_(OFile *fp, VObject *o)