[qfcc] Add macro support for __FILE__ and __LINE__

There are some expansion problems, but this moves their handling to
where it needs to be.
This commit is contained in:
Bill Currie 2023-11-01 16:07:12 +09:00
parent bbae71c488
commit 82ce36c981
3 changed files with 81 additions and 0 deletions

View file

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

View file

@ -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 = &macro->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) {

View file

@ -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 = &macro->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 = &macro->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;
}