Properly handle string and char constants when preprocessing: don't unescape and keep surrounding quotes

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-02 18:48:32 +01:00
parent b219d4b468
commit b5970707c0
2 changed files with 26 additions and 17 deletions

38
lexer.c
View file

@ -381,10 +381,10 @@ static int lex_skipwhite(lex_file *lex)
if (ch == '/') if (ch == '/')
{ {
/* one line comment */ /* one line comment */
haswhite = true;
ch = lex_getch(lex); ch = lex_getch(lex);
if (lex->flags.preprocessing) { if (lex->flags.preprocessing) {
haswhite = true;
if (!lex_tokench(lex, '/') || if (!lex_tokench(lex, '/') ||
!lex_tokench(lex, '/')) !lex_tokench(lex, '/'))
{ {
@ -408,8 +408,8 @@ static int lex_skipwhite(lex_file *lex)
if (ch == '*') if (ch == '*')
{ {
/* multiline comment */ /* multiline comment */
haswhite = true;
if (lex->flags.preprocessing) { if (lex->flags.preprocessing) {
haswhite = true;
if (!lex_tokench(lex, '/') || if (!lex_tokench(lex, '/') ||
!lex_tokench(lex, '*')) !lex_tokench(lex, '*'))
{ {
@ -550,7 +550,7 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote)
if (ch == quote) if (ch == quote)
return TOKEN_STRINGCONST; return TOKEN_STRINGCONST;
if (ch == '\\') { if (!lex->flags.preprocessing && ch == '\\') {
ch = lex_getch(lex); ch = lex_getch(lex);
if (ch == EOF) { if (ch == EOF) {
lexerror(lex, "unexpected end of file"); lexerror(lex, "unexpected end of file");
@ -1066,8 +1066,12 @@ int lex_do(lex_file *lex)
if (ch == '"') if (ch == '"')
{ {
lex->flags.nodigraphs = true; lex->flags.nodigraphs = true;
if (lex->flags.preprocessing && !lex_tokench(lex, ch))
return TOKEN_FATAL;
lex->tok.ttype = lex_finish_string(lex, '"'); lex->tok.ttype = lex_finish_string(lex, '"');
while (lex->tok.ttype == TOKEN_STRINGCONST) if (lex->flags.preprocessing && !lex_tokench(lex, ch))
return TOKEN_FATAL;
while (!lex->flags.preprocessing && lex->tok.ttype == TOKEN_STRINGCONST)
{ {
/* Allow c style "string" "continuation" */ /* Allow c style "string" "continuation" */
ch = lex_skipwhite(lex); ch = lex_skipwhite(lex);
@ -1091,23 +1095,27 @@ int lex_do(lex_file *lex)
* Likewise actual unescaping has to be done by the parser. * Likewise actual unescaping has to be done by the parser.
* The difference is we don't allow 'char' 'continuation'. * The difference is we don't allow 'char' 'continuation'.
*/ */
lex->tok.ttype = lex_finish_string(lex, '\''); if (lex->flags.preprocessing && !lex_tokench(lex, ch))
if (!lex_endtoken(lex)) return TOKEN_FATAL;
return (lex->tok.ttype = TOKEN_FATAL); lex->tok.ttype = lex_finish_string(lex, '\'');
if (lex->flags.preprocessing && !lex_tokench(lex, ch))
return TOKEN_FATAL;
if (!lex_endtoken(lex))
return (lex->tok.ttype = TOKEN_FATAL);
/* It's a vector if we can successfully scan 3 floats */ /* It's a vector if we can successfully scan 3 floats */
#ifdef WIN32 #ifdef WIN32
if (sscanf_s(lex->tok.value, " %f %f %f ", if (sscanf_s(lex->tok.value, " %f %f %f ",
&lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3) &lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3)
#else #else
if (sscanf(lex->tok.value, " %f %f %f ", if (sscanf(lex->tok.value, " %f %f %f ",
&lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3) &lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3)
#endif #endif
{ {
lex->tok.ttype = TOKEN_VECTORCONST; lex->tok.ttype = TOKEN_VECTORCONST;
} }
return lex->tok.ttype; return lex->tok.ttype;
} }
if (isdigit(ch)) if (isdigit(ch))

View file

@ -9,7 +9,7 @@ bool preprocess(const char *filename)
do { do {
tok = lex_do(lex); tok = lex_do(lex);
/* #if 0
if (tok == TOKEN_EOL) if (tok == TOKEN_EOL)
printf("EOL"); printf("EOL");
else if (tok >= TOKEN_START && tok <= TOKEN_FATAL) else if (tok >= TOKEN_START && tok <= TOKEN_FATAL)
@ -20,13 +20,14 @@ bool preprocess(const char *filename)
printf(">>%s<<\n", lex->tok.value); printf(">>%s<<\n", lex->tok.value);
else else
printf("\n"); printf("\n");
*/ #else
if (tok == TOKEN_EOL) if (tok == TOKEN_EOL)
printf("\n"); printf("\n");
else if (tok >= TOKEN_START && tok < TOKEN_EOF) else if (tok >= TOKEN_START && tok < TOKEN_EOF)
printf("%s", lex->tok.value); printf("%s", lex->tok.value);
else else
printf("%c", tok); printf("%c", tok);
#endif
} while (tok < TOKEN_EOF); } while (tok < TOKEN_EOF);
lex_close(lex); lex_close(lex);