summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Kanios <keith@kanios.net>2010-08-01 02:30:33 -0500
committerKeith Kanios <keith@kanios.net>2010-08-01 02:30:33 -0500
commit973d4a49e81fa4fc1d246d34582ef1713dcd2628 (patch)
treea89879518e6781648ceab91cde342070a44d5466
parentd7b654c73da25a597f526303b967fcb713c0ae20 (diff)
downloadnasm-973d4a49e81fa4fc1d246d34582ef1713dcd2628.tar.gz
preproc.c: initial branch of revamped preprocessor
-rw-r--r--preproc.c1456
1 files changed, 758 insertions, 698 deletions
diff --git a/preproc.c b/preproc.c
index d75b58eb..44c44ec7 100644
--- a/preproc.c
+++ b/preproc.c
@@ -83,7 +83,8 @@
typedef struct SMacro SMacro;
typedef struct MMacro MMacro;
-typedef struct MMacroInvocation MMacroInvocation;
+typedef struct ExpDef ExpDef;
+typedef struct ExpInv ExpInv;
typedef struct Context Context;
typedef struct Token Token;
typedef struct Blocks Blocks;
@@ -114,64 +115,6 @@ struct SMacro {
};
/*
- * Store the definition of a multi-line macro. This is also used to
- * store the interiors of `%rep...%endrep' blocks, which are
- * effectively self-re-invoking multi-line macros which simply
- * don't have a name or bother to appear in the hash tables. %rep
- * blocks are signified by having a NULL `name' field.
- *
- * In a MMacro describing a `%rep' block, the `in_progress' field
- * isn't merely boolean, but gives the number of repeats left to
- * run.
- *
- * The `next' field is used for storing MMacros in hash tables; the
- * `next_active' field is for stacking them on istk entries.
- *
- * When a MMacro is being expanded, `params', `iline', `nparam',
- * `paramlen', `rotate' and `unique' are local to the invocation.
- */
-struct MMacro {
- MMacro *next;
- MMacroInvocation *prev; /* previous invocation */
- char *name;
- int nparam_min, nparam_max;
- bool casesense;
- bool plus; /* is the last parameter greedy? */
- bool nolist; /* is this macro listing-inhibited? */
- int64_t in_progress; /* is this macro currently being expanded? */
- int32_t max_depth; /* maximum number of recursive expansions allowed */
- Token *dlist; /* All defaults as one list */
- Token **defaults; /* Parameter default pointers */
- int ndefs; /* number of default parameters */
- Line *expansion;
-
- MMacro *next_active;
- MMacro *rep_nest; /* used for nesting %rep */
- Token **params; /* actual parameters */
- Token *iline; /* invocation line */
- unsigned int nparam, rotate;
- int *paramlen;
- uint64_t unique;
- int lineno; /* Current line number on expansion */
- uint64_t condcnt; /* number of if blocks... */
-};
-
-
-/* Store the definition of a multi-line macro, as defined in a
- * previous recursive macro expansion.
- */
-struct MMacroInvocation {
- MMacroInvocation *prev; /* previous invocation */
- Token **params; /* actual parameters */
- Token *iline; /* invocation line */
- unsigned int nparam, rotate;
- int *paramlen;
- uint64_t unique;
- uint64_t condcnt;
-};
-
-
-/*
* The context stack is composed of a linked list of these.
*/
struct Context {
@@ -246,11 +189,85 @@ struct Token {
*/
struct Line {
Line *next;
- MMacro *finishes;
Token *first;
};
/*
+ * Expansion Types
+ */
+enum pp_exp_type {
+ EXP_NONE = 0, EXP_PREDEF,
+ EXP_MMACRO, EXP_REP,
+ EXP_IF,
+ EXP_MAX = INT_MAX /* Keep compiler from reducing the range */
+};
+
+/*
+ * Store the definition of an expansion. This is also used to
+ * store the interiors of `%rep...%endrep' blocks, which are
+ * effectively self-re-invoking multi-line macros which simply
+ * don't have a name or bother to appear in the hash tables. %rep
+ * blocks are signified by having a NULL `name' field.
+ *
+ * In a ExpDef describing a `%rep' block, the `cur_depth' field
+ * isn't merely boolean, but gives the number of repeats left to
+ * run.
+ *
+ * The `next' field is used for storing ExpDef in hash tables; the
+ * `prev' field is for the `expansions` linked-list.
+ */
+struct ExpDef {
+ ExpDef *prev; /* previous definition */
+ ExpDef *next; /* next in hash table */
+ enum pp_exp_type type; /* expansion type */
+ char *name;
+ int nparam_min, nparam_max;
+ bool casesense;
+ bool plus; /* is the last parameter greedy? */
+ bool nolist; /* is this expansion listing-inhibited? */
+ Token *dlist; /* All defaults as one list */
+ Token **defaults; /* Parameter default pointers */
+ int ndefs; /* number of default parameters */
+
+ Line *label;
+ Line *line;
+ Line *last;
+
+ uint32_t def_depth; /* current number of definition pairs deep */
+ uint32_t cur_depth; /* current number of expansions */
+ uint32_t max_depth; /* maximum number of expansions allowed */
+
+ int state; /* condition state */
+ bool ignoring; /* ignoring definition lines */
+};
+
+/*
+ * Store the invocation of an expansion.
+ *
+ * The `prev' field is for the `istk->expansion` linked-list.
+ *
+ * When an expansion is being expanded, `params', `iline', `nparam',
+ * `paramlen', `rotate' and `unique' are local to the invocation.
+ */
+struct ExpInv {
+ ExpInv *prev; /* previous invocation */
+ enum pp_exp_type type; /* expansion type */
+ ExpDef *def; /* pointer to expansion definition */
+ Line *label; /* pointer to label */
+ char *label_text; /* pointer to label text */
+ Line *current; /* pointer to current line in invocation */
+
+ Token **params; /* actual parameters */
+ Token *iline; /* invocation line */
+ unsigned int nparam, rotate;
+ int *paramlen;
+
+ uint64_t unique;
+ bool emitting;
+ int lineno; /* current line number in expansion */
+};
+
+/*
* To handle an arbitrary level of file inclusion, we maintain a
* stack (ie linked list) of these things.
*/
@@ -258,10 +275,9 @@ struct Include {
Include *next;
FILE *fp;
Cond *conds;
- Line *expansion;
+ ExpInv *expansion;
char *fname;
int lineno, lineinc;
- MMacro *mstk; /* stack of active macros/reps */
};
/*
@@ -281,10 +297,6 @@ struct IncPath {
* included from within the true branch of a `%if' won't terminate
* it and cause confusion: instead, rightly, it'll cause an error.)
*/
-struct Cond {
- Cond *next;
- int state;
-};
enum {
/*
* These states are for use just after %if or %elif: IF_TRUE
@@ -349,15 +361,6 @@ static const enum pp_conds inverse_ccs[] = {
c_Z, c_NO, c_NP, c_PO, c_PE, -1, c_NS, c_NZ
};
-/*
- * Directive names.
- */
-/* If this is a an IF, ELIF, ELSE or ENDIF keyword */
-static int is_condition(enum preproc_token arg)
-{
- return PP_IS_COND(arg) || (arg == PP_ELSE) || (arg == PP_ENDIF);
-}
-
/* For TASM compatibility we need to be able to recognise TASM compatible
* conditional compilation directives. Using the NASM pre-processor does
* not work, so we look for them specifically from the following list and
@@ -394,9 +397,9 @@ static bool do_predef;
static ListGen *list;
/*
- * The current set of multi-line macros we have defined.
+ * The current set of expansion definitions we have defined.
*/
-static struct hash_table mmacros;
+static struct hash_table expdefs;
/*
* The current set of single-line macros we have defined.
@@ -404,10 +407,14 @@ static struct hash_table mmacros;
static struct hash_table smacros;
/*
- * The multi-line macro we are currently defining, or the %rep
- * block we are currently reading, if any.
+ * Linked List of all active expansion definitions
*/
-static MMacro *defining;
+struct ExpDef *expansions = NULL;
+
+/*
+ * The expansion we are currently defining
+ */
+static ExpDef *defining = NULL;
static uint64_t nested_mac_count;
static uint64_t nested_rep_count;
@@ -457,7 +464,11 @@ static void *new_Block(size_t size);
static void delete_Blocks(void);
static Token *new_Token(Token * next, enum pp_token_type type,
const char *text, int txtlen);
+static Token *copy_Token(Token * tline);
static Token *delete_Token(Token * t);
+static Line *new_Line(void);
+static ExpDef *new_ExpDef(void);
+static ExpInv *new_ExpInv(void);
/*
* Macros for safe checking of token pointers, avoid *(NULL)
@@ -590,15 +601,15 @@ static void free_llist(Line * list)
}
/*
- * Free an MMacro
+ * Free an ExpDef
*/
-static void free_mmacro(MMacro * m)
+static void free_expdef(ExpDef * ed)
{
- nasm_free(m->name);
- free_tlist(m->dlist);
- nasm_free(m->defaults);
- free_llist(m->expansion);
- nasm_free(m);
+ nasm_free(ed->name);
+ free_tlist(ed->dlist);
+ nasm_free(ed->defaults);
+ free_llist(ed->line);
+ nasm_free(ed);
}
/*
@@ -621,25 +632,25 @@ static void free_smacro_table(struct hash_table *smt)
hash_free(smt);
}
-static void free_mmacro_table(struct hash_table *mmt)
+static void free_mmacro_table(struct hash_table *edt)
{
- MMacro *m, *tmp;
+ ExpDef *ed, *tmp;
const char *key;
struct hash_tbl_node *it = NULL;
it = NULL;
- while ((m = hash_iterate(mmt, &it, &key)) != NULL) {
+ while ((ed = hash_iterate(edt, &it, &key)) != NULL) {
nasm_free((void *)key);
- list_for_each_safe(m ,tmp, m)
- free_mmacro(m);
+ list_for_each_safe(ed ,tmp, ed)
+ free_expdef(ed);
}
- hash_free(mmt);
+ hash_free(edt);
}
static void free_macros(void)
{
free_smacro_table(&smacros);
- free_mmacro_table(&mmacros);
+ free_mmacro_table(&expdefs);
}
/*
@@ -648,7 +659,7 @@ static void free_macros(void)
static void init_macros(void)
{
hash_init(&smacros, HASH_LARGE);
- hash_init(&mmacros, HASH_LARGE);
+ hash_init(&expdefs, HASH_LARGE);
}
/*
@@ -698,7 +709,7 @@ hash_findix(struct hash_table *hash, const char *str)
}
/*
- * read line from standart macros set,
+ * read line from standard macros set,
* if there no more left -- return NULL
*/
static char *line_from_stdmac(void)
@@ -739,6 +750,7 @@ static char *line_from_stdmac(void)
stdmacpos = extrastdmac;
any_extrastdmac = false;
} else if (do_predef) {
+ ExpInv *ei;
Line *pd, *l;
Token *head, **tail, *t;
@@ -757,12 +769,14 @@ static char *line_from_stdmac(void)
tail = &(*tail)->next;
}
- l = nasm_malloc(sizeof(Line));
- l->next = istk->expansion;
- l->first = head;
- l->finishes = NULL;
-
- istk->expansion = l;
+ l = new_Line();
+ l->first = head;
+ ei = new_ExpInv();
+ ei->type = EXP_PREDEF;
+ ei->current = l;
+ ei->emitting = true;
+ ei->prev = istk->expansion;
+ istk->expansion = ei;
}
do_predef = false;
}
@@ -1192,6 +1206,34 @@ static Token *new_Token(Token * next, enum pp_token_type type,
return t;
}
+static Token *copy_Token(Token * tline)
+{
+ Token *t, *tt, *first = NULL, *prev = NULL;
+ int i;
+ for (tt = tline; tt != NULL; tt = tt->next) {
+ if (!freeTokens) {
+ freeTokens = (Token *) new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
+ for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
+ freeTokens[i].next = &freeTokens[i + 1];
+ freeTokens[i].next = NULL;
+ }
+ t = freeTokens;
+ freeTokens = t->next;
+ t->next = NULL;
+ t->text = ((tt->text != NULL) ? strdup(tt->text) : NULL);
+ t->a.mac = tt->a.mac;
+ t->a.len = tt->a.len;
+ t->type = tt->type;
+ if (prev != NULL) {
+ prev->next = t;
+ } else {
+ first = t;
+ }
+ prev = t;
+ }
+ return first;
+}
+
static Token *delete_Token(Token * t)
{
Token *next = t->next;
@@ -1280,6 +1322,72 @@ static char *detoken(Token * tlist, bool expand_locals)
}
/*
+ * Initialize a new Line
+ */
+static Line *new_Line(void)
+{
+ Line *l = nasm_malloc(sizeof(Line));
+ l->next = NULL;
+ l->first = NULL;
+ return l;
+}
+
+
+/*
+ * Initialize a new Expansion Definition
+ */
+static ExpDef *new_ExpDef(void)
+{
+ ExpDef *ed = nasm_malloc(sizeof(ExpDef));
+ ed->prev = NULL;
+ ed->next = NULL;
+ ed->type = EXP_NONE;
+ ed->name = NULL;
+ ed->nparam_min = 0;
+ ed->nparam_max = 0;
+ ed->casesense = true;
+ ed->plus = false;
+ ed->label = NULL;
+ ed->line = NULL;
+ ed->last = NULL;
+ ed->dlist = NULL;
+ ed->defaults = NULL;
+ ed->ndefs = 0;
+ ed->state = COND_NEVER;
+ ed->nolist = false;
+ ed->def_depth = 0;
+ ed->cur_depth = 0;
+ ed->max_depth = 0;
+ ed->ignoring = false;
+ return ed;
+}
+
+
+/*
+ * Initialize a new Expansion Instance
+ */
+static ExpInv *new_ExpInv(void)
+{
+ unique ++;
+ ExpInv *ei = nasm_malloc(sizeof(ExpInv));
+ ei->prev = NULL;
+ ei->type = EXP_NONE;
+ ei->def = NULL;
+ ei->label = NULL;
+ ei->label_text = NULL;
+ ei->current = NULL;
+ ei->params = NULL;
+ ei->iline = NULL;
+ ei->nparam = 0;
+ ei->rotate = 0;
+ ei->paramlen = NULL;
+ ei->unique = unique;
+ ei->emitting = false;
+ ei->lineno = 0;
+ return ei;
+}
+
+/*
* A scanner, suitable for use by the expression evaluator, which
* operates on a line of Tokens. Expects a pointer to a pointer to
* the first token in the line to be passed in as its private_data
@@ -1787,7 +1895,7 @@ static bool if_condition(Token * tline, enum preproc_token ct)
case PPC_IFMACRO:
{
bool found = false;
- MMacro searching, *mmac;
+ ExpDef searching, *ed;
skip_white_(tline);
tline = expand_id(tline);
@@ -1800,9 +1908,9 @@ static bool if_condition(Token * tline, enum preproc_token ct)
searching.casesense = true;
searching.plus = false;
searching.nolist = false;
- searching.in_progress = 0;
+ //searching.in_progress = 0;
searching.max_depth = 0;
- searching.rep_nest = NULL;
+ //searching.rep_nest = NULL;
searching.nparam_min = 0;
searching.nparam_max = INT_MAX;
tline = expand_smacro(tline->next);
@@ -1843,17 +1951,17 @@ static bool if_condition(Token * tline, enum preproc_token ct)
tline = tline->next;
searching.plus = true;
}
- mmac = (MMacro *) hash_findix(&mmacros, searching.name);
- while (mmac) {
- if (!strcmp(mmac->name, searching.name) &&
- (mmac->nparam_min <= searching.nparam_max
+ ed = (ExpDef *) hash_findix(&expdefs, searching.name);
+ while (ed != NULL) {
+ if (!strcmp(ed->name, searching.name) &&
+ (ed->nparam_min <= searching.nparam_max
|| searching.plus)
- && (searching.nparam_min <= mmac->nparam_max
- || mmac->plus)) {
+ && (searching.nparam_min <= ed->nparam_max
+ || ed->plus)) {
found = true;
break;
}
- mmac = mmac->next;
+ ed = ed->next;
}
if (tline && tline->next)
error(ERR_WARNING|ERR_PASS1,
@@ -2018,7 +2126,7 @@ static void undef_smacro(Context *ctx, const char *mname)
/*
* Parse a mmacro specification.
*/
-static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive)
+static bool parse_mmacro_spec(Token *tline, ExpDef *def, const char *directive)
{
bool err;
@@ -2030,12 +2138,11 @@ static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive)
return false;
}
- def->prev = NULL;
def->name = nasm_strdup(tline->text);
def->plus = false;
def->nolist = false;
- def->in_progress = 0;
- def->rep_nest = NULL;
+// def->in_progress = 0;
+// def->rep_nest = NULL;
def->nparam_min = 0;
def->nparam_max = 0;
@@ -2089,7 +2196,7 @@ static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive)
def->dlist = NULL;
def->defaults = NULL;
}
- def->expansion = NULL;
+ def->line = NULL;
if (def->defaults && def->ndefs > def->nparam_max - def->nparam_min &&
!def->plus)
@@ -2138,13 +2245,11 @@ static int do_directive(Token * tline)
const char *mname;
Include *inc;
Context *ctx;
- Cond *cond;
- MMacro *mmac, **mmhead;
Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
- Line *l;
struct tokenval tokval;
expr *evalresult;
- MMacro *tmp_defining; /* Used when manipulating rep_nest */
+ ExpDef *ed, *eed, **edhead;
+ ExpInv *ei, *eei;
int64_t count;
size_t len;
int severity;
@@ -2159,72 +2264,15 @@ static int do_directive(Token * tline)
i = pp_token_hash(tline->text);
- /*
- * FIXME: We zap execution of PP_RMACRO, PP_IRMACRO, PP_EXITMACRO
- * since they are known to be buggy at moment, we need to fix them
- * in future release (2.09-2.10)
- */
- if (i == PP_RMACRO || i == PP_RMACRO || i == PP_EXITMACRO) {
- error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
- tline->text);
- return NO_DIRECTIVE_FOUND;
- }
-
- /*
- * If we're in a non-emitting branch of a condition construct,
- * or walking to the end of an already terminated %rep block,
- * we should ignore all directives except for condition
- * directives.
- */
- if (((istk->conds && !emitting(istk->conds->state)) ||
- (istk->mstk && !istk->mstk->in_progress)) && !is_condition(i)) {
- return NO_DIRECTIVE_FOUND;
- }
-
- /*
- * If we're defining a macro or reading a %rep block, we should
- * ignore all directives except for %macro/%imacro (which nest),
- * %endm/%endmacro, and (only if we're in a %rep block) %endrep.
- * If we're in a %rep block, another %rep nests, so should be let through.
- */
- if (defining && i != PP_MACRO && i != PP_IMACRO &&
- i != PP_RMACRO && i != PP_IRMACRO &&
- i != PP_ENDMACRO && i != PP_ENDM &&
- (defining->name || (i != PP_ENDREP && i != PP_REP))) {
- return NO_DIRECTIVE_FOUND;
- }
-
- if (defining) {
- if (i == PP_MACRO || i == PP_IMACRO ||
- i == PP_RMACRO || i == PP_IRMACRO) {
- nested_mac_count++;
- return NO_DIRECTIVE_FOUND;
- } else if (nested_mac_count > 0) {
- if (i == PP_ENDMACRO) {
- nested_mac_count--;
- return NO_DIRECTIVE_FOUND;
- }
- }
- if (!defining->name) {
- if (i == PP_REP) {
- nested_rep_count++;
- return NO_DIRECTIVE_FOUND;
- } else if (nested_rep_count > 0) {
- if (i == PP_ENDREP) {
- nested_rep_count--;
- return NO_DIRECTIVE_FOUND;
- }
- }
- }
- }
-
switch (i) {
case PP_INVALID:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
tline->text);
return NO_DIRECTIVE_FOUND; /* didn't get it */
case PP_STACKSIZE:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
/* Directive to tell NASM what the default stack size is. The
* default is for a 16-bit stack, and this can be overriden with
* %stacksize large.
@@ -2274,6 +2322,7 @@ static int do_directive(Token * tline)
return DIRECTIVE_FOUND;
case PP_ARG:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
/* TASM like ARG directive to define arguments to functions, in
* the following form:
*
@@ -2343,6 +2392,7 @@ static int do_directive(Token * tline)
return DIRECTIVE_FOUND;
case PP_LOCAL:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
/* TASM like LOCAL directive to define local variables for a
* function, in the following form:
*
@@ -2424,6 +2474,7 @@ static int do_directive(Token * tline)
return DIRECTIVE_FOUND;
case PP_CLEAR:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
if (tline->next)
error(ERR_WARNING|ERR_PASS1,
"trailing garbage after `%%clear' ignored");
@@ -2433,6 +2484,7 @@ static int do_directive(Token * tline)
return DIRECTIVE_FOUND;
case PP_DEPEND:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
t = tline->next = expand_smacro(tline->next);
skip_white_(t);
if (!t || (t->type != TOK_STRING &&
@@ -2458,6 +2510,7 @@ static int do_directive(Token * tline)
return DIRECTIVE_FOUND;
case PP_INCLUDE:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
t = tline->next = expand_smacro(tline->next);
skip_white_(t);
@@ -2475,7 +2528,6 @@ static int do_directive(Token * tline)
nasm_unquote_cstr(p, i);
inc = nasm_malloc(sizeof(Include));
inc->next = istk;
- inc->conds = NULL;
inc->fp = inc_fopen(p, dephead, &deptail, pass == 0);
if (!inc->fp) {
/* -MG given but file not found */
@@ -2485,7 +2537,6 @@ static int do_directive(Token * tline)
inc->lineno = src_set_linnum(0);
inc->lineinc = 1;
inc->expansion = NULL;
- inc->mstk = NULL;
istk = inc;
list->uplevel(LIST_INCLUDE);
}
@@ -2493,6 +2544,7 @@ static int do_directive(Token * tline)
return DIRECTIVE_FOUND;
case PP_USE:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
{
static macros_t *use_pkg;
const char *pkg_macro = NULL;
@@ -2528,6 +2580,7 @@ static int do_directive(Token * tline)
case PP_PUSH:
case PP_REPL:
case PP_POP:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
tline = tline->next;
skip_white_(tline);
tline = expand_id(tline);
@@ -2587,6 +2640,7 @@ static int do_directive(Token * tline)
goto issue_error;
issue_error:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
{
/* Only error out if this is the final pass */
if (pass != 2 && i != PP_FATAL)
@@ -2613,39 +2667,59 @@ issue_error:
}
CASE_PP_IF:
- if (istk->conds && !emitting(istk->conds->state))
- j = COND_NEVER;
- else {
- j = if_condition(tline->next, i);
- tline->next = NULL; /* it got freed */
- j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
- }
- cond = nasm_malloc(sizeof(Cond));
- cond->next = istk->conds;
- cond->state = j;
- istk->conds = cond;
- if(istk->mstk)
- istk->mstk->condcnt ++;
+ if (defining != NULL) {
+ if (defining->type == EXP_IF) {
+ defining->def_depth ++;
+ }
+ return NO_DIRECTIVE_FOUND;
+ }
+ if ((istk->expansion != NULL) &&
+ (istk->expansion->emitting == false)) {
+ j = COND_NEVER;
+ } else {
+ j = if_condition(tline->next, i);
+ tline->next = NULL; /* it got freed */
+ j = (((j < 0) ? COND_NEVER : j) ? COND_IF_TRUE : COND_IF_FALSE);
+ }
+ ed = new_ExpDef();
+ ed->type = EXP_IF;
+ ed->state = j;
+ ed->nolist = NULL;
+ ed->def_depth = 0;
+ ed->cur_depth = 0;
+ ed->max_depth = 0;
+ ed->ignoring = ((ed->state == COND_IF_TRUE) ? false : true);
+ ed->prev = defining;
+ defining = ed;
free_tlist(origline);
return DIRECTIVE_FOUND;
CASE_PP_ELIF:
- if (!istk->conds)
- error(ERR_FATAL, "`%s': no matching `%%if'", pp_directives[i]);
- switch(istk->conds->state) {
- case COND_IF_TRUE:
- istk->conds->state = COND_DONE;
- break;
+ if (defining != NULL) {
+ if ((defining->type != EXP_IF) || (defining->def_depth > 0)) {
+ return NO_DIRECTIVE_FOUND;
+ }
+ }
+ if ((defining == NULL) || (defining->type != EXP_IF)) {
+ error(ERR_FATAL, "`%s': no matching `%%if'", pp_directives[i]);
+ }
+ switch (defining->state) {
+ case COND_IF_TRUE:
+ defining->state = COND_DONE;
+ defining->ignoring = true;
+ break;
- case COND_DONE:
- case COND_NEVER:
- break;
+ case COND_DONE:
+ case COND_NEVER:
+ defining->ignoring = true;
+ break;
case COND_ELSE_TRUE:
case COND_ELSE_FALSE:
error_precond(ERR_WARNING|ERR_PASS1,
"`%%elif' after `%%else' ignored");
- istk->conds->state = COND_NEVER;
+ defining->state = COND_NEVER;
+ defining->ignoring = true;
break;
case COND_IF_FALSE:
@@ -2659,53 +2733,81 @@ issue_error:
*/
j = if_condition(expand_mmac_params(tline->next), i);
tline->next = NULL; /* it got freed */
- istk->conds->state =
+ defining->state =
j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
+ defining->ignoring = ((defining->state == COND_IF_TRUE) ? false : true);
break;
}
free_tlist(origline);
return DIRECTIVE_FOUND;
case PP_ELSE:
+ if (defining != NULL) {
+ if ((defining->type != EXP_IF) || (defining->def_depth > 0)) {
+ return NO_DIRECTIVE_FOUND;
+ }
+ }
if (tline->next)
error_precond(ERR_WARNING|ERR_PASS1,
"trailing garbage after `%%else' ignored");
- if (!istk->conds)
- error(ERR_FATAL, "`%%else': no matching `%%if'");
- switch(istk->conds->state) {
- case COND_IF_TRUE:
- case COND_DONE:
- istk->conds->state = COND_ELSE_FALSE;
- break;
-
- case COND_NEVER:
- break;
-
- case COND_IF_FALSE:
- istk->conds->state = COND_ELSE_TRUE;
- break;
+ if ((defining == NULL) || (defining->type != EXP_IF)) {
+ error(ERR_FATAL, "`%s': no matching `%%if'", pp_directives[i]);
+ }
+ switch (defining->state) {
+ case COND_IF_TRUE:
+ case COND_DONE:
+ defining->state = COND_ELSE_FALSE;
+ defining->ignoring = true;
+ break;
+
+ case COND_NEVER:
+ defining->ignoring = true;
+ break;
+
+ case COND_IF_FALSE:
+ defining->state = COND_ELSE_TRUE;
+ defining->ignoring = false;
+ break;
case COND_ELSE_TRUE:
case COND_ELSE_FALSE:
error_precond(ERR_WARNING|ERR_PASS1,
"`%%else' after `%%else' ignored.");
- istk->conds->state = COND_NEVER;
+ defining->state = COND_NEVER;
+ defining->ignoring = true;
break;
}
free_tlist(origline);
return DIRECTIVE_FOUND;
case PP_ENDIF:
+ if (defining != NULL) {
+ if (defining->type == EXP_IF) {
+ if (defining->def_depth > 0) {
+ defining->def_depth --;
+ return NO_DIRECTIVE_FOUND;
+ }
+ } else {
+ return NO_DIRECTIVE_FOUND;
+ }
+ }
if (tline->next)
error_precond(ERR_WARNING|ERR_PASS1,
"trailing garbage after `%%endif' ignored");
- if (!istk->conds)
- error(ERR_FATAL, "`%%endif': no matching `%%if'");
- cond = istk->conds;
- istk->conds = cond->next;
- nasm_free(cond);
- if(istk->mstk)
- istk->mstk->condcnt --;
+ if ((defining == NULL) || (defining->type != EXP_IF)) {
+ error(ERR_NONFATAL, "`%%endif': no matching `%%if'");
+ }
+ ed = defining;
+ defining = ed->prev;
+ ed->prev = expansions;
+ expansions = ed;
+ ei = new_ExpInv();
+ ei->type = EXP_IF;
+ ei->def = ed;
+ ei->current = ed->line;
+ ei->emitting = true;
+ ei->prev = istk->expansion;
+ istk->expansion = ei;
free_tlist(origline);
return DIRECTIVE_FOUND;
@@ -2713,99 +2815,123 @@ issue_error:
case PP_IRMACRO:
case PP_MACRO:
case PP_IMACRO:
- if (defining) {
- error(ERR_FATAL, "`%s': already defining a macro",
- pp_directives[i]);
- return DIRECTIVE_FOUND;
- }
- defining = nasm_malloc(sizeof(MMacro));
- defining->max_depth =
+ if (defining != NULL) {
+ if (defining->type == EXP_MMACRO) {
+ defining->def_depth ++;
+ }
+ return NO_DIRECTIVE_FOUND;
+ }
+ ed = new_ExpDef();
+ ed->max_depth =
(i == PP_RMACRO) || (i == PP_IRMACRO) ? DEADMAN_LIMIT : 0;
- defining->casesense = (i == PP_MACRO) || (i == PP_RMACRO);
- if (!parse_mmacro_spec(tline, defining, pp_directives[i])) {
- nasm_free(defining);
- defining = NULL;
+ ed->casesense = (i == PP_MACRO) || (i == PP_RMACRO);
+ if (!parse_mmacro_spec(tline, ed, pp_directives[i])) {
+ nasm_free(ed);
+ ed = NULL;
return DIRECTIVE_FOUND;
}
-
- mmac = (MMacro *) hash_findix(&mmacros, defining->name);
- while (mmac) {
- if (!strcmp(mmac->name, defining->name) &&
- (mmac->nparam_min <= defining->nparam_max
- || defining->plus)
- && (defining->nparam_min <= mmac->nparam_max
- || mmac->plus)) {
- error(ERR_WARNING|ERR_PASS1,
- "redefining multi-line macro `%s'", defining->name);
- return DIRECTIVE_FOUND;
- }
- mmac = mmac->next;
- }
+ ed->type = EXP_MMACRO;
+ ed->def_depth = 0;
+ ed->cur_depth = 0;
+ ed->max_depth = (ed->max_depth + 1);
+ ed->ignoring = false;
+ ed->prev = defining;
+ defining = ed;
+
+ eed = (ExpDef *) hash_findix(&expdefs, ed->name);
+ while (eed) {
+ if (!strcmp(eed->name, ed->name) &&
+ (eed->nparam_min <= ed->nparam_max
+ || ed->plus)
+ && (ed->nparam_min <= eed->nparam_max
+ || eed->plus)) {
+ error(ERR_WARNING|ERR_PASS1,
+ "redefining multi-line macro `%s'", ed->name);
+ return DIRECTIVE_FOUND;
+ }
+ eed = eed->next;
+ }
free_tlist(origline);
return DIRECTIVE_FOUND;
case PP_ENDM:
case PP_ENDMACRO:
- if (! (defining && defining->name)) {
- error(ERR_NONFATAL, "`%s': not defining a macro", tline->text);
- return DIRECTIVE_FOUND;
- }
- mmhead = (MMacro **) hash_findi_add(&mmacros, defining->name);
- defining->next = *mmhead;
- *mmhead = defining;
- defining = NULL;
+ if (defining != NULL) {
+ if (defining->type == EXP_MMACRO) {
+ if (defining->def_depth > 0) {
+ defining->def_depth --;
+ return NO_DIRECTIVE_FOUND;
+ }
+ } else {
+ return NO_DIRECTIVE_FOUND;
+ }
+ }
+ if (!(defining) || (defining->type != EXP_MMACRO)) {
+ error(ERR_NONFATAL, "`%s': not defining a macro", tline->text);
+ return DIRECTIVE_FOUND;
+ }
+ edhead = (ExpDef **) hash_findi_add(&expdefs, defining->name);
+ defining->next = *edhead;
+ *edhead = defining;
+ ed = defining;
+ defining = ed->prev;
+ ed->prev = expansions;
+ expansions = ed;
+ ed = NULL;
free_tlist(origline);
return DIRECTIVE_FOUND;
case PP_EXITMACRO:
- /*
- * We must search along istk->expansion until we hit a
- * macro-end marker for a macro with a name. Then we
- * bypass all lines between exitmacro and endmacro.
- */
- list_for_each(l, istk->expansion)
- if (l->finishes && l->finishes->name)
- break;
-
- if (l) {
- /*
- * Remove all conditional entries relative to this
- * macro invocation. (safe to do in this context)
- */
- for ( ; l->finishes->condcnt > 0; l->finishes->condcnt --) {
- cond = istk->conds;
- istk->conds = cond->next;
- nasm_free(cond);
- }
- istk->expansion = l;
- } else {
- error(ERR_NONFATAL, "`%%exitmacro' not within `%%macro' block");
- }
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
+ /*
+ * We must search along istk->expansion until we hit a
+ * macro invocation. Then we disable the emitting state(s)
+ * between exitmacro and endmacro.
+ */
+ for (ei = istk->expansion; ei != NULL; ei = ei->prev) {
+ if(ei->type == EXP_MMACRO) {
+ break;
+ }
+ }
+
+ if (ei != NULL) {
+ /*
+ * Set all invocations leading back to the macro
+ * invocation to a non-emitting state.
+ */
+ for (eei = istk->expansion; eei != ei; eei = eei->prev) {
+ eei->emitting = false;
+ }
+ eei->emitting = false;
+ } else {
+ error(ERR_NONFATAL, "`%%exitmacro' not within `%%macro' block");
+ }
free_tlist(origline);
return DIRECTIVE_FOUND;
case PP_UNMACRO:
case PP_UNIMACRO:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
{
- MMacro **mmac_p;
- MMacro spec;
+ ExpDef **ed_p;
+ ExpDef spec;
spec.casesense = (i == PP_UNMACRO);
if (!parse_mmacro_spec(tline, &spec, pp_directives[i])) {
return DIRECTIVE_FOUND;
}
- mmac_p = (MMacro **) hash_findi(&mmacros, spec.name, NULL);
- while (mmac_p && *mmac_p) {
- mmac = *mmac_p;
- if (mmac->casesense == spec.casesense &&
- !mstrcmp(mmac->name, spec.name, spec.casesense) &&
- mmac->nparam_min == spec.nparam_min &&
- mmac->nparam_max == spec.nparam_max &&
- mmac->plus == spec.plus) {
- *mmac_p = mmac->next;
- free_mmacro(mmac);
+ ed_p = (ExpDef **) hash_findi(&expdefs, spec.name, NULL);
+ while (ed_p && *ed_p) {
+ ed = *ed_p;
+ if (ed->casesense == spec.casesense &&
+ !mstrcmp(ed->name, spec.name, spec.casesense) &&
+ ed->nparam_min == spec.nparam_min &&
+ ed->nparam_max == spec.nparam_max &&
+ ed->plus == spec.plus) {
+ *ed_p = ed->next;
+ free_expdef(ed);
} else {
- mmac_p = &mmac->next;
+ ed_p = &ed->next;
}
}
free_tlist(origline);
@@ -2814,6 +2940,7 @@ issue_error:
}
case PP_ROTATE:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
if (tline->next && tline->next->type == TOK_WHITESPACE)
tline = tline->next;
if (!tline->next) {
@@ -2839,26 +2966,33 @@ issue_error:
error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
return DIRECTIVE_FOUND;
}
- mmac = istk->mstk;
- while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
- mmac = mmac->next_active;
- if (!mmac) {
- error(ERR_NONFATAL, "`%%rotate' invoked outside a macro call");
- } else if (mmac->nparam == 0) {
- error(ERR_NONFATAL,
- "`%%rotate' invoked within macro without parameters");
- } else {
- int rotate = mmac->rotate + reloc_value(evalresult);
-
- rotate %= (int)mmac->nparam;
- if (rotate < 0)
- rotate += mmac->nparam;
-
- mmac->rotate = rotate;
- }
+ for (ei = istk->expansion; ei != NULL; ei = ei->prev) {
+ if (ei->type == EXP_MMACRO) {
+ break;
+ }
+ }
+ if (ei == NULL) {
+ error(ERR_NONFATAL, "`%%rotate' invoked outside a macro call");
+ } else if (ei->nparam == 0) {
+ error(ERR_NONFATAL,
+ "`%%rotate' invoked within macro without parameters");
+ } else {
+ int rotate = ei->rotate + reloc_value(evalresult);
+
+ rotate %= (int)ei->nparam;
+ if (rotate < 0)
+ rotate += ei->nparam;
+ ei->rotate = rotate;
+ }
return DIRECTIVE_FOUND;
case PP_REP:
+ if (defining != NULL) {
+ if (defining->type == EXP_REP) {
+ defining->def_depth ++;
+ }
+ return NO_DIRECTIVE_FOUND;
+ }
nolist = false;
do {
tline = tline->next;
@@ -2895,26 +3029,29 @@ issue_error:
count = 0;
}
free_tlist(origline);
-
- tmp_defining = defining;
- defining = nasm_malloc(sizeof(MMacro));
- defining->prev = NULL;
- defining->name = NULL; /* flags this macro as a %rep block */
- defining->casesense = false;
- defining->plus = false;
- defining->nolist = nolist;
- defining->in_progress = count;
- defining->max_depth = 0;
- defining->nparam_min = defining->nparam_max = 0;
- defining->defaults = NULL;
- defining->dlist = NULL;
- defining->expansion = NULL;
- defining->next_active = istk->mstk;
- defining->rep_nest = tmp_defining;
+ ed = new_ExpDef();
+ ed->type = EXP_REP;
+ ed->nolist = nolist;
+ ed->def_depth = 0;
+ ed->cur_depth = 1;
+ ed->max_depth = (count - 1);
+ ed->ignoring = false;
+ ed->prev = defining;
+ defining = ed;
return DIRECTIVE_FOUND;
case PP_ENDREP:
- if (!defining || defining->name) {
+ if (defining != NULL) {
+ if (defining->type == EXP_REP) {
+ if (defining->def_depth > 0) {
+ defining->def_depth --;
+ return NO_DIRECTIVE_FOUND;
+ }
+ } else {
+ return NO_DIRECTIVE_FOUND;
+ }
+ }
+ if ((defining == NULL) || (defining->type != EXP_REP)) {
error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
return DIRECTIVE_FOUND;
}
@@ -2930,34 +3067,48 @@ issue_error:
* continues) until the whole expansion is forcibly removed
* from istk->expansion by a %exitrep.
*/
- l = nasm_malloc(sizeof(Line));
- l->next = istk->expansion;
- l->finishes = defining;
- l->first = NULL;
- istk->expansion = l;
-
- istk->mstk = defining;
-
- list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
- tmp_defining = defining;
- defining = defining->rep_nest;
+ ed = defining;
+ defining = ed->prev;
+ ed->prev = expansions;
+ expansions = ed;
+ ei = new_ExpInv();
+ ei->type = EXP_REP;
+ ei->def = ed;
+ ei->current = ed->line;
+ ei->emitting = ((ed->max_depth > 0) ? true : false);
+ list->uplevel(ed->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
+ ei->prev = istk->expansion;
+ istk->expansion = ei;
free_tlist(origline);
return DIRECTIVE_FOUND;
case PP_EXITREP:
- /*
- * We must search along istk->expansion until we hit a
- * macro-end marker for a macro with no name. Then we set
- * its `in_progress' flag to 0.
- */
- list_for_each(l, istk->expansion)
- if (l->finishes && !l->finishes->name)
- break;
-
- if (l)
- l->finishes->in_progress = 1;
- else
- error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
+ /*
+ * We must search along istk->expansion until we hit a
+ * rep invocation. Then we disable the emitting state(s)
+ * between exitrep and endrep.
+ */
+ for (ei = istk->expansion; ei != NULL; ei = ei->prev) {
+ if (ei->type == EXP_REP) {
+ break;
+ }
+ }
+
+ if (ei != NULL) {
+ /*
+ * Set all invocations leading back to the rep
+ * invocation to a non-emitting state.
+ */
+ for (eei = istk->expansion; eei != ei; eei = eei->prev) {
+ eei->emitting = false;
+ }
+ eei->emitting = false;
+ eei->current = NULL;
+ eei->def->cur_depth = eei->def->max_depth;
+ } else {
+ error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
+ }
free_tlist(origline);
return DIRECTIVE_FOUND;
@@ -2965,6 +3116,7 @@ issue_error:
case PP_IXDEFINE:
case PP_DEFINE:
case PP_IDEFINE:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
casesense = (i == PP_DEFINE || i == PP_XDEFINE);
tline = tline->next;
@@ -3056,6 +3208,7 @@ issue_error:
return DIRECTIVE_FOUND;
case PP_UNDEF:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
tline = tline->next;
skip_white_(tline);
tline = expand_id(tline);
@@ -3079,6 +3232,7 @@ issue_error:
case PP_DEFSTR:
case PP_IDEFSTR:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
casesense = (i == PP_DEFSTR);
tline = tline->next;
@@ -3120,6 +3274,7 @@ issue_error:
case PP_DEFTOK:
case PP_IDEFTOK:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
casesense = (i == PP_DEFTOK);
tline = tline->next;
@@ -3166,6 +3321,7 @@ issue_error:
return DIRECTIVE_FOUND;
case PP_PATHSEARCH:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
{
FILE *fp;
StrList *xsl = NULL;
@@ -3232,6 +3388,7 @@ issue_error:
}
case PP_STRLEN:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
casesense = true;
tline = tline->next;
@@ -3278,6 +3435,7 @@ issue_error:
return DIRECTIVE_FOUND;
case PP_STRCAT:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
casesense = true;
tline = tline->next;
@@ -3339,6 +3497,7 @@ issue_error:
return DIRECTIVE_FOUND;
case PP_SUBSTR:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
{
int64_t a1, a2;
size_t len;
@@ -3437,6 +3596,7 @@ issue_error:
case PP_ASSIGN:
case PP_IASSIGN:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
casesense = (i == PP_ASSIGN);
tline = tline->next;
@@ -3494,6 +3654,7 @@ issue_error:
return DIRECTIVE_FOUND;
case PP_LINE:
+ if (defining != NULL) return NO_DIRECTIVE_FOUND;
/*
* Syntax is `%line nnn[+mmm] [filename]'
*/
@@ -3684,12 +3845,12 @@ static bool paste_tokens(Token **head, bool handle_paste_tokens)
/*
* expands to a list of tokens from %{x:y}
*/
-static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last)
+static Token *expand_mmac_params_range(ExpInv *ei, Token *tline, Token ***last)
{
Token *t = tline, **tt, *tm, *head;
char *pos;
int fst, lst, j, i;
-
+
pos = strchr(tline->text, ':');
nasm_assert(pos);
@@ -3705,12 +3866,12 @@ static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last)
goto err;
/* the values should be sane */
- if ((fst > (int)mac->nparam || fst < (-(int)mac->nparam)) ||
- (lst > (int)mac->nparam || lst < (-(int)mac->nparam)))
+ if ((fst > (int)ei->nparam || fst < (-(int)ei->nparam)) ||
+ (lst > (int)ei->nparam || lst < (-(int)ei->nparam)))
goto err;
- fst = fst < 0 ? fst + (int)mac->nparam + 1: fst;
- lst = lst < 0 ? lst + (int)mac->nparam + 1: lst;
+ fst = fst < 0 ? fst + (int)ei->nparam + 1: fst;
+ lst = lst < 0 ? lst + (int)ei->nparam + 1: lst;
/* counted from zero */
fst--, lst--;
@@ -3718,15 +3879,15 @@ static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last)
/*
* it will be at least one token
*/
- tm = mac->params[(fst + mac->rotate) % mac->nparam];
+ tm = ei->params[(fst + ei->rotate) % ei->nparam];
t = new_Token(NULL, tm->type, tm->text, 0);
head = t, tt = &t->next;
if (fst < lst) {
for (i = fst + 1; i <= lst; i++) {
t = new_Token(NULL, TOK_OTHER, ",", 0);
*tt = t, tt = &t->next;
- j = (i + mac->rotate) % mac->nparam;
- tm = mac->params[j];
+ j = (i + ei->rotate) % ei->nparam;
+ tm = ei->params[j];
t = new_Token(NULL, tm->type, tm->text, 0);
*tt = t, tt = &t->next;
}
@@ -3734,8 +3895,8 @@ static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last)
for (i = fst - 1; i >= lst; i--) {
t = new_Token(NULL, TOK_OTHER, ",", 0);
*tt = t, tt = &t->next;
- j = (i + mac->rotate) % mac->nparam;
- tm = mac->params[j];
+ j = (i + ei->rotate) % ei->nparam;
+ tm = ei->params[j];
t = new_Token(NULL, tm->type, tm->text, 0);
*tt = t, tt = &t->next;
}
@@ -3774,15 +3935,17 @@ static Token *expand_mmac_params(Token * tline)
char tmpbuf[30];
unsigned int n;
int i;
- MMacro *mac;
+ ExpInv *ei;
t = tline;
tline = tline->next;
- mac = istk->mstk;
- while (mac && !mac->name) /* avoid mistaking %reps for macros */
- mac = mac->next_active;
- if (!mac) {
+ for (ei = istk->expansion; ei != NULL; ei = ei->prev) {
+ if (ei->type == EXP_MMACRO) {
+ break;
+ }
+ }
+ if (ei == NULL) {
error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
} else {
pos = strchr(t->text, ':');
@@ -3793,24 +3956,29 @@ static Token *expand_mmac_params(Token * tline)
* forms %1, %-1, %+1, %%foo, %0.
*/
case '0':
- type = TOK_NUMBER;
- snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam);
- text = nasm_strdup(tmpbuf);
- break;
+ if ((strlen(t->text) > 2) && (t->text[2] == '0')) {
+ type = TOK_ID;
+ text = nasm_strdup(ei->label_text);
+ } else {
+ type = TOK_NUMBER;
+ snprintf(tmpbuf, sizeof(tmpbuf), "%d", ei->nparam);
+ text = nasm_strdup(tmpbuf);
+ }
+ break;
case '%':
type = TOK_ID;
snprintf(tmpbuf, sizeof(tmpbuf), "..@%"PRIu64".",
- mac->unique);
+ ei->unique);
text = nasm_strcat(tmpbuf, t->text + 2);
break;
case '-':
n = atoi(t->text + 2) - 1;
- if (n >= mac->nparam)
+ if (n >= ei->nparam)
tt = NULL;
else {
- if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
+ if (ei->nparam > 1)
+ n = (n + ei->rotate) % ei->nparam;
+ tt = ei->params[n];
}
cc = find_cc(tt);
if (cc == -1) {
@@ -3831,12 +3999,12 @@ static Token *expand_mmac_params(Token * tline)
break;
case '+':
n = atoi(t->text + 2) - 1;
- if (n >= mac->nparam)
+ if (n >= ei->nparam)
tt = NULL;
else {
- if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
+ if (ei->nparam > 1)
+ n = (n + ei->rotate) % ei->nparam;
+ tt = ei->params[n];
}
cc = find_cc(tt);
if (cc == -1) {
@@ -3851,15 +4019,15 @@ static Token *expand_mmac_params(Token * tline)
break;
default:
n = atoi(t->text + 1) - 1;
- if (n >= mac->nparam)
+ if (n >= ei->nparam)
tt = NULL;
else {
- if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
+ if (ei->nparam > 1)
+ n = (n + ei->rotate) % ei->nparam;
+ tt = ei->params[n];
}
if (tt) {
- for (i = 0; i < mac->paramlen[n]; i++) {
+ for (i = 0; i < ei->paramlen[n]; i++) {
*tail = new_Token(NULL, tt->type, tt->text, 0);
tail = &(*tail)->next;
tt = tt->next;
@@ -3873,7 +4041,7 @@ static Token *expand_mmac_params(Token * tline)
* seems we have a parameters range here
*/
Token *head, **last;
- head = expand_mmac_params_range(mac, t, &last);
+ head = expand_mmac_params_range(ei, t, &last);
if (head != t) {
*tail = head;
*last = tline;
@@ -4318,19 +4486,19 @@ static Token *expand_id(Token * tline)
/*
* Determine whether the given line constitutes a multi-line macro
- * call, and return the MMacro structure called if so. Doesn't have
+ * call, and return the ExpDef structure called if so. Doesn't have
* to check for an initial label - that's taken care of in
* expand_mmacro - but must check numbers of parameters. Guaranteed
* to be called with tline->type == TOK_ID, so the putative macro
* name is easy to find.
*/
-static MMacro *is_mmacro(Token * tline, Token *** params_array)
+static ExpDef *is_mmacro(Token * tline, Token *** params_array)
{
- MMacro *head, *m;
+ ExpDef *head, *ed;
Token **params;
int nparam;
- head = (MMacro *) hash_findix(&mmacros, tline->text);
+ head = (ExpDef *) hash_findix(&expdefs, tline->text);
/*
* Efficiency: first we see if any macro exists with the given
@@ -4338,10 +4506,10 @@ static MMacro *is_mmacro(Token * tline, Token *** params_array)
* count the parameters, and then we look further along the
* list if necessary to find the proper MMacro.
*/
- list_for_each(m, head)
- if (!mstrcmp(m->name, tline->text, m->casesense))
+ list_for_each(ed, head)
+ if (!mstrcmp(ed->name, tline->text, ed->casesense))
break;
- if (!m)
+ if (!ed)
return NULL;
/*
@@ -4351,36 +4519,23 @@ static MMacro *is_mmacro(Token * tline, Token *** params_array)
count_mmac_params(tline->next, &nparam, &params);
/*
- * So we know how many parameters we've got. Find the MMacro
+ * So we know how many parameters we've got. Find the ExpDef
* structure that handles this number.
*/
- while (m) {
- if (m->nparam_min <= nparam
- && (m->plus || nparam <= m->nparam_max)) {
- /*
- * This one is right. Just check if cycle removal
- * prohibits us using it before we actually celebrate...
- */
- if (m->in_progress > m->max_depth) {
- if (m->max_depth > 0) {
- error(ERR_WARNING,
- "reached maximum recursion depth of %i",
- m->max_depth);
- }
- nasm_free(params);
- return NULL;
- }
+ while (ed) {
+ if (ed->nparam_min <= nparam
+ && (ed->plus || nparam <= ed->nparam_max)) {
/*
* It's right, and we can use it. Add its default
* parameters to the end of our list if necessary.
*/
- if (m->defaults && nparam < m->nparam_min + m->ndefs) {
+ if (ed->defaults && nparam < ed->nparam_min + ed->ndefs) {
params =
nasm_realloc(params,
- ((m->nparam_min + m->ndefs +
+ ((ed->nparam_min + ed->ndefs +
1) * sizeof(*params)));
- while (nparam < m->nparam_min + m->ndefs) {
- params[nparam] = m->defaults[nparam - m->nparam_min];
+ while (nparam < ed->nparam_min + ed->ndefs) {
+ params[nparam] = ed->defaults[nparam - ed->nparam_min];
nparam++;
}
}
@@ -4389,8 +4544,8 @@ static MMacro *is_mmacro(Token * tline, Token *** params_array)
* we're in Plus mode), ignore parameters beyond
* nparam_max.
*/
- if (m->plus && nparam > m->nparam_max)
- nparam = m->nparam_max;
+ if (ed->plus && nparam > ed->nparam_max)
+ nparam = ed->nparam_max;
/*
* Then terminate the parameter list, and leave.
*/
@@ -4400,14 +4555,14 @@ static MMacro *is_mmacro(Token * tline, Token *** params_array)
}
params[nparam] = NULL;
*params_array = params;
- return m;
+ return ed;
}
/*
* This one wasn't right: look for the next one with the
* same name.
*/
- list_for_each(m, m->next)
- if (!mstrcmp(m->name, tline->text, m->casesense))
+ list_for_each(ed, ed->next)
+ if (!mstrcmp(ed->name, tline->text, ed->casesense))
break;
}
@@ -4422,51 +4577,6 @@ static MMacro *is_mmacro(Token * tline, Token *** params_array)
return NULL;
}
-
-/*
- * Save MMacro invocation specific fields in
- * preparation for a recursive macro expansion
- */
-static void push_mmacro(MMacro *m)
-{
- MMacroInvocation *i;
-
- i = nasm_malloc(sizeof(MMacroInvocation));
- i->prev = m->prev;
- i->params = m->params;
- i->iline = m->iline;
- i->nparam = m->nparam;
- i->rotate = m->rotate;
- i->paramlen = m->paramlen;
- i->unique = m->unique;
- i->condcnt = m->condcnt;
- m->prev = i;
-}
-
-
-/*
- * Restore MMacro invocation specific fields that were
- * saved during a previous recursive macro expansion
- */
-static void pop_mmacro(MMacro *m)
-{
- MMacroInvocation *i;
-
- if (m->prev) {
- i = m->prev;
- m->prev = i->prev;
- m->params = i->params;
- m->iline = i->iline;
- m->nparam = i->nparam;
- m->rotate = i->rotate;
- m->paramlen = i->paramlen;
- m->unique = i->unique;
- m->condcnt = i->condcnt;
- nasm_free(i);
- }
-}
-
-
/*
* Expand the multi-line macro call made by the given line, if
* there is one to be expanded. If there is, push the expansion on
@@ -4478,8 +4588,9 @@ static int expand_mmacro(Token * tline)
Token *label = NULL;
int dont_prepend = 0;
Token **params, *t, *mtok, *tt;
- MMacro *m;
- Line *l, *ll;
+ Line *l;
+ ExpDef *ed;
+ ExpInv *ei;
int i, nparam, *paramlen;
const char *mname;
@@ -4489,8 +4600,8 @@ static int expand_mmacro(Token * tline)
if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID))
return 0;
mtok = t;
- m = is_mmacro(t, &params);
- if (m) {
+ ed = is_mmacro(t, &params);
+ if (ed != NULL) {
mname = t->text;
} else {
Token *last;
@@ -4510,7 +4621,7 @@ static int expand_mmacro(Token * tline)
if (tok_type_(t, TOK_WHITESPACE))
last = t, t = t->next;
}
- if (!tok_type_(t, TOK_ID) || !(m = is_mmacro(t, &params)))
+ if (!tok_type_(t, TOK_ID) || !(ed = is_mmacro(t, &params)))
return 0;
last->next = NULL;
mname = t->text;
@@ -4527,7 +4638,7 @@ static int expand_mmacro(Token * tline)
for (i = 0; params[i]; i++) {
int brace = false;
- int comma = (!m->plus || i < nparam - 1);
+ int comma = (!ed->plus || i < nparam - 1);
t = params[i];
skip_white_(t);
@@ -4548,6 +4659,17 @@ static int expand_mmacro(Token * tline)
}
}
+ if (ed->cur_depth >= ed->max_depth) {
+ if (ed->max_depth > 1) {
+ error(ERR_WARNING,
+ "reached maximum macro recursion depth of %i for %s",
+ ed->max_depth,ed->name);
+ }
+ return 0;
+ } else {
+ ed->cur_depth ++;
+ }
+
/*
* OK, we have a MMacro structure together with a set of
* parameters. We must now go through the expansion and push
@@ -4561,42 +4683,34 @@ static int expand_mmacro(Token * tline)
* macro as in progress, and set up its invocation-specific
* variables.
*/
- ll = nasm_malloc(sizeof(Line));
- ll->next = istk->expansion;
- ll->finishes = m;
- ll->first = NULL;
- istk->expansion = ll;
-
- /*
- * Save the previous MMacro expansion in the case of
- * macro recursion
- */
- if (m->max_depth && m->in_progress)
- push_mmacro(m);
-
- m->in_progress ++;
- m->params = params;
- m->iline = tline;
- m->nparam = nparam;
- m->rotate = 0;
- m->paramlen = paramlen;
- m->unique = unique++;
- m->lineno = 0;
- m->condcnt = 0;
-
- m->next_active = istk->mstk;
- istk->mstk = m;
-
+ ei = new_ExpInv();
+ ei->type = EXP_MMACRO;
+ ei->def = ed;
+// ei->label = label;
+ ei->label_text = detoken(label, false);
+ ei->current = ed->line;
+ ei->emitting = true;
+// ei->iline = tline;
+ ei->params = params;
+ ei->nparam = nparam;
+ ei->rotate = 0;
+ ei->paramlen = paramlen;
+ ei->lineno = 0;
+
+ ei->prev = istk->expansion;
+ istk->expansion = ei;
+
+ /***** todo: relocate %? (Q) and %?? (QQ); %00 already relocated *****/
+ /*
list_for_each(l, m->expansion) {
Token **tail;
- ll = nasm_malloc(sizeof(Line));
- ll->finishes = NULL;
- ll->next = istk->expansion;
- istk->expansion = ll;
- tail = &ll->first;
+ l = new_Line();
+ l->next = istk->expansion;
+ istk->expansion = l;
+ tail = &l->first;
- list_for_each(t, l->first) {
+ list_for_each(t, ei->current->first) {
Token *x = t;
switch (t->type) {
case TOK_PREPROC_Q:
@@ -4612,7 +4726,7 @@ static int expand_mmacro(Token * tline)
if (!x)
continue;
}
- /* fall through */
+ // fall through
default:
tt = *tail = new_Token(NULL, x->type, x->text, 0);
break;
@@ -4620,7 +4734,7 @@ static int expand_mmacro(Token * tline)
tail = &tt->next;
}
*tail = NULL;
- }
+ */
/*
* If we had a label, push it on as the first line of
@@ -4630,11 +4744,9 @@ static int expand_mmacro(Token * tline)
if (dont_prepend < 0)
free_tlist(startline);
else {
- ll = nasm_malloc(sizeof(Line));
- ll->finishes = NULL;
- ll->next = istk->expansion;
- istk->expansion = ll;
- ll->first = startline;
+ l = new_Line();
+ ei->label = l;
+ l->first = startline;
if (!dont_prepend) {
while (label->next)
label = label->next;
@@ -4643,7 +4755,7 @@ static int expand_mmacro(Token * tline)
}
}
- list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
+ list->uplevel(ed->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
return 1;
}
@@ -4655,11 +4767,15 @@ static void verror(int severity, const char *fmt, va_list arg)
vsnprintf(buff, sizeof(buff), fmt, arg);
- if (istk && istk->mstk && istk->mstk->name)
- nasm_error(severity, "(%s:%d) %s", istk->mstk->name,
- istk->mstk->lineno, buff);
- else
+ if ((istk != NULL) &&
+ (istk->expansion != NULL) &&
+ (istk->expansion->type == EXP_MMACRO)) {
+ ExpDef *ed = istk->expansion->def;
+ nasm_error(severity, "(%s:%d) %s", ed->name,
+ istk->expansion->lineno, buff);
+ } else {
nasm_error(severity, "%s", buff);
+ }
}
/*
@@ -4671,7 +4787,10 @@ static void error(int severity, const char *fmt, ...)
va_list arg;
/* If we're in a dead branch of IF or something like it, ignore the error */
- if (istk && istk->conds && !emitting(istk->conds->state))
+ if ((istk != NULL) &&
+ (istk->expansion != NULL) &&
+ (istk->expansion->type == EXP_IF) &&
+ !emitting(istk->expansion->def->state))
return;
va_start(arg, fmt);
@@ -4690,7 +4809,10 @@ static void error_precond(int severity, const char *fmt, ...)
va_list arg;
/* Only ignore the error if it's really in a dead branch */
- if (istk && istk->conds && istk->conds->state == COND_NEVER)
+ if ((istk != NULL) &&
+ (istk->expansion != NULL) &&
+ (istk->expansion->type == EXP_IF) &&
+ (istk->expansion->def->state == COND_NEVER))
return;
va_start(arg, fmt);
@@ -4706,9 +4828,7 @@ pp_reset(char *file, int apass, ListGen * listgen, StrList **deplist)
cstk = NULL;
istk = nasm_malloc(sizeof(Include));
istk->next = NULL;
- istk->conds = NULL;
istk->expansion = NULL;
- istk->mstk = NULL;
istk->fp = fopen(file, "r");
istk->fname = NULL;
src_set_fname(nasm_strdup(file));
@@ -4763,114 +4883,79 @@ static char *pp_getline(void)
{
char *line;
Token *tline;
-
+
while (1) {
/*
- * Fetch a tokenized line, either from the macro-expansion
+ * Fetch a tokenized line, either from the expansion
* buffer or from the input file.
*/
tline = NULL;
- while (istk->expansion && istk->expansion->finishes) {
- Line *l = istk->expansion;
- if (!l->finishes->name && l->finishes->in_progress > 1) {
- Line *ll;
-
- /*
- * This is a macro-end marker for a macro with no
- * name, which means it's not really a macro at all
- * but a %rep block, and the `in_progress' field is
- * more than 1, meaning that we still need to
- * repeat. (1 means the natural last repetition; 0
- * means termination by %exitrep.) We have
- * therefore expanded up to the %endrep, and must
- * push the whole block on to the expansion buffer
- * again. We don't bother to remove the macro-end
- * marker: we'd only have to generate another one
- * if we did.
- */
- l->finishes->in_progress--;
- list_for_each(l, l->finishes->expansion) {
- Token *t, *tt, **tail;
-
- ll = nasm_malloc(sizeof(Line));
- ll->next = istk->expansion;
- ll->finishes = NULL;
- ll->first = NULL;
- tail = &ll->first;
-
- list_for_each(t, l->first) {
- if (t->text || t->type == TOK_WHITESPACE) {
- tt = *tail = new_Token(NULL, t->type, t->text, 0);
- tail = &tt->next;
- }
- }
-
- istk->expansion = ll;
- }
- } else {
- /*
- * Check whether a `%rep' was started and not ended
- * within this macro expansion. This can happen and
- * should be detected. It's a fatal error because
- * I'm too confused to work out how to recover
- * sensibly from it.
- */
- if (defining) {
- if (defining->name)
- error(ERR_PANIC,
- "defining with name in expansion");
- else if (istk->mstk->name)
- error(ERR_FATAL,
- "`%%rep' without `%%endrep' within"
- " expansion of macro `%s'",
- istk->mstk->name);
- }
-
- /*
- * FIXME: investigate the relationship at this point between
- * istk->mstk and l->finishes
- */
- {
- MMacro *m = istk->mstk;
- istk->mstk = m->next_active;
- if (m->name) {
- /*
- * This was a real macro call, not a %rep, and
- * therefore the parameter information needs to
- * be freed.
- */
- if (m->prev) {
- pop_mmacro(m);
- l->finishes->in_progress --;
- } else {
- nasm_free(m->params);
- free_tlist(m->iline);
- nasm_free(m->paramlen);
- l->finishes->in_progress = 0;
- }
- } else
- free_mmacro(m);
- }
- istk->expansion = l->next;
- nasm_free(l);
- list->downlevel(LIST_MACRO);
- }
- }
+
while (1) { /* until we get a line we can use */
-
- if (istk->expansion) { /* from a macro expansion */
- char *p;
- Line *l = istk->expansion;
- if (istk->mstk)
- istk->mstk->lineno++;
- tline = l->first;
- istk->expansion = l->next;
- nasm_free(l);
- p = detoken(tline, false);
- list->line(LIST_MACRO, p);
- nasm_free(p);
- break;
- }
+ /*
+ * Fetch a tokenized line from the expansion buffer
+ */
+ if (istk->expansion != NULL) {
+
+ ExpInv *e = istk->expansion;
+ if (e->current != NULL) {
+ if (e->emitting == false) {
+ e->current = NULL;
+ continue;
+ }
+ Line *l = NULL;
+ l = e->current;
+ e->current = l->next;
+ e->lineno++;
+ tline = copy_Token(l->first);
+ if (((e->type == EXP_REP) || (e->type == EXP_MMACRO))
+ && (e->def->nolist == false)) {
+ char *p = detoken(tline, false);
+ list->line(LIST_MACRO, p);
+ nasm_free(p);
+ }
+ break;
+ } else if ((e->type == EXP_REP) &&
+ (e->def->cur_depth < e->def->max_depth)) {
+ e->def->cur_depth ++;
+ e->current = e->def->line;
+ e->lineno = 0;
+ continue;
+ } else {
+ istk->expansion = e->prev;
+ ExpDef *ed = e->def;
+ if (ed != NULL) {
+ if (ed->cur_depth > 0) {
+ ed->cur_depth --;
+ } else if ((ed->type != EXP_MMACRO) && (ed->type != EXP_IF)) {
+ /***** should this really be right here??? *****/
+ /*
+ Line *l = NULL, *ll = NULL;
+ for (l = ed->line; l != NULL;) {
+ if (l->first != NULL) {
+ free_tlist(l->first);
+ l->first = NULL;
+ }
+ ll = l;
+ l = l->next;
+ nasm_free(ll);
+ }
+ expansions = ed->prev;
+ nasm_free(ed);
+ */
+ }
+ if ((e->type == EXP_REP) || (e->type == EXP_MMACRO)) {
+ list->downlevel(LIST_MACRO);
+ }
+ }
+ nasm_free(e);
+ continue;
+ }
+ }
+
+ /*
+ * Read in line from input and tokenize
+ */
line = read_line();
if (line) { /* from the current input file */
line = prepreproc(line);
@@ -4878,15 +4963,17 @@ static char *pp_getline(void)
nasm_free(line);
break;
}
+
/*
* The current file has ended; work down the istk
*/
{
Include *i = istk;
fclose(i->fp);
- if (i->conds)
- error(ERR_FATAL,
- "expected `%%endif' before end of file");
+ if (i->expansion != NULL) {
+ error(ERR_FATAL,
+ "end of file while still in an expansion");
+ }
/* only set line and file name if there's a next node */
if (i->next) {
src_set_linnum(i->lineno);
@@ -4895,64 +4982,50 @@ static char *pp_getline(void)
istk = i->next;
list->downlevel(LIST_INCLUDE);
nasm_free(i);
- if (!istk)
+ if (istk == NULL) {
return NULL;
- if (istk->expansion && istk->expansion->finishes)
- break;
+ }
+ continue;
}
- }
-
- /*
- * We must expand MMacro parameters and MMacro-local labels
- * _before_ we plunge into directive processing, to cope
- * with things like `%define something %1' such as STRUC
- * uses. Unless we're _defining_ a MMacro, in which case
- * those tokens should be left alone to go into the
- * definition; and unless we're in a non-emitting
- * condition, in which case we don't want to meddle with
- * anything.
- */
- if (!defining && !(istk->conds && !emitting(istk->conds->state))
- && !(istk->mstk && !istk->mstk->in_progress)) {
- tline = expand_mmac_params(tline);
- }
-
+ }
+
+ if (defining == NULL) {
+ tline = expand_mmac_params(tline);
+ }
+
/*
* Check the line to see if it's a preprocessor directive.
*/
if (do_directive(tline) == DIRECTIVE_FOUND) {
continue;
- } else if (defining) {
+ } else if (defining != NULL) {
/*
- * We're defining a multi-line macro. We emit nothing
- * at all, and just
- * shove the tokenized line on to the macro definition.
+ * We're defining an expansion. We emit nothing at all,
+ * and just shove the tokenized line on to the definition.
*/
- Line *l = nasm_malloc(sizeof(Line));
- l->next = defining->expansion;
- l->first = tline;
- l->finishes = NULL;
- defining->expansion = l;
+ if (defining->ignoring == false) {
+ Line *l = new_Line();
+ l->first = tline;
+ if (defining->line == NULL) {
+ defining->line = l;
+ defining->last = l;
+ } else {
+ defining->last->next = l;
+ defining->last = l;
+ }
+ } else {
+ //free_tlist(tline); /***** sanity check: is this supposed to be here? *****/
+ }
continue;
- } else if (istk->conds && !emitting(istk->conds->state)) {
+ } else if ((istk->expansion != NULL) &&
+ (istk->expansion->emitting != true)) {
/*
- * We're in a non-emitting branch of a condition block.
+ * We're in a non-emitting branch of an expansion.
* Emit nothing at all, not even a blank line: when we
- * emerge from the condition we'll give a line-number
+ * emerge from the expansion we'll give a line-number
* directive so we keep our place correctly.
*/
- free_tlist(tline);
- continue;
- } else if (istk->mstk && !istk->mstk->in_progress) {
- /*
- * We're in a %rep block which has been terminated, so
- * we're walking through to the %endrep without
- * emitting anything. Emit nothing at all, not even a
- * blank line: when we emerge from the %rep block we'll
- * give a line-number directive so we keep our place
- * correctly.
- */
- free_tlist(tline);
+ free_tlist(tline);
continue;
} else {
tline = expand_smacro(tline);
@@ -4960,36 +5033,28 @@ static char *pp_getline(void)
/*
* De-tokenize the line again, and emit it.
*/
- line = detoken(tline, true);
- free_tlist(tline);
+ line = detoken(tline, true);
+ free_tlist(tline);
break;
} else {
continue; /* expand_mmacro calls free_tlist */
}
}
- }
-
- return line;
+ }
+ return line;
}
static void pp_cleanup(int pass)
{
- if (defining) {
- if (defining->name) {
- error(ERR_NONFATAL,
- "end of file while still defining macro `%s'",
- defining->name);
- } else {
- error(ERR_NONFATAL, "end of file while still in %%rep");
- }
-
- free_mmacro(defining);
- defining = NULL;
+ if (defining != NULL) {
+ error(ERR_NONFATAL, "end of file while still defining an expansion");
+ nasm_free(defining); /***** todo: free everything to avoid mem leaks *****/
+ defining = NULL;
}
- while (cstk)
+ while (cstk != NULL)
ctx_pop();
free_macros();
- while (istk) {
+ while (istk != NULL) {
Include *i = istk;
istk = istk->next;
fclose(i->fp);
@@ -5039,10 +5104,9 @@ void pp_pre_include(char *fname)
space = new_Token(name, TOK_WHITESPACE, NULL, 0);
inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
- l = nasm_malloc(sizeof(Line));
+ l = new_Line();
l->next = predef;
l->first = inc;
- l->finishes = NULL;
predef = l;
}
@@ -5061,10 +5125,9 @@ void pp_pre_define(char *definition)
if (equals)
*equals = '=';
- l = nasm_malloc(sizeof(Line));
+ l = new_Line();
l->next = predef;
l->first = def;
- l->finishes = NULL;
predef = l;
}
@@ -5077,18 +5140,15 @@ void pp_pre_undefine(char *definition)
def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
space->next = tokenize(definition);
- l = nasm_malloc(sizeof(Line));
+ l = new_Line();
l->next = predef;
l->first = def;
- l->finishes = NULL;
predef = l;
}
/*
- * Added by Keith Kanios:
- *
* This function is used to assist with "runtime" preprocessor
- * directives. (e.g. pp_runtime("%define __BITS__ 64");)
+ * directives, e.g. pp_runtime("%define __BITS__ 64");
*
* ERRORS ARE IGNORED HERE, SO MAKE COMPLETELY SURE THAT YOU
* PASS A VALID STRING TO THIS FUNCTION!!!!!