From d8319155434f3577a2442ad6a27db59e6cfdd4d3 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 11 Jul 2020 20:43:40 -0700 Subject: [PATCH] preproc: add %is...() function-like macros Add the first "preprocessor functions". These are simply "magic" single-line macros with a suitable expansion function. The first application is functions equal to the %if directives, e.g. %ifdef blah == %if %isdef(blah) except can be used anywhere (not just in %if statements like defined() in C.) Signed-off-by: H. Peter Anvin --- asm/pptok.pl | 4 ++++ asm/preproc.c | 62 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/asm/pptok.pl b/asm/pptok.pl index 47924897..f40cb58e 100755 --- a/asm/pptok.pl +++ b/asm/pptok.pl @@ -124,9 +124,11 @@ if ($what eq 'h') { print OUT "enum preproc_token {\n"; $n = 0; + my $maxlen = 0; foreach $pt (@pptok) { if (defined($pt)) { printf OUT " %-24s = %3d,\n", "PP_\U$pt\E", $n; + $maxlen = length($pt) if (length($pt) > $maxlen); } $n++; } @@ -143,6 +145,8 @@ if ($what eq 'h') { printf OUT "#define PP_HAS_CASE(x) ((x) >= PP_%s)\n", uc($pptok[$first_itoken]); print OUT "#define PP_INSENSITIVE(x) ((x) & 1)\n"; + # The +1 here is for the initial % sign + printf OUT "#define PP_TOKLEN_MAX %d\n", $maxlen+1; print OUT "\n"; foreach $ct (@cctok) { diff --git a/asm/preproc.c b/asm/preproc.c index 8fb9dfbb..63d40e61 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -3050,8 +3050,10 @@ static SMacro *define_smacro(const char *mname, bool casesense, smac->params = tmpl->params; smac->alias = tmpl->alias; smac->greedy = tmpl->greedy; - if (tmpl->expand) - smac->expand = tmpl->expand; + if (tmpl->expand) { + smac->expand = tmpl->expand; + smac->expandpvt = tmpl->expandpvt; + } } if (list_option('s')) { list_smacro_def((smac->alias ? PP_DEFALIAS : PP_DEFINE) @@ -5543,8 +5545,8 @@ static SMacro *expand_one_smacro(Token ***tpp) /* Note: we own the expansion this returns. */ t = m->expand(m, params, nparam); - tafter = tline->next; /* Skip past the macro call */ - tline->next = NULL; /* Truncate list at the macro call end */ + tafter = tline->next; /* Skip past the macro call */ + tline->next = NULL; /* Truncate list at the macro call end */ tline = tafter; tup = NULL; @@ -6634,33 +6636,65 @@ stdmac_ptr(const SMacro *s, Token **params, int nparams) } } +static Token * +stdmac_is(const SMacro *s, Token **params, int nparams) +{ + int retval; + struct Token *pline = params[0]; + + (void)nparams; + + params[0] = NULL; /* Don't free this later */ + + retval = if_condition(pline, s->expandpvt.u) == COND_IF_TRUE; + return make_tok_num(NULL, retval); +} + /* Add magic standard macros */ struct magic_macros { const char *name; int nparam; ExpandSMacro func; }; -static const struct magic_macros magic_macros[] = -{ - { "__?FILE?__", 0, stdmac_file }, - { "__?LINE?__", 0, stdmac_line }, - { "__?BITS?__", 0, stdmac_bits }, - { "__?PTR?__", 0, stdmac_ptr }, - { NULL, 0, NULL } -}; - static void pp_add_magic_stdmac(void) { + static const struct magic_macros magic_macros[] = { + { "__?FILE?__", 0, stdmac_file }, + { "__?LINE?__", 0, stdmac_line }, + { "__?BITS?__", 0, stdmac_bits }, + { "__?PTR?__", 0, stdmac_ptr }, + { NULL, 0, NULL } + }; const struct magic_macros *m; SMacro tmpl; + enum preproc_token pt; + char name_buf[PP_TOKLEN_MAX+1]; + /* Simple standard magic macros */ nasm_zero(tmpl); - for (m = magic_macros; m->name; m++) { tmpl.nparam = m->nparam; tmpl.expand = m->func; define_smacro(m->name, true, NULL, &tmpl); } + + /* %is...() macro functions */ + tmpl.nparam = 1; + tmpl.greedy = true; + tmpl.expand = stdmac_is; + name_buf[0] = '%'; + name_buf[1] = 'i'; + name_buf[2] = 's'; + for (pt = PP_IF; pt < PP_IFN; pt++) { + if (pp_directives[pt]) { + nasm_new(tmpl.params); + + tmpl.params[0].flags = SPARM_GREEDY; + strcpy(name_buf+3, pp_directives[pt]+3); + tmpl.expandpvt.u = pt; + define_smacro(name_buf, false, NULL, &tmpl); + } + } } static void pp_reset_stdmac(enum preproc_mode mode)