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
@@ -50,6 +50,8 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
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
@@ -135,6 +137,7 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
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;
@@ -158,6 +161,7 @@ int 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,
@@ -289,10 +293,14 @@ attr: 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
@@ -451,10 +459,15 @@ static void enterAttr(const char *s1, const char *s2)
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 }
@@ -641,6 +654,20 @@ static char* lexGetWord() {
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 */
@@ -1010,6 +1037,7 @@ static int yylex() {
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);
@@ -1017,13 +1045,12 @@ static int yylex() {
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"));
@@ -1054,8 +1081,10 @@ static int yylex() {
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();
diff --git a/library/backend/vcc_yacc.cpp b/library/backend/vcc_yacc.cpp
index bc05f87..68f11b5 100644
--- a/library/backend/vcc_yacc.cpp
+++ b/library/backend/vcc_yacc.cpp
@@ -1,6 +1,5 @@
1#ifndef lint 1#ifndef lint
2 /*static char yysccsid[] = "from: @(#)yaccpar1.9 (Berkeley) 02/21/93";*/ 2 static char yysccsid[] = "@(#)yaccpar1.9 (Berkeley) 02/21/93";
3static char yyrcsid[] = "$Id$";
4#endif 3#endif
5#define YYBYACC 1 4#define YYBYACC 1
6#define YYMAJOR 1 5#define YYMAJOR 1
@@ -8,32 +7,8 @@ static char yyrcsid[] = "$Id$";
8#define yyclearin (yychar=(-1)) 7#define yyclearin (yychar=(-1))
9#define yyerrok (yyerrflag=0) 8#define yyerrok (yyerrflag=0)
10#define YYRECOVERING (yyerrflag!=0) 9#define YYRECOVERING (yyerrflag!=0)
11#define yyparse vccparse 10#define YYPREFIX "yy"
12#define yylex vcclex 11#line 1 "vcc.y"
13#define yyerror vccerror
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/***************************************************************************
@@ -86,6 +61,8 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
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
@@ -155,27 +132,23 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
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;
@@ -199,6 +172,7 @@ int 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,
@@ -221,12 +195,12 @@ static void enterValues(const char *value);
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
@@ -246,73 +220,73 @@ typedef union {
246#define ID 273 220#define ID 273
247#define STRING 274 221#define STRING 274
248#define YYERRCODE 256 222#define YYERRCODE 256
249short vcclhs[] = { -1, 223short yylhs[] = { -1,
250 0, 6, 6, 5, 5, 8, 3, 9, 3, 7, 224 0, 6, 6, 5, 5, 8, 3, 9, 3, 7,
251 7, 13, 10, 10, 15, 11, 11, 14, 14, 16, 225 7, 13, 10, 10, 15, 11, 11, 14, 14, 16,
252 17, 17, 1, 18, 12, 12, 2, 2, 20, 4, 226 17, 18, 17, 1, 19, 12, 12, 2, 2, 21,
253 21, 4, 19, 19, 22, 22, 22, 25, 23, 26, 227 4, 22, 4, 20, 20, 23, 23, 23, 26, 24,
254 23, 27, 24, 28, 24, 228 27, 24, 28, 25, 29, 25,
255}; 229};
256short vcclen[] = { 2, 230short yylen[] = { 2,
257 1, 2, 1, 1, 1, 0, 4, 0, 3, 2, 231 1, 2, 1, 1, 1, 0, 4, 0, 3, 2,
258 1, 0, 5, 1, 0, 3, 1, 2, 1, 2, 232 1, 0, 5, 1, 0, 3, 1, 2, 1, 2,
259 1, 3, 1, 0, 4, 1, 1, 0, 0, 4, 233 1, 0, 4, 1, 0, 4, 1, 1, 0, 0,
260 0, 3, 2, 1, 1, 1, 1, 0, 4, 0, 234 4, 0, 3, 2, 1, 1, 1, 1, 0, 4,
261 3, 0, 4, 0, 3, 235 0, 3, 0, 4, 0, 3,
262}; 236};
263short vccdefred[] = { 0, 237short yydefred[] = { 0,
264 0, 0, 0, 4, 5, 3, 0, 0, 0, 0, 238 0, 0, 0, 4, 5, 3, 0, 0, 0, 0,
265 0, 2, 14, 23, 0, 0, 11, 0, 9, 0, 239 0, 2, 14, 24, 0, 0, 11, 0, 9, 0,
266 0, 0, 0, 34, 35, 36, 32, 0, 7, 10, 240 0, 0, 0, 35, 36, 37, 33, 0, 7, 10,
267 12, 0, 0, 0, 0, 30, 33, 0, 0, 19, 241 12, 0, 0, 0, 0, 31, 34, 0, 0, 19,
268 0, 0, 41, 0, 45, 0, 20, 18, 27, 0, 242 0, 0, 42, 0, 46, 0, 20, 18, 28, 0,
269 0, 39, 43, 0, 24, 13, 22, 0, 25, 243 0, 40, 44, 22, 25, 13, 0, 0, 23, 26,
270}; 244};
271short vccdgoto[] = { 3, 245short yydgoto[] = { 3,
272 15, 50, 4, 5, 6, 7, 22, 8, 9, 17, 246 15, 50, 4, 5, 6, 7, 22, 8, 9, 17,
273 18, 51, 41, 39, 28, 40, 47, 58, 23, 10, 247 18, 51, 41, 39, 28, 40, 47, 57, 58, 23,
274 11, 24, 25, 26, 32, 33, 34, 35, 248 10, 11, 24, 25, 26, 32, 33, 34, 35,
275}; 249};
276short vccsindex[] = { -262, 250short yysindex[] = { -255,
277 0, 0, 0, 0, 0, 0, -262, -252, -219, -249, 251 0, 0, 0, 0, 0, 0, -255, -215, -257, -234,
278 -256, 0, 0, 0, 0, -227, 0, -242, 0, 0, 252 -245, 0, 0, 0, 0, -242, 0, -210, 0, 0,
279 0, -252, -254, 0, 0, 0, 0, -208, 0, 0, 253 0, -215, -253, 0, 0, 0, 0, -247, 0, 0,
280 0, -252, -228, -252, -213, 0, 0, -212, -208, 0, 254 0, -215, -227, -215, -226, 0, 0, -221, -247, 0,
281 -214, -233, 0, -224, 0, -195, 0, 0, 0, -197, 255 -211, -237, 0, -218, 0, -204, 0, 0, 0, -198,
282 -199, 0, 0, -212, 0, 0, 0, -214, 0, 256 -199, 0, 0, 0, 0, 0, -221, -211, 0, 0,
283}; 257};
284short vccrindex[] = { 0, 258short yyrindex[] = { 0,
285 -222, -238, 0, 0, 0, 0, 65, 0, 0, 0, 259 -216, -239, 0, 0, 0, 0, 65, 0, 0, 0,
286 0, 0, 0, 0, -215, 0, 0, 0, 0, -220, 260 0, 0, 0, 0, -213, 0, 0, 0, 0, -214,
287 -218, -260, 0, 0, 0, 0, 0, 0, 0, 0, 261 -212, -264, 0, 0, 0, 0, 0, 0, 0, 0,
288 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 262 0, 0, 0, 0, 0, 0, 0, 0, -192, 0,
289 -250, 0, 0, 0, 0, -202, 0, 0, 0, -196, 263 -252, 0, 0, 0, 0, -209, 0, 0, 0, -196,
290 0, 0, 0, 0, 0, 0, 0, -250, 0, 264 0, 0, 0, 0, 0, 0, 0, -252, 0, 0,
291}; 265};
292short vccgindex[] = { 0, 266short yygindex[] = { 0,
293 3, 0, 0, 0, 61, 0, -7, 0, 0, -16, 267 -36, 0, 0, 0, 61, 0, -7, 0, 0, -16,
294 0, 11, 0, 0, 0, 31, 0, 0, 0, 0, 268 0, 11, 0, 0, 0, 31, 0, 0, 0, 0,
295 0, 48, 0, 0, 0, 0, 0, 0, 269 0, 0, 48, 0, 0, 0, 0, 0, 0,
296}; 270};
297#define YYTABLESIZE 71 271#define YYTABLESIZE 71
298short vcctable[] = { 30, 272short yytable[] = { 30,
299 16, 13, 1, 13, 2, 30, 13, 37, 37, 28, 273 16, 46, 13, 38, 38, 30, 38, 29, 19, 1,
300 37, 27, 28, 36, 20, 31, 21, 29, 14, 20, 274 29, 2, 38, 13, 36, 20, 30, 21, 13, 14,
301 14, 21, 13, 14, 42, 30, 44, 30, 13, 31, 275 59, 13, 27, 29, 42, 30, 44, 30, 32, 30,
302 29, 13, 29, 6, 29, 38, 52, 42, 29, 14, 276 14, 30, 52, 30, 20, 14, 21, 13, 14, 6,
303 46, 43, 17, 8, 15, 14, 19, 53, 14, 40, 277 13, 39, 43, 43, 17, 45, 15, 31, 21, 8,
304 6, 38, 38, 44, 42, 21, 57, 21, 45, 49, 278 21, 14, 54, 53, 14, 41, 6, 14, 39, 45,
305 14, 54, 55, 56, 1, 16, 26, 12, 59, 48, 279 43, 55, 49, 56, 1, 16, 27, 12, 60, 48,
306 37, 280 37,
307}; 281};
308short vcccheck[] = { 16, 282short yycheck[] = { 16,
309 8, 256, 265, 256, 267, 22, 256, 268, 269, 260, 283 8, 38, 256, 268, 269, 22, 271, 260, 266, 265,
310 271, 268, 263, 268, 269, 258, 271, 256, 273, 269, 284 263, 267, 260, 256, 268, 269, 256, 271, 256, 273,
311 273, 271, 256, 273, 32, 42, 34, 44, 256, 268, 285 57, 256, 268, 266, 32, 42, 34, 44, 268, 269,
312 269, 256, 271, 256, 273, 256, 270, 256, 266, 273, 286 273, 271, 270, 273, 269, 273, 271, 256, 273, 256,
313 38, 270, 258, 266, 260, 273, 266, 272, 273, 270, 287 256, 256, 270, 256, 258, 272, 260, 258, 258, 266,
314 273, 260, 273, 272, 273, 258, 54, 260, 272, 274, 288 260, 273, 257, 272, 273, 270, 273, 273, 273, 272,
315 273, 257, 260, 263, 0, 258, 263, 7, 58, 39, 289 273, 260, 274, 263, 0, 258, 263, 7, 58, 39,
316 23, 290 23,
317}; 291};
318#define YYFINAL 3 292#define YYFINAL 3
@@ -321,7 +295,7 @@ short vcccheck[] = { 16,
321#endif 295#endif
322#define YYMAXTOKEN 274 296#define YYMAXTOKEN 274
323#if YYDEBUG 297#if YYDEBUG
324char *vccname[] = { 298char *yyname[] = {
325"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 299"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -332,7 +306,7 @@ char *vccname[] = {
332"SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL", 306"SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL",
333"END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING", 307"END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING",
334}; 308};
335char *vccrule[] = { 309char *yyrule[] = {
336"$accept : mime", 310"$accept : mime",
337"mime : vobjects", 311"mime : vobjects",
338"vobjects : vobjects vobject", 312"vobjects : vobjects vobject",
@@ -355,30 +329,31 @@ char *vccrule[] = {
355"attr_params : attr_param", 329"attr_params : attr_param",
356"attr_param : SEMICOLON attr", 330"attr_param : SEMICOLON attr",
357"attr : name", 331"attr : name",
358"attr : name EQ name",
359"name : ID",
360"$$5 :", 332"$$5 :",
361"values : value SEMICOLON $$5 values", 333"attr : name EQ $$5 name",
334"name : ID",
335"$$6 :",
336"values : value SEMICOLON $$6 values",
362"values : value", 337"values : value",
363"value : STRING", 338"value : STRING",
364"value :", 339"value :",
365"$$6 :",
366"vcal : BEGIN_VCAL $$6 calitems END_VCAL",
367"$$7 :", 340"$$7 :",
368"vcal : BEGIN_VCAL $$7 END_VCAL", 341"vcal : BEGIN_VCAL $$7 calitems END_VCAL",
342"$$8 :",
343"vcal : BEGIN_VCAL $$8 END_VCAL",
369"calitems : calitems calitem", 344"calitems : calitems calitem",
370"calitems : calitem", 345"calitems : calitem",
371"calitem : eventitem", 346"calitem : eventitem",
372"calitem : todoitem", 347"calitem : todoitem",
373"calitem : items", 348"calitem : items",
374"$$8 :",
375"eventitem : BEGIN_VEVENT $$8 items END_VEVENT",
376"$$9 :", 349"$$9 :",
377"eventitem : BEGIN_VEVENT $$9 END_VEVENT", 350"eventitem : BEGIN_VEVENT $$9 items END_VEVENT",
378"$$10 :", 351"$$10 :",
379"todoitem : BEGIN_VTODO $$10 items END_VTODO", 352"eventitem : BEGIN_VEVENT $$10 END_VEVENT",
380"$$11 :", 353"$$11 :",
381"todoitem : BEGIN_VTODO $$11 END_VTODO", 354"todoitem : BEGIN_VTODO $$11 items END_VTODO",
355"$$12 :",
356"todoitem : BEGIN_VTODO $$12 END_VTODO",
382}; 357};
383#endif 358#endif
384#ifdef YYSTACKSIZE 359#ifdef YYSTACKSIZE
@@ -403,7 +378,7 @@ YYSTYPE yylval;
403short yyss[YYSTACKSIZE]; 378short yyss[YYSTACKSIZE];
404YYSTYPE yyvs[YYSTACKSIZE]; 379YYSTYPE yyvs[YYSTACKSIZE];
405#define yystacksize YYSTACKSIZE 380#define yystacksize YYSTACKSIZE
406#line 382 "backend/vcc.y" 381#line 390 "vcc.y"
407 382
408/*------------------------------------*/ 383/*------------------------------------*/
409static int pushVObject(const char *prop) 384static int pushVObject(const char *prop)
@@ -476,10 +451,15 @@ static void enterAttr(const char *s1, const char *s2)
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 }
@@ -666,6 +646,20 @@ static char* lexGetWord() {
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 */
@@ -1035,6 +1029,7 @@ static int yylex() {
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);
@@ -1042,13 +1037,12 @@ static int yylex() {
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"));
@@ -1079,8 +1073,10 @@ static int yylex() {
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();
@@ -1242,17 +1238,13 @@ void mime_error_(char *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
@@ -1276,7 +1268,7 @@ yyparse()
1276 *yyssp = yystate = 0; 1268 *yyssp = yystate = 0;
1277 1269
1278yyloop: 1270yyloop:
1279 if ((yyn = yydefred[yystate]) != 0) goto yyreduce; 1271 if (yyn = yydefred[yystate]) goto yyreduce;
1280 if (yychar < 0) 1272 if (yychar < 0)
1281 { 1273 {
1282 if ((yychar = yylex()) < 0) yychar = 0; 1274 if ((yychar = yylex()) < 0) yychar = 0;
@@ -1316,6 +1308,10 @@ yyloop:
1316 goto yyreduce; 1308 goto yyreduce;
1317 } 1309 }
1318 if (yyerrflag) goto yyinrecovery; 1310 if (yyerrflag) goto yyinrecovery;
1311#ifdef lint
1312 goto yynewerror;
1313#endif
1314yynewerror:
1319 yyerror("syntax error"); 1315 yyerror("syntax error");
1320#ifdef lint 1316#ifdef lint
1321 goto yyerrlab; 1317 goto yyerrlab;
@@ -1384,49 +1380,49 @@ yyreduce:
1384 switch (yyn) 1380 switch (yyn)
1385 { 1381 {
1386case 2: 1382case 2:
1387#line 221 "backend/vcc.y" 1383#line 225 "vcc.y"
1388{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; } 1384{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
1389break; 1385break;
1390case 3: 1386case 3:
1391#line 223 "backend/vcc.y" 1387#line 227 "vcc.y"
1392{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; } 1388{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
1393break; 1389break;
1394case 6: 1390case 6:
1395#line 232 "backend/vcc.y" 1391#line 236 "vcc.y"
1396{ 1392{
1397 lexPushMode(L_VCARD); 1393 lexPushMode(L_VCARD);
1398 if (!pushVObject(VCCardProp)) YYERROR; 1394 if (!pushVObject(VCCardProp)) YYERROR;
1399 } 1395 }
1400break; 1396break;
1401case 7: 1397case 7:
1402#line 237 "backend/vcc.y" 1398#line 241 "vcc.y"
1403{ 1399{
1404 lexPopMode(0); 1400 lexPopMode(0);
1405 yyval.vobj = popVObject(); 1401 yyval.vobj = popVObject();
1406 } 1402 }
1407break; 1403break;
1408case 8: 1404case 8:
1409#line 242 "backend/vcc.y" 1405#line 246 "vcc.y"
1410{ 1406{
1411 lexPushMode(L_VCARD); 1407 lexPushMode(L_VCARD);
1412 if (!pushVObject(VCCardProp)) YYERROR; 1408 if (!pushVObject(VCCardProp)) YYERROR;
1413 } 1409 }
1414break; 1410break;
1415case 9: 1411case 9:
1416#line 247 "backend/vcc.y" 1412#line 251 "vcc.y"
1417{ 1413{
1418 lexPopMode(0); 1414 lexPopMode(0);
1419 yyval.vobj = popVObject(); 1415 yyval.vobj = popVObject();
1420 } 1416 }
1421break; 1417break;
1422case 12: 1418case 12:
1423#line 258 "backend/vcc.y" 1419#line 262 "vcc.y"
1424{ 1420{
1425 lexPushMode(L_VALUES); 1421 lexPushMode(L_VALUES);
1426 } 1422 }
1427break; 1423break;
1428case 13: 1424case 13:
1429#line 262 "backend/vcc.y" 1425#line 266 "vcc.y"
1430{ 1426{
1431 if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) 1427 if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
1432 lexPopMode(0); 1428 lexPopMode(0);
@@ -1434,115 +1430,121 @@ case 13:
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;
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
@@ -1103,7 +1103,7 @@ static void writeEncString(OFile *fp, const char *s, bool nosemi)
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) {
@@ -1111,7 +1111,8 @@ static bool includesUnprintable(VObject *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 }
@@ -1161,7 +1162,7 @@ static void writeAttrValue(OFile *fp, VObject *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));
@@ -1229,7 +1230,7 @@ static void writeProp(OFile *fp, VObject *o)
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 }
@@ -1254,7 +1255,7 @@ static void writeProp(OFile *fp, VObject *o)
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);