[qfcc] Implement command-line macro definitions

This takes care of __QFCC__ not being defined
This commit is contained in:
Bill Currie 2023-10-29 18:19:03 +09:00
parent dfd57ed74f
commit e402d0fa21
4 changed files with 76 additions and 9 deletions

View file

@ -49,6 +49,7 @@ void intermediate_file (struct dstring_s *ifile, const char *filename,
FILE *preprocess_file (const char *filename, const char *ext);
extern const char *cpp_name;
extern struct dstring_s *tempname;
extern struct symtab_s *cpp_macros;
void cpp_write_dependencies (const char *sourcefile);

View file

@ -95,6 +95,7 @@ bool rua_defined (const char *sym, void *scanner);
void rua_undefine (const char *sym, void *scanner);
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);
#include "tools/qfcc/source/pre-parse.h"

View file

@ -62,7 +62,9 @@
#include "tools/qfcc/include/diagnostic.h"
#include "tools/qfcc/include/options.h"
#include "tools/qfcc/include/qfcc.h"
#include "tools/qfcc/include/rua-lang.h"
#include "tools/qfcc/include/strpool.h"
#include "tools/qfcc/include/symtab.h"
typedef struct cpp_arg_s {
struct cpp_arg_s *next;
@ -97,6 +99,7 @@ static bool cpp_dep_generate = false;
static bool cpp_dep_phony = false;
static bool cpp_dep_quote = false;
symtab_t *cpp_macros;
const char *cpp_name = CPP_NAME;
dstring_t *tempname;
@ -382,25 +385,38 @@ cpp_include (const char *opt, const char *arg)
void cpp_define (const char *arg)
{
#if 0
if (!cpp_macros) {
cpp_macros = new_symtab (stab_global);
cpp_macros = new_symtab (0, stab_global);
}
#endif
size_t len = strlen (arg);
if (len > 0x10000) {
error (0, "command line define too long: %zd", len);
return;
}
char argstr[len + 4];
strcpy (argstr, arg);
argstr[len] = '\n';
argstr[len + 1] = 0;
char *eq = strchr (argstr, '=');
if (eq) {
*eq = ' ';
} else {
strcpy (argstr + len, " 1\n");
}
rua_parse_define (argstr);
arg = va (0, "-D%s", arg);
CPP_ADD (def, arg);
}
void cpp_undefine (const char *arg)
{
#if 0
if (cpp_macros) {
auto sym = symtab_lookup (cpp_macros, arg);
if (sym) {
symtab_removesymbol (cpp_macros, sym);
}
}
#endif
arg = va (0, "-D%s", arg);
CPP_ADD (undef, arg);
}

View file

@ -1110,7 +1110,7 @@ expand_macro (rua_extra_t *extra, rua_macro_t *macro)
{
int num_tokens = macro->num_tokens;
for (auto t = macro->tokens; t; t = t->next) {
if (t->token == -rua_id) {
if (t->token == -rua_id && macro->params) {
auto sym = symtab_lookup (macro->params, t->text);
if (sym) {
num_tokens += extra->arg_list.a[sym->s.offset]->num_tokens - 1;
@ -1124,7 +1124,7 @@ expand_macro (rua_extra_t *extra, rua_macro_t *macro)
int argid = 0;
for (auto t = macro->tokens; t; t = t->next) {
auto e = t;
if (t->token == -rua_id) {
if (t->token == -rua_id && macro->params) {
auto sym = symtab_lookup (macro->params, t->text);
if (sym) {
int param = sym->s.offset;
@ -1419,7 +1419,7 @@ qc_yyparse (FILE *in)
.arg_list = DARRAY_STATIC_INIT (8),
.include_stack = DARRAY_STATIC_INIT (8),
.dstr = dstring_new (),
.macro_tab = new_symtab (0, stab_global),
.macro_tab = cpp_macros ? cpp_macros : new_symtab (0, stab_global),
};
yylex_init_extra (&extra, &scanner);
@ -1718,7 +1718,7 @@ dump_state_stack (void *scanner)
extra ? extra->recording ? "true" : "false" : "n/a",
extra ? extra->expand ? "true" : "false" : "n/a",
extra ? extra->params ? "true" : "false" : "n/a",
GETSTR(pr.source_file), pr.source_line);
pr.strings ? GETSTR(pr.source_file) : "", pr.source_line);
}
static void
@ -1878,3 +1878,52 @@ rua_embed_file (const char *name, void *scanner)
internal_error (0, "not implemented");
(void)yy_top_state;
}
int
rua_parse_define (const char *def)
{
int status;
yyscan_t scanner;
rua_tok_t tok = { .location = { 1, 1, 1, 1 }, };
rua_extra_t extra = {
.preprocessor = true,
.pre_state = pre_yypstate_new (),
.expr_stack = DARRAY_STATIC_INIT (32),
.macro_tab = cpp_macros,
};
yylex_init_extra (&extra, &scanner);
yy_scan_string (def, scanner);
yy_push_state (PREPROC, scanner);
int token = -1;
do {
if (token == -1) {
token = PRE_DEFINE;
} else {
token = yylex (&tok, &tok.location, scanner);
status = 0;
}
while (token) {
status = qc_process (&extra, token, &tok, scanner);
if (status != YYPUSH_MORE || !extra.expr_stack.size) {
break;
}
auto expr = DARRAY_REMOVE (&extra.expr_stack);
token = expr.token;
tok = (rua_tok_t) {
.location = expr.location,
.textlen = expr.textlen,
.text = expr.text, // macro token strings use save_string
.token = token,
};
}
} while (status == YYPUSH_MORE);
yylex_destroy (scanner);
pre_yypstate_delete (extra.pre_state);
free (extra.expr_stack.a);
dstring_delete (extra.dstr);
return status;
}