%{ /*************************************************************************** (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. For purposes of this license notice, the term Licensors shall mean, collectively, Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. The term Licensor shall mean any of the Licensors. Subject to acceptance of the following conditions, permission is hereby granted by Licensors without the need for written agreement and without license or royalty fees, to use, copy, modify and distribute this software for any purpose. The above copyright notice and the following four paragraphs must be reproduced in all copies of this software and any software including this software. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS. IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The software is provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the government are subject to restrictions set forth in DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. ***************************************************************************/ /* * src: vcc.c * doc: Parser for vCard and vCalendar. Note that this code is * generated by a yacc parser generator. Generally it should not * be edited by hand. The real source is vcc.y. The #line directives * can be commented out here to make it easier to trace through * in a debugger. However, if a bug is found it should * be fixed in vcc.y and this file regenerated. */ /* debugging utilities */ #if __DEBUG #define DBG_(x) printf x #else #define DBG_(x) #endif /**** External Functions ****/ /* assign local name to parser variables and functions so that we can use more than one yacc based parser. */ #define yyparse mime_parse #define yylex mime_lex #define yyerror mime_error #define yychar mime_char /* #define p_yyval p_mime_val */ #undef yyval #define yyval mime_yyval /* #define p_yylval p_mime_lval */ #undef yylval #define yylval mime_yylval #define yydebug mime_debug #define yynerrs mime_nerrs #define yyerrflag mime_errflag #define yyss mime_ss #define yyssp mime_ssp #define yyvs mime_vs #define yyvsp mime_vsp #define yylhs mime_lhs #define yylen mime_len #define yydefred mime_defred #define yydgoto mime_dgoto #define yysindex mime_sindex #define yyrindex mime_rindex #define yygindex mime_gindex #define yytable mime_table #define yycheck mime_check #define yyname mime_name #define yyrule mime_rule #define YYPREFIX "mime_" #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 #endif #endif #include #ifndef __MWERKS__ #include #endif #include #include #include #include "vcc.h" static int yylex(void); static void yyerror(char *s); /**** Types, Constants ****/ #define YYDEBUG 1 /* 1 to compile in some debugging code */ #define MAXTOKEN 256 /* maximum token (line) length */ #define YYSTACKSIZE 50 /* ~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 extern void Parse_Debug(const char *s); extern void yyerror(char *s); #if __CPLUSPLUS__ }; #endif int yyparse(void); enum LexMode { L_NORMAL, L_VCARD, L_VCAL, L_VEVENT, L_VTODO, L_VALUES, L_BASE64, L_QUOTED_PRINTABLE }; /**** Private Forward Declarations ****/ static int pushVObject(const char *prop); static VObject* popVObject(void); #ifndef _SUPPORT_LINE_FOLDING static char* lexDataFromBase64(void); #endif static void lexPopMode(int top); static int lexWithinMode(enum LexMode mode); static void lexPushMode(enum LexMode mode); static void enterProps(const char *s); static void enterAttr(const char *s1, const char *s2); #if 0 static void enterValues(const char *value); #endif static void mime_error_(char *s); static void appendValue(const char *value); %} /***************************************************************************/ /*** The grammar ****/ /***************************************************************************/ %union { char *str; VObject *vobj; } %token EQ COLON DOT SEMICOLON SPACE HTAB LINESEP NEWLINE BEGIN_VCARD END_VCARD BEGIN_VCAL END_VCAL BEGIN_VEVENT END_VEVENT BEGIN_VTODO END_VTODO ID /* * NEWLINE is the token that would occur outside a vCard, * while LINESEP is the token that would occur inside a vCard. */ %token STRING ID %type name value %type vcard vcal vobject %start mime %% mime: vobjects ; vobjects: vobject { addList(&vObjList, $1); curObj = 0; } vobjects | vobject { addList(&vObjList, $1); curObj = 0; } ; vobject: vcard | vcal ; vcard: BEGIN_VCARD { lexPushMode(L_VCARD); if (!pushVObject(VCCardProp)) YYERROR; } items END_VCARD { lexPopMode(0); $$ = popVObject(); } | BEGIN_VCARD { lexPushMode(L_VCARD); if (!pushVObject(VCCardProp)) YYERROR; } END_VCARD { lexPopMode(0); $$ = popVObject(); } ; items: item items | item ; item: prop COLON { lexPushMode(L_VALUES); } values LINESEP { if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) lexPopMode(0); lexPopMode(0); } | error ; prop: name { enterProps($1); } attr_params | name { enterProps($1); } ; attr_params: attr_param attr_params | attr_param ; attr_param: SEMICOLON attr ; attr: name { enterAttr($1,0); } | name EQ name { enterAttr($1,$3); } ; name: ID ; values: value SEMICOLON { appendValue($1); } values | value { appendValue($1); } ; value: STRING | { $$ = 0; } ; vcal: BEGIN_VCAL { if (!pushVObject(VCCalProp)) YYERROR; } calitems END_VCAL { $$ = popVObject(); } | BEGIN_VCAL { if (!pushVObject(VCCalProp)) YYERROR; } END_VCAL { $$ = popVObject(); } ; calitems: calitem calitems | calitem ; calitem: eventitem | todoitem | items ; eventitem: BEGIN_VEVENT { lexPushMode(L_VEVENT); if (!pushVObject(VCEventProp)) YYERROR; } items END_VEVENT { lexPopMode(0); popVObject(); } | BEGIN_VEVENT { lexPushMode(L_VEVENT); if (!pushVObject(VCEventProp)) YYERROR; } END_VEVENT { lexPopMode(0); popVObject(); } ; todoitem: BEGIN_VTODO { lexPushMode(L_VTODO); if (!pushVObject(VCTodoProp)) YYERROR; } items END_VTODO { lexPopMode(0); popVObject(); } | BEGIN_VTODO { lexPushMode(L_VTODO); if (!pushVObject(VCTodoProp)) YYERROR; } END_VTODO { lexPopMode(0); popVObject(); } ; %% /* ///////////////////////////////////////////////////////////////////////// */ 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 appendValue(const char *value) { char *p1, *p2; wchar_t *p3; int i; if (fieldedProp && *fieldedProp) { if (value) { addPropValue(curProp, *fieldedProp, value); } /* else this field is empty, advance to next field */ fieldedProp++; } else { if (value) { if (vObjectUStringZValue(curProp)) { p1 = fakeCString(vObjectUStringZValue(curProp)); p2 = malloc(sizeof(char *) * (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); } #if 0 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) { setVObjectUStringZValue_(curProp,fakeUnicode(value,0)); } } deleteStr(value); } #endif 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 = NULL; 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 int instead of char so that EOF / can be represented correctly. */ unsigned long len; int 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;iRead(&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)) { lexAppendc(c); lexSkipLookahead(); c = lexLookahead(); } lexAppendc(0); return lexStr(); } #if 0 static void lexPushLookahead(char *s, int len) { int putptr; if (len == 0) len = strlen(s); putptr = (int)lexBuf.getPtr - len; /* this function assumes that length of word to push back / is not greater than MAX_LEX_LOOKAHEAD. */ if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; lexBuf.getPtr = putptr; while (*s) { lexBuf.buf[putptr] = *s++; putptr = (putptr + 1) % MAX_LEX_LOOKAHEAD; } lexBuf.len += len; } #endif 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 #ifndef _SUPPORT_LINE_FOLDING static char* lexGetStrUntil(char *termset) { int c = lexLookahead(); lexClearToken(); while (c != EOF && !strchr(termset,c)) { lexAppendc(c); lexSkipLookahead(); c = lexLookahead(); } lexAppendc(0); 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 static void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) #else static 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() { int 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': case ';': { lexPushLookaheadc(cur); goto EndString; } case EOF: break; default: lexAppendc(cur); break; } /* switch */ } while (cur != EOF); EndString: lexAppendc(0); return lexStr(); } /* LexQuotedPrintable */ static 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(); #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. */ /* 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 (isalpha(c)) { char *t = lexGetWord(); yylval.str = t; if (!stricmp(t, "begin")) { return match_begin_end_name(0); } else if (!stricmp(t,"end")) { return match_begin_end_name(1); } else { DBG_(("db: ID '%s'\n", t)); return ID; } } else { /* unknow token */ return 0; } break; } } } } return 0; } /***************************************************************************/ /*** Public Functions ****/ /***************************************************************************/ static VObject* Parse_MIMEHelper() { ObjStackTop = -1; mime_numErrors = 0; mime_lineNum = 1; vObjList = 0; curObj = 0; if (yyparse() != 0) { finiLex(); return 0; } finiLex(); return vObjList; } /* ///////////////////////////////////////////////////////////////////////// */ DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) { initLex(input, len, 0); return Parse_MIMEHelper(); } #if INCLUDEMFC DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) { unsigned long startPos; VObject *result; initLex(0,-1,file); startPos = file->GetPosition(); if (!(result = Parse_MIMEHelper())) file->Seek(startPos, CFile::begin); return result; } #else VObject* Parse_MIME_FromFile(FILE *file) { VObject *result; long startPos; initLex(0,(unsigned long)-1,file); startPos = ftell(file); if (!(result = Parse_MIMEHelper())) { fseek(file,startPos,SEEK_SET); } return result; } DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname) { FILE *fp = fopen(fname,"r"); if (fp) { VObject* o = Parse_MIME_FromFile(fp); fclose(fp); return o; } else { char msg[256]; snprintf(msg, sizeof(msg), "can't open file '%s' for reading\n", fname); mime_error_(msg); return 0; } } #endif /* ///////////////////////////////////////////////////////////////////////// */ static MimeErrorHandler mimeErrorHandler; DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me) { mimeErrorHandler = me; } static void mime_error(char *s) { char msg[256]; if (mimeErrorHandler) { sprintf(msg,"%s at line %d", s, mime_lineNum); mimeErrorHandler(msg); } } static void mime_error_(char *s) { if (mimeErrorHandler) { mimeErrorHandler(s); } } -1/+2 * SIZEify (maintainer timeout)Trevor Johnson2004-03-313-0/+3 * Clean up USE_{LIBTOOL,AUTOCONF,AUTOMAKE} to appropriate *_VER variablesAde Lovett2004-03-251-1/+1 * SIZE-ify my ports.Thierry Thomas2004-03-191-0/+1 * - add new WWWClement Laforet2004-03-151-0/+2 * Move textproc/dico to french/dico.Christian Weisgerber2004-03-142-1/+2 * Whoa there, boy, that's a mighty big commit y'all have there...Ade Lovett2004-03-141-1/+1 * Update to 0.70.6.Christian Weisgerber2004-03-137-222/+192 * Lots of clean-up:Christian Weisgerber2004-03-133-17/+256 * - Remove unneeded dependencyKirill Ponomarev2004-03-121-4/+0 * Update to KDE 3.2.1 / QT 3.3.1Michael Nottebrock2004-03-109-4/+79 * french/xtel: fixing WWW.Edwin Groothuis2004-03-073-9/+10 * - Fix typoPav Lucistnik2004-03-031-1/+1 * Chase repomove graphics/hdf* -> science/hdf*Pav Lucistnik2004-02-262-2/+2 * - Drop maintainershipClement Laforet2004-02-083-9/+7 * Added size; cleaned pkg-descr.Mark Linimon2004-02-075-15/+17 * Update to KDE 3.2.0Michael Nottebrock2004-02-0515-172/+813 * Bump PORTREVISION on all ports that depend on gettext to aid with upgrading.Joe Marcus Clarke2004-02-047-0/+7 * Bump PORTREVISION on all ports that depend on gettext to aid with upgrading.Joe Marcus Clarke2004-02-041-1/+1 * Add USE_GETTEXT and bump PORTREVISION.Joe Marcus Clarke2004-02-045-10/+10 * - Fix dependency checking for efitasPav Lucistnik2004-01-311-1/+1 * SIZEify.Trevor Johnson2004-01-295-0/+5 * Add size data.Trevor Johnson2004-01-281-0/+13 * Now gettext 0.12.1 is gettext-old.Trevor Johnson2004-01-245-5/+5 * - Fix build on BentoPav Lucistnik2004-01-231-1/+0 * - Update my email addressClement Laforet2004-01-131-1/+1 * remove commented-out variables accidently commited in.Edwin Groothuis2003-12-291-1/+1 * french/fr-geonext: Interactive (dynamic) elementary Geometry SoftwareEdwin Groothuis2003-12-295-0/+86 * french/facturier: fixing ${APACHE_PORT} usage.Edwin Groothuis2003-12-291-4/+4 * Spell NOPORTDOCS correctly in Cyrille Lefevre's ports.Peter Pentchev2003-12-121-1/+1 * - www.code-aster.org was reorganized. fix fetchingPav Lucistnik2003-12-1110-35/+26 * . Catch up with the move of metis-edf.Greg Lewis2003-12-101-1/+1 * - Upgrading french/aster from 7.1 to 7.2;Oliver Lehmann2003-12-0814-287/+517 * Add gibi 2000Oliver Lehmann2003-12-087-0/+2329 * Define USE_PERL5_BUILD, not erroneous USE_PERL.Trevor Johnson2003-11-201-1/+1 * Define USE_PERL to make Perl available for (mostly deprecated)Trevor Johnson2003-11-201-0/+1 * OpenOffice -> OpenOffice.orgMaho Nakata2003-11-093-3/+3 * Add OpenOffice.org 1.1 for frenchMaho Nakata2003-11-092-0/+17 * Forgot to change Makefile s..Maho Nakata2003-11-081-1/+1 * rename openoffice* to openoffice-1.0* accodingly (repo copy).Maho Nakata2003-11-081-1/+1 * As announced on Aug 7, remove the broken spip portKris Kennaway2003-11-086-397/+0 * rename openoffice to openoffice-1.0 after repocopyMaho Nakata2003-11-082-18/+2 * Ignore this port as it does not work with AbiWord-2.0.Joe Marcus Clarke2003-11-071-0/+2 * - upgrade french/facturier to its latest release;James E. Housley2003-11-069-277/+352 * Remove AbiWord-1.x now that 2.0 has been released, and is the new stableJoe Marcus Clarke2003-11-011-1/+1 * Per distfile survey, chase distribution filenames. The filenameMark Linimon2003-10-281-1/+1 * utilize SITE_PERLYing-Chieh Liao2003-10-242-2/+2 * BROKEN: Broken dependencyKris Kennaway2003-10-131-0/+2 * Maintainer update: textproc/dico (1.1)Edwin Groothuis2003-10-103-38/+37 * pkg-descr contains the descr of Acrobat Reader, fix it.Erwin Lansing2003-10-071-4/+0 * fix a typoOliver Lehmann2003-09-281-1/+1 * 1) asteru.exe is linked against libtcl and libtk, but only aOliver Lehmann2003-09-281-9/+12 * ECHO -> ECHO_MSGEdwin Groothuis2003-09-272-4/+4 * Translation update: fix checksum.Will Andrews2003-09-222-2/+2 * Upgrade to Qt 3.2.1 / KDE 3.1.4. See x11/kde3/Makefile rev 1.64 for details.Will Andrews2003-09-182-4/+2 * Conditionalise dependencies on databases/p5-DBI: for perlErwin Lansing2003-09-161-1/+0 * Maintainer update: add a faster mirror for distfiles/patches.Sergey A. Osokin2003-09-091-1/+2 * french/aster: tarball has been rerolled.Edwin Groothuis2003-09-081-1/+1 * Fix build on 4-STABLEOliver Lehmann2003-08-182-6/+7 * unbreak fetch and build of portEdwin Groothuis2003-08-172-4/+2 * - replace blas by atlas by default and add a knob to keep blasOliver Lehmann2003-08-123-18/+54 * - chase the upgrade from py22 to py23.Oliver Lehmann2003-08-101-0/+1 * - a typo has been introduced with portrevision 1, and the script homard wasOliver Lehmann2003-08-101-4/+4 * move BROKEN and the bsd.port.pre.mk include some lines downOliver Lehmann2003-07-311-7/+6 * fix typo introduced in the last commitOliver Lehmann2003-07-311-3/+3 * mark it as broken for systems < 5 until the build is fixed for 4Oliver Lehmann2003-07-311-0/+5 * Update KDE to the latest official release, KDE 3.1.3Michael Nottebrock2003-07-294-2/+6 * fix french/aster: fixing BUILD_DEPENDSDaichi GOTO2003-07-281-4/+9 * Add aster 7.1, analyse des structures et thermo-mécanique.Oliver Lehmann2003-07-2611-0/+3559 * 1) fix "make -V PORTNAME"Oliver Lehmann2003-07-241-9/+12 * Add homard 5.5, a refinement and de-refinement mesh tool.Oliver Lehmann2003-07-246-0/+136 * Add med 2.1.5, modélisation et Échanges de Données.Oliver Lehmann2003-07-2310-0/+181 * Add eficas 1.4, aSter Command FIle Editor.Oliver Lehmann2003-07-236-0/+992 * Fix distinfo for generated files: I mistakenly left "linux-" inTrevor Johnson2003-07-061-1/+1 * Security fix: update to the latest versions: 7.1 for AmericanTrevor Johnson2003-07-038-520/+31 * Update to 0.61.7: security fix.Christian Weisgerber2003-06-124-28/+17 * Update to KDE 3.1.2Mario Sergio Fujikawa Ferreira2003-05-206-12/+76 * Bring back from Attic: localized messages and documentation for kofficeMario Sergio Fujikawa Ferreira2003-05-2013-0/+964 * BROKEN: Does not fetchKris Kennaway2003-05-061-0/+2 * Remove USE_GNOMENG.Joe Marcus Clarke2003-04-201-1/+0 * Add hyphenation dictionaries to the slave ports.Martin Blapp2003-04-091-0/+1 * Rejoice, for the long awaited upgrade to kde 3.1.1 is here!Alan Eldridge2003-04-064-10/+48 * removed commented out line.Edwin Groothuis2003-03-301-1/+1 * french/facturier, an invoicing application for small enterprises.Edwin Groothuis2003-03-3013-0/+616 * gfaim website no longer exists, hosting distfile @ homeYen-Ming Lee2003-03-242-3/+1 * Clear moonlight beckons.Ade Lovett2003-03-0710-5/+5 * Remove pkg-comment from remaining master/slave port sets.Ade Lovett2003-03-072-1/+1 * Retire comment file.Trevor Johnson2003-03-011-1/+0 * De-pkg-comment.Akinori MUSHA2003-02-212-1/+1 * De-pkg-comment.Akinori MUSHA2003-02-2110-5/+5 * De-pkg-comment.Akinori MUSHA2003-02-212-1/+1 * Remove redundant category 'editors' in slave ports.Martin Blapp2003-02-132-2/+2 * Version bump and master sites fix.Christian Weisgerber2003-02-042-4/+3 * Upgrade kde-i18n to 3.1. Note that the following modules did not get aWill Andrews2003-01-294-302/+1394 * mastersite -> MASTER_SITE_SOURCEFORGEEdwin Groothuis2003-01-201-2/+3 * maintainer update: fix path to databaseEdwin Groothuis2003-01-181-0/+3 * New port misc/gfaimEdwin Groothuis2003-01-177-0/+68 * New port: AbiWord french dictionaryEdwin Groothuis2003-01-176-0/+34 * New Port : /usr/ports/french/SPIP-1.4Edwin Groothuis2003-01-047-0/+395 * New Port : french/dacodeEdwin Groothuis2003-01-037-0/+743 * New port: JDictionary plugin: French-Hungarian dictionary version 1.0Edwin Groothuis2003-01-036-0/+41 * "french" should be the primary category.Akinori MUSHA2002-12-091-1/+1 * Sort entries.Akinori MUSHA2002-11-281-1/+1 * Removed in preparation for update to cups 1.1.16.Alan Eldridge2002-11-244-59/+0 * Fix pkg-deinstall handling.Christian Weisgerber2002-11-142-37/+2 * Import plgrenouille 0.61.5.Christian Weisgerber2002-11-1411-0/+443 * o Rollback PORTCOMMENT modifications while this feature's implementationMario Sergio Fujikawa Ferreira2002-11-112-2/+1 * Use PORTCOMMENT in the Makefile, and whack the pkg-comment.Adam Weinberger2002-11-072-1/+2 * Remove the StUdLyCaPs from maintainer name, 'cause some folks won't realizeAlan Eldridge2002-11-013-3/+3 * Changed MAINTAINER to my FreeBSD address.Alan Eldridge2002-11-013-3/+3 * * make fetchable againOliver Braun2002-11-018-51/+48 * Fix categories to match dir containing port. bsd.port.mk (and portlint)Alan Eldridge2002-10-302-2/+4 * The release notes say:Trevor Johnson2002-10-151-0/+3 * I remove the linux-netscape6 ports from ports/french, ports/german,Trevor Johnson2002-10-1415-671/+58 * 1. Removed comments from pkg-plist files per will's request.Alan Eldridge2002-10-114-2/+4 * texas chainsaw kde2 massacreAlan Eldridge2002-09-111-2/+0 * texas chainsaw kde2 massacreAlan Eldridge2002-09-104-68/+0 * move patch into correct dir,Dirk Meyer2002-09-101-0/+0 * fixing 5.0 package build with gcc32Dirk Meyer2002-09-101-0/+12 * build aspell with dictionaryDirk Meyer2002-09-104-0/+24 * Update to 3.0.3. Not much changed here: [1] i18n PKGNAMEs converted toWill Andrews2002-08-256-8/+6 * Forgot to take maintainership of these buggers, too.Alan Eldridge2002-08-213-3/+3 * 1) Add localized help files to the build. Only available for french,Martin Blapp2002-08-192-0/+2 * Add OpenOffice.org spelling dictionary ports. They are based on MySpell,Martin Blapp2002-08-121-0/+1 * Add OpenOffice.org spelling dictionary ports. They are based on MySpell,Martin Blapp2002-08-124-2/+19 * Use MASTERDIRMartin Blapp2002-08-032-2/+2 * 1. Changed the lib depends on gettext to a build depends. This will meanAlan Eldridge2002-08-032-4/+4 * Bump PORTREVISION. KDE is fragile enough in its dependencies; we don'tAlan Eldridge2002-08-022-0/+2 * Chase shlib rev of devel/gettextAde Lovett2002-08-022-2/+2 * Add support for spelling dictionaries. Remove the pkg-plist for theMartin Blapp2002-07-162-0/+2 * Fix MASTER_SITE_SUBDIR.Will Andrews2002-07-102-2/+2 * PERL -> REINPLACE_CMDYing-Chieh Liao2002-07-082-3/+14 * Update to 3.0.2 -- full log available in ports/x11/kde3/Makefile,v 1.51.Will Andrews2002-07-056-172/+54 * Removed suffix which I put there without understanding the implications.Alan Eldridge2002-07-032-2/+0 * New port: Makefile for cups metaport with french manpages. Redone toAlan Eldridge2002-07-031-0/+20 * will be replacedAlan Eldridge2002-07-021-21/+0 * New port: cups lpr binaries with french manpages.Alan Eldridge2002-07-022-0/+21 * New port: cups-base with french manpages. Makefile redone to quiet portlint.Alan Eldridge2002-07-022-0/+19 * New port: cups with french manpages. v. 1.1.15.1Alan Eldridge2002-07-022-0/+22 * Upgrade to KDE 3.0.1. The delay in this upgrade is mainly due to theWill Andrews2002-06-166-342/+290 * Add French OpenOffice slave portMartin Blapp2002-06-153-0/+31 * Remove some unused code.Trevor Johnson2002-05-232-14/+2 * Update to 6.2.3. Belatedly, I confirmed that 6.2.2 supportsTrevor Johnson2002-05-174-26/+28 * Add home page.Trevor Johnson2002-05-172-0/+4 * Please welcome Qt3/KDE3 to our ports tree. This includes work since theWill Andrews2002-04-2211-18/+2833 * Update Japanese, German, and French Netscape ports to version 6.2.2Trevor Johnson2002-04-144-30/+28 * Update English Netscape to 6.2.2, with unknown changes. The French,Trevor Johnson2002-03-282-0/+4 * Cleanups to fix FORBIDDEN and other miscellaneous stuff.Ade Lovett2002-03-138-8/+105 * Make grammatical corrections and translate some forgotten parts ofTrevor Johnson2002-03-056-44/+42 * Correct the comment block: I forgot to change it when I copiedTrevor Johnson2002-03-042-6/+6 * Add new port of Netscape 6 (Linux binary) with French localization.Trevor Johnson2002-03-0419-0/+1229 * Use ${ECHO_CMD} instead of ${ECHO} where you mean the echo command;Akinori MUSHA2002-01-291-1/+1 * Mark FORBIDDEN; this port can easily be induced to dump core in setuidKris Kennaway2002-01-261-0/+2 * Fix translation. In a later step the ports will be unifiedMartin Blapp2002-01-221-2/+2 * Update maintainer addressMario Sergio Fujikawa Ferreira2002-01-211-1/+1 * Add new ports: french/koffice-i18n, german/koffice-i18n and japanese/koffice-...SADA Kenji2002-01-214-0/+52 * A small adjustment for .include<bsd.port.pre.mk>.Yoshio MITA2002-01-201-2/+2 * Build failure problem is solved (.include <bsd.port.pre.mk> had toYoshio MITA2002-01-201-2/+2 * unbreak: USE_IMAKE should be prior to pre.mk.FUJISHIMA Satsuki2002-01-191-6/+7 * Update maintainer's email addressDavid W. Chapman Jr.2002-01-181-1/+1 * include pre.mk for XFREE86_VERSION usage.FUJISHIMA Satsuki2002-01-071-2/+2 * Add x11/XFree86-4-clients for mkfontdir if XFREE86_VERSION=4.Will Andrews2002-01-071-0/+5 * copy a default temporary host.def if you do not have oneYing-Chieh Liao2002-01-012-0/+20 * Hardcode another /cdrom, since the define is not overwritten by theMartin Blapp2001-12-281-3/+1 * Re-support LANG for pkg-message.Will Andrews2001-12-271-0/+2 * Add xtel 3.3.0, an emulator for the french Minitel.Will Andrews2001-12-2612-0/+297 * Hardcode the /cdrom path, until bsd.port.mk is fixed. I don't knowMartin Blapp2001-12-251-0/+1 * Remove (incorrect) re-definition of ACLOCAL so this port builds again.Steve Price2001-12-251-1/+0 * Maintainer is now a committerMartin Blapp2001-12-241-1/+1 * Bump PORTREVISION due to recent update of sunsolve patch.Dmitry Sivachenko2001-12-201-0/+1 * Update for new sunsolve patch.Dmitry Sivachenko2001-12-183-5/+48 * Use AUTOMAKE_ARGS instead of setting AUTOMAKE to "automake <args>"Pete Fritchman2001-10-301-1/+1 * Fix the CDROM install of StarOffice.Chris D. Faulhaber2001-10-031-8/+16 * honor PREFIX: USE_GMAKE and MAKE_ARGSMario Sergio Fujikawa Ferreira2001-09-131-0/+2 * Use full path to mount and utilites, because /sbin might not be in PATH.Alexander Langer2001-09-061-17/+17 * - Add check for installed and running linprocfsAlexander Langer2001-09-051-3/+37 * Update MAINTAINER email: clefevre@redirect.to -> clefevre@citeweb.netMario Sergio Fujikawa Ferreira2001-08-301-1/+1 * Change maintainer's email address:Peter Pentchev2001-06-161-1/+1 * Spelling corrections.Greg Lehey2001-05-214-16/+16 * Add fr-php_doc - a french version of lang/php_doc.Dirk Froemberg2001-04-292-0/+13 * KDE2 messages and documentation translated into french language.Dmitry Sivachenko2001-04-134-0/+52 * Add dico 1.1, an interactive dictionary in french.Will Andrews2001-03-1112-0/+263 * The path needs to be dinked with for the install-user target as well.John Baldwin2001-03-021-1/+2 * Ensure that /bin is at the head of the path when running the setup programJohn Baldwin2001-03-021-1/+1 * Makefile style fix.Jimmy Olgeni2001-02-061-3/+3 * Add SunSolve Patch 109939-02.Alexander Langer2000-12-242-3/+22 * Fix default $PATH settings for user-installation.Alexander Langer2000-12-241-0/+4 * Update MASTER_SITESChris D. Faulhaber2000-12-121-2/+1 * Apply the CDROM install fix from editors/staroffice52/Makefile rev 1.22.David E. O'Brien2000-10-151-3/+4 * Change PKGDIR from pkg/ to . Also fix places where ${PKGDIR} isSatoshi Asami2000-10-081-1/+1 * - Fix ${LINUXBASE} for /compat/linuxChris D. Faulhaber2000-09-231-8/+7 * Add category "french" and "german" as appropriate.Satoshi Asami2000-09-222-1/+2 * Finish moving this port from textproc/fr-ispell to french/ispell.Satoshi Asami2000-09-221-2/+1 * French version of staroffice (version 5.2).Satoshi Asami2000-09-2210-0/+3219 * Remove staroffice52, so addport can add it back.Satoshi Asami2000-09-221-1/+0 * New category french starts today!Satoshi Asami2000-09-223-0/+12 * Change MAINTAINER: alex@big.endian.de --> alex@FreeBSD.orgAlexander Langer2000-06-101-1/+1 * Update with the new PORTNAME/PORTVERSION variablesChris Piazza2000-04-101-2/+2