mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-12-18 00:11:06 +00:00
tempcommitting WARN_UNKNOWN_CONTROL_SEQUENCE and handling of backslashes in strings
This commit is contained in:
parent
7324eee421
commit
42ab396e38
3 changed files with 58 additions and 5 deletions
43
lexer.c
43
lexer.c
|
@ -24,6 +24,25 @@ void lexerror(lex_file *lex, const char *fmt, ...)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lexwarn(lex_file *lex, int warn, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (!OPTS_WARN(warn))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (lex)
|
||||||
|
printf("warning %s:%lu: ", lex->name, (unsigned long)lex->sline);
|
||||||
|
else
|
||||||
|
printf("warning: ");
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
token* token_new()
|
token* token_new()
|
||||||
{
|
{
|
||||||
token *tok = (token*)mem_a(sizeof(token));
|
token *tok = (token*)mem_a(sizeof(token));
|
||||||
|
@ -333,10 +352,6 @@ 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 (!lex_tokench(lex, ch))
|
|
||||||
return (lex->tok->ttype = TOKEN_FATAL);
|
|
||||||
|
|
||||||
/* as lexer we only care about \" to not terminate the string prematurely */
|
|
||||||
if (ch == '\\') {
|
if (ch == '\\') {
|
||||||
ch = lex_getch(lex);
|
ch = lex_getch(lex);
|
||||||
if (ch == EOF) {
|
if (ch == EOF) {
|
||||||
|
@ -344,10 +359,28 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote)
|
||||||
lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
|
lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
|
||||||
return (lex->tok->ttype = TOKEN_ERROR);
|
return (lex->tok->ttype = TOKEN_ERROR);
|
||||||
}
|
}
|
||||||
/* so we just add the next character no matter what it actually is */
|
|
||||||
|
switch (ch) {
|
||||||
|
case '\\': break;
|
||||||
|
case 'a': ch = '\a'; break;
|
||||||
|
case 'b': ch = '\b'; break;
|
||||||
|
case 'r': ch = '\r'; break;
|
||||||
|
case 'n': ch = '\n'; break;
|
||||||
|
case 't': ch = '\t'; break;
|
||||||
|
case 'f': ch = '\f'; break;
|
||||||
|
case 'v': ch = '\v'; break;
|
||||||
|
default:
|
||||||
|
lexwarn(lex, WARN_UNKNOWN_CONTROL_SEQUENCE, "unrecognized control sequence: \\%c", ch);
|
||||||
|
/* so we just add the character plus backslash no matter what it actually is */
|
||||||
|
if (!lex_tokench(lex, '\\'))
|
||||||
|
return (lex->tok->ttype = TOKEN_FATAL);
|
||||||
|
}
|
||||||
|
/* add the character finally */
|
||||||
if (!lex_tokench(lex, ch))
|
if (!lex_tokench(lex, ch))
|
||||||
return (lex->tok->ttype = TOKEN_FATAL);
|
return (lex->tok->ttype = TOKEN_FATAL);
|
||||||
}
|
}
|
||||||
|
else if (!lex_tokench(lex, ch))
|
||||||
|
return (lex->tok->ttype = TOKEN_FATAL);
|
||||||
}
|
}
|
||||||
lexerror(lex, "unexpected end of file within string constant");
|
lexerror(lex, "unexpected end of file within string constant");
|
||||||
lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
|
lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
|
||||||
|
|
19
main.c
19
main.c
|
@ -308,6 +308,22 @@ static bool options_parse(int argc, char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void options_setflag(uint32_t *flags, size_t idx, bool on)
|
||||||
|
{
|
||||||
|
longbit lb = LONGBIT(idx);
|
||||||
|
#if 0
|
||||||
|
if (on)
|
||||||
|
flags[lb.idx] |= (1<<(lb.bit));
|
||||||
|
else
|
||||||
|
flags[lb.idx] &= ~(1<<(lb.bit));
|
||||||
|
#else
|
||||||
|
if (on)
|
||||||
|
flags[0] |= (1<<(lb));
|
||||||
|
else
|
||||||
|
flags[0] &= ~(1<<(lb));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool parser_init();
|
bool parser_init();
|
||||||
bool parser_compile(const char *filename);
|
bool parser_compile(const char *filename);
|
||||||
bool parser_finish(const char *output);
|
bool parser_finish(const char *output);
|
||||||
|
@ -317,6 +333,9 @@ int main(int argc, char **argv) {
|
||||||
size_t itr;
|
size_t itr;
|
||||||
app_name = argv[0];
|
app_name = argv[0];
|
||||||
|
|
||||||
|
/* default options / warn flags */
|
||||||
|
options_setflag(opts_warn, WARN_UNKNOWN_CONTROL_SEQUENCE, true);
|
||||||
|
|
||||||
if (!options_parse(argc, argv)) {
|
if (!options_parse(argc, argv)) {
|
||||||
return usage();
|
return usage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GMQCC_DEFINE_FLAG(UNUSED_VARIABLE)
|
GMQCC_DEFINE_FLAG(UNUSED_VARIABLE)
|
||||||
|
GMQCC_DEFINE_FLAG(UNKNOWN_CONTROL_SEQUENCE)
|
||||||
|
|
Loading…
Reference in a new issue