From e71816f9c444832381f6958878deffd1fd9bf1e3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 23 Oct 2023 22:00:14 +0900 Subject: [PATCH] [qfcc] Implement preprocessor-only output Currently only to stdout, but it makes debugging preprocessing much easier. --- tools/qfcc/source/qc-lex.l | 53 ++++++++++++++++++++++++++++---------- tools/qfcc/source/qfcc.c | 6 ++++- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 3068a18a2..158b73456 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -130,6 +130,7 @@ typedef enum { rua_vector, rua_string, rua_char, + rua_space, rua_num_term, } rua_term; @@ -174,7 +175,7 @@ pp_vnumber '({s}*{m}?{pp_number}){2,4}{s}*'{ULFD}? yylval->pointer = 0; // ensure pointer vals are null "/*" { warning (0, "nested /* in comment"); } -\*+"/" { yy_pop_state (yyscanner); } +\*+"/" { yy_pop_state (yyscanner); return -rua_space; } \n { next_line (yylloc); } [^*/\n]* /* munch on anything but possible end of comment */ \/+[^*\n]* /* handle /s not followed by * */ @@ -189,7 +190,7 @@ pp_vnumber '({s}*{m}?{pp_number}){2,4}{s}*'{ULFD}? yy_push_state (DIRECTIVE, yyscanner); extra->preprocessor = true; } -<*>^{s}* { yy_push_state (BOL, yyscanner); } +<*>^{s}* { yy_push_state (BOL, yyscanner); return -rua_space; } #{s}* { BEGIN (DIRECTIVE); extra->preprocessor = true; } . { yy_pop_state (yyscanner); @@ -211,10 +212,12 @@ pp_vnumber '({s}*{m}?{pp_number}){2,4}{s}*'{ULFD}? \r*\n | \r*\n { next_line (yylloc); return PRE_EOD; } -^[^#\n \t]+ { BEGIN (SUPPRESSC); } -.* /* nom nom */ +^[^#/\n \t]+ { BEGIN (SUPPRESSC); } +[^/\n]* /* nom nom */ +\/[^/\n]* /* nom nom */ \n { next_line (yylloc); BEGIN (SUPPRESS); } \n { next_line (yylloc); } +\/[^/\n]* /* nom nom */ <> { error (0, "unterminated #if"); return 0; } [^\\\r\n]* { return PRE_TEXT; } @@ -312,7 +315,7 @@ pp_vnumber '({s}*{m}?{pp_number}){2,4}{s}*'{ULFD}? } } -<*>{s}+ /* skip */ +<*>{s}+ { return -rua_space; } <*>. { error (0, "all your typo are belong to us:%d %d-%d", @@ -528,6 +531,9 @@ keyword_get_key (const void *kw, void *unused) static int process_keyword (YYSTYPE *lval, keyword_t *keyword, const char *token) { + if (lval->text == lval->str_text) { + lval->text = save_string (lval->str_text); + } if (keyword->value == STRUCT) { lval->value.op = token[0]; } else if (keyword->value == OBJECT_NAME) { @@ -1004,6 +1010,9 @@ parse_string (rua_tok_t *tok, int type, yyscan_t scanner) static void next_line (rua_loc_t *loc) { + if (options.preprocess_only) { + puts (""); + } loc->first_line = loc->last_line; loc->first_column = loc->last_column; loc->last_column = 1; @@ -1023,16 +1032,23 @@ static void user_action (rua_tok_t *tok, rua_loc_t *loc, const char *text, size_t textlen, int state) { - if (state != COMMENT && state != SUPPRESS) { - if (textlen < sizeof (tok->text)) { - strncpy (tok->str_text, text, textlen); - tok->str_text[textlen] = 0; - tok->text = tok->str_text; - } else { - tok->text = save_string (text); - } - tok->textlen = textlen; + if (state == COMMENT || state == LCOMMENT || isspace (*text)) { + tok->str_text[0] = ' '; + tok->str_text[1] = 0; + tok->text = tok->str_text; + textlen = 1; + } else if (state == SUPPRESS) { + tok->str_text[0] = 0; + tok->text = tok->str_text; + textlen = 0; + } else if (textlen < sizeof (tok->text)) { + strncpy (tok->str_text, text, textlen); + tok->str_text[textlen] = 0; + tok->text = tok->str_text; + } else { + tok->text = save_string (text); } + tok->textlen = textlen; loc->first_line = loc->last_line; loc->first_column = loc->last_column; // \n handling rules will take care of the column and line @@ -1078,6 +1094,11 @@ qc_process (rua_extra_t *extra, int token, rua_tok_t *tok, yyscan_t scanner) case rua_char: token = parse_string (tok, -token, scanner); break; + case rua_space: + if (options.preprocess_only) { + printf (" "); + } + break; } } if (token >= 0) { @@ -1092,6 +1113,10 @@ qc_process (rua_extra_t *extra, int token, rua_tok_t *tok, yyscan_t scanner) } return pre_yypush_parse (state, token, tok, loc, scanner); } else { + if (options.preprocess_only) { + printf ("%s", tok->text); + return token ? YYPUSH_MORE : 0; + } auto state = extra->qc_state; return qc_yypush_parse (state, token, value, loc, scanner); } diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index d09a85ebb..b3273eed6 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -390,8 +390,12 @@ compile_to_obj (const char *file, const char *obj, lang_t lang) } yyin = preprocess_file (file, 0); - if (options.preprocess_only || !yyin) + if (options.preprocess_only || !yyin) { + if (yyin) { + return yyparse (yyin); + } return !options.preprocess_only; + } InitData (); chain_initial_types ();