author | eilers <eilers> | 2003-03-27 16:17:48 (UTC) |
---|---|---|
committer | eilers <eilers> | 2003-03-27 16:17:48 (UTC) |
commit | 390a5a0c332c8c6fb380c1ed4cd6adae3e544a08 (patch) (side-by-side diff) | |
tree | 7ad6266be3d78d25ae061a0be067f82f8d666246 /library/backend/vcc_yacc.cpp | |
parent | ff43585778968407bb08473e45ddd1d942f8d8c8 (diff) | |
download | opie-390a5a0c332c8c6fb380c1ed4cd6adae3e544a08.zip opie-390a5a0c332c8c6fb380c1ed4cd6adae3e544a08.tar.gz opie-390a5a0c332c8c6fb380c1ed4cd6adae3e544a08.tar.bz2 |
using releases from qtopia-free-1.6.0-snapshot-20030324 which fixes the
following bugs #776 and #490:
Now, we could successfully parse vcards from palm 4 + 5 and
quoted-printable encoded lines .. !
Diffstat (limited to 'library/backend/vcc_yacc.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | library/backend/vcc_yacc.cpp | 139 |
1 files changed, 79 insertions, 60 deletions
diff --git a/library/backend/vcc_yacc.cpp b/library/backend/vcc_yacc.cpp index b2b0c14..5649522 100644 --- a/library/backend/vcc_yacc.cpp +++ b/library/backend/vcc_yacc.cpp @@ -137,49 +137,49 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. #ifndef _NO_LINE_FOLDING
#define _SUPPORT_LINE_FOLDING 1
#endif
/* undef below if compile with MFC */
/* #define INCLUDEMFC 1 */
#if defined(WIN32) || defined(_WIN32)
#ifdef INCLUDEMFC
#include <afx.h>
#endif
#endif
#include <string.h>
#ifndef __MWERKS__
#include <stdlib.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/*#ifdef PALMTOPCENTER
*/ /*#include <qpe/vobject_p.h>
*/ /*#else
*/ -#include <qtopia/private/vobject_p.h> +#include "vobject_p.h"
/*#endif
*/ /**** Types, Constants ****/
#define YYDEBUG 0 /* 1 to compile in some debugging code */
#define MAXTOKEN 256 /* maximum token (line) length */
#define YYSTACKSIZE 100 /* ~unref ?
*/ #define MAXLEVEL 10 /* max # of nested objects parseable */
/* (includes outermost) */
/**** Global Variables ****/
int mime_lineNum, mime_numErrors; /* yyerror() can use these */
static VObject* vObjList;
static VObject *curProp;
static VObject *curObj;
static VObject* ObjStack[MAXLEVEL];
static int ObjStackTop;
/* A helpful utility for the rest of the app. */
#if __CPLUSPLUS__
extern "C" {
#endif
@@ -722,58 +722,64 @@ static void handleMoreRFC822LineBreak(int c) { a = lexLookahead();
if (a == ' ' || a == '\t') {
/* continuation, throw away all the \n and spaces read so
* far
*/
lexSkipWhite();
lexPushLookaheadc(';');
}
else {
lexPushLookaheadc('\n');
lexPushLookaheadc(';');
}
}
else {
lexPushLookaheadc(';');
}
}
}
static char* lexGet1Value() {
int c;
lexSkipWhite();
c = lexLookahead();
lexClearToken();
- while (c != EOF && c != ';') {
+ while (c != EOF && (c != ';' || !fieldedProp)) {
if (c == '\\' ) {
int a;
lexSkipLookahead();
a = lexLookahead();
- if ( a != ';' ) {
- lexAppendc('\\');
- } else {
+ if ( a == ';' ) {
lexAppendc( ';' );
lexSkipLookahead();
+ } else if ( a == '\n' ) {
+ lexAppendc( '\n' );
+ lexSkipLookahead();
+ } else if ( a == '\\' ) {
+ lexAppendc( '\\' );
+ lexSkipLookahead();
+ } else {
+ lexAppendc('\\');
}
} else if (c == '\n') {
int a;
lexSkipLookahead();
a = lexLookahead();
if (a == ' ' || a == '\t') {
lexAppendc(' ');
lexSkipLookahead();
}
else {
lexPushLookaheadc('\n');
break;
}
}
else {
lexAppendc(c);
lexSkipLookahead();
}
c = lexLookahead();
}
lexAppendc(0);
handleMoreRFC822LineBreak(c);
return c==EOF?0:lexStr();
}
@@ -929,110 +935,121 @@ static char * lexGetDataFromBase64() }
static int match_begin_end_name(int end) {
int token;
lexSkipWhite();
if (lexLookahead() != ':') return ID;
lexSkipLookahead();
lexSkipWhite();
token = match_begin_name(end);
if (token == ID) {
lexPushLookaheadc(':');
DBG_(("db: ID '%s'\n", yylval.str));
return ID;
}
else if (token != 0) {
lexSkipLookaheadWord();
deleteStr(yylval.str);
DBG_(("db: begin/end %d\n", token));
return token;
}
return 0;
}
static char* lexGetQuotedPrintable()
- {
- int cur;
-
+{
+ int c;
+ lexSkipWhite();
+ c = lexLookahead();
lexClearToken();
- do {
- cur = lexGetc();
- switch (cur) {
- case '=': {
- int c = 0;
- int next[2];
- int i;
- for (i = 0; i < 2; i++) {
- next[i] = lexGetc();
- if (next[i] >= '0' && next[i] <= '9')
- c = c * 16 + next[i] - '0';
- else if (next[i] >= 'A' && next[i] <= 'F')
- c = c * 16 + next[i] - 'A' + 10;
- else
- break;
- }
- if (i == 0) {
- /* single '=' follow by LINESEP is continuation sign? */
- if (next[0] == '\n') {
- ++mime_lineNum;
- }
- else {
- lexPushLookaheadc('=');
- goto EndString;
- }
- }
- else if (i == 1) {
- lexPushLookaheadc(next[1]);
- lexPushLookaheadc(next[0]);
- lexAppendc('=');
- } else {
- lexAppendc(c);
- }
- break;
- } /* '=' */
- case '\n': {
- lexPushLookaheadc('\n');
- goto EndString;
- }
- case (int)EOF:
- break;
- default:
- lexAppendc(cur);
- break;
- } /* switch */
- } while (cur != (int)EOF);
-EndString:
+ while (c != EOF && c != ';') {
+ if (c == '\n') {
+ // break, leave '\n' on remaining chars.
+ break;
+ } else if (c == '=') {
+ int cur = 0;
+ int next;
+
+ lexSkipLookahead(); // skip '='
+ next = lexLookahead();
+
+ if (next == '\n') {
+ // skip and only skip the \n
+ lexSkipLookahead();
+ c = lexLookahead();
+ ++mime_lineNum; // aid in error reporting
+ continue;
+ } else if (next >= '0' && next <= '9') {
+ cur = next - '0';
+ } else if (next >= 'A' && next <= 'F') {
+ cur = next - 'A' + 10;
+ } else {
+ // we have been sent buggy stuff. doesn't matter
+ // what we do so long as we keep going.
+ // should probably spit an error here
+ lexSkipLookahead();
+ c = lexLookahead();
+ continue;
+ }
+
+ lexSkipLookahead(); // skip A-Z0-9
+ next = lexLookahead();
+
+ cur = cur * 16;
+ // this time really just expecting 0-9A-F
+ if (next >= '0' && next <= '9') {
+ cur += next - '0';
+ } else if (next >= 'A' && next <= 'F') {
+ cur += next - 'A' + 10;
+ } else {
+ // we have been sent buggy stuff. doesn't matter
+ // what we do so long as we keep going.
+ // should probably spit an error here
+ lexSkipLookahead();
+ c = lexLookahead();
+ continue;
+ }
+
+ // got a valid escaped =. append it.
+ lexSkipLookahead(); // skip second 0-9A-F
+ lexAppendc(cur);
+ } else {
+ lexSkipLookahead(); // skip whatever we just read.
+ lexAppendc(c); // and append it.
+ }
+ c = lexLookahead();
+ }
lexAppendc(0);
- return lexStr();
- } /* LexQuotedPrintable */
+ return c==EOF?0:lexStr();
+}
static int yylex() {
int lexmode = LEXMODE();
if (lexmode == L_VALUES) {
int c = lexGetc();
- if (c == ';') {
+ if (c == ';' && fieldedProp) {
DBG_(("db: SEMICOLON\n"));
lexPushLookaheadc(c);
handleMoreRFC822LineBreak(c);
lexSkipLookahead();
return SEMICOLON;
}
else if (strchr("\n",c)) {
++mime_lineNum;
/* consume all line separator(s) adjacent to each other */
c = lexLookahead();
while (strchr("\n",c)) {
lexSkipLookahead();
c = lexLookahead();
++mime_lineNum;
}
DBG_(("db: LINESEP\n"));
return LINESEP;
}
else {
char *p = 0;
lexPushLookaheadc(c);
if (lexWithinMode(L_BASE64)) {
/* get each char and convert to bin on the fly... */
p = lexGetDataFromBase64();
@@ -1044,54 +1061,56 @@ static int yylex() { }
else {
#ifdef _SUPPORT_LINE_FOLDING
p = lexGet1Value();
#else
p = lexGetStrUntil(";\n");
#endif
}
if (p) {
DBG_(("db: STRING: '%s'\n", p));
yylval.str = p;
return STRING;
}
else return 0;
}
}
else {
/* normal mode */
while (1) {
int c = lexGetc();
switch(c) {
case ':': {
/* consume all line separator(s) adjacent to each other */
/* ignoring linesep immediately after colon. */
+ /* I don't see this in the spec, and it breaks null values -- WA
c = lexLookahead();
while (strchr("\n",c)) {
lexSkipLookahead();
c = lexLookahead();
++mime_lineNum;
}
+ */
DBG_(("db: COLON\n"));
return COLON;
}
case ';':
DBG_(("db: SEMICOLON\n"));
return SEMICOLON;
case '=':
DBG_(("db: EQ\n"));
return EQ;
/* ignore whitespace in this mode */
case '\t':
case ' ': continue;
case '\n': {
++mime_lineNum;
continue;
}
case EOF: return 0;
break;
default: {
lexPushLookaheadc(c);
if (isalnum(c)) {
char *t = lexGetWord();
yylval.str = t;
if (!qstricmp(t, "begin")) {
@@ -1196,49 +1215,49 @@ DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname) static MimeErrorHandler mimeErrorHandler;
DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me)
{
mimeErrorHandler = me;
}
void mime_error(char *s)
{
char msg[256];
if (mimeErrorHandler) {
sprintf(msg,"%s at line %d", s, mime_lineNum);
mimeErrorHandler(msg);
}
}
void mime_error_(char *s)
{
if (mimeErrorHandler) {
mimeErrorHandler(s);
}
}
-#line 1221 "y.tab.c" +#line 1240 "y.tab.c" #define YYABORT goto yyabort #define YYREJECT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab int #if defined(__STDC__) yyparse(void) #else yyparse() #endif { register int yym, yyn, yystate; #if YYDEBUG register char *yys; extern char *getenv(); if (yys = getenv("YYDEBUG")) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif @@ -1496,49 +1515,49 @@ case 42: if (!pushVObject(VCTodoProp)) YYERROR;
} break; case 43: #line 366 "backend/vcc.y" {
lexPopMode(0);
popVObject();
} break; case 44: #line 371 "backend/vcc.y" {
lexPushMode(L_VTODO);
if (!pushVObject(VCTodoProp)) YYERROR;
} break; case 45: #line 376 "backend/vcc.y" {
lexPopMode(0);
popVObject();
} break; -#line 1521 "y.tab.c" +#line 1540 "y.tab.c" } yyssp -= yym; yystate = *yyssp; yyvsp -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state 0 to\ state %d\n", YYPREFIX, YYFINAL); #endif yystate = YYFINAL; *++yyssp = YYFINAL; *++yyvsp = yyval; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; |