tempcommitting WARN_UNKNOWN_CONTROL_SEQUENCE and handling of backslashes in strings

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-08-08 12:24:01 +02:00
parent 7324eee421
commit 42ab396e38
3 changed files with 58 additions and 5 deletions

43
lexer.c
View file

@ -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
View file

@ -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();
} }

View file

@ -3,3 +3,4 @@
#endif #endif
GMQCC_DEFINE_FLAG(UNUSED_VARIABLE) GMQCC_DEFINE_FLAG(UNUSED_VARIABLE)
GMQCC_DEFINE_FLAG(UNKNOWN_CONTROL_SEQUENCE)