diff options
author | H. Peter Anvin (Intel) <hpa@zytor.com> | 2019-08-14 23:45:57 -0700 |
---|---|---|
committer | H. Peter Anvin (Intel) <hpa@zytor.com> | 2019-08-14 23:50:37 -0700 |
commit | 5e3d741b00ecbcfbc682697f033d698fce8b38b3 (patch) | |
tree | 9900a2a038ab166b18b92bdd7f33899a7b8038cf | |
parent | 522bcad4aebc54ce4107db851c91628dc94e1ed1 (diff) | |
download | nasm-5e3d741b00ecbcfbc682697f033d698fce8b38b3.tar.gz |
preproc: introduce alias smacros, cleanups
Introduce "alias smacros", which are the smacro equivalent of
symlinks; when used with the various smacro-defining and undefining
directives, they affect the macro they are aliased to. Only explicit
%defalias, %idefalias, and %undefalias affect them.
This is intended for being able to rename macros while retaining the
legacy names.
This patch also removes an *astonishing* amount of duplicated
code:
1. Every caller to defined_smacro() and undef_smacro() would call
get_ctx() to mangle the macro name; push that into those functions.
2. Common code to get an smacro identifier.
3. Every code path that returns DIRECTIVE_FOUND also has to do
free_tlist(origline); make it do so.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r-- | asm/pptok.dat | 3 | ||||
-rw-r--r-- | asm/preproc.c | 587 |
2 files changed, 276 insertions, 314 deletions
diff --git a/asm/pptok.dat b/asm/pptok.dat index a5a6e590..2a465d43 100644 --- a/asm/pptok.dat +++ b/asm/pptok.dat @@ -50,6 +50,7 @@ %arg %assign %clear +%defalias %define %defstr %deftok @@ -65,6 +66,7 @@ %exitrep %fatal %iassign +%idefalias %idefine %idefstr %ideftok @@ -93,6 +95,7 @@ %strlen %substr %undef +%undefalias %unimacro %unmacro %use diff --git a/asm/preproc.c b/asm/preproc.c index 51b6b33d..664950fc 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -114,6 +114,7 @@ struct SMacro { unsigned int nparam; bool casesense; bool in_progress; + bool alias; /* This is an alias macro */ }; /* @@ -2208,61 +2209,103 @@ list_smacro_def(enum preproc_token op, const Context *ctx, const SMacro *m) } /* - * Common code for defining an smacro + * Common code for defining an smacro. The tmpl argument, if not NULL, + * contains any macro parameters that aren't explicit arguments; + * those are the more uncommon macro variants. */ -static SMacro *define_smacro(Context *ctx, const char *mname, - bool casesense, int nparam, - bool *eval_param, Token *expansion) +static SMacro *define_smacro(const char *mname, bool casesense, + Token *expansion, const SMacro *tmpl) { SMacro *smac, **smhead; struct hash_table *smtbl; + Context *ctx; + bool defining_alias = false; + unsigned int nparam = 0; - if (smacro_defined(ctx, mname, nparam, &smac, casesense)) { - if (!smac) { + if (tmpl) { + defining_alias = tmpl->alias; + nparam = tmpl->nparam; + } + + while (1) { + ctx = get_ctx(mname, &mname); + + if (!smacro_defined(ctx, mname, nparam, &smac, casesense)) { + /* Create a new macro */ + smtbl = ctx ? &ctx->localmac : &smacros; + smhead = (SMacro **) hash_findi_add(smtbl, mname); + nasm_new(smac); + smac->next = *smhead; + *smhead = smac; + break; + } else if (!smac) { nasm_warn(WARN_OTHER, "single-line macro `%s' defined both with and" " without parameters", mname); /* * Some instances of the old code considered this a failure, * some others didn't. What is the right thing to do here? */ - free_tlist(expansion); - return NULL; /* Failure */ - } else { + goto fail; + } else if (!smac->alias || defining_alias) { /* * We're redefining, so we have to take over an * existing SMacro structure. This means freeing * what was already in it, but not the structure itself. */ clear_smacro(smac); + break; + } else if (smac->in_progress) { + nasm_nonfatal("macro alias loop"); + goto fail; + } else { + /* It is an alias macro; follow the alias link */ + SMacro *s; + + smac->in_progress = true; + s = define_smacro(smac->expansion->text, casesense, + expansion, tmpl); + smac->in_progress = false; + return s; } - } else { - smtbl = ctx ? &ctx->localmac : &smacros; - smhead = (SMacro **) hash_findi_add(smtbl, mname); - nasm_new(smac); - smac->next = *smhead; - *smhead = smac; } - smac->name = nasm_strdup(mname); + + smac->name = nasm_strdup(mname); smac->casesense = casesense; - smac->nparam = nparam; - smac->eval_param = eval_param; smac->expansion = expansion; - smac->expand = smacro_expand_default; - - if (list_option('m')) - list_smacro_def(casesense ? PP_DEFINE : PP_IDEFINE, ctx, smac); - + smac->expand = smacro_expand_default; + if (tmpl) { + smac->nparam = tmpl->nparam; + smac->eval_param = tmpl->eval_param; + smac->alias = tmpl->alias; + if (tmpl->expand) + smac->expand = tmpl->expand; + } + if (list_option('m')) { + static const enum preproc_token op[2][2] = { + { PP_DEFINE, PP_IDEFINE }, + { PP_DEFALIAS, PP_IDEFALIAS } + }; + list_smacro_def(op[!!smac->alias][casesense], ctx, smac); + } return smac; + +fail: + free_tlist(expansion); + if (tmpl && tmpl->eval_param) + nasm_free(tmpl->eval_param); + return NULL; } /* * Undefine an smacro */ -static void undef_smacro(Context *ctx, const char *mname) +static void undef_smacro(const char *mname, bool undefalias) { SMacro **smhead, *s, **sp; struct hash_table *smtbl; + Context *ctx; + ctx = get_ctx(mname, &mname); smtbl = ctx ? &ctx->localmac : &smacros; smhead = (SMacro **)hash_findi(smtbl, mname, NULL); @@ -2273,10 +2316,21 @@ static void undef_smacro(Context *ctx, const char *mname) sp = smhead; while ((s = *sp) != NULL) { if (!mstrcmp(s->name, mname, s->casesense)) { - if (list_option('m')) - list_smacro_def(PP_UNDEF, ctx, s); - *sp = s->next; - free_smacro(s); + if (s->alias && !undefalias) { + if (s->in_progress) { + nasm_nonfatal("macro alias loop"); + } else { + s->in_progress = true; + undef_smacro(s->expansion->text, false); + s->in_progress = false; + } + } else { + if (list_option('m')) + list_smacro_def(s->alias ? PP_UNDEFALIAS : PP_UNDEF, + ctx, s); + *sp = s->next; + free_smacro(s); + } } else { sp = &s->next; } @@ -2391,6 +2445,33 @@ static void do_pragma_preproc(Token *tline) (void)tline; /* Nothing else to do at present */ } +static bool is_macro_id(const Token *t) +{ + return t && (t->type == TOK_ID || + (t->type == TOK_PREPROC_ID && t->text[1] == '$')); +} + +static char *get_id(Token **tp, enum preproc_token pp, const char *err) +{ + char *id; + Token *t = *tp; + + t = t->next; /* Skip directive */ + skip_white_(t); + t = expand_id(t); + + if (!is_macro_id(t)) { + nasm_nonfatal("`%s' expects a %s", pp_directives[pp], + err ? err : "macro identifier"); + return NULL; + } + + id = t->text; + skip_white_(t); + *tp = t; + return id; +} + /** * find and process preprocessor directive in passed line * Find out if a line contains a preprocessor directive, and deal @@ -2505,7 +2586,7 @@ static int do_directive(Token *tline, Token **output) dname = pp_directives[i]; /* Directive name, for error messages */ casesense = true; /* Default to case sensitive */ switch (i) { - case PP_INVALID: + default: nasm_nonfatal("unknown preprocessor directive `%s'", tline->text); return NO_DIRECTIVE_FOUND; /* didn't get it */ @@ -2549,8 +2630,7 @@ static int do_directive(Token *tline, Token **output) *output = tline; } } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_STACKSIZE: /* Directive to tell NASM what the default stack size is. The @@ -2562,8 +2642,6 @@ static int do_directive(Token *tline, Token **output) tline = tline->next; if (!tline || tline->type != TOK_ID) { nasm_nonfatal("`%s' missing size parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; } if (nasm_stricmp(tline->text, "flat") == 0) { /* All subsequent ARG directives are for a 32-bit stack */ @@ -2595,11 +2673,8 @@ static int do_directive(Token *tline, Token **output) LocalOffset = 0; } else { nasm_nonfatal("`%s' invalid size type", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_ARG: /* TASM like ARG directive to define arguments to functions, in @@ -2618,8 +2693,7 @@ static int do_directive(Token *tline, Token **output) tline = tline->next; if (!tline || tline->type != TOK_ID) { nasm_nonfatal("`%s' missing argument parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } arg = tline->text; @@ -2628,14 +2702,12 @@ static int do_directive(Token *tline, Token **output) if (!tline || tline->type != TOK_OTHER || tline->text[0] != ':') { nasm_nonfatal("syntax error processing `%s' directive", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } tline = tline->next; if (!tline || tline->type != TOK_ID) { nasm_nonfatal("`%s' missing size type parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } /* Allow macro expansion of type parameter */ @@ -2645,8 +2717,7 @@ static int do_directive(Token *tline, Token **output) if (!size) { nasm_nonfatal("invalid size type for `%s' missing directive", dname); free_tlist(tt); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } free_tlist(tt); @@ -2665,8 +2736,7 @@ static int do_directive(Token *tline, Token **output) tline = tline->next; } while (tline && tline->type == TOK_OTHER && tline->text[0] == ','); ArgOffset = offset; - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_LOCAL: /* TASM like LOCAL directive to define local variables for a @@ -2689,8 +2759,7 @@ static int do_directive(Token *tline, Token **output) tline = tline->next; if (!tline || tline->type != TOK_ID) { nasm_nonfatal("`%s' missing argument parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } local = tline->text; @@ -2699,14 +2768,12 @@ static int do_directive(Token *tline, Token **output) if (!tline || tline->type != TOK_OTHER || tline->text[0] != ':') { nasm_nonfatal("syntax error processing `%s' directive", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } tline = tline->next; if (!tline || tline->type != TOK_ID) { nasm_nonfatal("`%s' missing size type parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } /* Allow macro expansion of type parameter */ @@ -2716,8 +2783,7 @@ static int do_directive(Token *tline, Token **output) if (!size) { nasm_nonfatal("invalid size type for `%s' missing directive", dname); free_tlist(tt); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } free_tlist(tt); @@ -2742,16 +2808,14 @@ static int do_directive(Token *tline, Token **output) tline = tline->next; } while (tline && tline->type == TOK_OTHER && tline->text[0] == ','); LocalOffset = offset; - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_CLEAR: if (tline->next) nasm_warn(WARN_OTHER, "trailing garbage after `%s' ignored", dname); free_macros(); init_macros(); - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_DEPEND: t = tline->next = expand_smacro(tline->next); @@ -2759,8 +2823,7 @@ static int do_directive(Token *tline, Token **output) if (!t || (t->type != TOK_STRING && t->type != TOK_INTERNAL_STRING)) { nasm_nonfatal("`%s' expects a file name", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; /* but we did _something_ */ + goto done; } if (t->next) nasm_warn(WARN_OTHER, "trailing garbage after `%s' ignored", dname); @@ -2768,8 +2831,7 @@ static int do_directive(Token *tline, Token **output) if (t->type != TOK_INTERNAL_STRING) nasm_unquote_cstr(p, NULL); strlist_add(deplist, p); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; case PP_INCLUDE: t = tline->next = expand_smacro(tline->next); @@ -2778,8 +2840,7 @@ static int do_directive(Token *tline, Token **output) if (!t || (t->type != TOK_STRING && t->type != TOK_INTERNAL_STRING)) { nasm_nonfatal("`%s' expects a file name", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; /* but we did _something_ */ + goto done; } if (t->next) nasm_warn(WARN_OTHER, "trailing garbage after `%s' ignored", dname); @@ -2806,25 +2867,15 @@ static int do_directive(Token *tline, Token **output) istk = inc; lfmt->uplevel(LIST_INCLUDE, 0); } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_USE: { static macros_t *use_pkg; const char *pkg_macro = NULL; - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - - if (!tline || (tline->type != TOK_STRING && - tline->type != TOK_INTERNAL_STRING && - tline->type != TOK_ID)) { - nasm_nonfatal("`%s' expects a package name", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; /* but we did _something_ */ - } + if (!(mname = get_id(&tline, i, "package name"))) + goto done; if (tline->next) nasm_warn(WARN_OTHER, "trailing garbage after `%s' ignored", dname); if (tline->type == TOK_STRING) @@ -2852,8 +2903,7 @@ static int do_directive(Token *tline, Token **output) istk = inc; lfmt->uplevel(LIST_INCLUDE, 0); } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; } case PP_PUSH: case PP_REPL: @@ -2865,8 +2915,7 @@ static int do_directive(Token *tline, Token **output) if (!tok_type_(tline, TOK_ID)) { nasm_nonfatal("`%s' expects a context identifier", pp_directives[i]); - free_tlist(origline); - return DIRECTIVE_FOUND; /* but we did _something_ */ + goto done; } if (tline->next) nasm_warn(WARN_OTHER, "trailing garbage after `%s' ignored", @@ -2903,8 +2952,7 @@ static int do_directive(Token *tline, Token **output) } nasm_free(p); } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_FATAL: severity = ERR_FATAL; goto issue_error; @@ -2938,8 +2986,7 @@ issue_error: nasm_error(severity, "%s", p); nasm_free(p); } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; } CASE_PP_IF: @@ -2955,9 +3002,8 @@ issue_error: cond->state = j; istk->conds = cond; if(istk->mstk) - istk->mstk->condcnt ++; - free_tlist(origline); - return DIRECTIVE_FOUND; + istk->mstk->condcnt++; + break; CASE_PP_ELIF: if (!istk->conds) @@ -3022,8 +3068,7 @@ issue_error: istk->conds->state = COND_NEVER; break; } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_ENDIF: if (tline->next) @@ -3035,9 +3080,8 @@ issue_error: istk->conds = cond->next; nasm_free(cond); if(istk->mstk) - istk->mstk->condcnt --; - free_tlist(origline); - return DIRECTIVE_FOUND; + istk->mstk->condcnt--; + break; case PP_IRMACRO: case PP_IMACRO: @@ -3045,17 +3089,15 @@ issue_error: /* fall through */ case PP_RMACRO: case PP_MACRO: - if (defining) { + if (defining) nasm_fatal("`%s': already defining a macro", dname); - return DIRECTIVE_FOUND; - } + defining = nasm_zalloc(sizeof(MMacro)); defining->max_depth = nasm_limit[LIMIT_MACRO_LEVELS]; defining->casesense = casesense; if (!parse_mmacro_spec(tline, defining, dname)) { nasm_free(defining); - defining = NULL; - return DIRECTIVE_FOUND; + goto done; } src_get(&defining->xline, &defining->fname); @@ -3069,25 +3111,23 @@ issue_error: || mmac->plus)) { nasm_warn(WARN_OTHER, "redefining multi-line macro `%s'", defining->name); - return DIRECTIVE_FOUND; + break; } mmac = mmac->next; } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_ENDM: case PP_ENDMACRO: - if (! (defining && defining->name)) { + if (!(defining && defining->name)) { nasm_nonfatal("`%s': not defining a macro", tline->text); - return DIRECTIVE_FOUND; + goto done; } mmhead = (MMacro **) hash_findi_add(&mmacros, defining->name); defining->next = *mmhead; *mmhead = defining; defining = NULL; - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_EXITMACRO: /* @@ -3113,8 +3153,7 @@ issue_error: } else { nasm_nonfatal("`%%exitmacro' not within `%%macro' block"); } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_UNIMACRO: casesense = false; @@ -3126,7 +3165,7 @@ issue_error: spec.casesense = casesense; if (!parse_mmacro_spec(tline, &spec, dname)) { - return DIRECTIVE_FOUND; + goto done; } mmac_p = (MMacro **) hash_findi(&mmacros, spec.name, NULL); while (mmac_p && *mmac_p) { @@ -3142,9 +3181,8 @@ issue_error: mmac_p = &mmac->next; } } - free_tlist(origline); free_tlist(spec.dlist); - return DIRECTIVE_FOUND; + break; } case PP_ROTATE: @@ -3157,7 +3195,6 @@ issue_error: } t = expand_smacro(tline->next); tline->next = NULL; - free_tlist(origline); pps.tptr = tline = t; pps.ntokens = -1; tokval.t_type = TOKEN_INVALID; @@ -3188,7 +3225,7 @@ issue_error: mmac->rotate = rotate; } - return DIRECTIVE_FOUND; + break; case PP_REP: nolist = false; @@ -3211,15 +3248,13 @@ issue_error: /* XXX: really critical?! */ evalresult = evaluate(ppscan, &pps, &tokval, NULL, true, NULL); - if (!evalresult) { - free_tlist(origline); - return DIRECTIVE_FOUND; - } + if (!evalresult) + goto done; if (tokval.t_type) nasm_warn(WARN_OTHER, "trailing garbage after expression ignored"); if (!is_simple(evalresult)) { nasm_nonfatal("non-constant value given to `%%rep'"); - return DIRECTIVE_FOUND; + goto done; } count = reloc_value(evalresult); if (count > nasm_limit[LIMIT_REP]) { @@ -3242,8 +3277,6 @@ issue_error: nasm_nonfatal("`%%rep' expects a repeat count"); count = 0; } - free_tlist(origline); - tmp_defining = defining; nasm_new(defining); defining->nolist = nolist; @@ -3251,12 +3284,12 @@ issue_error: defining->next_active = istk->mstk; defining->rep_nest = tmp_defining; src_get(&defining->xline, &defining->fname); - return DIRECTIVE_FOUND; + break; case PP_ENDREP: if (!defining || defining->name) { nasm_nonfatal("`%%endrep': no matching `%%rep'"); - return DIRECTIVE_FOUND; + goto done; } /* @@ -3281,8 +3314,7 @@ issue_error: lfmt->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO, 0); tmp_defining = defining; defining = defining->rep_nest; - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_EXITREP: /* @@ -3298,31 +3330,25 @@ issue_error: l->finishes->in_progress = 1; else nasm_nonfatal("`%%exitrep' not within `%%rep' block"); - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_IDEFINE: case PP_IXDEFINE: + case PP_IDEFALIAS: casesense = false; /* fall through */ case PP_DEFINE: case PP_XDEFINE: + case PP_DEFALIAS: { bool have_eval_params = false; bool *eval_params = NULL; + SMacro tmpl; - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%s' expects a macro identifier", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; - } + if (!(mname = get_id(&tline, i, NULL))) + goto done; - ctx = get_ctx(tline->text, &mname); + nasm_zero(tmpl); last = tline; param_start = tline = tline->next; nparam = 0; @@ -3337,8 +3363,7 @@ issue_error: skip_white_(tline); if (!tline) { nasm_nonfatal("parameter identifier expected"); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } if (tok_is_(tline, "=")) { have_eval_params = true; @@ -3364,8 +3389,7 @@ issue_error: } else { nasm_nonfatal("`%s': parameter identifier expected", tline->text); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } } tline->type = tok_smac_param(nparam++); @@ -3376,8 +3400,7 @@ issue_error: } else { if (!tok_is_(tline, ")")) { nasm_nonfatal("`)' expected to terminate macro template"); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } break; } @@ -3402,25 +3425,45 @@ issue_error: last = tline, tline = tline->next; last->next = NULL; - /* Expand the macro definition now for %xdefine and %ixdefine */ - if ((i == PP_XDEFINE) || (i == PP_IXDEFINE)) - tline = expand_smacro(tline); + if (unlikely(i == PP_DEFALIAS || i == PP_IDEFALIAS)) { + macro_start = tline; + if (!is_macro_id(macro_start)) { + nasm_nonfatal("`%s' expects a macro identifier to alias", + dname); + goto done; + } + tt = macro_start->next; + macro_start->next = NULL; + tline = tline->next; + skip_white_(tline); + if (tline && tline->type) { + nasm_warn(WARN_OTHER, + "trailing garbage after aliasing identifier ignored"); + } + free_tlist(tt); + tmpl.alias = true; + } else { + /* Expand the macro definition now for %xdefine and %ixdefine */ + if (i == PP_XDEFINE || i == PP_IXDEFINE) + tline = expand_smacro(tline); - macro_start = NULL; - t = tline; - while (t) { - if (t->type == TOK_ID) { - list_for_each(tt, param_start) - if (is_smac_param(tt->type) && - tt->len == t->len && - !memcmp(tt->text, t->text, tt->len)) - t->type = tt->type; + macro_start = NULL; + t = tline; + while (t) { + if (t->type == TOK_ID) { + list_for_each(tt, param_start) + if (is_smac_param(tt->type) && + tt->len == t->len && + !memcmp(tt->text, t->text, tt->len)) + t->type = tt->type; + } + tt = t->next; + t->next = macro_start; + macro_start = t; + t = tt; } - tt = t->next; - t->next = macro_start; - macro_start = t; - t = tt; } + /* * Good. We now have a macro name, a parameter count, and a * token list (in reverse order) for an expansion. We ought @@ -3429,48 +3472,29 @@ issue_error: * carefully re-terminated after chopping off the expansion * from the end). */ - define_smacro(ctx, mname, casesense, nparam, eval_params, macro_start); - - free_tlist(origline); - return DIRECTIVE_FOUND; - } + tmpl.nparam = nparam; + tmpl.eval_param = eval_params; + define_smacro(mname, casesense, macro_start, &tmpl); + break; + } case PP_UNDEF: - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%%undef' expects a macro identifier"); - free_tlist(origline); - return DIRECTIVE_FOUND; - } + case PP_UNDEFALIAS: + if (!(mname = get_id(&tline, i, NULL))) + goto done; if (tline->next) nasm_warn(WARN_OTHER, "trailing garbage after macro name ignored"); - /* Find the context that symbol belongs to */ - ctx = get_ctx(tline->text, &mname); - undef_smacro(ctx, mname); - free_tlist(origline); - return DIRECTIVE_FOUND; + undef_smacro(mname, i == PP_UNDEFALIAS); + break; case PP_IDEFSTR: casesense = false; /* fall through */ case PP_DEFSTR: - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%s' expects a macro identifier", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; - } + if (!(mname = get_id(&tline, i, NULL))) + goto done; - ctx = get_ctx(tline->text, &mname); last = tline; tline = expand_smacro(tline->next); last->next = NULL; @@ -3487,25 +3511,16 @@ issue_error: * zero, and a string token to use as an expansion. Create * and store an SMacro. */ - define_smacro(ctx, mname, casesense, 0, NULL, macro_start); - free_tlist(origline); - return DIRECTIVE_FOUND; + define_smacro(mname, casesense, macro_start, NULL); + break; case PP_IDEFTOK: casesense = false; /* fall through */ case PP_DEFTOK: - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%s' expects a macro identifier as first parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; - } - ctx = get_ctx(tline->text, &mname); + if (!(mname = get_id(&tline, i, NULL))) + goto done; + last = tline; tline = expand_smacro(tline->next); last->next = NULL; @@ -3515,10 +3530,9 @@ issue_error: t = t->next; /* t should now point to the string */ if (!tok_type_(t, TOK_STRING)) { - nasm_nonfatal("`%s` requires string as second parameter", dname); + nasm_nonfatal("`%s' requires string as second parameter", dname); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } /* @@ -3534,10 +3548,9 @@ issue_error: * zero, and a numeric token to use as an expansion. Create * and store an SMacro. */ - define_smacro(ctx, mname, casesense, 0, NULL, macro_start); + define_smacro(mname, casesense, macro_start, NULL); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_IPATHSEARCH: casesense = false; @@ -3546,17 +3559,9 @@ issue_error: { const char *found_path; - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%s' expects a macro identifier as first parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; - } - ctx = get_ctx(tline->text, &mname); + if (!(mname = get_id(&tline, i, NULL))) + goto done; + last = tline; tline = expand_smacro(tline->next); last->next = NULL; @@ -3569,8 +3574,7 @@ issue_error: t->type != TOK_INTERNAL_STRING)) { nasm_nonfatal("`%s' expects a file name", dname); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; /* but we did _something_ */ + goto done; } if (t->next) nasm_warn(WARN_OTHER, "trailing garbage after `%s' ignored", dname); @@ -3588,27 +3592,18 @@ issue_error: * zero, and a string token to use as an expansion. Create * and store an SMacro. */ - define_smacro(ctx, mname, casesense, 0, NULL, macro_start); + define_smacro(mname, casesense, macro_start, NULL); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + break; } case PP_ISTRLEN: casesense = false; /* fall through */ case PP_STRLEN: - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%s' expects a macro identifier as first parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; - } - ctx = get_ctx(tline->text, &mname); + if (!(mname = get_id(&tline, i, NULL))) + goto done; + last = tline; tline = expand_smacro(tline->next); last->next = NULL; @@ -3631,7 +3626,7 @@ issue_error: * zero, and a numeric token to use as an expansion. Create * and store an SMacro. */ - define_smacro(ctx, mname, casesense, 0, NULL, macro_start); + define_smacro(mname, casesense, macro_start, NULL); free_tlist(tline); free_tlist(origline); return DIRECTIVE_FOUND; @@ -3640,17 +3635,9 @@ issue_error: casesense = false; /* fall through */ case PP_STRCAT: - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%s' expects a macro identifier as first parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; - } - ctx = get_ctx(tline->text, &mname); + if (!(mname = get_id(&tline, i, NULL))) + goto done; + last = tline; tline = expand_smacro(tline->next); last->next = NULL; @@ -3670,8 +3657,7 @@ issue_error: default: nasm_nonfatal("non-string passed to `%s': %s", dname, t->text); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } } @@ -3690,10 +3676,9 @@ issue_error: */ macro_start = make_tok_qstr(pp); nasm_free(pp); - define_smacro(ctx, mname, casesense, 0, NULL, macro_start); + define_smacro(mname, casesense, macro_start, NULL); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + break; case PP_ISUBSTR: casesense = false; @@ -3703,17 +3688,9 @@ issue_error: int64_t start, count; size_t len; - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%s' expects a macro identifier as first parameter", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; - } - ctx = get_ctx(tline->text, &mname); + if (!(mname = get_id(&tline, i, NULL))) + goto done; + last = tline; tline = expand_smacro(tline->next); last->next = NULL; @@ -3727,8 +3704,7 @@ issue_error: if (!tok_type_(t, TOK_STRING)) { nasm_nonfatal("`%s' requires string as second parameter", dname); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } pps.tptr = t->next; @@ -3737,13 +3713,11 @@ issue_error: evalresult = evaluate(ppscan, &pps, &tokval, NULL, true, NULL); if (!evalresult) { free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } else if (!is_simple(evalresult)) { nasm_nonfatal("non-constant value given to `%s'", dname); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } start = evalresult->value - 1; @@ -3756,13 +3730,11 @@ issue_error: evalresult = evaluate(ppscan, &pps, &tokval, NULL, true, NULL); if (!evalresult) { free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } else if (!is_simple(evalresult)) { nasm_nonfatal("non-constant value given to `%s'", dname); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } count = evalresult->value; } @@ -3789,27 +3761,18 @@ issue_error: * zero, and a numeric token to use as an expansion. Create * and store an SMacro. */ - define_smacro(ctx, mname, casesense, 0, NULL, macro_start); + define_smacro(mname, casesense, macro_start, NULL); free_tlist(tline); - free_tlist(origline); - return DIRECTIVE_FOUND; + break; } case PP_IASSIGN: casesense = false; /* fall through */ case PP_ASSIGN: - tline = tline->next; - skip_white_(tline); - tline = expand_id(tline); - if (!tline || (tline->type != TOK_ID && - (tline->type != TOK_PREPROC_ID || - tline->text[1] != '$'))) { - nasm_nonfatal("`%s' expects a macro identifier", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; - } - ctx = get_ctx(tline->text, &mname); + if (!(mname = get_id(&tline, i, NULL))) + goto done; + last = tline; tline = expand_smacro(tline->next); last->next = NULL; @@ -3819,10 +3782,8 @@ issue_error: tokval.t_type = TOKEN_INVALID; evalresult = evaluate(ppscan, &pps, &tokval, NULL, true, NULL); free_tlist(tline); - if (!evalresult) { - free_tlist(origline); - return DIRECTIVE_FOUND; - } + if (!evalresult) + goto done; if (tokval.t_type) nasm_warn(WARN_OTHER, "trailing garbage after expression ignored"); @@ -3840,24 +3801,21 @@ issue_error: * zero, and a numeric token to use as an expansion. Create * and store an SMacro. */ - define_smacro(ctx, mname, casesense, 0, NULL, macro_start); - free_tlist(origline); - return DIRECTIVE_FOUND; + define_smacro(mname, casesense, macro_start, NULL); + break; case PP_LINE: /* * Syntax is `%line nnn[+mmm] [filename]' */ - if (unlikely(pp_noline)) { - free_tlist(origline); - return DIRECTIVE_FOUND; - } + if (unlikely(pp_noline)) + goto done; + tline = tline->next; skip_white_(tline); if (!tok_type_(tline, TOK_NUMBER)) { nasm_nonfatal("`%s' expects line number", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } k = readnum(tline->text, &err); m = 1; @@ -3866,8 +3824,7 @@ issue_error: tline = tline->next; if (!tok_type_(tline, TOK_NUMBER)) { nasm_nonfatal("`%s' expects line increment", dname); - free_tlist(origline); - return DIRECTIVE_FOUND; + goto done; } m = readnum(tline->text, &err); tline = tline->next; @@ -3880,13 +3837,12 @@ issue_error: src_set_fname(fname); nasm_free(fname); } - free_tlist(origline); - return DIRECTIVE_FOUND; + break; + } - default: - nasm_nonfatal("preprocessor directive `%s' not yet implemented", dname); +done: + free_tlist(origline); return DIRECTIVE_FOUND; - } } /* @@ -5328,7 +5284,7 @@ stdmac_ptr(const SMacro *s, Token **params, unsigned int nparams) /* Add magic standard macros */ struct magic_macros { const char *name; - int nparams; + int nparam; ExpandSMacro func; }; static const struct magic_macros magic_macros[] = @@ -5343,11 +5299,14 @@ static const struct magic_macros magic_macros[] = static void pp_add_magic_stdmac(void) { const struct magic_macros *m; - SMacro *s; + SMacro tmpl; + + nasm_zero(tmpl); for (m = magic_macros; m->name; m++) { - s = define_smacro(NULL, m->name, true, m->nparams, NULL, NULL); - s->expand = m->func; + tmpl.nparam = m->nparam; + tmpl.expand = m->func; + define_smacro(m->name, true, NULL, &tmpl); } } @@ -5428,7 +5387,7 @@ pp_reset(const char *file, enum preproc_mode mode, struct strlist *dep_list) panic(); } - define_smacro(NULL, "__PASS__", true, 0, NULL, make_tok_num(apass)); + define_smacro("__PASS__", true, make_tok_num(apass), NULL); } static void pp_init(void) |