summaryrefslogtreecommitdiffabout
path: root/libkcal/versit/vcc.c
Side-by-side diff
Diffstat (limited to 'libkcal/versit/vcc.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/versit/vcc.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/libkcal/versit/vcc.c b/libkcal/versit/vcc.c
index 9be752d..5413813 100644
--- a/libkcal/versit/vcc.c
+++ b/libkcal/versit/vcc.c
@@ -1381,769 +1381,770 @@ yyerrlab1:
goto yyerrhandle;
/*-------------------------------------------------------------------.
| yyerrdefault -- current state does not do anything special for the |
| error token. |
`-------------------------------------------------------------------*/
yyerrdefault:
#if 0
/* This is wrong; only states that explicitly want error tokens
should shift them. */
/* If its default is to accept any token, ok. Otherwise pop it. */
yyn = yydefact[yystate];
if (yyn)
goto yydefault;
#endif
/*---------------------------------------------------------------.
| yyerrpop -- pop the current state because it cannot handle the |
| error token |
`---------------------------------------------------------------*/
yyerrpop:
if (yyssp == yyss)
YYABORT;
yyvsp--;
yystate = *--yyssp;
#if YYLSP_NEEDED
yylsp--;
#endif
#if YYDEBUG
if (yydebug)
{
short *yyssp1 = yyss - 1;
YYFPRINTF (stderr, "Error: state stack now");
while (yyssp1 != yyssp)
YYFPRINTF (stderr, " %d", *++yyssp1);
YYFPRINTF (stderr, "\n");
}
#endif
/*--------------.
| yyerrhandle. |
`--------------*/
yyerrhandle:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yyerrdefault;
yyn += YYTERROR;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
goto yyerrdefault;
yyn = yytable[yyn];
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrpop;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
YYDPRINTF ((stderr, "Shifting error token, "));
*++yyvsp = yylval;
#if YYLSP_NEEDED
*++yylsp = yylloc;
#endif
yystate = yyn;
goto yynewstate;
/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here. |
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
goto yyreturn;
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
yyresult = 1;
goto yyreturn;
/*---------------------------------------------.
| yyoverflowab -- parser overflow comes here. |
`---------------------------------------------*/
yyoverflowlab:
yyerror ("parser stack overflow");
yyresult = 2;
/* Fall through. */
yyreturn:
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
return yyresult;
}
#line 373 "vcc.y"
static int pushVObject(const char *prop)
{
VObject *newObj;
if (ObjStackTop == MAXLEVEL)
return FALSE;
ObjStack[++ObjStackTop] = curObj;
if (curObj) {
newObj = addProp(curObj,prop);
curObj = newObj;
}
else
curObj = newVObject(prop);
return TRUE;
}
/* This pops the recently built vCard off the stack and returns it. */
static VObject* popVObject()
{
VObject *oldObj;
if (ObjStackTop < 0) {
yyerror("pop on empty Object Stack\n");
return 0;
}
oldObj = curObj;
curObj = ObjStack[ObjStackTop--];
return oldObj;
}
static void enterValues(const char *value)
{
if (fieldedProp && *fieldedProp) {
if (value) {
addPropValue(curProp,*fieldedProp,value);
}
/* else this field is empty, advance to next field */
fieldedProp++;
}
else {
if (value) {
char *p1, *p2;
wchar_t *p3;
int i;
/* If the property already has a string value, we append this one,
using ';' to separate the values. */
if (vObjectUStringZValue(curProp)) {
p1 = fakeCString(vObjectUStringZValue(curProp));
p2 = malloc((strlen(p1)+strlen(value)+1));
strcpy(p2, p1);
deleteStr(p1);
i = strlen(p2);
p2[i] = ';';
p2[i+1] = '\0';
p2 = strcat(p2, value);
p3 = (wchar_t *) vObjectUStringZValue(curProp);
free(p3);
setVObjectUStringZValue_(curProp,fakeUnicode(p2,0));
deleteStr(p2);
} else {
setVObjectUStringZValue_(curProp,fakeUnicode(value,0));
}
}
}
deleteStr(value);
}
static void enterProps(const char *s)
{
curProp = addGroup(curObj,s);
deleteStr(s);
}
static void enterAttr(const char *s1, const char *s2)
{
const char *p1, *p2;
p1 = lookupProp_(s1);
if (s2) {
VObject *a;
p2 = lookupProp_(s2);
a = addProp(curProp,p1);
setVObjectStringZValue(a,p2);
}
else
addProp(curProp,p1);
if (stricmp(p1,VCBase64Prop) == 0 || (s2 && stricmp(p2,VCBase64Prop)==0))
lexPushMode(L_BASE64);
else if (stricmp(p1,VCQuotedPrintableProp) == 0
|| (s2 && stricmp(p2,VCQuotedPrintableProp)==0))
lexPushMode(L_QUOTED_PRINTABLE);
deleteStr(s1); deleteStr(s2);
}
#define MAX_LEX_LOOKAHEAD_0 32
#define MAX_LEX_LOOKAHEAD 64
#define MAX_LEX_MODE_STACK_SIZE 10
#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
struct LexBuf {
/* input */
#ifdef INCLUDEMFC
CFile *inputFile;
#else
FILE *inputFile;
#endif
char *inputString;
unsigned long curPos;
unsigned long inputLen;
/* lookahead buffer */
/* -- lookahead buffer is short instead of char so that EOF
/ can be represented correctly.
*/
unsigned long len;
short buf[MAX_LEX_LOOKAHEAD];
unsigned long getPtr;
/* context stack */
unsigned long lexModeStackTop;
enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE];
/* token buffer */
unsigned long maxToken;
char *strs;
unsigned long strsLen;
} lexBuf;
static void lexPushMode(enum LexMode mode)
{
if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1))
yyerror("lexical context stack overflow");
else {
lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
}
}
static void lexPopMode(int top)
{
/* special case of pop for ease of error recovery -- this
version will never underflow */
if (top)
lexBuf.lexModeStackTop = 0;
else
if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--;
}
static int lexWithinMode(enum LexMode mode) {
unsigned long i;
for (i=0;i<lexBuf.lexModeStackTop;i++)
if (mode == lexBuf.lexModeStack[i]) return 1;
return 0;
}
static char lexGetc_()
{
/* get next char from input, no buffering. */
if (lexBuf.curPos == lexBuf.inputLen)
return EOF;
else if (lexBuf.inputString)
return *(lexBuf.inputString + lexBuf.curPos++);
else {
#ifdef INCLUDEMFC
char result;
return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF;
#else
return fgetc(lexBuf.inputFile);
#endif
}
}
static int lexGeta()
{
++lexBuf.len;
return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
}
static int lexGeta_(int i)
{
++lexBuf.len;
return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_());
}
static void lexSkipLookahead() {
if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
/* don't skip EOF. */
lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
lexBuf.len--;
}
}
static int lexLookahead() {
int c = (lexBuf.len)?
lexBuf.buf[lexBuf.getPtr]:
lexGeta();
/* do the \r\n -> \n or \r -> \n translation here */
if (c == '\r') {
int a = (lexBuf.len>1)?
lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]:
lexGeta_(1);
if (a == '\n') {
lexSkipLookahead();
}
lexBuf.buf[lexBuf.getPtr] = c = '\n';
}
else if (c == '\n') {
int a = (lexBuf.len>1)?
lexBuf.buf[lexBuf.getPtr+1]:
lexGeta_(1);
if (a == '\r') {
lexSkipLookahead();
}
lexBuf.buf[lexBuf.getPtr] = '\n';
}
return c;
}
static int lexGetc() {
int c = lexLookahead();
if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
/* EOF will remain in lookahead buffer */
lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
lexBuf.len--;
}
return c;
}
static void lexSkipLookaheadWord() {
if (lexBuf.strsLen <= lexBuf.len) {
lexBuf.len -= lexBuf.strsLen;
lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD;
}
}
static void lexClearToken()
{
lexBuf.strsLen = 0;
}
static void lexAppendc(int c)
{
lexBuf.strs[lexBuf.strsLen] = c;
/* append up to zero termination */
if (c == 0) return;
lexBuf.strsLen++;
if (lexBuf.strsLen > lexBuf.maxToken) {
/* double the token string size */
lexBuf.maxToken <<= 1;
lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken);
}
}
static char* lexStr() {
return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1);
}
static void lexSkipWhite() {
int c = lexLookahead();
while (c == ' ' || c == '\t') {
lexSkipLookahead();
c = lexLookahead();
}
}
static char* lexGetWord() {
int c;
lexSkipWhite();
lexClearToken();
c = lexLookahead();
- while (c != EOF && !strchr("\t\n ;:=",c)) {
+ // LR while (c != EOF && !strchr("\t\n ;:=",c)) {
+ while (c != EOF && !strchr("\t\n;:=",c)) {
lexAppendc(c);
lexSkipLookahead();
c = lexLookahead();
}
lexAppendc(0);
return lexStr();
}
static void lexPushLookaheadc(int c) {
int putptr;
/* can't putback EOF, because it never leaves lookahead buffer */
if (c == EOF) return;
putptr = (int)lexBuf.getPtr - 1;
if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
lexBuf.getPtr = putptr;
lexBuf.buf[putptr] = c;
lexBuf.len += 1;
}
static char* lexLookaheadWord() {
/* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
/ and thing bigger than that will stop the lookahead and return 0;
/ leading white spaces are not recoverable.
*/
int c;
int len = 0;
int curgetptr = 0;
lexSkipWhite();
lexClearToken();
curgetptr = (int)lexBuf.getPtr; /* remember! */
while (len < (MAX_LEX_LOOKAHEAD_0)) {
c = lexGetc();
len++;
if (c == EOF || strchr("\t\n ;:=", c)) {
lexAppendc(0);
/* restore lookahead buf. */
lexBuf.len += len;
lexBuf.getPtr = curgetptr;
return lexStr();
}
else
lexAppendc(c);
}
lexBuf.len += len; /* char that has been moved to lookahead buffer */
lexBuf.getPtr = curgetptr;
return 0;
}
#ifdef _SUPPORT_LINE_FOLDING
static void handleMoreRFC822LineBreak(int c) {
/* suport RFC 822 line break in cases like
* ADR: foo;
* morefoo;
* more foo;
*/
if (c == ';') {
int a;
lexSkipLookahead();
/* skip white spaces */
a = lexLookahead();
while (a == ' ' || a == '\t') {
lexSkipLookahead();
a = lexLookahead();
}
if (a == '\n') {
lexSkipLookahead();
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 != ';') {
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();
}
#endif
static int match_begin_name(int end) {
char *n = lexLookaheadWord();
int token = ID;
if (n) {
if (!stricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
else if (!stricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
else if (!stricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
else if (!stricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
deleteStr(n);
return token;
}
return 0;
}
#ifdef INCLUDEMFC
void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
#else
void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
#endif
{
/* initialize lex mode stack */
lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
/* iniatialize lex buffer. */
lexBuf.inputString = (char*) inputstring;
lexBuf.inputLen = inputlen;
lexBuf.curPos = 0;
lexBuf.inputFile = inputfile;
lexBuf.len = 0;
lexBuf.getPtr = 0;
lexBuf.maxToken = MAXTOKEN;
lexBuf.strs = (char*)malloc(MAXTOKEN);
lexBuf.strsLen = 0;
}
static void finiLex() {
free(lexBuf.strs);
}
/* This parses and converts the base64 format for binary encoding into
* a decoded buffer (allocated with new). See RFC 1521.
*/
static char * lexGetDataFromBase64()
{
unsigned long bytesLen = 0, bytesMax = 0;
int quadIx = 0, pad = 0;
unsigned long trip = 0;
unsigned char b;
int c;
unsigned char *bytes = NULL;
unsigned char *oldBytes = NULL;
DBG_(("db: lexGetDataFromBase64\n"));
while (1) {
c = lexGetc();
if (c == '\n') {
++mime_lineNum;
if (lexLookahead() == '\n') {
/* a '\n' character by itself means end of data */
break;
}
else continue; /* ignore '\n' */
}
else {
if ((c >= 'A') && (c <= 'Z'))
b = (unsigned char)(c - 'A');
else if ((c >= 'a') && (c <= 'z'))
b = (unsigned char)(c - 'a') + 26;
else if ((c >= '0') && (c <= '9'))
b = (unsigned char)(c - '0') + 52;
else if (c == '+')
b = 62;
else if (c == '/')
b = 63;
else if (c == '=') {
b = 0;
pad++;
} else if ((c == ' ') || (c == '\t')) {
continue;
} else { /* error condition */
if (bytes) free(bytes);
else if (oldBytes) free(oldBytes);
/* error recovery: skip until 2 adjacent newlines. */
DBG_(("db: invalid character 0x%x '%c'\n", c,c));
if (c != EOF) {
c = lexGetc();
while (c != EOF) {
if (c == '\n' && lexLookahead() == '\n') {
++mime_lineNum;
break;
}
c = lexGetc();
}
}
return NULL;
}
trip = (trip << 6) | b;
if (++quadIx == 4) {
unsigned char outBytes[3];
int numOut;
int i;
for (i = 0; i < 3; i++) {
outBytes[2-i] = (unsigned char)(trip & 0xFF);
trip >>= 8;
}
numOut = 3 - pad;
if (bytesLen + numOut > bytesMax) {
if (!bytes) {
bytesMax = 1024;
bytes = (unsigned char*)malloc((size_t)bytesMax);
}
else {
bytesMax <<= 2;
oldBytes = bytes;
bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
}
if (bytes == 0) {
mime_error("out of memory while processing BASE64 data\n");
}
}
if (bytes) {
memcpy(bytes + bytesLen, outBytes, numOut);
bytesLen += numOut;
}
trip = 0;
quadIx = 0;
}
}
} /* while */
DBG_(("db: bytesLen = %d\n", bytesLen));
/* kludge: all this won't be necessary if we have tree form
representation */
if (bytes) {
setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
free(bytes);
}
else if (oldBytes) {
setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
free(oldBytes);
}
return 0;
}
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()
{
char cur;
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 (char)EOF:
break;
default:
lexAppendc(cur);
break;
} /* switch */
} while (cur != (char)EOF);
EndString:
lexAppendc(0);
return lexStr();
} /* LexQuotedPrintable */
int yylex() {
int lexmode = LEXMODE();
if (lexmode == L_VALUES) {
int c = lexGetc();
if (c == ';') {
DBG_(("db: SEMICOLON\n"));
lexPushLookaheadc(c);
#ifdef _SUPPORT_LINE_FOLDING
handleMoreRFC822LineBreak(c);
#endif
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();
yylval.str = p;
return STRING;
}
else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
p = lexGetQuotedPrintable();
}
else {
#ifdef _SUPPORT_LINE_FOLDING
p = lexGet1Value();