From: Dale Weiler Date: Wed, 30 Jan 2013 05:49:08 +0000 (+0000) Subject: Removing #error/#warning/#message from parser, and making it part of preprocessor... X-Git-Tag: before-library~193 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=e12d492d6737380da4a1949cb04951b062d75201;p=xonotic%2Fgmqcc.git Removing #error/#warning/#message from parser, and making it part of preprocessor as directives again. --- diff --git a/ftepp.c b/ftepp.c index 34eec59..ce5dd8a 100644 --- a/ftepp.c +++ b/ftepp.c @@ -1269,6 +1269,79 @@ static char *ftepp_include_find(ftepp_t *ftepp, const char *file) return filename; } +static bool ftepp_directive_warning(ftepp_t *ftepp) { + char *message = NULL; + + if (!ftepp_skipspace(ftepp)) + return false; + + /* handle the odd non string constant case so it works like C */ + if (ftepp->token != TOKEN_STRINGCONST) { + bool store = false; + vec_upload(message, "#warning", 8); + ftepp_next(ftepp); + while (ftepp->token != TOKEN_EOL) { + vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + ftepp_next(ftepp); + } + vec_push(message, '\0'); + store = ftepp_warn(ftepp, WARN_CPP, message); + vec_free(message); + return store; + } + + unescape (ftepp_tokval(ftepp), ftepp_tokval(ftepp)); + return ftepp_warn(ftepp, WARN_CPP, "#warning %s", ftepp_tokval(ftepp)); +} + +static void ftepp_directive_error(ftepp_t *ftepp) { + char *message = NULL; + + if (!ftepp_skipspace(ftepp)) + return; + + /* handle the odd non string constant case so it works like C */ + if (ftepp->token != TOKEN_STRINGCONST) { + vec_upload(message, "#error", 6); + ftepp_next(ftepp); + while (ftepp->token != TOKEN_EOL) { + vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + ftepp_next(ftepp); + } + vec_push(message, '\0'); + ftepp_error(ftepp, message); + vec_free(message); + return; + } + + unescape (ftepp_tokval(ftepp), ftepp_tokval(ftepp)); + ftepp_error(ftepp, "#error %s", ftepp_tokval(ftepp)); +} + +static void ftepp_directive_message(ftepp_t *ftepp) { + char *message = NULL; + + if (!ftepp_skipspace(ftepp)) + return; + + /* handle the odd non string constant case so it works like C */ + if (ftepp->token != TOKEN_STRINGCONST) { + vec_upload(message, "#message", 8); + ftepp_next(ftepp); + while (ftepp->token != TOKEN_EOL) { + vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp))); + ftepp_next(ftepp); + } + vec_push(message, '\0'); + con_cprintmsg(&ftepp->lex->tok.ctx, LVL_MSG, "message", message); + vec_free(message); + return; + } + + unescape (ftepp_tokval(ftepp), ftepp_tokval(ftepp)); + con_cprintmsg(&ftepp->lex->tok.ctx, LVL_MSG, "message", ftepp_tokval(ftepp)); +} + /** * Include a file. * FIXME: do we need/want a -I option? @@ -1464,6 +1537,18 @@ static bool ftepp_hash(ftepp_t *ftepp) ftepp_out(ftepp, "#", false); break; } + else if (!strcmp(ftepp_tokval(ftepp), "warning")) { + ftepp_directive_warning(ftepp); + break; + } + else if (!strcmp(ftepp_tokval(ftepp), "error")) { + ftepp_directive_error(ftepp); + break; + } + else if (!strcmp(ftepp_tokval(ftepp), "message")) { + ftepp_directive_message(ftepp); + break; + } else { if (ftepp->output_on) { ftepp_error(ftepp, "unrecognized preprocessor directive: `%s`", ftepp_tokval(ftepp)); diff --git a/parser.c b/parser.c index a54094a..5b1e011 100644 --- a/parser.c +++ b/parser.c @@ -3292,24 +3292,6 @@ static bool parse_eol(parser_t *parser) return parser->tok == TOKEN_EOL; } -/* - * Traditionally you'd implement warning, error, and message - * directives in the preprocessor. However, like #pragma, these - * shouldn't depend on -fftepp to utilize. So they're instead - * implemented here. - */ -enum { - PARSE_DIRECTIVE_ERROR, - PARSE_DIRECTIVE_MESSAGE, - PARSE_DIRECTIVE_WARNING, - PARSE_DIRECTIVE_COUNT -}; - -static const char *parser_directives[PARSE_DIRECTIVE_COUNT] = { - "error", - "message", - "warning" -}; static bool parse_pragma_do(parser_t *parser) { if (!parse_skipwhite(parser) || parser->tok != TOKEN_IDENT) { @@ -3336,85 +3318,25 @@ static bool parse_pragma_do(parser_t *parser) { return true; } -static bool parse_directive_or_pragma_do(parser_t *parser, bool *pragma) { - - size_t type = PARSE_DIRECTIVE_COUNT; - - if (!parser_next(parser) || parser->tok != TOKEN_IDENT) { - parseerror(parser, "expected `pragma, error, message, warning` after `#`, got `%s`", - parser_tokval(parser)); - - return false; - } - - if (!strcmp(parser_tokval(parser), "pragma" )) { - *pragma = true; - - return parse_pragma_do(parser); - } - - if (!strcmp(parser_tokval(parser), "error" )) type = PARSE_DIRECTIVE_ERROR; - if (!strcmp(parser_tokval(parser), "message")) type = PARSE_DIRECTIVE_MESSAGE; - if (!strcmp(parser_tokval(parser), "warning")) type = PARSE_DIRECTIVE_WARNING; - - switch (type) { - case PARSE_DIRECTIVE_ERROR: - case PARSE_DIRECTIVE_MESSAGE: - case PARSE_DIRECTIVE_WARNING: - *pragma = false; - - if (!parse_skipwhite(parser) || parser->tok != TOKEN_STRINGCONST) { - parseerror(parser, "expected %s, got `%`", parser_directives[type], parser_tokval(parser)); - return false; - } - - switch (type) { - case PARSE_DIRECTIVE_ERROR: - con_cprintmsg(&parser->lex->tok.ctx, LVL_ERROR, "error", parser_tokval(parser)); - compile_errors ++; /* hack */ - break; - /*break;*/ - - case PARSE_DIRECTIVE_MESSAGE: - con_cprintmsg(&parser->lex->tok.ctx, LVL_MSG, "message", parser_tokval(parser)); - break; - - case PARSE_DIRECTIVE_WARNING: - con_cprintmsg(&parser->lex->tok.ctx, LVL_WARNING, "warning", parser_tokval(parser)); - break; - } - - if (!parse_eol(parser)) { - parseerror(parser, "parse error after `%` directive", parser_directives[type]); - return false; - } - - return (type != PARSE_DIRECTIVE_ERROR); - } - - parseerror(parser, "invalid directive `%s`", parser_tokval(parser)); - return false; -} -static bool parse_directive_or_pragma(parser_t *parser) +static bool parse_pragma(parser_t *parser) { bool rv; - bool pragma; /* true when parsing pragma */ parser->lex->flags.preprocessing = true; parser->lex->flags.mergelines = true; - rv = parse_directive_or_pragma_do(parser, &pragma); + rv = parse_pragma_do(parser); if (parser->tok != TOKEN_EOL) { - parseerror(parser, "junk after %s", (pragma) ? "pragma" : "directive"); + parseerror(parser, "junk after pragma"); rv = false; } parser->lex->flags.preprocessing = false; parser->lex->flags.mergelines = false; if (!parser_next(parser)) { - parseerror(parser, "parse error after %s", (pragma) ? "pragma" : "directive"); + parseerror(parser, "parse error after pragma"); rv = false; } return rv; @@ -5595,7 +5517,7 @@ static bool parser_global_statement(parser_t *parser) } else if (parser->tok == '#') { - return parse_directive_or_pragma(parser); + return parse_pragma(parser); } else if (parser->tok == '$') {