-rw-r--r-- | library/backend/vcc.y | 103 |
1 files changed, 56 insertions, 47 deletions
diff --git a/library/backend/vcc.y b/library/backend/vcc.y index e326a64..5bcf0cb 100644 --- a/library/backend/vcc.y +++ b/library/backend/vcc.y | |||
@@ -496,49 +496,49 @@ static void lexPushMode(enum LexMode mode) | |||
496 | if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) | 496 | if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) |
497 | yyerror("lexical context stack overflow"); | 497 | yyerror("lexical context stack overflow"); |
498 | else { | 498 | else { |
499 | lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; | 499 | lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; |
500 | } | 500 | } |
501 | } | 501 | } |
502 | 502 | ||
503 | static void lexPopMode(int top) | 503 | static void lexPopMode(int top) |
504 | { | 504 | { |
505 | /* special case of pop for ease of error recovery -- this | 505 | /* special case of pop for ease of error recovery -- this |
506 | version will never underflow */ | 506 | version will never underflow */ |
507 | if (top) | 507 | if (top) |
508 | lexBuf.lexModeStackTop = 0; | 508 | lexBuf.lexModeStackTop = 0; |
509 | else | 509 | else |
510 | if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; | 510 | if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; |
511 | } | 511 | } |
512 | 512 | ||
513 | static int lexWithinMode(enum LexMode mode) { | 513 | static int lexWithinMode(enum LexMode mode) { |
514 | unsigned long i; | 514 | unsigned long i; |
515 | for (i=0;i<lexBuf.lexModeStackTop;i++) | 515 | for (i=0;i<lexBuf.lexModeStackTop;i++) |
516 | if (mode == lexBuf.lexModeStack[i]) return 1; | 516 | if (mode == lexBuf.lexModeStack[i]) return 1; |
517 | return 0; | 517 | return 0; |
518 | } | 518 | } |
519 | 519 | ||
520 | static char lexGetc_() | 520 | static int lexGetc_() |
521 | { | 521 | { |
522 | /* get next char from input, no buffering. */ | 522 | /* get next char from input, no buffering. */ |
523 | if (lexBuf.curPos == lexBuf.inputLen) | 523 | if (lexBuf.curPos == lexBuf.inputLen) |
524 | return EOF; | 524 | return EOF; |
525 | else if (lexBuf.inputString) | 525 | else if (lexBuf.inputString) |
526 | return *(lexBuf.inputString + lexBuf.curPos++); | 526 | return *(lexBuf.inputString + lexBuf.curPos++); |
527 | else { | 527 | else { |
528 | #ifdef INCLUDEMFC | 528 | #ifdef INCLUDEMFC |
529 | char result; | 529 | char result; |
530 | return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF; | 530 | return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF; |
531 | #else | 531 | #else |
532 | return fgetc(lexBuf.inputFile); | 532 | return fgetc(lexBuf.inputFile); |
533 | #endif | 533 | #endif |
534 | } | 534 | } |
535 | } | 535 | } |
536 | 536 | ||
537 | static int lexGeta() | 537 | static int lexGeta() |
538 | { | 538 | { |
539 | ++lexBuf.len; | 539 | ++lexBuf.len; |
540 | return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); | 540 | return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); |
541 | } | 541 | } |
542 | 542 | ||
543 | static int lexGeta_(int i) | 543 | static int lexGeta_(int i) |
544 | { | 544 | { |
@@ -910,102 +910,111 @@ static char * lexGetDataFromBase64() | |||
910 | 910 | ||
911 | static int match_begin_end_name(int end) { | 911 | static int match_begin_end_name(int end) { |
912 | int token; | 912 | int token; |
913 | lexSkipWhite(); | 913 | lexSkipWhite(); |
914 | if (lexLookahead() != ':') return ID; | 914 | if (lexLookahead() != ':') return ID; |
915 | lexSkipLookahead(); | 915 | lexSkipLookahead(); |
916 | lexSkipWhite(); | 916 | lexSkipWhite(); |
917 | token = match_begin_name(end); | 917 | token = match_begin_name(end); |
918 | if (token == ID) { | 918 | if (token == ID) { |
919 | lexPushLookaheadc(':'); | 919 | lexPushLookaheadc(':'); |
920 | DBG_(("db: ID '%s'\n", yylval.str)); | 920 | DBG_(("db: ID '%s'\n", yylval.str)); |
921 | return ID; | 921 | return ID; |
922 | } | 922 | } |
923 | else if (token != 0) { | 923 | else if (token != 0) { |
924 | lexSkipLookaheadWord(); | 924 | lexSkipLookaheadWord(); |
925 | deleteStr(yylval.str); | 925 | deleteStr(yylval.str); |
926 | DBG_(("db: begin/end %d\n", token)); | 926 | DBG_(("db: begin/end %d\n", token)); |
927 | return token; | 927 | return token; |
928 | } | 928 | } |
929 | return 0; | 929 | return 0; |
930 | } | 930 | } |
931 | 931 | ||
932 | static char* lexGetQuotedPrintable() | 932 | static char* lexGetQuotedPrintable() |
933 | { | 933 | { |
934 | char cur; | 934 | int c; |
935 | 935 | lexSkipWhite(); | |
936 | c = lexLookahead(); | ||
936 | lexClearToken(); | 937 | lexClearToken(); |
937 | do { | 938 | |
938 | cur = lexGetc(); | 939 | while (c != EOF && c != ';') { |
939 | switch (cur) { | 940 | if (c == '\n') { |
940 | case '=': { | 941 | // break, leave '\n' on remaining chars. |
941 | int c = 0; | ||
942 | int next[2]; | ||
943 | int i; | ||
944 | for (i = 0; i < 2; i++) { | ||
945 | next[i] = lexGetc(); | ||
946 | if (next[i] >= '0' && next[i] <= '9') | ||
947 | c = c * 16 + next[i] - '0'; | ||
948 | else if (next[i] >= 'A' && next[i] <= 'F') | ||
949 | c = c * 16 + next[i] - 'A' + 10; | ||
950 | else | ||
951 | break; | 942 | break; |
943 | } else if (c == '=') { | ||
944 | int cur = 0; | ||
945 | int next; | ||
946 | |||
947 | lexSkipLookahead(); // skip '=' | ||
948 | next = lexLookahead(); | ||
949 | |||
950 | if (next == '\n') { | ||
951 | // skip and only skip the \n | ||
952 | lexSkipLookahead(); | ||
953 | c = lexLookahead(); | ||
954 | ++mime_lineNum; // aid in error reporting | ||
955 | continue; | ||
956 | } else if (next >= '0' && next <= '9') { | ||
957 | cur = next - '0'; | ||
958 | } else if (next >= 'A' && next <= 'F') { | ||
959 | cur = next - 'A' + 10; | ||
960 | } else { | ||
961 | // we have been sent buggy stuff. doesn't matter | ||
962 | // what we do so long as we keep going. | ||
963 | // should probably spit an error here | ||
964 | c = lexLookahead(); | ||
965 | continue; | ||
952 | } | 966 | } |
953 | if (i == 0) { | 967 | |
954 | /* single '=' follow by LINESEP is continuation sign? */ | 968 | lexSkipLookahead(); // skip A-Z0-9 |
955 | if (next[0] == '\n') { | 969 | next = lexLookahead(); |
956 | ++mime_lineNum; | 970 | |
957 | } | 971 | cur = cur * 16; |
958 | else { | 972 | // this time really just expecting 0-9A-F |
959 | lexPushLookaheadc('='); | 973 | if (next >= '0' && next <= '9') { |
960 | goto EndString; | 974 | cur += next - '0'; |
961 | } | 975 | } else if (next >= 'A' && next <= 'F') { |
976 | cur += next - 'A' + 10; | ||
977 | } else { | ||
978 | // we have been sent buggy stuff. doesn't matter | ||
979 | // what we do so long as we keep going. | ||
980 | // should probably spit an error here | ||
981 | c = lexLookahead(); | ||
982 | continue; | ||
962 | } | 983 | } |
963 | else if (i == 1) { | 984 | |
964 | lexPushLookaheadc(next[1]); | 985 | // got a valid escaped =. append it. |
965 | lexPushLookaheadc(next[0]); | 986 | lexSkipLookahead(); // skip second 0-9A-F |
966 | lexAppendc('='); | 987 | lexAppendc(cur); |
967 | } else { | 988 | } else { |
968 | lexAppendc(c); | 989 | lexSkipLookahead(); // skip whatever we just read. |
990 | lexAppendc(c); // and append it. | ||
969 | } | 991 | } |
970 | break; | 992 | c = lexLookahead(); |
971 | } /* '=' */ | ||
972 | case '\n': { | ||
973 | lexPushLookaheadc('\n'); | ||
974 | goto EndString; | ||
975 | } | 993 | } |
976 | case (char)EOF: | ||
977 | break; | ||
978 | default: | ||
979 | lexAppendc(cur); | ||
980 | break; | ||
981 | } /* switch */ | ||
982 | } while (cur != (char)EOF); | ||
983 | |||
984 | EndString: | ||
985 | lexAppendc(0); | 994 | lexAppendc(0); |
986 | return lexStr(); | 995 | return c==EOF?0:lexStr(); |
987 | } /* LexQuotedPrintable */ | 996 | } |
988 | 997 | ||
989 | static int yylex() { | 998 | static int yylex() { |
990 | 999 | ||
991 | int lexmode = LEXMODE(); | 1000 | int lexmode = LEXMODE(); |
992 | if (lexmode == L_VALUES) { | 1001 | if (lexmode == L_VALUES) { |
993 | int c = lexGetc(); | 1002 | int c = lexGetc(); |
994 | if (c == ';') { | 1003 | if (c == ';') { |
995 | DBG_(("db: SEMICOLON\n")); | 1004 | DBG_(("db: SEMICOLON\n")); |
996 | lexPushLookaheadc(c); | 1005 | lexPushLookaheadc(c); |
997 | handleMoreRFC822LineBreak(c); | 1006 | handleMoreRFC822LineBreak(c); |
998 | lexSkipLookahead(); | 1007 | lexSkipLookahead(); |
999 | return SEMICOLON; | 1008 | return SEMICOLON; |
1000 | } | 1009 | } |
1001 | else if (strchr("\n",c)) { | 1010 | else if (strchr("\n",c)) { |
1002 | ++mime_lineNum; | 1011 | ++mime_lineNum; |
1003 | /* consume all line separator(s) adjacent to each other */ | 1012 | /* consume all line separator(s) adjacent to each other */ |
1004 | c = lexLookahead(); | 1013 | c = lexLookahead(); |
1005 | while (strchr("\n",c)) { | 1014 | while (strchr("\n",c)) { |
1006 | lexSkipLookahead(); | 1015 | lexSkipLookahead(); |
1007 | c = lexLookahead(); | 1016 | c = lexLookahead(); |
1008 | ++mime_lineNum; | 1017 | ++mime_lineNum; |
1009 | } | 1018 | } |
1010 | DBG_(("db: LINESEP\n")); | 1019 | DBG_(("db: LINESEP\n")); |
1011 | return LINESEP; | 1020 | return LINESEP; |