📄 vcc_yacc.cpp
字号:
unsigned long i;
for (i=0;i<lexBuf.lexModeStackTop;i++)
if (mode == lexBuf.lexModeStack[i]) return 1;
return 0;
}
static int 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)) {
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 != ';' || !fieldedProp)) {
if (c == '\\' ) {
int a;
lexSkipLookahead();
a = lexLookahead();
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();
}
#endif
static int match_begin_name(int end) {
char *n = lexLookaheadWord();
int token = ID;
if (n) {
if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
else if (!qstricmp(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 int 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();
lexSkipWhite();
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 { /* 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') {
lexSkipWhite();
if(lexLookahead() == '\n') {
++mime_lineNum;
break;
}
}
c = lexGetc();
}
}
return c != EOF;
}
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 bytesLen;
}
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 c;
lexSkipWhite();
c = lexLookahead();
lexClearToken();
while (c != EOF && (c != ';' || !fieldedProp)) {
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 c==EOF?0:lexStr();
}
static int yylex() {
int lexmode = LEXMODE();
if (lexmode == L_VALUES) {
int c = lexGetc();
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... */
yylval.str = NULL;
return lexGetDataFromBase64() ? STRING : 0;
}
else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
p = lexGetQuotedPrintable();
}
else {
#ifdef _SUPPORT_LINE_FOLDING
p = lexGet1Value();
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -