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
@@ -1509,513 +1509,514 @@ static int pushVObject(const char *prop)
}
/* 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);