mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-27 22:22:17 +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 == '/')
|
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))
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue