mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-27 14:12:36 +00:00
Properly handle string and char constants when preprocessing: don't unescape and keep surrounding quotes
This commit is contained in:
parent
b219d4b468
commit
b5970707c0
2 changed files with 26 additions and 17 deletions
38
lexer.c
38
lexer.c
|
@ -381,10 +381,10 @@ static int lex_skipwhite(lex_file *lex)
|
|||
if (ch == '/')
|
||||
{
|
||||
/* one line comment */
|
||||
haswhite = true;
|
||||
ch = lex_getch(lex);
|
||||
|
||||
if (lex->flags.preprocessing) {
|
||||
haswhite = true;
|
||||
if (!lex_tokench(lex, '/') ||
|
||||
!lex_tokench(lex, '/'))
|
||||
{
|
||||
|
@ -408,8 +408,8 @@ static int lex_skipwhite(lex_file *lex)
|
|||
if (ch == '*')
|
||||
{
|
||||
/* multiline comment */
|
||||
haswhite = true;
|
||||
if (lex->flags.preprocessing) {
|
||||
haswhite = true;
|
||||
if (!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)
|
||||
return TOKEN_STRINGCONST;
|
||||
|
||||
if (ch == '\\') {
|
||||
if (!lex->flags.preprocessing && ch == '\\') {
|
||||
ch = lex_getch(lex);
|
||||
if (ch == EOF) {
|
||||
lexerror(lex, "unexpected end of file");
|
||||
|
@ -1066,8 +1066,12 @@ int lex_do(lex_file *lex)
|
|||
if (ch == '"')
|
||||
{
|
||||
lex->flags.nodigraphs = true;
|
||||
if (lex->flags.preprocessing && !lex_tokench(lex, ch))
|
||||
return TOKEN_FATAL;
|
||||
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" */
|
||||
ch = lex_skipwhite(lex);
|
||||
|
@ -1091,23 +1095,27 @@ int lex_do(lex_file *lex)
|
|||
* Likewise actual unescaping has to be done by the parser.
|
||||
* The difference is we don't allow 'char' 'continuation'.
|
||||
*/
|
||||
lex->tok.ttype = lex_finish_string(lex, '\'');
|
||||
if (!lex_endtoken(lex))
|
||||
return (lex->tok.ttype = TOKEN_FATAL);
|
||||
if (lex->flags.preprocessing && !lex_tokench(lex, ch))
|
||||
return 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 */
|
||||
#ifdef WIN32
|
||||
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)
|
||||
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)
|
||||
#else
|
||||
if (sscanf(lex->tok.value, " %f %f %f ",
|
||||
&lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3)
|
||||
if (sscanf(lex->tok.value, " %f %f %f ",
|
||||
&lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3)
|
||||
#endif
|
||||
{
|
||||
lex->tok.ttype = TOKEN_VECTORCONST;
|
||||
}
|
||||
{
|
||||
lex->tok.ttype = TOKEN_VECTORCONST;
|
||||
}
|
||||
|
||||
return lex->tok.ttype;
|
||||
return lex->tok.ttype;
|
||||
}
|
||||
|
||||
if (isdigit(ch))
|
||||
|
|
|
@ -9,7 +9,7 @@ bool preprocess(const char *filename)
|
|||
|
||||
do {
|
||||
tok = lex_do(lex);
|
||||
/*
|
||||
#if 0
|
||||
if (tok == TOKEN_EOL)
|
||||
printf("EOL");
|
||||
else if (tok >= TOKEN_START && tok <= TOKEN_FATAL)
|
||||
|
@ -20,13 +20,14 @@ bool preprocess(const char *filename)
|
|||
printf(">>%s<<\n", lex->tok.value);
|
||||
else
|
||||
printf("\n");
|
||||
*/
|
||||
#else
|
||||
if (tok == TOKEN_EOL)
|
||||
printf("\n");
|
||||
else if (tok >= TOKEN_START && tok < TOKEN_EOF)
|
||||
printf("%s", lex->tok.value);
|
||||
else
|
||||
printf("%c", tok);
|
||||
#endif
|
||||
} while (tok < TOKEN_EOF);
|
||||
|
||||
lex_close(lex);
|
||||
|
|
Loading…
Reference in a new issue