From 82ce36c981267650078c9ca2d53787aeac2e2dd9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 1 Nov 2023 16:07:12 +0900 Subject: [PATCH] [qfcc] Add macro support for __FILE__ and __LINE__ There are some expansion problems, but this moves their handling to where it needs to be. --- tools/qfcc/include/rua-lang.h | 7 +++++ tools/qfcc/source/cpp.c | 21 ++++++++++++++ tools/qfcc/source/qc-lex.l | 53 +++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/tools/qfcc/include/rua-lang.h b/tools/qfcc/include/rua-lang.h index 3b9b7f56a..3cf24ece8 100644 --- a/tools/qfcc/include/rua-lang.h +++ b/tools/qfcc/include/rua-lang.h @@ -47,6 +47,9 @@ typedef struct rua_expr_s { const char *text; } rua_expr_t; +typedef struct rua_macro_s rua_macro_t; +typedef void (*rua_macro_f) (rua_macro_t *macro, void *scanner); + typedef struct rua_macro_s { const char *name; symtab_t *params; @@ -54,6 +57,7 @@ typedef struct rua_macro_s { rua_expr_t **tail; int num_tokens; int num_params; + rua_macro_f update; } rua_macro_t; typedef struct rua_tok_s { @@ -97,6 +101,9 @@ void rua_include_file (const char *name, void *scanner); void rua_embed_file (const char *name, void *scanner); int rua_parse_define (const char *def); +void rua_macro_file (rua_macro_t *macro, void *scanner); +void rua_macro_line (rua_macro_t *macro, void *scanner); + #include "tools/qfcc/source/pre-parse.h" #endif//__rua_lang_h diff --git a/tools/qfcc/source/cpp.c b/tools/qfcc/source/cpp.c index 8865a4b5e..a65dbaab4 100644 --- a/tools/qfcc/source/cpp.c +++ b/tools/qfcc/source/cpp.c @@ -384,10 +384,31 @@ cpp_include (const char *opt, const char *arg) } #undef CPP_INCLUDE +static void +make_magic_macro (symtab_t *tab, const char *name, rua_macro_f update) +{ + rua_macro_t *macro = malloc (sizeof (*macro)); + *macro = (rua_macro_t) { + .name = save_string (name), + .tail = ¯o->tokens, + .update = update, + }; + auto sym = symtab_lookup (tab, macro->name); + if (sym) { + internal_error (0, "\"%s\" redefined", macro->name); + } + sym = new_symbol (macro->name); + sym->sy_type = sy_macro; + sym->s.macro = macro; + symtab_addsymbol (tab, sym); +} + void cpp_define (const char *arg) { if (!cpp_macros) { cpp_macros = new_symtab (0, stab_global); + make_magic_macro (cpp_macros, "__FILE__", rua_macro_file); + make_magic_macro (cpp_macros, "__LINE__", rua_macro_line); } size_t len = strlen (arg); if (len > 0x10000) { diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index bf7fc1629..76a2e89f1 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -1426,6 +1426,9 @@ qc_process (rua_extra_t *extra, int token, rua_tok_t *tok, yyscan_t scanner) } } if (macro) { + if (macro->update) { + macro->update (macro, scanner); + } expand_macro (extra, macro); if (0) dump_expr_stack (extra); return YYPUSH_MORE; @@ -2008,3 +2011,53 @@ rua_parse_define (const char *def) dstring_delete (extra.dstr); return status; } + +void +rua_macro_file (rua_macro_t *macro, void *scanner) +{ + int file = pr.source_file; + if (macro->tokens && macro->tokens->location.file == file) { + return; + } + macro->tokens = 0; + macro->tail = ¯o->tokens; + macro->num_tokens = 0; + + rua_expr_t *expr = malloc (sizeof (*expr)); + macro->num_tokens++; + const char *file_str = save_string (va (0, "\"%s\"", + quote_string (GETSTR (file)))); + *expr = (rua_expr_t) { + .location = { .file = file }, + .textlen = strlen (file_str), + .token = -rua_string, + .text = file_str, + }; + *macro->tail = expr; + macro->tail = &expr->next; +} + +void +rua_macro_line (rua_macro_t *macro, void *scanner) +{ + int line = pr.source_line; + + if (macro->tokens && macro->tokens->location.first_line == line) { + return; + } + macro->tokens = 0; + macro->tail = ¯o->tokens; + macro->num_tokens = 0; + + rua_expr_t *expr = malloc (sizeof (*expr)); + macro->num_tokens++; + const char *line_str = save_string (va (0, "%d", line)); + *expr = (rua_expr_t) { + .location = { .first_line = line }, + .textlen = strlen (line_str), + .token = -rua_number, + .text = line_str, + }; + *macro->tail = expr; + macro->tail = &expr->next; +}