Switch the preprocessor over to using the hash table library
[platform/upstream/nasm.git] / preproc.c
1 /* -*- mode: c; c-file-style: "bsd" -*- */
2 /* preproc.c   macro preprocessor for the Netwide Assembler
3  *
4  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
5  * Julian Hall. All rights reserved. The software is
6  * redistributable under the licence given in the file "Licence"
7  * distributed in the NASM archive.
8  *
9  * initial version 18/iii/97 by Simon Tatham
10  */
11
12 /* Typical flow of text through preproc
13  *
14  * pp_getline gets tokenized lines, either
15  *
16  *   from a macro expansion
17  *
18  * or
19  *   {
20  *   read_line  gets raw text from stdmacpos, or predef, or current input file
21  *   tokenize   converts to tokens
22  *   }
23  *
24  * expand_mmac_params is used to expand %1 etc., unless a macro is being
25  * defined or a false conditional is being processed
26  * (%0, %1, %+1, %-1, %%foo
27  *
28  * do_directive checks for directives
29  *
30  * expand_smacro is used to expand single line macros
31  *
32  * expand_mmacro is used to expand multi-line macros
33  *
34  * detoken is used to convert the line back to text
35  */
36
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <stdlib.h>
40 #include <stddef.h>
41 #include <string.h>
42 #include <ctype.h>
43 #include <limits.h>
44 #include <inttypes.h>
45
46 #include "nasm.h"
47 #include "nasmlib.h"
48 #include "preproc.h"
49 #include "hashtbl.h"
50
51 typedef struct SMacro SMacro;
52 typedef struct MMacro MMacro;
53 typedef struct Context Context;
54 typedef struct Token Token;
55 typedef struct Blocks Blocks;
56 typedef struct Line Line;
57 typedef struct Include Include;
58 typedef struct Cond Cond;
59 typedef struct IncPath IncPath;
60
61 /*
62  * Note on the storage of both SMacro and MMacros: the hash table
63  * indexes them case-insensitively, and we then have to go through a
64  * linked list of potential case aliases (and, for MMacros, parameter
65  * ranges); this is to preserve the matching semantics of the earlier
66  * code.  If the number of case aliases for a specific macro is a
67  * performance issue, you may want to reconsider your coding style.
68  */
69
70 /*
71  * Store the definition of a single-line macro.
72  */
73 struct SMacro {
74     SMacro *next;
75     char *name;
76     int casesense;
77     int nparam;
78     int in_progress;
79     Token *expansion;
80 };
81
82 /*
83  * Store the definition of a multi-line macro. This is also used to
84  * store the interiors of `%rep...%endrep' blocks, which are
85  * effectively self-re-invoking multi-line macros which simply
86  * don't have a name or bother to appear in the hash tables. %rep
87  * blocks are signified by having a NULL `name' field.
88  *
89  * In a MMacro describing a `%rep' block, the `in_progress' field
90  * isn't merely boolean, but gives the number of repeats left to
91  * run.
92  *
93  * The `next' field is used for storing MMacros in hash tables; the
94  * `next_active' field is for stacking them on istk entries.
95  *
96  * When a MMacro is being expanded, `params', `iline', `nparam',
97  * `paramlen', `rotate' and `unique' are local to the invocation.
98  */
99 struct MMacro {
100     MMacro *next;
101     char *name;
102     int casesense;
103     int nparam_min, nparam_max;
104     int plus;                   /* is the last parameter greedy? */
105     int nolist;                 /* is this macro listing-inhibited? */
106     int in_progress;
107     Token *dlist;               /* All defaults as one list */
108     Token **defaults;           /* Parameter default pointers */
109     int ndefs;                  /* number of default parameters */
110     Line *expansion;
111
112     MMacro *next_active;
113     MMacro *rep_nest;           /* used for nesting %rep */
114     Token **params;             /* actual parameters */
115     Token *iline;               /* invocation line */
116     int nparam, rotate, *paramlen;
117     uint32_t unique;
118     int lineno;                 /* Current line number on expansion */
119 };
120
121 /*
122  * The context stack is composed of a linked list of these.
123  */
124 struct Context {
125     Context *next;
126     SMacro *localmac;
127     char *name;
128     uint32_t number;
129 };
130
131 /*
132  * This is the internal form which we break input lines up into.
133  * Typically stored in linked lists.
134  *
135  * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
136  * necessarily used as-is, but is intended to denote the number of
137  * the substituted parameter. So in the definition
138  *
139  *     %define a(x,y) ( (x) & ~(y) )
140  * 
141  * the token representing `x' will have its type changed to
142  * TOK_SMAC_PARAM, but the one representing `y' will be
143  * TOK_SMAC_PARAM+1.
144  *
145  * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
146  * which doesn't need quotes around it. Used in the pre-include
147  * mechanism as an alternative to trying to find a sensible type of
148  * quote to use on the filename we were passed.
149  */
150 enum pp_token_type {
151     TOK_NONE = 0, TOK_WHITESPACE, TOK_COMMENT, TOK_ID,
152     TOK_PREPROC_ID, TOK_STRING,
153     TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM,
154     TOK_INTERNAL_STRING
155 };
156
157 struct Token {
158     Token *next;
159     char *text;
160     SMacro *mac;                /* associated macro for TOK_SMAC_END */
161     enum pp_token_type type;
162 };
163
164 /*
165  * Multi-line macro definitions are stored as a linked list of
166  * these, which is essentially a container to allow several linked
167  * lists of Tokens.
168  * 
169  * Note that in this module, linked lists are treated as stacks
170  * wherever possible. For this reason, Lines are _pushed_ on to the
171  * `expansion' field in MMacro structures, so that the linked list,
172  * if walked, would give the macro lines in reverse order; this
173  * means that we can walk the list when expanding a macro, and thus
174  * push the lines on to the `expansion' field in _istk_ in reverse
175  * order (so that when popped back off they are in the right
176  * order). It may seem cockeyed, and it relies on my design having
177  * an even number of steps in, but it works...
178  *
179  * Some of these structures, rather than being actual lines, are
180  * markers delimiting the end of the expansion of a given macro.
181  * This is for use in the cycle-tracking and %rep-handling code.
182  * Such structures have `finishes' non-NULL, and `first' NULL. All
183  * others have `finishes' NULL, but `first' may still be NULL if
184  * the line is blank.
185  */
186 struct Line {
187     Line *next;
188     MMacro *finishes;
189     Token *first;
190 };
191
192 /*
193  * To handle an arbitrary level of file inclusion, we maintain a
194  * stack (ie linked list) of these things.
195  */
196 struct Include {
197     Include *next;
198     FILE *fp;
199     Cond *conds;
200     Line *expansion;
201     char *fname;
202     int lineno, lineinc;
203     MMacro *mstk;               /* stack of active macros/reps */
204 };
205
206 /*
207  * Include search path. This is simply a list of strings which get
208  * prepended, in turn, to the name of an include file, in an
209  * attempt to find the file if it's not in the current directory.
210  */
211 struct IncPath {
212     IncPath *next;
213     char *path;
214 };
215
216 /*
217  * Conditional assembly: we maintain a separate stack of these for
218  * each level of file inclusion. (The only reason we keep the
219  * stacks separate is to ensure that a stray `%endif' in a file
220  * included from within the true branch of a `%if' won't terminate
221  * it and cause confusion: instead, rightly, it'll cause an error.)
222  */
223 struct Cond {
224     Cond *next;
225     int state;
226 };
227 enum {
228     /*
229      * These states are for use just after %if or %elif: IF_TRUE
230      * means the condition has evaluated to truth so we are
231      * currently emitting, whereas IF_FALSE means we are not
232      * currently emitting but will start doing so if a %else comes
233      * up. In these states, all directives are admissible: %elif,
234      * %else and %endif. (And of course %if.)
235      */
236     COND_IF_TRUE, COND_IF_FALSE,
237     /*
238      * These states come up after a %else: ELSE_TRUE means we're
239      * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
240      * any %elif or %else will cause an error.
241      */
242     COND_ELSE_TRUE, COND_ELSE_FALSE,
243     /*
244      * This state means that we're not emitting now, and also that
245      * nothing until %endif will be emitted at all. It's for use in
246      * two circumstances: (i) when we've had our moment of emission
247      * and have now started seeing %elifs, and (ii) when the
248      * condition construct in question is contained within a
249      * non-emitting branch of a larger condition construct.
250      */
251     COND_NEVER
252 };
253 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
254
255 /* 
256  * These defines are used as the possible return values for do_directive
257  */
258 #define NO_DIRECTIVE_FOUND  0
259 #define DIRECTIVE_FOUND     1
260
261 /*
262  * Condition codes. Note that we use c_ prefix not C_ because C_ is
263  * used in nasm.h for the "real" condition codes. At _this_ level,
264  * we treat CXZ and ECXZ as condition codes, albeit non-invertible
265  * ones, so we need a different enum...
266  */
267 static const char *conditions[] = {
268     "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
269     "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
270     "np", "ns", "nz", "o", "p", "pe", "po", "rcxz", "s", "z"
271 };
272 enum {
273     c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE,
274     c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO,
275     c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_RCXZ, c_S, c_Z
276 };
277 static int inverse_ccs[] = {
278     c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE,
279     c_A, c_AE, c_B, c_BE, c_C, c_E, c_G, c_GE, c_L, c_LE, c_O, c_P, c_S,
280     c_Z, c_NO, c_NP, c_PO, c_PE, -1, c_NS, c_NZ
281 };
282
283 /*
284  * Directive names.
285  */
286 /* If this is a an IF, ELIF, ELSE or ENDIF keyword */
287 static int is_condition(enum preproc_token arg)
288 {
289     return PP_IS_COND(arg) || (arg == PP_ELSE) || (arg == PP_ENDIF);
290 }
291
292 /* For TASM compatibility we need to be able to recognise TASM compatible
293  * conditional compilation directives. Using the NASM pre-processor does
294  * not work, so we look for them specifically from the following list and
295  * then jam in the equivalent NASM directive into the input stream.
296  */
297
298 #ifndef MAX
299 #       define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
300 #endif
301
302 enum {
303     TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
304     TM_IFNDEF, TM_INCLUDE, TM_LOCAL
305 };
306
307 static const char *tasm_directives[] = {
308     "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
309     "ifndef", "include", "local"
310 };
311
312 static int StackSize = 4;
313 static char *StackPointer = "ebp";
314 static int ArgOffset = 8;
315 static int LocalOffset = 4;
316
317 static Context *cstk;
318 static Include *istk;
319 static IncPath *ipath = NULL;
320
321 static efunc _error;            /* Pointer to client-provided error reporting function */
322 static evalfunc evaluate;
323
324 static int pass;                /* HACK: pass 0 = generate dependencies only */
325
326 static uint32_t unique;    /* unique identifier numbers */
327
328 static Line *predef = NULL;
329
330 static ListGen *list;
331
332 /*
333  * The current set of multi-line macros we have defined.
334  */
335 static struct hash_table *mmacros;
336
337 /*
338  * The current set of single-line macros we have defined.
339  */
340 static struct hash_table *smacros;
341
342 /*
343  * The multi-line macro we are currently defining, or the %rep
344  * block we are currently reading, if any.
345  */
346 static MMacro *defining;
347
348 /*
349  * The number of macro parameters to allocate space for at a time.
350  */
351 #define PARAM_DELTA 16
352
353 /*
354  * The standard macro set: defined as `static char *stdmac[]'. Also
355  * gives our position in the macro set, when we're processing it.
356  */
357 #include "macros.c"
358 static const char **stdmacpos;
359
360 /*
361  * The extra standard macros that come from the object format, if
362  * any.
363  */
364 static const char **extrastdmac = NULL;
365 int any_extrastdmac;
366
367 /*
368  * Tokens are allocated in blocks to improve speed
369  */
370 #define TOKEN_BLOCKSIZE 4096
371 static Token *freeTokens = NULL;
372 struct Blocks {
373     Blocks *next;
374     void *chunk;
375 };
376
377 static Blocks blocks = { NULL, NULL };
378
379 /*
380  * Forward declarations.
381  */
382 static Token *expand_mmac_params(Token * tline);
383 static Token *expand_smacro(Token * tline);
384 static Token *expand_id(Token * tline);
385 static Context *get_ctx(char *name, int all_contexts);
386 static void make_tok_num(Token * tok, int32_t val);
387 static void error(int severity, const char *fmt, ...);
388 static void *new_Block(size_t size);
389 static void delete_Blocks(void);
390 static Token *new_Token(Token * next, enum pp_token_type type, char *text, int txtlen);
391 static Token *delete_Token(Token * t);
392
393 /*
394  * Macros for safe checking of token pointers, avoid *(NULL)
395  */
396 #define tok_type_(x,t) ((x) && (x)->type == (t))
397 #define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
398 #define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
399 #define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
400
401 /* Handle TASM specific directives, which do not contain a % in
402  * front of them. We do it here because I could not find any other
403  * place to do it for the moment, and it is a hack (ideally it would
404  * be nice to be able to use the NASM pre-processor to do it).
405  */
406 static char *check_tasm_directive(char *line)
407 {
408     int32_t i, j, k, m, len;
409     char *p = line, *oldline, oldchar;
410
411     /* Skip whitespace */
412     while (isspace(*p) && *p != 0)
413         p++;
414
415     /* Binary search for the directive name */
416     i = -1;
417     j = elements(tasm_directives);
418     len = 0;
419     while (!isspace(p[len]) && p[len] != 0)
420         len++;
421     if (len) {
422         oldchar = p[len];
423         p[len] = 0;
424         while (j - i > 1) {
425             k = (j + i) / 2;
426             m = nasm_stricmp(p, tasm_directives[k]);
427             if (m == 0) {
428                 /* We have found a directive, so jam a % in front of it
429                  * so that NASM will then recognise it as one if it's own.
430                  */
431                 p[len] = oldchar;
432                 len = strlen(p);
433                 oldline = line;
434                 line = nasm_malloc(len + 2);
435                 line[0] = '%';
436                 if (k == TM_IFDIFI) {
437                     /* NASM does not recognise IFDIFI, so we convert it to
438                      * %ifdef BOGUS. This is not used in NASM comaptible
439                      * code, but does need to parse for the TASM macro
440                      * package.
441                      */
442                     strcpy(line + 1, "ifdef BOGUS");
443                 } else {
444                     memcpy(line + 1, p, len + 1);
445                 }
446                 nasm_free(oldline);
447                 return line;
448             } else if (m < 0) {
449                 j = k;
450             } else
451                 i = k;
452         }
453         p[len] = oldchar;
454     }
455     return line;
456 }
457
458 /*
459  * The pre-preprocessing stage... This function translates line
460  * number indications as they emerge from GNU cpp (`# lineno "file"
461  * flags') into NASM preprocessor line number indications (`%line
462  * lineno file').
463  */
464 static char *prepreproc(char *line)
465 {
466     int lineno, fnlen;
467     char *fname, *oldline;
468
469     if (line[0] == '#' && line[1] == ' ') {
470         oldline = line;
471         fname = oldline + 2;
472         lineno = atoi(fname);
473         fname += strspn(fname, "0123456789 ");
474         if (*fname == '"')
475             fname++;
476         fnlen = strcspn(fname, "\"");
477         line = nasm_malloc(20 + fnlen);
478         snprintf(line, 20 + fnlen, "%%line %d %.*s", lineno, fnlen, fname);
479         nasm_free(oldline);
480     }
481     if (tasm_compatible_mode)
482         return check_tasm_directive(line);
483     return line;
484 }
485
486 /*
487  * Free a linked list of tokens.
488  */
489 static void free_tlist(Token * list)
490 {
491     while (list) {
492         list = delete_Token(list);
493     }
494 }
495
496 /*
497  * Free a linked list of lines.
498  */
499 static void free_llist(Line * list)
500 {
501     Line *l;
502     while (list) {
503         l = list;
504         list = list->next;
505         free_tlist(l->first);
506         nasm_free(l);
507     }
508 }
509
510 /*
511  * Free an MMacro
512  */
513 static void free_mmacro(MMacro * m)
514 {
515     nasm_free(m->name);
516     free_tlist(m->dlist);
517     nasm_free(m->defaults);
518     free_llist(m->expansion);
519     nasm_free(m);
520 }
521
522 /*
523  * Free all currently defined macros, and free the hash tables
524  */
525 static void free_macros(void)
526 {
527     struct hash_tbl_node *it;
528     const char *key;
529     SMacro *s;
530     MMacro *m;
531
532     it = NULL;
533     while ((s = hash_iterate(smacros, &it, &key)) != NULL) {
534         nasm_free((void *)key);
535         while (s) {
536             SMacro *ns = s->next;
537             nasm_free(s->name);
538             free_tlist(s->expansion);
539             nasm_free(s);
540             s = ns;
541         }
542     }
543     hash_free(smacros);
544
545     it = NULL;
546     while ((m = hash_iterate(mmacros, &it, &key)) != NULL) {
547         nasm_free((void *)key);
548         while (m) {
549             MMacro *nm = m->next;
550             free_mmacro(m);
551             m = nm;
552         }
553     }
554     hash_free(mmacros);
555 }
556
557 /*
558  * Initialize the hash tables
559  */
560 static void init_macros(void)
561 {
562     smacros = hash_init();
563     mmacros = hash_init();
564 }
565
566 /*
567  * Pop the context stack.
568  */
569 static void ctx_pop(void)
570 {
571     Context *c = cstk;
572     SMacro *smac, *s;
573
574     cstk = cstk->next;
575     smac = c->localmac;
576     while (smac) {
577         s = smac;
578         smac = smac->next;
579         nasm_free(s->name);
580         free_tlist(s->expansion);
581         nasm_free(s);
582     }
583     nasm_free(c->name);
584     nasm_free(c);
585 }
586
587 #define BUF_DELTA 512
588 /*
589  * Read a line from the top file in istk, handling multiple CR/LFs
590  * at the end of the line read, and handling spurious ^Zs. Will
591  * return lines from the standard macro set if this has not already
592  * been done.
593  */
594 static char *read_line(void)
595 {
596     char *buffer, *p, *q;
597     int bufsize, continued_count;
598
599     if (stdmacpos) {
600         if (*stdmacpos) {
601             char *ret = nasm_strdup(*stdmacpos++);
602             if (!*stdmacpos && any_extrastdmac) {
603                 stdmacpos = extrastdmac;
604                 any_extrastdmac = FALSE;
605                 return ret;
606             }
607             /*
608              * Nasty hack: here we push the contents of `predef' on
609              * to the top-level expansion stack, since this is the
610              * most convenient way to implement the pre-include and
611              * pre-define features.
612              */
613             if (!*stdmacpos) {
614                 Line *pd, *l;
615                 Token *head, **tail, *t;
616
617                 for (pd = predef; pd; pd = pd->next) {
618                     head = NULL;
619                     tail = &head;
620                     for (t = pd->first; t; t = t->next) {
621                         *tail = new_Token(NULL, t->type, t->text, 0);
622                         tail = &(*tail)->next;
623                     }
624                     l = nasm_malloc(sizeof(Line));
625                     l->next = istk->expansion;
626                     l->first = head;
627                     l->finishes = FALSE;
628                     istk->expansion = l;
629                 }
630             }
631             return ret;
632         } else {
633             stdmacpos = NULL;
634         }
635     }
636
637     bufsize = BUF_DELTA;
638     buffer = nasm_malloc(BUF_DELTA);
639     p = buffer;
640     continued_count = 0;
641     while (1) {
642         q = fgets(p, bufsize - (p - buffer), istk->fp);
643         if (!q)
644             break;
645         p += strlen(p);
646         if (p > buffer && p[-1] == '\n') {
647             /* Convert backslash-CRLF line continuation sequences into
648                nothing at all (for DOS and Windows) */
649             if (((p - 2) > buffer) && (p[-3] == '\\') && (p[-2] == '\r')) {
650                 p -= 3;
651                 *p = 0;
652                 continued_count++;
653             }
654             /* Also convert backslash-LF line continuation sequences into
655                nothing at all (for Unix) */
656             else if (((p - 1) > buffer) && (p[-2] == '\\')) {
657                 p -= 2;
658                 *p = 0;
659                 continued_count++;
660             } else {
661                 break;
662             }
663         }
664         if (p - buffer > bufsize - 10) {
665             int32_t offset = p - buffer;
666             bufsize += BUF_DELTA;
667             buffer = nasm_realloc(buffer, bufsize);
668             p = buffer + offset;        /* prevent stale-pointer problems */
669         }
670     }
671
672     if (!q && p == buffer) {
673         nasm_free(buffer);
674         return NULL;
675     }
676
677     src_set_linnum(src_get_linnum() + istk->lineinc +
678                    (continued_count * istk->lineinc));
679
680     /*
681      * Play safe: remove CRs as well as LFs, if any of either are
682      * present at the end of the line.
683      */
684     while (--p >= buffer && (*p == '\n' || *p == '\r'))
685         *p = '\0';
686
687     /*
688      * Handle spurious ^Z, which may be inserted into source files
689      * by some file transfer utilities.
690      */
691     buffer[strcspn(buffer, "\032")] = '\0';
692
693     list->line(LIST_READ, buffer);
694
695     return buffer;
696 }
697
698 /*
699  * Tokenize a line of text. This is a very simple process since we
700  * don't need to parse the value out of e.g. numeric tokens: we
701  * simply split one string into many.
702  */
703 static Token *tokenize(char *line)
704 {
705     char *p = line;
706     enum pp_token_type type;
707     Token *list = NULL;
708     Token *t, **tail = &list;
709
710     while (*line) {
711         p = line;
712         if (*p == '%') {
713             p++;
714             if (isdigit(*p) ||
715                 ((*p == '-' || *p == '+') && isdigit(p[1])) ||
716                 ((*p == '+') && (isspace(p[1]) || !p[1]))) {
717                 do {
718                     p++;
719                 }
720                 while (isdigit(*p));
721                 type = TOK_PREPROC_ID;
722             } else if (*p == '{') {
723                 p++;
724                 while (*p && *p != '}') {
725                     p[-1] = *p;
726                     p++;
727                 }
728                 p[-1] = '\0';
729                 if (*p)
730                     p++;
731                 type = TOK_PREPROC_ID;
732             } else if (isidchar(*p) ||
733                        ((*p == '!' || *p == '%' || *p == '$') &&
734                         isidchar(p[1]))) {
735                 do {
736                     p++;
737                 }
738                 while (isidchar(*p));
739                 type = TOK_PREPROC_ID;
740             } else {
741                 type = TOK_OTHER;
742                 if (*p == '%')
743                     p++;
744             }
745         } else if (isidstart(*p) || (*p == '$' && isidstart(p[1]))) {
746             type = TOK_ID;
747             p++;
748             while (*p && isidchar(*p))
749                 p++;
750         } else if (*p == '\'' || *p == '"') {
751             /*
752              * A string token.
753              */
754             char c = *p;
755             p++;
756             type = TOK_STRING;
757             while (*p && *p != c)
758                 p++;
759
760             if (*p) {
761                 p++;
762             } else {
763                 error(ERR_WARNING, "unterminated string");
764                 /* Handling unterminated strings by UNV */
765                 /* type = -1; */
766             }
767         } else if (isnumstart(*p)) {
768             /*
769              * A number token.
770              */
771             type = TOK_NUMBER;
772             p++;
773             while (*p && isnumchar(*p))
774                 p++;
775         } else if (isspace(*p)) {
776             type = TOK_WHITESPACE;
777             p++;
778             while (*p && isspace(*p))
779                 p++;
780             /*
781              * Whitespace just before end-of-line is discarded by
782              * pretending it's a comment; whitespace just before a
783              * comment gets lumped into the comment.
784              */
785             if (!*p || *p == ';') {
786                 type = TOK_COMMENT;
787                 while (*p)
788                     p++;
789             }
790         } else if (*p == ';') {
791             type = TOK_COMMENT;
792             while (*p)
793                 p++;
794         } else {
795             /*
796              * Anything else is an operator of some kind. We check
797              * for all the double-character operators (>>, <<, //,
798              * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
799              * else is a single-character operator.
800              */
801             type = TOK_OTHER;
802             if ((p[0] == '>' && p[1] == '>') ||
803                 (p[0] == '<' && p[1] == '<') ||
804                 (p[0] == '/' && p[1] == '/') ||
805                 (p[0] == '<' && p[1] == '=') ||
806                 (p[0] == '>' && p[1] == '=') ||
807                 (p[0] == '=' && p[1] == '=') ||
808                 (p[0] == '!' && p[1] == '=') ||
809                 (p[0] == '<' && p[1] == '>') ||
810                 (p[0] == '&' && p[1] == '&') ||
811                 (p[0] == '|' && p[1] == '|') ||
812                 (p[0] == '^' && p[1] == '^')) {
813                 p++;
814             }
815             p++;
816         }
817
818         /* Handling unterminated string by UNV */
819         /*if (type == -1)
820            {
821            *tail = t = new_Token(NULL, TOK_STRING, line, p-line+1);
822            t->text[p-line] = *line;
823            tail = &t->next;
824            }
825            else */
826         if (type != TOK_COMMENT) {
827             *tail = t = new_Token(NULL, type, line, p - line);
828             tail = &t->next;
829         }
830         line = p;
831     }
832     return list;
833 }
834
835 /*
836  * this function allocates a new managed block of memory and
837  * returns a pointer to the block.  The managed blocks are 
838  * deleted only all at once by the delete_Blocks function.
839  */
840 static void *new_Block(size_t size)
841 {
842     Blocks *b = &blocks;
843
844     /* first, get to the end of the linked list */
845     while (b->next)
846         b = b->next;
847     /* now allocate the requested chunk */
848     b->chunk = nasm_malloc(size);
849
850     /* now allocate a new block for the next request */
851     b->next = nasm_malloc(sizeof(Blocks));
852     /* and initialize the contents of the new block */
853     b->next->next = NULL;
854     b->next->chunk = NULL;
855     return b->chunk;
856 }
857
858 /*
859  * this function deletes all managed blocks of memory
860  */
861 static void delete_Blocks(void)
862 {
863     Blocks *a, *b = &blocks;
864
865     /* 
866      * keep in mind that the first block, pointed to by blocks
867      * is a static and not dynamically allocated, so we don't 
868      * free it.
869      */
870     while (b) {
871         if (b->chunk)
872             nasm_free(b->chunk);
873         a = b;
874         b = b->next;
875         if (a != &blocks)
876             nasm_free(a);
877     }
878 }
879
880 /*
881  *  this function creates a new Token and passes a pointer to it 
882  *  back to the caller.  It sets the type and text elements, and
883  *  also the mac and next elements to NULL.
884  */
885 static Token *new_Token(Token * next, enum pp_token_type type, char *text, int txtlen)
886 {
887     Token *t;
888     int i;
889
890     if (freeTokens == NULL) {
891         freeTokens = (Token *) new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
892         for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
893             freeTokens[i].next = &freeTokens[i + 1];
894         freeTokens[i].next = NULL;
895     }
896     t = freeTokens;
897     freeTokens = t->next;
898     t->next = next;
899     t->mac = NULL;
900     t->type = type;
901     if (type == TOK_WHITESPACE || text == NULL) {
902         t->text = NULL;
903     } else {
904         if (txtlen == 0)
905             txtlen = strlen(text);
906         t->text = nasm_malloc(1 + txtlen);
907         strncpy(t->text, text, txtlen);
908         t->text[txtlen] = '\0';
909     }
910     return t;
911 }
912
913 static Token *delete_Token(Token * t)
914 {
915     Token *next = t->next;
916     nasm_free(t->text);
917     t->next = freeTokens;
918     freeTokens = t;
919     return next;
920 }
921
922 /*
923  * Convert a line of tokens back into text.
924  * If expand_locals is not zero, identifiers of the form "%$*xxx"
925  * will be transformed into ..@ctxnum.xxx
926  */
927 static char *detoken(Token * tlist, int expand_locals)
928 {
929     Token *t;
930     int len;
931     char *line, *p;
932
933     len = 0;
934     for (t = tlist; t; t = t->next) {
935         if (t->type == TOK_PREPROC_ID && t->text[1] == '!') {
936             char *p = getenv(t->text + 2);
937             nasm_free(t->text);
938             if (p)
939                 t->text = nasm_strdup(p);
940             else
941                 t->text = NULL;
942         }
943         /* Expand local macros here and not during preprocessing */
944         if (expand_locals &&
945             t->type == TOK_PREPROC_ID && t->text &&
946             t->text[0] == '%' && t->text[1] == '$') {
947             Context *ctx = get_ctx(t->text, FALSE);
948             if (ctx) {
949                 char buffer[40];
950                 char *p, *q = t->text + 2;
951
952                 q += strspn(q, "$");
953                 snprintf(buffer, sizeof(buffer), "..@%"PRIu32".", ctx->number);
954                 p = nasm_strcat(buffer, q);
955                 nasm_free(t->text);
956                 t->text = p;
957             }
958         }
959         if (t->type == TOK_WHITESPACE) {
960             len++;
961         } else if (t->text) {
962             len += strlen(t->text);
963         }
964     }
965     p = line = nasm_malloc(len + 1);
966     for (t = tlist; t; t = t->next) {
967         if (t->type == TOK_WHITESPACE) {
968             *p = ' ';
969             p++;
970             *p = '\0';
971         } else if (t->text) {
972             strcpy(p, t->text);
973             p += strlen(p);
974         }
975     }
976     *p = '\0';
977     return line;
978 }
979
980 /*
981  * A scanner, suitable for use by the expression evaluator, which
982  * operates on a line of Tokens. Expects a pointer to a pointer to
983  * the first token in the line to be passed in as its private_data
984  * field.
985  */
986 static int ppscan(void *private_data, struct tokenval *tokval)
987 {
988     Token **tlineptr = private_data;
989     Token *tline;
990
991     do {
992         tline = *tlineptr;
993         *tlineptr = tline ? tline->next : NULL;
994     }
995     while (tline && (tline->type == TOK_WHITESPACE ||
996                      tline->type == TOK_COMMENT));
997
998     if (!tline)
999         return tokval->t_type = TOKEN_EOS;
1000
1001     if (tline->text[0] == '$' && !tline->text[1])
1002         return tokval->t_type = TOKEN_HERE;
1003     if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[2])
1004         return tokval->t_type = TOKEN_BASE;
1005
1006     if (tline->type == TOK_ID) {
1007         tokval->t_charptr = tline->text;
1008         if (tline->text[0] == '$') {
1009             tokval->t_charptr++;
1010             return tokval->t_type = TOKEN_ID;
1011         }
1012
1013         /*
1014          * This is the only special case we actually need to worry
1015          * about in this restricted context.
1016          */
1017         if (!nasm_stricmp(tline->text, "seg"))
1018             return tokval->t_type = TOKEN_SEG;
1019
1020         return tokval->t_type = TOKEN_ID;
1021     }
1022
1023     if (tline->type == TOK_NUMBER) {
1024         int rn_error;
1025
1026         tokval->t_integer = readnum(tline->text, &rn_error);
1027         if (rn_error)
1028             return tokval->t_type = TOKEN_ERRNUM;
1029         tokval->t_charptr = NULL;
1030         return tokval->t_type = TOKEN_NUM;
1031     }
1032
1033     if (tline->type == TOK_STRING) {
1034         int rn_warn;
1035         char q, *r;
1036         int l;
1037
1038         r = tline->text;
1039         q = *r++;
1040         l = strlen(r);
1041
1042         if (l == 0 || r[l - 1] != q)
1043             return tokval->t_type = TOKEN_ERRNUM;
1044         tokval->t_integer = readstrnum(r, l - 1, &rn_warn);
1045         if (rn_warn)
1046             error(ERR_WARNING | ERR_PASS1, "character constant too long");
1047         tokval->t_charptr = NULL;
1048         return tokval->t_type = TOKEN_NUM;
1049     }
1050
1051     if (tline->type == TOK_OTHER) {
1052         if (!strcmp(tline->text, "<<"))
1053             return tokval->t_type = TOKEN_SHL;
1054         if (!strcmp(tline->text, ">>"))
1055             return tokval->t_type = TOKEN_SHR;
1056         if (!strcmp(tline->text, "//"))
1057             return tokval->t_type = TOKEN_SDIV;
1058         if (!strcmp(tline->text, "%%"))
1059             return tokval->t_type = TOKEN_SMOD;
1060         if (!strcmp(tline->text, "=="))
1061             return tokval->t_type = TOKEN_EQ;
1062         if (!strcmp(tline->text, "<>"))
1063             return tokval->t_type = TOKEN_NE;
1064         if (!strcmp(tline->text, "!="))
1065             return tokval->t_type = TOKEN_NE;
1066         if (!strcmp(tline->text, "<="))
1067             return tokval->t_type = TOKEN_LE;
1068         if (!strcmp(tline->text, ">="))
1069             return tokval->t_type = TOKEN_GE;
1070         if (!strcmp(tline->text, "&&"))
1071             return tokval->t_type = TOKEN_DBL_AND;
1072         if (!strcmp(tline->text, "^^"))
1073             return tokval->t_type = TOKEN_DBL_XOR;
1074         if (!strcmp(tline->text, "||"))
1075             return tokval->t_type = TOKEN_DBL_OR;
1076     }
1077
1078     /*
1079      * We have no other options: just return the first character of
1080      * the token text.
1081      */
1082     return tokval->t_type = tline->text[0];
1083 }
1084
1085 /*
1086  * Compare a string to the name of an existing macro; this is a
1087  * simple wrapper which calls either strcmp or nasm_stricmp
1088  * depending on the value of the `casesense' parameter.
1089  */
1090 static int mstrcmp(char *p, char *q, int casesense)
1091 {
1092     return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
1093 }
1094
1095 /*
1096  * Return the Context structure associated with a %$ token. Return
1097  * NULL, having _already_ reported an error condition, if the
1098  * context stack isn't deep enough for the supplied number of $
1099  * signs.
1100  * If all_contexts == TRUE, contexts that enclose current are
1101  * also scanned for such smacro, until it is found; if not -
1102  * only the context that directly results from the number of $'s
1103  * in variable's name.
1104  */
1105 static Context *get_ctx(char *name, int all_contexts)
1106 {
1107     Context *ctx;
1108     SMacro *m;
1109     int i;
1110
1111     if (!name || name[0] != '%' || name[1] != '$')
1112         return NULL;
1113
1114     if (!cstk) {
1115         error(ERR_NONFATAL, "`%s': context stack is empty", name);
1116         return NULL;
1117     }
1118
1119     for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--) {
1120         ctx = ctx->next;
1121 /*        i--;  Lino - 02/25/02 */
1122     }
1123     if (!ctx) {
1124         error(ERR_NONFATAL, "`%s': context stack is only"
1125               " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
1126         return NULL;
1127     }
1128     if (!all_contexts)
1129         return ctx;
1130
1131     do {
1132         /* Search for this smacro in found context */
1133         m = ctx->localmac;
1134         while (m) {
1135             if (!mstrcmp(m->name, name, m->casesense))
1136                 return ctx;
1137             m = m->next;
1138         }
1139         ctx = ctx->next;
1140     }
1141     while (ctx);
1142     return NULL;
1143 }
1144
1145 /*
1146  * Open an include file. This routine must always return a valid
1147  * file pointer if it returns - it's responsible for throwing an
1148  * ERR_FATAL and bombing out completely if not. It should also try
1149  * the include path one by one until it finds the file or reaches
1150  * the end of the path.
1151  */
1152 static FILE *inc_fopen(char *file)
1153 {
1154     FILE *fp;
1155     char *prefix = "", *combine;
1156     IncPath *ip = ipath;
1157     static int namelen = 0;
1158     int len = strlen(file);
1159
1160     while (1) {
1161         combine = nasm_malloc(strlen(prefix) + len + 1);
1162         strcpy(combine, prefix);
1163         strcat(combine, file);
1164         fp = fopen(combine, "r");
1165         if (pass == 0 && fp) {
1166             namelen += strlen(combine) + 1;
1167             if (namelen > 62) {
1168                 printf(" \\\n  ");
1169                 namelen = 2;
1170             }
1171             printf(" %s", combine);
1172         }
1173         nasm_free(combine);
1174         if (fp)
1175             return fp;
1176         if (!ip)
1177             break;
1178         prefix = ip->path;
1179         ip = ip->next;
1180     }
1181
1182     error(ERR_FATAL, "unable to open include file `%s'", file);
1183     return NULL;                /* never reached - placate compilers */
1184 }
1185
1186 /*
1187  * Search for a key in the hash index; adding it if necessary
1188  * (in which case we initialize the data pointer to NULL.)
1189  */
1190 static void **
1191 hash_findi_add(struct hash_table *hash, const char *str)
1192 {
1193     struct hash_insert hi;
1194     void **r;
1195     char *strx;
1196
1197     r = hash_findi(hash, str, &hi);
1198     if (r)
1199         return r;
1200
1201     strx = nasm_strdup(str);    /* Use a more efficient allocator here? */
1202     return hash_add(&hi, strx, NULL);
1203 }
1204
1205 /*
1206  * Like hash_findi, but returns the data element rather than a pointer
1207  * to it.  Used only when not adding a new element, hence no third
1208  * argument.
1209  */
1210 static void *
1211 hash_findix(struct hash_table *hash, const char *str)
1212 {
1213     void **p;
1214
1215     p = hash_findi(hash, str, NULL);
1216     return p ? *p : NULL;
1217 }
1218
1219 /*
1220  * Determine if we should warn on defining a single-line macro of
1221  * name `name', with `nparam' parameters. If nparam is 0 or -1, will
1222  * return TRUE if _any_ single-line macro of that name is defined.
1223  * Otherwise, will return TRUE if a single-line macro with either
1224  * `nparam' or no parameters is defined.
1225  *
1226  * If a macro with precisely the right number of parameters is
1227  * defined, or nparam is -1, the address of the definition structure
1228  * will be returned in `defn'; otherwise NULL will be returned. If `defn'
1229  * is NULL, no action will be taken regarding its contents, and no
1230  * error will occur.
1231  *
1232  * Note that this is also called with nparam zero to resolve
1233  * `ifdef'.
1234  *
1235  * If you already know which context macro belongs to, you can pass
1236  * the context pointer as first parameter; if you won't but name begins
1237  * with %$ the context will be automatically computed. If all_contexts
1238  * is true, macro will be searched in outer contexts as well.
1239  */
1240 static int
1241 smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
1242                int nocase)
1243 {
1244     SMacro *m;
1245
1246     if (ctx) {
1247         m = ctx->localmac;
1248     } else if (name[0] == '%' && name[1] == '$') {
1249         if (cstk)
1250             ctx = get_ctx(name, FALSE);
1251         if (!ctx)
1252             return FALSE;       /* got to return _something_ */
1253         m = ctx->localmac;
1254     } else {
1255         m = (SMacro *) hash_findix(smacros, name);
1256     }
1257
1258     while (m) {
1259         if (!mstrcmp(m->name, name, m->casesense && nocase) &&
1260             (nparam <= 0 || m->nparam == 0 || nparam == m->nparam)) {
1261             if (defn) {
1262                 if (nparam == m->nparam || nparam == -1)
1263                     *defn = m;
1264                 else
1265                     *defn = NULL;
1266             }
1267             return TRUE;
1268         }
1269         m = m->next;
1270     }
1271
1272     return FALSE;
1273 }
1274
1275 /*
1276  * Count and mark off the parameters in a multi-line macro call.
1277  * This is called both from within the multi-line macro expansion
1278  * code, and also to mark off the default parameters when provided
1279  * in a %macro definition line.
1280  */
1281 static void count_mmac_params(Token * t, int *nparam, Token *** params)
1282 {
1283     int paramsize, brace;
1284
1285     *nparam = paramsize = 0;
1286     *params = NULL;
1287     while (t) {
1288         if (*nparam >= paramsize) {
1289             paramsize += PARAM_DELTA;
1290             *params = nasm_realloc(*params, sizeof(**params) * paramsize);
1291         }
1292         skip_white_(t);
1293         brace = FALSE;
1294         if (tok_is_(t, "{"))
1295             brace = TRUE;
1296         (*params)[(*nparam)++] = t;
1297         while (tok_isnt_(t, brace ? "}" : ","))
1298             t = t->next;
1299         if (t) {                /* got a comma/brace */
1300             t = t->next;
1301             if (brace) {
1302                 /*
1303                  * Now we've found the closing brace, look further
1304                  * for the comma.
1305                  */
1306                 skip_white_(t);
1307                 if (tok_isnt_(t, ",")) {
1308                     error(ERR_NONFATAL,
1309                           "braces do not enclose all of macro parameter");
1310                     while (tok_isnt_(t, ","))
1311                         t = t->next;
1312                 }
1313                 if (t)
1314                     t = t->next;        /* eat the comma */
1315             }
1316         }
1317     }
1318 }
1319
1320 /*
1321  * Determine whether one of the various `if' conditions is true or
1322  * not.
1323  *
1324  * We must free the tline we get passed.
1325  */
1326 static int if_condition(Token * tline, enum preproc_token ct)
1327 {
1328     enum pp_conditional i = PP_COND(ct);
1329     int j;
1330     Token *t, *tt, **tptr, *origline;
1331     struct tokenval tokval;
1332     expr *evalresult;
1333     enum pp_token_type needtype;
1334
1335     origline = tline;
1336
1337     switch (i) {
1338     case PPC_IFCTX:
1339         j = FALSE;              /* have we matched yet? */
1340         while (cstk && tline) {
1341             skip_white_(tline);
1342             if (!tline || tline->type != TOK_ID) {
1343                 error(ERR_NONFATAL,
1344                       "`%s' expects context identifiers", pp_directives[ct]);
1345                 free_tlist(origline);
1346                 return -1;
1347             }
1348             if (!nasm_stricmp(tline->text, cstk->name))
1349                 j = TRUE;
1350             tline = tline->next;
1351         }
1352         break;
1353
1354     case PPC_IFDEF:
1355         j = FALSE;              /* have we matched yet? */
1356         while (tline) {
1357             skip_white_(tline);
1358             if (!tline || (tline->type != TOK_ID &&
1359                            (tline->type != TOK_PREPROC_ID ||
1360                             tline->text[1] != '$'))) {
1361                 error(ERR_NONFATAL,
1362                       "`%s' expects macro identifiers", pp_directives[ct]);
1363                 goto fail;
1364             }
1365             if (smacro_defined(NULL, tline->text, 0, NULL, 1))
1366                 j = TRUE;
1367             tline = tline->next;
1368         }
1369         break;
1370
1371     case PPC_IFIDN:
1372     case PPC_IFIDNI:
1373         tline = expand_smacro(tline);
1374         t = tt = tline;
1375         while (tok_isnt_(tt, ","))
1376             tt = tt->next;
1377         if (!tt) {
1378             error(ERR_NONFATAL,
1379                   "`%s' expects two comma-separated arguments",
1380                   pp_directives[ct]);
1381             goto fail;
1382         }
1383         tt = tt->next;
1384         j = TRUE;               /* assume equality unless proved not */
1385         while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt) {
1386             if (tt->type == TOK_OTHER && !strcmp(tt->text, ",")) {
1387                 error(ERR_NONFATAL, "`%s': more than one comma on line",
1388                       pp_directives[ct]);
1389                 goto fail;
1390             }
1391             if (t->type == TOK_WHITESPACE) {
1392                 t = t->next;
1393                 continue;
1394             }
1395             if (tt->type == TOK_WHITESPACE) {
1396                 tt = tt->next;
1397                 continue;
1398             }
1399             if (tt->type != t->type) {
1400                 j = FALSE;      /* found mismatching tokens */
1401                 break;
1402             }
1403             /* Unify surrounding quotes for strings */
1404             if (t->type == TOK_STRING) {
1405                 tt->text[0] = t->text[0];
1406                 tt->text[strlen(tt->text) - 1] = t->text[0];
1407             }
1408             if (mstrcmp(tt->text, t->text, i == PPC_IFIDN) != 0) {
1409                 j = FALSE;      /* found mismatching tokens */
1410                 break;
1411             }
1412
1413             t = t->next;
1414             tt = tt->next;
1415         }
1416         if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
1417             j = FALSE;          /* trailing gunk on one end or other */
1418         break;
1419
1420     case PPC_IFMACRO:
1421         {
1422             int found = 0;
1423             MMacro searching, *mmac;
1424
1425             tline = tline->next;
1426             skip_white_(tline);
1427             tline = expand_id(tline);
1428             if (!tok_type_(tline, TOK_ID)) {
1429                 error(ERR_NONFATAL,
1430                       "`%s' expects a macro name", pp_directives[ct]);
1431                 goto fail;
1432             }
1433             searching.name = nasm_strdup(tline->text);
1434             searching.casesense = (i == PP_MACRO);
1435             searching.plus = FALSE;
1436             searching.nolist = FALSE;
1437             searching.in_progress = FALSE;
1438             searching.rep_nest = NULL;
1439             searching.nparam_min = 0;
1440             searching.nparam_max = INT_MAX;
1441             tline = expand_smacro(tline->next);
1442             skip_white_(tline);
1443             if (!tline) {
1444             } else if (!tok_type_(tline, TOK_NUMBER)) {
1445                 error(ERR_NONFATAL,
1446                       "`%s' expects a parameter count or nothing",
1447                       pp_directives[ct]);
1448             } else {
1449                 searching.nparam_min = searching.nparam_max =
1450                     readnum(tline->text, &j);
1451                 if (j)
1452                     error(ERR_NONFATAL,
1453                           "unable to parse parameter count `%s'",
1454                           tline->text);
1455             }
1456             if (tline && tok_is_(tline->next, "-")) {
1457                 tline = tline->next->next;
1458                 if (tok_is_(tline, "*"))
1459                     searching.nparam_max = INT_MAX;
1460                 else if (!tok_type_(tline, TOK_NUMBER))
1461                     error(ERR_NONFATAL,
1462                           "`%s' expects a parameter count after `-'",
1463                           pp_directives[ct]);
1464                 else {
1465                     searching.nparam_max = readnum(tline->text, &j);
1466                     if (j)
1467                         error(ERR_NONFATAL,
1468                               "unable to parse parameter count `%s'",
1469                               tline->text);
1470                     if (searching.nparam_min > searching.nparam_max)
1471                         error(ERR_NONFATAL,
1472                               "minimum parameter count exceeds maximum");
1473                 }
1474             }
1475             if (tline && tok_is_(tline->next, "+")) {
1476                 tline = tline->next;
1477                 searching.plus = TRUE;
1478             }
1479             mmac = (MMacro *) hash_findix(mmacros, searching.name);
1480             while (mmac) {
1481                 if (!strcmp(mmac->name, searching.name) &&
1482                     (mmac->nparam_min <= searching.nparam_max
1483                      || searching.plus)
1484                     && (searching.nparam_min <= mmac->nparam_max
1485                         || mmac->plus)) {
1486                     found = TRUE;
1487                     break;
1488                 }
1489                 mmac = mmac->next;
1490             }
1491             nasm_free(searching.name);
1492             j = found;
1493             break;
1494         }
1495
1496     case PPC_IFID:
1497         needtype = TOK_ID;
1498         goto iftype;
1499     case PPC_IFNUM:
1500         needtype = TOK_NUMBER;
1501         goto iftype;
1502     case PPC_IFSTR:
1503         needtype = TOK_STRING;
1504         goto iftype;
1505
1506     iftype:
1507         tline = expand_smacro(tline);
1508         t = tline;
1509         while (tok_type_(t, TOK_WHITESPACE))
1510             t = t->next;
1511         j = FALSE;              /* placate optimiser */
1512         if (t)
1513             j = t->type == needtype;
1514         break;
1515
1516     case PPC_IF:
1517         t = tline = expand_smacro(tline);
1518         tptr = &t;
1519         tokval.t_type = TOKEN_INVALID;
1520         evalresult = evaluate(ppscan, tptr, &tokval,
1521                               NULL, pass | CRITICAL, error, NULL);
1522         if (!evalresult)
1523             return -1;
1524         if (tokval.t_type)
1525             error(ERR_WARNING,
1526                   "trailing garbage after expression ignored");
1527         if (!is_simple(evalresult)) {
1528             error(ERR_NONFATAL,
1529                   "non-constant value given to `%s'", pp_directives[ct]);
1530             goto fail;
1531         }
1532         j = reloc_value(evalresult) != 0;
1533         return j;
1534
1535     default:
1536         error(ERR_FATAL,
1537               "preprocessor directive `%s' not yet implemented",
1538               pp_directives[ct]);
1539         goto fail;
1540     }
1541
1542     free_tlist(origline);
1543     return j ^ PP_NEGATIVE(ct);
1544     
1545 fail:
1546     free_tlist(origline);
1547     return -1;
1548 }
1549
1550 /*
1551  * Expand macros in a string. Used in %error and %include directives.
1552  * First tokenize the string, apply "expand_smacro" and then de-tokenize back.
1553  * The returned variable should ALWAYS be freed after usage.
1554  */
1555 void expand_macros_in_string(char **p)
1556 {
1557     Token *line = tokenize(*p);
1558     line = expand_smacro(line);
1559     *p = detoken(line, FALSE);
1560 }
1561
1562 /**
1563  * find and process preprocessor directive in passed line
1564  * Find out if a line contains a preprocessor directive, and deal
1565  * with it if so.
1566  * 
1567  * If a directive _is_ found, it is the responsibility of this routine
1568  * (and not the caller) to free_tlist() the line.
1569  *
1570  * @param tline a pointer to the current tokeninzed line linked list
1571  * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND
1572  * 
1573  */
1574 static int do_directive(Token * tline)
1575 {
1576     enum preproc_token i;
1577     int j;
1578     int nparam, nolist;
1579     int k, m;
1580     int offset;
1581     char *p, *mname;
1582     Include *inc;
1583     Context *ctx;
1584     Cond *cond;
1585     SMacro *smac, **smhead;
1586     MMacro *mmac, **mmhead;
1587     Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
1588     Line *l;
1589     struct tokenval tokval;
1590     expr *evalresult;
1591     MMacro *tmp_defining;       /* Used when manipulating rep_nest */
1592
1593     origline = tline;
1594
1595     skip_white_(tline);
1596     if (!tok_type_(tline, TOK_PREPROC_ID) ||
1597         (tline->text[1] == '%' || tline->text[1] == '$'
1598          || tline->text[1] == '!'))
1599         return NO_DIRECTIVE_FOUND;
1600
1601     i = pp_token_hash(tline->text);
1602
1603     /*
1604      * If we're in a non-emitting branch of a condition construct,
1605      * or walking to the end of an already terminated %rep block,
1606      * we should ignore all directives except for condition
1607      * directives.
1608      */
1609     if (((istk->conds && !emitting(istk->conds->state)) ||
1610          (istk->mstk && !istk->mstk->in_progress)) && !is_condition(i)) {
1611         return NO_DIRECTIVE_FOUND;
1612     }
1613
1614     /*
1615      * If we're defining a macro or reading a %rep block, we should
1616      * ignore all directives except for %macro/%imacro (which
1617      * generate an error), %endm/%endmacro, and (only if we're in a
1618      * %rep block) %endrep. If we're in a %rep block, another %rep
1619      * causes an error, so should be let through.
1620      */
1621     if (defining && i != PP_MACRO && i != PP_IMACRO &&
1622         i != PP_ENDMACRO && i != PP_ENDM &&
1623         (defining->name || (i != PP_ENDREP && i != PP_REP))) {
1624         return NO_DIRECTIVE_FOUND;
1625     }
1626
1627     switch (i) {
1628     case PP_INVALID:
1629         error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
1630               tline->text);
1631         return NO_DIRECTIVE_FOUND;      /* didn't get it */
1632
1633     case PP_STACKSIZE:
1634         /* Directive to tell NASM what the default stack size is. The
1635          * default is for a 16-bit stack, and this can be overriden with
1636          * %stacksize large.
1637          * the following form:
1638          *
1639          *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1640          */
1641         tline = tline->next;
1642         if (tline && tline->type == TOK_WHITESPACE)
1643             tline = tline->next;
1644         if (!tline || tline->type != TOK_ID) {
1645             error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
1646             free_tlist(origline);
1647             return DIRECTIVE_FOUND;
1648         }
1649         if (nasm_stricmp(tline->text, "flat") == 0) {
1650             /* All subsequent ARG directives are for a 32-bit stack */
1651             StackSize = 4;
1652             StackPointer = "ebp";
1653             ArgOffset = 8;
1654             LocalOffset = 4;
1655         } else if (nasm_stricmp(tline->text, "large") == 0) {
1656             /* All subsequent ARG directives are for a 16-bit stack,
1657              * far function call.
1658              */
1659             StackSize = 2;
1660             StackPointer = "bp";
1661             ArgOffset = 4;
1662             LocalOffset = 2;
1663         } else if (nasm_stricmp(tline->text, "small") == 0) {
1664             /* All subsequent ARG directives are for a 16-bit stack,
1665              * far function call. We don't support near functions.
1666              */
1667             StackSize = 2;
1668             StackPointer = "bp";
1669             ArgOffset = 6;
1670             LocalOffset = 2;
1671         } else {
1672             error(ERR_NONFATAL, "`%%stacksize' invalid size type");
1673             free_tlist(origline);
1674             return DIRECTIVE_FOUND;
1675         }
1676         free_tlist(origline);
1677         return DIRECTIVE_FOUND;
1678
1679     case PP_ARG:
1680         /* TASM like ARG directive to define arguments to functions, in
1681          * the following form:
1682          *
1683          *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1684          */
1685         offset = ArgOffset;
1686         do {
1687             char *arg, directive[256];
1688             int size = StackSize;
1689
1690             /* Find the argument name */
1691             tline = tline->next;
1692             if (tline && tline->type == TOK_WHITESPACE)
1693                 tline = tline->next;
1694             if (!tline || tline->type != TOK_ID) {
1695                 error(ERR_NONFATAL, "`%%arg' missing argument parameter");
1696                 free_tlist(origline);
1697                 return DIRECTIVE_FOUND;
1698             }
1699             arg = tline->text;
1700
1701             /* Find the argument size type */
1702             tline = tline->next;
1703             if (!tline || tline->type != TOK_OTHER
1704                 || tline->text[0] != ':') {
1705                 error(ERR_NONFATAL,
1706                       "Syntax error processing `%%arg' directive");
1707                 free_tlist(origline);
1708                 return DIRECTIVE_FOUND;
1709             }
1710             tline = tline->next;
1711             if (!tline || tline->type != TOK_ID) {
1712                 error(ERR_NONFATAL, "`%%arg' missing size type parameter");
1713                 free_tlist(origline);
1714                 return DIRECTIVE_FOUND;
1715             }
1716
1717             /* Allow macro expansion of type parameter */
1718             tt = tokenize(tline->text);
1719             tt = expand_smacro(tt);
1720             if (nasm_stricmp(tt->text, "byte") == 0) {
1721                 size = MAX(StackSize, 1);
1722             } else if (nasm_stricmp(tt->text, "word") == 0) {
1723                 size = MAX(StackSize, 2);
1724             } else if (nasm_stricmp(tt->text, "dword") == 0) {
1725                 size = MAX(StackSize, 4);
1726             } else if (nasm_stricmp(tt->text, "qword") == 0) {
1727                 size = MAX(StackSize, 8);
1728             } else if (nasm_stricmp(tt->text, "tword") == 0) {
1729                 size = MAX(StackSize, 10);
1730             } else {
1731                 error(ERR_NONFATAL,
1732                       "Invalid size type for `%%arg' missing directive");
1733                 free_tlist(tt);
1734                 free_tlist(origline);
1735                 return DIRECTIVE_FOUND;
1736             }
1737             free_tlist(tt);
1738
1739             /* Now define the macro for the argument */
1740             snprintf(directive, sizeof(directive), "%%define %s (%s+%d)",
1741                      arg, StackPointer, offset);
1742             do_directive(tokenize(directive));
1743             offset += size;
1744
1745             /* Move to the next argument in the list */
1746             tline = tline->next;
1747             if (tline && tline->type == TOK_WHITESPACE)
1748                 tline = tline->next;
1749         }
1750         while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
1751         free_tlist(origline);
1752         return DIRECTIVE_FOUND;
1753
1754     case PP_LOCAL:
1755         /* TASM like LOCAL directive to define local variables for a
1756          * function, in the following form:
1757          *
1758          *      LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1759          *
1760          * The '= LocalSize' at the end is ignored by NASM, but is
1761          * required by TASM to define the local parameter size (and used
1762          * by the TASM macro package).
1763          */
1764         offset = LocalOffset;
1765         do {
1766             char *local, directive[256];
1767             int size = StackSize;
1768
1769             /* Find the argument name */
1770             tline = tline->next;
1771             if (tline && tline->type == TOK_WHITESPACE)
1772                 tline = tline->next;
1773             if (!tline || tline->type != TOK_ID) {
1774                 error(ERR_NONFATAL,
1775                       "`%%local' missing argument parameter");
1776                 free_tlist(origline);
1777                 return DIRECTIVE_FOUND;
1778             }
1779             local = tline->text;
1780
1781             /* Find the argument size type */
1782             tline = tline->next;
1783             if (!tline || tline->type != TOK_OTHER
1784                 || tline->text[0] != ':') {
1785                 error(ERR_NONFATAL,
1786                       "Syntax error processing `%%local' directive");
1787                 free_tlist(origline);
1788                 return DIRECTIVE_FOUND;
1789             }
1790             tline = tline->next;
1791             if (!tline || tline->type != TOK_ID) {
1792                 error(ERR_NONFATAL,
1793                       "`%%local' missing size type parameter");
1794                 free_tlist(origline);
1795                 return DIRECTIVE_FOUND;
1796             }
1797
1798             /* Allow macro expansion of type parameter */
1799             tt = tokenize(tline->text);
1800             tt = expand_smacro(tt);
1801             if (nasm_stricmp(tt->text, "byte") == 0) {
1802                 size = MAX(StackSize, 1);
1803             } else if (nasm_stricmp(tt->text, "word") == 0) {
1804                 size = MAX(StackSize, 2);
1805             } else if (nasm_stricmp(tt->text, "dword") == 0) {
1806                 size = MAX(StackSize, 4);
1807             } else if (nasm_stricmp(tt->text, "qword") == 0) {
1808                 size = MAX(StackSize, 8);
1809             } else if (nasm_stricmp(tt->text, "tword") == 0) {
1810                 size = MAX(StackSize, 10);
1811             } else {
1812                 error(ERR_NONFATAL,
1813                       "Invalid size type for `%%local' missing directive");
1814                 free_tlist(tt);
1815                 free_tlist(origline);
1816                 return DIRECTIVE_FOUND;
1817             }
1818             free_tlist(tt);
1819
1820             /* Now define the macro for the argument */
1821             snprintf(directive, sizeof(directive), "%%define %s (%s-%d)",
1822                      local, StackPointer, offset);
1823             do_directive(tokenize(directive));
1824             offset += size;
1825
1826             /* Now define the assign to setup the enter_c macro correctly */
1827             snprintf(directive, sizeof(directive),
1828                      "%%assign %%$localsize %%$localsize+%d", size);
1829             do_directive(tokenize(directive));
1830
1831             /* Move to the next argument in the list */
1832             tline = tline->next;
1833             if (tline && tline->type == TOK_WHITESPACE)
1834                 tline = tline->next;
1835         }
1836         while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
1837         free_tlist(origline);
1838         return DIRECTIVE_FOUND;
1839
1840     case PP_CLEAR:
1841         if (tline->next)
1842             error(ERR_WARNING, "trailing garbage after `%%clear' ignored");
1843         free_macros();
1844         init_macros();
1845         free_tlist(origline);
1846         return DIRECTIVE_FOUND;
1847
1848     case PP_INCLUDE:
1849         tline = tline->next;
1850         skip_white_(tline);
1851         if (!tline || (tline->type != TOK_STRING &&
1852                        tline->type != TOK_INTERNAL_STRING)) {
1853             error(ERR_NONFATAL, "`%%include' expects a file name");
1854             free_tlist(origline);
1855             return DIRECTIVE_FOUND;     /* but we did _something_ */
1856         }
1857         if (tline->next)
1858             error(ERR_WARNING,
1859                   "trailing garbage after `%%include' ignored");
1860         if (tline->type != TOK_INTERNAL_STRING) {
1861             p = tline->text + 1;        /* point past the quote to the name */
1862             p[strlen(p) - 1] = '\0';    /* remove the trailing quote */
1863         } else
1864             p = tline->text;    /* internal_string is easier */
1865         expand_macros_in_string(&p);
1866         inc = nasm_malloc(sizeof(Include));
1867         inc->next = istk;
1868         inc->conds = NULL;
1869         inc->fp = inc_fopen(p);
1870         inc->fname = src_set_fname(p);
1871         inc->lineno = src_set_linnum(0);
1872         inc->lineinc = 1;
1873         inc->expansion = NULL;
1874         inc->mstk = NULL;
1875         istk = inc;
1876         list->uplevel(LIST_INCLUDE);
1877         free_tlist(origline);
1878         return DIRECTIVE_FOUND;
1879
1880     case PP_PUSH:
1881         tline = tline->next;
1882         skip_white_(tline);
1883         tline = expand_id(tline);
1884         if (!tok_type_(tline, TOK_ID)) {
1885             error(ERR_NONFATAL, "`%%push' expects a context identifier");
1886             free_tlist(origline);
1887             return DIRECTIVE_FOUND;     /* but we did _something_ */
1888         }
1889         if (tline->next)
1890             error(ERR_WARNING, "trailing garbage after `%%push' ignored");
1891         ctx = nasm_malloc(sizeof(Context));
1892         ctx->next = cstk;
1893         ctx->localmac = NULL;
1894         ctx->name = nasm_strdup(tline->text);
1895         ctx->number = unique++;
1896         cstk = ctx;
1897         free_tlist(origline);
1898         break;
1899
1900     case PP_REPL:
1901         tline = tline->next;
1902         skip_white_(tline);
1903         tline = expand_id(tline);
1904         if (!tok_type_(tline, TOK_ID)) {
1905             error(ERR_NONFATAL, "`%%repl' expects a context identifier");
1906             free_tlist(origline);
1907             return DIRECTIVE_FOUND;     /* but we did _something_ */
1908         }
1909         if (tline->next)
1910             error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
1911         if (!cstk)
1912             error(ERR_NONFATAL, "`%%repl': context stack is empty");
1913         else {
1914             nasm_free(cstk->name);
1915             cstk->name = nasm_strdup(tline->text);
1916         }
1917         free_tlist(origline);
1918         break;
1919
1920     case PP_POP:
1921         if (tline->next)
1922             error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
1923         if (!cstk)
1924             error(ERR_NONFATAL, "`%%pop': context stack is already empty");
1925         else
1926             ctx_pop();
1927         free_tlist(origline);
1928         break;
1929
1930     case PP_ERROR:
1931         tline->next = expand_smacro(tline->next);
1932         tline = tline->next;
1933         skip_white_(tline);
1934         if (tok_type_(tline, TOK_STRING)) {
1935             p = tline->text + 1;        /* point past the quote to the name */
1936             p[strlen(p) - 1] = '\0';    /* remove the trailing quote */
1937             expand_macros_in_string(&p);
1938             error(ERR_NONFATAL, "%s", p);
1939             nasm_free(p);
1940         } else {
1941             p = detoken(tline, FALSE);
1942             error(ERR_WARNING, "%s", p);
1943             nasm_free(p);
1944         }
1945         free_tlist(origline);
1946         break;
1947
1948     CASE_PP_IF:
1949         if (istk->conds && !emitting(istk->conds->state))
1950             j = COND_NEVER;
1951         else {
1952             j = if_condition(tline->next, i);
1953             tline->next = NULL; /* it got freed */
1954             free_tlist(origline);
1955             j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
1956         }
1957         cond = nasm_malloc(sizeof(Cond));
1958         cond->next = istk->conds;
1959         cond->state = j;
1960         istk->conds = cond;
1961         return DIRECTIVE_FOUND;
1962
1963     CASE_PP_ELIF:
1964         if (!istk->conds)
1965             error(ERR_FATAL, "`%s': no matching `%%if'", pp_directives[i]);
1966         if (emitting(istk->conds->state)
1967             || istk->conds->state == COND_NEVER)
1968             istk->conds->state = COND_NEVER;
1969         else {
1970             /*
1971              * IMPORTANT: In the case of %if, we will already have
1972              * called expand_mmac_params(); however, if we're
1973              * processing an %elif we must have been in a
1974              * non-emitting mode, which would have inhibited
1975              * the normal invocation of expand_mmac_params().  Therefore,
1976              * we have to do it explicitly here.
1977              */
1978             j = if_condition(expand_mmac_params(tline->next), i);
1979             tline->next = NULL; /* it got freed */
1980             free_tlist(origline);
1981             istk->conds->state =
1982                 j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
1983         }
1984         return DIRECTIVE_FOUND;
1985
1986     case PP_ELSE:
1987         if (tline->next)
1988             error(ERR_WARNING, "trailing garbage after `%%else' ignored");
1989         if (!istk->conds)
1990             error(ERR_FATAL, "`%%else': no matching `%%if'");
1991         if (emitting(istk->conds->state)
1992             || istk->conds->state == COND_NEVER)
1993             istk->conds->state = COND_ELSE_FALSE;
1994         else
1995             istk->conds->state = COND_ELSE_TRUE;
1996         free_tlist(origline);
1997         return DIRECTIVE_FOUND;
1998
1999     case PP_ENDIF:
2000         if (tline->next)
2001             error(ERR_WARNING, "trailing garbage after `%%endif' ignored");
2002         if (!istk->conds)
2003             error(ERR_FATAL, "`%%endif': no matching `%%if'");
2004         cond = istk->conds;
2005         istk->conds = cond->next;
2006         nasm_free(cond);
2007         free_tlist(origline);
2008         return DIRECTIVE_FOUND;
2009
2010     case PP_MACRO:
2011     case PP_IMACRO:
2012         if (defining)
2013             error(ERR_FATAL,
2014                   "`%%%smacro': already defining a macro",
2015                   (i == PP_IMACRO ? "i" : ""));
2016         tline = tline->next;
2017         skip_white_(tline);
2018         tline = expand_id(tline);
2019         if (!tok_type_(tline, TOK_ID)) {
2020             error(ERR_NONFATAL,
2021                   "`%%%smacro' expects a macro name",
2022                   (i == PP_IMACRO ? "i" : ""));
2023             return DIRECTIVE_FOUND;
2024         }
2025         defining = nasm_malloc(sizeof(MMacro));
2026         defining->name = nasm_strdup(tline->text);
2027         defining->casesense = (i == PP_MACRO);
2028         defining->plus = FALSE;
2029         defining->nolist = FALSE;
2030         defining->in_progress = FALSE;
2031         defining->rep_nest = NULL;
2032         tline = expand_smacro(tline->next);
2033         skip_white_(tline);
2034         if (!tok_type_(tline, TOK_NUMBER)) {
2035             error(ERR_NONFATAL,
2036                   "`%%%smacro' expects a parameter count",
2037                   (i == PP_IMACRO ? "i" : ""));
2038             defining->nparam_min = defining->nparam_max = 0;
2039         } else {
2040             defining->nparam_min = defining->nparam_max =
2041                 readnum(tline->text, &j);
2042             if (j)
2043                 error(ERR_NONFATAL,
2044                       "unable to parse parameter count `%s'", tline->text);
2045         }
2046         if (tline && tok_is_(tline->next, "-")) {
2047             tline = tline->next->next;
2048             if (tok_is_(tline, "*"))
2049                 defining->nparam_max = INT_MAX;
2050             else if (!tok_type_(tline, TOK_NUMBER))
2051                 error(ERR_NONFATAL,
2052                       "`%%%smacro' expects a parameter count after `-'",
2053                       (i == PP_IMACRO ? "i" : ""));
2054             else {
2055                 defining->nparam_max = readnum(tline->text, &j);
2056                 if (j)
2057                     error(ERR_NONFATAL,
2058                           "unable to parse parameter count `%s'",
2059                           tline->text);
2060                 if (defining->nparam_min > defining->nparam_max)
2061                     error(ERR_NONFATAL,
2062                           "minimum parameter count exceeds maximum");
2063             }
2064         }
2065         if (tline && tok_is_(tline->next, "+")) {
2066             tline = tline->next;
2067             defining->plus = TRUE;
2068         }
2069         if (tline && tok_type_(tline->next, TOK_ID) &&
2070             !nasm_stricmp(tline->next->text, ".nolist")) {
2071             tline = tline->next;
2072             defining->nolist = TRUE;
2073         }
2074         mmac = (MMacro *) hash_findix(mmacros, defining->name);
2075         while (mmac) {
2076             if (!strcmp(mmac->name, defining->name) &&
2077                 (mmac->nparam_min <= defining->nparam_max
2078                  || defining->plus)
2079                 && (defining->nparam_min <= mmac->nparam_max
2080                     || mmac->plus)) {
2081                 error(ERR_WARNING,
2082                       "redefining multi-line macro `%s'", defining->name);
2083                 break;
2084             }
2085             mmac = mmac->next;
2086         }
2087         /*
2088          * Handle default parameters.
2089          */
2090         if (tline && tline->next) {
2091             defining->dlist = tline->next;
2092             tline->next = NULL;
2093             count_mmac_params(defining->dlist, &defining->ndefs,
2094                               &defining->defaults);
2095         } else {
2096             defining->dlist = NULL;
2097             defining->defaults = NULL;
2098         }
2099         defining->expansion = NULL;
2100         free_tlist(origline);
2101         return DIRECTIVE_FOUND;
2102
2103     case PP_ENDM:
2104     case PP_ENDMACRO:
2105         if (!defining) {
2106             error(ERR_NONFATAL, "`%s': not defining a macro", tline->text);
2107             return DIRECTIVE_FOUND;
2108         }
2109         mmhead = (MMacro **) hash_findi_add(mmacros, defining->name);
2110         defining->next = *mmhead;
2111         *mmhead = defining;
2112         defining = NULL;
2113         free_tlist(origline);
2114         return DIRECTIVE_FOUND;
2115
2116     case PP_ROTATE:
2117         if (tline->next && tline->next->type == TOK_WHITESPACE)
2118             tline = tline->next;
2119         if (tline->next == NULL) {
2120             free_tlist(origline);
2121             error(ERR_NONFATAL, "`%%rotate' missing rotate count");
2122             return DIRECTIVE_FOUND;
2123         }
2124         t = expand_smacro(tline->next);
2125         tline->next = NULL;
2126         free_tlist(origline);
2127         tline = t;
2128         tptr = &t;
2129         tokval.t_type = TOKEN_INVALID;
2130         evalresult =
2131             evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2132         free_tlist(tline);
2133         if (!evalresult)
2134             return DIRECTIVE_FOUND;
2135         if (tokval.t_type)
2136             error(ERR_WARNING,
2137                   "trailing garbage after expression ignored");
2138         if (!is_simple(evalresult)) {
2139             error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
2140             return DIRECTIVE_FOUND;
2141         }
2142         mmac = istk->mstk;
2143         while (mmac && !mmac->name)     /* avoid mistaking %reps for macros */
2144             mmac = mmac->next_active;
2145         if (!mmac) {
2146             error(ERR_NONFATAL, "`%%rotate' invoked outside a macro call");
2147         } else if (mmac->nparam == 0) {
2148             error(ERR_NONFATAL,
2149                   "`%%rotate' invoked within macro without parameters");
2150         } else {
2151             mmac->rotate = mmac->rotate + reloc_value(evalresult);
2152
2153             if (mmac->rotate < 0)
2154                 mmac->rotate =
2155                     mmac->nparam - (-mmac->rotate) % mmac->nparam;
2156             mmac->rotate %= mmac->nparam;
2157         }
2158         return DIRECTIVE_FOUND;
2159
2160     case PP_REP:
2161         nolist = FALSE;
2162         do {
2163             tline = tline->next;
2164         } while (tok_type_(tline, TOK_WHITESPACE));
2165
2166         if (tok_type_(tline, TOK_ID) &&
2167             nasm_stricmp(tline->text, ".nolist") == 0) {
2168             nolist = TRUE;
2169             do {
2170                 tline = tline->next;
2171             } while (tok_type_(tline, TOK_WHITESPACE));
2172         }
2173
2174         if (tline) {
2175             t = expand_smacro(tline);
2176             tptr = &t;
2177             tokval.t_type = TOKEN_INVALID;
2178             evalresult =
2179                 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2180             if (!evalresult) {
2181                 free_tlist(origline);
2182                 return DIRECTIVE_FOUND;
2183             }
2184             if (tokval.t_type)
2185                 error(ERR_WARNING,
2186                       "trailing garbage after expression ignored");
2187             if (!is_simple(evalresult)) {
2188                 error(ERR_NONFATAL, "non-constant value given to `%%rep'");
2189                 return DIRECTIVE_FOUND;
2190             }
2191             i = (int)reloc_value(evalresult) + 1;
2192         } else {
2193             error(ERR_NONFATAL, "`%%rep' expects a repeat count");
2194             i = 0;
2195         }
2196         free_tlist(origline);
2197
2198         tmp_defining = defining;
2199         defining = nasm_malloc(sizeof(MMacro));
2200         defining->name = NULL;  /* flags this macro as a %rep block */
2201         defining->casesense = 0;
2202         defining->plus = FALSE;
2203         defining->nolist = nolist;
2204         defining->in_progress = i;
2205         defining->nparam_min = defining->nparam_max = 0;
2206         defining->defaults = NULL;
2207         defining->dlist = NULL;
2208         defining->expansion = NULL;
2209         defining->next_active = istk->mstk;
2210         defining->rep_nest = tmp_defining;
2211         return DIRECTIVE_FOUND;
2212
2213     case PP_ENDREP:
2214         if (!defining || defining->name) {
2215             error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
2216             return DIRECTIVE_FOUND;
2217         }
2218
2219         /*
2220          * Now we have a "macro" defined - although it has no name
2221          * and we won't be entering it in the hash tables - we must
2222          * push a macro-end marker for it on to istk->expansion.
2223          * After that, it will take care of propagating itself (a
2224          * macro-end marker line for a macro which is really a %rep
2225          * block will cause the macro to be re-expanded, complete
2226          * with another macro-end marker to ensure the process
2227          * continues) until the whole expansion is forcibly removed
2228          * from istk->expansion by a %exitrep.
2229          */
2230         l = nasm_malloc(sizeof(Line));
2231         l->next = istk->expansion;
2232         l->finishes = defining;
2233         l->first = NULL;
2234         istk->expansion = l;
2235
2236         istk->mstk = defining;
2237
2238         list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
2239         tmp_defining = defining;
2240         defining = defining->rep_nest;
2241         free_tlist(origline);
2242         return DIRECTIVE_FOUND;
2243
2244     case PP_EXITREP:
2245         /*
2246          * We must search along istk->expansion until we hit a
2247          * macro-end marker for a macro with no name. Then we set
2248          * its `in_progress' flag to 0.
2249          */
2250         for (l = istk->expansion; l; l = l->next)
2251             if (l->finishes && !l->finishes->name)
2252                 break;
2253
2254         if (l)
2255             l->finishes->in_progress = 0;
2256         else
2257             error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
2258         free_tlist(origline);
2259         return DIRECTIVE_FOUND;
2260
2261     case PP_XDEFINE:
2262     case PP_IXDEFINE:
2263     case PP_DEFINE:
2264     case PP_IDEFINE:
2265         tline = tline->next;
2266         skip_white_(tline);
2267         tline = expand_id(tline);
2268         if (!tline || (tline->type != TOK_ID &&
2269                        (tline->type != TOK_PREPROC_ID ||
2270                         tline->text[1] != '$'))) {
2271             error(ERR_NONFATAL,
2272                   "`%%%s%sdefine' expects a macro identifier",
2273                   ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""),
2274                   ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : ""));
2275             free_tlist(origline);
2276             return DIRECTIVE_FOUND;
2277         }
2278
2279         ctx = get_ctx(tline->text, FALSE);
2280
2281         mname = tline->text;
2282         last = tline;
2283         param_start = tline = tline->next;
2284         nparam = 0;
2285
2286         /* Expand the macro definition now for %xdefine and %ixdefine */
2287         if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
2288             tline = expand_smacro(tline);
2289
2290         if (tok_is_(tline, "(")) {
2291             /*
2292              * This macro has parameters.
2293              */
2294
2295             tline = tline->next;
2296             while (1) {
2297                 skip_white_(tline);
2298                 if (!tline) {
2299                     error(ERR_NONFATAL, "parameter identifier expected");
2300                     free_tlist(origline);
2301                     return DIRECTIVE_FOUND;
2302                 }
2303                 if (tline->type != TOK_ID) {
2304                     error(ERR_NONFATAL,
2305                           "`%s': parameter identifier expected",
2306                           tline->text);
2307                     free_tlist(origline);
2308                     return DIRECTIVE_FOUND;
2309                 }
2310                 tline->type = TOK_SMAC_PARAM + nparam++;
2311                 tline = tline->next;
2312                 skip_white_(tline);
2313                 if (tok_is_(tline, ",")) {
2314                     tline = tline->next;
2315                     continue;
2316                 }
2317                 if (!tok_is_(tline, ")")) {
2318                     error(ERR_NONFATAL,
2319                           "`)' expected to terminate macro template");
2320                     free_tlist(origline);
2321                     return DIRECTIVE_FOUND;
2322                 }
2323                 break;
2324             }
2325             last = tline;
2326             tline = tline->next;
2327         }
2328         if (tok_type_(tline, TOK_WHITESPACE))
2329             last = tline, tline = tline->next;
2330         macro_start = NULL;
2331         last->next = NULL;
2332         t = tline;
2333         while (t) {
2334             if (t->type == TOK_ID) {
2335                 for (tt = param_start; tt; tt = tt->next)
2336                     if (tt->type >= TOK_SMAC_PARAM &&
2337                         !strcmp(tt->text, t->text))
2338                         t->type = tt->type;
2339             }
2340             tt = t->next;
2341             t->next = macro_start;
2342             macro_start = t;
2343             t = tt;
2344         }
2345         /*
2346          * Good. We now have a macro name, a parameter count, and a
2347          * token list (in reverse order) for an expansion. We ought
2348          * to be OK just to create an SMacro, store it, and let
2349          * free_tlist have the rest of the line (which we have
2350          * carefully re-terminated after chopping off the expansion
2351          * from the end).
2352          */
2353         if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE)) {
2354             if (!smac) {
2355                 error(ERR_WARNING,
2356                       "single-line macro `%s' defined both with and"
2357                       " without parameters", mname);
2358                 free_tlist(origline);
2359                 free_tlist(macro_start);
2360                 return DIRECTIVE_FOUND;
2361             } else {
2362                 /*
2363                  * We're redefining, so we have to take over an
2364                  * existing SMacro structure. This means freeing
2365                  * what was already in it.
2366                  */
2367                 nasm_free(smac->name);
2368                 free_tlist(smac->expansion);
2369             }
2370         } else {
2371             if (!ctx)
2372                 smhead = (SMacro **) hash_findi_add(smacros, mname);
2373             else
2374                 smhead = &ctx->localmac;
2375
2376             smac = nasm_malloc(sizeof(SMacro));
2377             smac->next = *smhead;
2378             *smhead = smac;
2379         }
2380         smac->name = nasm_strdup(mname);
2381         smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE));
2382         smac->nparam = nparam;
2383         smac->expansion = macro_start;
2384         smac->in_progress = FALSE;
2385         free_tlist(origline);
2386         return DIRECTIVE_FOUND;
2387
2388     case PP_UNDEF:
2389         tline = tline->next;
2390         skip_white_(tline);
2391         tline = expand_id(tline);
2392         if (!tline || (tline->type != TOK_ID &&
2393                        (tline->type != TOK_PREPROC_ID ||
2394                         tline->text[1] != '$'))) {
2395             error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
2396             free_tlist(origline);
2397             return DIRECTIVE_FOUND;
2398         }
2399         if (tline->next) {
2400             error(ERR_WARNING,
2401                   "trailing garbage after macro name ignored");
2402         }
2403
2404         /* Find the context that symbol belongs to */
2405         ctx = get_ctx(tline->text, FALSE);
2406         if (!ctx)
2407             smhead = (SMacro **) hash_findi(smacros, tline->text, NULL);
2408         else
2409             smhead = &ctx->localmac;
2410
2411         if (smhead) {
2412             SMacro *s, **sp;
2413
2414             mname = tline->text;
2415             last = tline;
2416             last->next = NULL;
2417             
2418             /*
2419              * We now have a macro name... go hunt for it.
2420              */
2421             for (sp = smhead; *sp; sp = &(*sp)->next) {
2422                 s = *sp;
2423                 if (!mstrcmp(s->name, tline->text, s->casesense)) {
2424                     *sp = s->next;
2425                     nasm_free(s->name);
2426                     free_tlist(s->expansion);
2427                     nasm_free(s);
2428                 }
2429             }
2430             free_tlist(origline);
2431         }
2432         return DIRECTIVE_FOUND;
2433
2434     case PP_STRLEN:
2435         tline = tline->next;
2436         skip_white_(tline);
2437         tline = expand_id(tline);
2438         if (!tline || (tline->type != TOK_ID &&
2439                        (tline->type != TOK_PREPROC_ID ||
2440                         tline->text[1] != '$'))) {
2441             error(ERR_NONFATAL,
2442                   "`%%strlen' expects a macro identifier as first parameter");
2443             free_tlist(origline);
2444             return DIRECTIVE_FOUND;
2445         }
2446         ctx = get_ctx(tline->text, FALSE);
2447
2448         mname = tline->text;
2449         last = tline;
2450         tline = expand_smacro(tline->next);
2451         last->next = NULL;
2452
2453         t = tline;
2454         while (tok_type_(t, TOK_WHITESPACE))
2455             t = t->next;
2456         /* t should now point to the string */
2457         if (t->type != TOK_STRING) {
2458             error(ERR_NONFATAL,
2459                   "`%%strlen` requires string as second parameter");
2460             free_tlist(tline);
2461             free_tlist(origline);
2462             return DIRECTIVE_FOUND;
2463         }
2464
2465         macro_start = nasm_malloc(sizeof(*macro_start));
2466         macro_start->next = NULL;
2467         make_tok_num(macro_start, strlen(t->text) - 2);
2468         macro_start->mac = NULL;
2469
2470         /*
2471          * We now have a macro name, an implicit parameter count of
2472          * zero, and a numeric token to use as an expansion. Create
2473          * and store an SMacro.
2474          */
2475         if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN)) {
2476             if (!smac)
2477                 error(ERR_WARNING,
2478                       "single-line macro `%s' defined both with and"
2479                       " without parameters", mname);
2480             else {
2481                 /*
2482                  * We're redefining, so we have to take over an
2483                  * existing SMacro structure. This means freeing
2484                  * what was already in it.
2485                  */
2486                 nasm_free(smac->name);
2487                 free_tlist(smac->expansion);
2488             }
2489         } else {
2490             if (!ctx)
2491                 smhead = (SMacro **) hash_findi_add(smacros, mname);
2492             else
2493                 smhead = &ctx->localmac;
2494
2495             smac = nasm_malloc(sizeof(SMacro));
2496             smac->next = *smhead;
2497             *smhead = smac;
2498         }
2499         smac->name = nasm_strdup(mname);
2500         smac->casesense = (i == PP_STRLEN);
2501         smac->nparam = 0;
2502         smac->expansion = macro_start;
2503         smac->in_progress = FALSE;
2504         free_tlist(tline);
2505         free_tlist(origline);
2506         return DIRECTIVE_FOUND;
2507
2508     case PP_SUBSTR:
2509         tline = tline->next;
2510         skip_white_(tline);
2511         tline = expand_id(tline);
2512         if (!tline || (tline->type != TOK_ID &&
2513                        (tline->type != TOK_PREPROC_ID ||
2514                         tline->text[1] != '$'))) {
2515             error(ERR_NONFATAL,
2516                   "`%%substr' expects a macro identifier as first parameter");
2517             free_tlist(origline);
2518             return DIRECTIVE_FOUND;
2519         }
2520         ctx = get_ctx(tline->text, FALSE);
2521
2522         mname = tline->text;
2523         last = tline;
2524         tline = expand_smacro(tline->next);
2525         last->next = NULL;
2526
2527         t = tline->next;
2528         while (tok_type_(t, TOK_WHITESPACE))
2529             t = t->next;
2530
2531         /* t should now point to the string */
2532         if (t->type != TOK_STRING) {
2533             error(ERR_NONFATAL,
2534                   "`%%substr` requires string as second parameter");
2535             free_tlist(tline);
2536             free_tlist(origline);
2537             return DIRECTIVE_FOUND;
2538         }
2539
2540         tt = t->next;
2541         tptr = &tt;
2542         tokval.t_type = TOKEN_INVALID;
2543         evalresult =
2544             evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2545         if (!evalresult) {
2546             free_tlist(tline);
2547             free_tlist(origline);
2548             return DIRECTIVE_FOUND;
2549         }
2550         if (!is_simple(evalresult)) {
2551             error(ERR_NONFATAL, "non-constant value given to `%%substr`");
2552             free_tlist(tline);
2553             free_tlist(origline);
2554             return DIRECTIVE_FOUND;
2555         }
2556
2557         macro_start = nasm_malloc(sizeof(*macro_start));
2558         macro_start->next = NULL;
2559         macro_start->text = nasm_strdup("'''");
2560         if (evalresult->value > 0
2561             && evalresult->value < strlen(t->text) - 1) {
2562             macro_start->text[1] = t->text[evalresult->value];
2563         } else {
2564             macro_start->text[2] = '\0';
2565         }
2566         macro_start->type = TOK_STRING;
2567         macro_start->mac = NULL;
2568
2569         /*
2570          * We now have a macro name, an implicit parameter count of
2571          * zero, and a numeric token to use as an expansion. Create
2572          * and store an SMacro.
2573          */
2574         if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR)) {
2575             if (!smac)
2576                 error(ERR_WARNING,
2577                       "single-line macro `%s' defined both with and"
2578                       " without parameters", mname);
2579             else {
2580                 /*
2581                  * We're redefining, so we have to take over an
2582                  * existing SMacro structure. This means freeing
2583                  * what was already in it.
2584                  */
2585                 nasm_free(smac->name);
2586                 free_tlist(smac->expansion);
2587             }
2588         } else {
2589             if (!ctx)
2590                 smhead = (SMacro **) hash_findi_add(smacros, tline->text);
2591             else
2592                 smhead = &ctx->localmac;
2593
2594             smac = nasm_malloc(sizeof(SMacro));
2595             smac->next = *smhead;
2596             *smhead = smac;
2597         }
2598         smac->name = nasm_strdup(mname);
2599         smac->casesense = (i == PP_SUBSTR);
2600         smac->nparam = 0;
2601         smac->expansion = macro_start;
2602         smac->in_progress = FALSE;
2603         free_tlist(tline);
2604         free_tlist(origline);
2605         return DIRECTIVE_FOUND;
2606
2607     case PP_ASSIGN:
2608     case PP_IASSIGN:
2609         tline = tline->next;
2610         skip_white_(tline);
2611         tline = expand_id(tline);
2612         if (!tline || (tline->type != TOK_ID &&
2613                        (tline->type != TOK_PREPROC_ID ||
2614                         tline->text[1] != '$'))) {
2615             error(ERR_NONFATAL,
2616                   "`%%%sassign' expects a macro identifier",
2617                   (i == PP_IASSIGN ? "i" : ""));
2618             free_tlist(origline);
2619             return DIRECTIVE_FOUND;
2620         }
2621         ctx = get_ctx(tline->text, FALSE);
2622
2623         mname = tline->text;
2624         last = tline;
2625         tline = expand_smacro(tline->next);
2626         last->next = NULL;
2627
2628         t = tline;
2629         tptr = &t;
2630         tokval.t_type = TOKEN_INVALID;
2631         evalresult =
2632             evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2633         free_tlist(tline);
2634         if (!evalresult) {
2635             free_tlist(origline);
2636             return DIRECTIVE_FOUND;
2637         }
2638
2639         if (tokval.t_type)
2640             error(ERR_WARNING,
2641                   "trailing garbage after expression ignored");
2642
2643         if (!is_simple(evalresult)) {
2644             error(ERR_NONFATAL,
2645                   "non-constant value given to `%%%sassign'",
2646                   (i == PP_IASSIGN ? "i" : ""));
2647             free_tlist(origline);
2648             return DIRECTIVE_FOUND;
2649         }
2650
2651         macro_start = nasm_malloc(sizeof(*macro_start));
2652         macro_start->next = NULL;
2653         make_tok_num(macro_start, reloc_value(evalresult));
2654         macro_start->mac = NULL;
2655
2656         /*
2657          * We now have a macro name, an implicit parameter count of
2658          * zero, and a numeric token to use as an expansion. Create
2659          * and store an SMacro.
2660          */
2661         if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN)) {
2662             if (!smac)
2663                 error(ERR_WARNING,
2664                       "single-line macro `%s' defined both with and"
2665                       " without parameters", mname);
2666             else {
2667                 /*
2668                  * We're redefining, so we have to take over an
2669                  * existing SMacro structure. This means freeing
2670                  * what was already in it.
2671                  */
2672                 nasm_free(smac->name);
2673                 free_tlist(smac->expansion);
2674             }
2675         } else {
2676             if (!ctx)
2677                 smhead = (SMacro **) hash_findi_add(smacros, mname);
2678             else
2679                 smhead = &ctx->localmac;
2680
2681             smac = nasm_malloc(sizeof(SMacro));
2682             smac->next = *smhead;
2683             *smhead = smac;
2684         }
2685         smac->name = nasm_strdup(mname);
2686         smac->casesense = (i == PP_ASSIGN);
2687         smac->nparam = 0;
2688         smac->expansion = macro_start;
2689         smac->in_progress = FALSE;
2690         free_tlist(origline);
2691         return DIRECTIVE_FOUND;
2692
2693     case PP_LINE:
2694         /*
2695          * Syntax is `%line nnn[+mmm] [filename]'
2696          */
2697         tline = tline->next;
2698         skip_white_(tline);
2699         if (!tok_type_(tline, TOK_NUMBER)) {
2700             error(ERR_NONFATAL, "`%%line' expects line number");
2701             free_tlist(origline);
2702             return DIRECTIVE_FOUND;
2703         }
2704         k = readnum(tline->text, &j);
2705         m = 1;
2706         tline = tline->next;
2707         if (tok_is_(tline, "+")) {
2708             tline = tline->next;
2709             if (!tok_type_(tline, TOK_NUMBER)) {
2710                 error(ERR_NONFATAL, "`%%line' expects line increment");
2711                 free_tlist(origline);
2712                 return DIRECTIVE_FOUND;
2713             }
2714             m = readnum(tline->text, &j);
2715             tline = tline->next;
2716         }
2717         skip_white_(tline);
2718         src_set_linnum(k);
2719         istk->lineinc = m;
2720         if (tline) {
2721             nasm_free(src_set_fname(detoken(tline, FALSE)));
2722         }
2723         free_tlist(origline);
2724         return DIRECTIVE_FOUND;
2725
2726     default:
2727         error(ERR_FATAL,
2728               "preprocessor directive `%s' not yet implemented",
2729               pp_directives[i]);
2730         break;
2731     }
2732     return DIRECTIVE_FOUND;
2733 }
2734
2735 /*
2736  * Ensure that a macro parameter contains a condition code and
2737  * nothing else. Return the condition code index if so, or -1
2738  * otherwise.
2739  */
2740 static int find_cc(Token * t)
2741 {
2742     Token *tt;
2743     int i, j, k, m;
2744
2745     skip_white_(t);
2746     if (t->type != TOK_ID)
2747         return -1;
2748     tt = t->next;
2749     skip_white_(tt);
2750     if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
2751         return -1;
2752
2753     i = -1;
2754     j = elements(conditions);
2755     while (j - i > 1) {
2756         k = (j + i) / 2;
2757         m = nasm_stricmp(t->text, conditions[k]);
2758         if (m == 0) {
2759             i = k;
2760             j = -2;
2761             break;
2762         } else if (m < 0) {
2763             j = k;
2764         } else
2765             i = k;
2766     }
2767     if (j != -2)
2768         return -1;
2769     return i;
2770 }
2771
2772 /*
2773  * Expand MMacro-local things: parameter references (%0, %n, %+n,
2774  * %-n) and MMacro-local identifiers (%%foo).
2775  */
2776 static Token *expand_mmac_params(Token * tline)
2777 {
2778     Token *t, *tt, **tail, *thead;
2779
2780     tail = &thead;
2781     thead = NULL;
2782
2783     while (tline) {
2784         if (tline->type == TOK_PREPROC_ID &&
2785             (((tline->text[1] == '+' || tline->text[1] == '-')
2786               && tline->text[2]) || tline->text[1] == '%'
2787              || (tline->text[1] >= '0' && tline->text[1] <= '9'))) {
2788             char *text = NULL;
2789             int type = 0, cc;   /* type = 0 to placate optimisers */
2790             char tmpbuf[30];
2791             int n, i;
2792             MMacro *mac;
2793
2794             t = tline;
2795             tline = tline->next;
2796
2797             mac = istk->mstk;
2798             while (mac && !mac->name)   /* avoid mistaking %reps for macros */
2799                 mac = mac->next_active;
2800             if (!mac)
2801                 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
2802             else
2803                 switch (t->text[1]) {
2804                     /*
2805                      * We have to make a substitution of one of the
2806                      * forms %1, %-1, %+1, %%foo, %0.
2807                      */
2808                 case '0':
2809                     type = TOK_NUMBER;
2810                     snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam);
2811                     text = nasm_strdup(tmpbuf);
2812                     break;
2813                 case '%':
2814                     type = TOK_ID;
2815                     snprintf(tmpbuf, sizeof(tmpbuf), "..@%"PRIu32".",
2816                              mac->unique);
2817                     text = nasm_strcat(tmpbuf, t->text + 2);
2818                     break;
2819                 case '-':
2820                     n = atoi(t->text + 2) - 1;
2821                     if (n >= mac->nparam)
2822                         tt = NULL;
2823                     else {
2824                         if (mac->nparam > 1)
2825                             n = (n + mac->rotate) % mac->nparam;
2826                         tt = mac->params[n];
2827                     }
2828                     cc = find_cc(tt);
2829                     if (cc == -1) {
2830                         error(ERR_NONFATAL,
2831                               "macro parameter %d is not a condition code",
2832                               n + 1);
2833                         text = NULL;
2834                     } else {
2835                         type = TOK_ID;
2836                         if (inverse_ccs[cc] == -1) {
2837                             error(ERR_NONFATAL,
2838                                   "condition code `%s' is not invertible",
2839                                   conditions[cc]);
2840                             text = NULL;
2841                         } else
2842                             text =
2843                                 nasm_strdup(conditions[inverse_ccs[cc]]);
2844                     }
2845                     break;
2846                 case '+':
2847                     n = atoi(t->text + 2) - 1;
2848                     if (n >= mac->nparam)
2849                         tt = NULL;
2850                     else {
2851                         if (mac->nparam > 1)
2852                             n = (n + mac->rotate) % mac->nparam;
2853                         tt = mac->params[n];
2854                     }
2855                     cc = find_cc(tt);
2856                     if (cc == -1) {
2857                         error(ERR_NONFATAL,
2858                               "macro parameter %d is not a condition code",
2859                               n + 1);
2860                         text = NULL;
2861                     } else {
2862                         type = TOK_ID;
2863                         text = nasm_strdup(conditions[cc]);
2864                     }
2865                     break;
2866                 default:
2867                     n = atoi(t->text + 1) - 1;
2868                     if (n >= mac->nparam)
2869                         tt = NULL;
2870                     else {
2871                         if (mac->nparam > 1)
2872                             n = (n + mac->rotate) % mac->nparam;
2873                         tt = mac->params[n];
2874                     }
2875                     if (tt) {
2876                         for (i = 0; i < mac->paramlen[n]; i++) {
2877                             *tail = new_Token(NULL, tt->type, tt->text, 0);
2878                             tail = &(*tail)->next;
2879                             tt = tt->next;
2880                         }
2881                     }
2882                     text = NULL;        /* we've done it here */
2883                     break;
2884                 }
2885             if (!text) {
2886                 delete_Token(t);
2887             } else {
2888                 *tail = t;
2889                 tail = &t->next;
2890                 t->type = type;
2891                 nasm_free(t->text);
2892                 t->text = text;
2893                 t->mac = NULL;
2894             }
2895             continue;
2896         } else {
2897             t = *tail = tline;
2898             tline = tline->next;
2899             t->mac = NULL;
2900             tail = &t->next;
2901         }
2902     }
2903     *tail = NULL;
2904     t = thead;
2905     for (; t && (tt = t->next) != NULL; t = t->next)
2906         switch (t->type) {
2907         case TOK_WHITESPACE:
2908             if (tt->type == TOK_WHITESPACE) {
2909                 t->next = delete_Token(tt);
2910             }
2911             break;
2912         case TOK_ID:
2913             if (tt->type == TOK_ID || tt->type == TOK_NUMBER) {
2914                 char *tmp = nasm_strcat(t->text, tt->text);
2915                 nasm_free(t->text);
2916                 t->text = tmp;
2917                 t->next = delete_Token(tt);
2918             }
2919             break;
2920         case TOK_NUMBER:
2921             if (tt->type == TOK_NUMBER) {
2922                 char *tmp = nasm_strcat(t->text, tt->text);
2923                 nasm_free(t->text);
2924                 t->text = tmp;
2925                 t->next = delete_Token(tt);
2926             }
2927             break;
2928         default:
2929             break;
2930         }
2931
2932     return thead;
2933 }
2934
2935 /*
2936  * Expand all single-line macro calls made in the given line.
2937  * Return the expanded version of the line. The original is deemed
2938  * to be destroyed in the process. (In reality we'll just move
2939  * Tokens from input to output a lot of the time, rather than
2940  * actually bothering to destroy and replicate.)
2941  */
2942 static Token *expand_smacro(Token * tline)
2943 {
2944     Token *t, *tt, *mstart, **tail, *thead;
2945     SMacro *head = NULL, *m;
2946     Token **params;
2947     int *paramsize;
2948     int nparam, sparam, brackets, rescan;
2949     Token *org_tline = tline;
2950     Context *ctx;
2951     char *mname;
2952
2953     /*
2954      * Trick: we should avoid changing the start token pointer since it can
2955      * be contained in "next" field of other token. Because of this
2956      * we allocate a copy of first token and work with it; at the end of
2957      * routine we copy it back
2958      */
2959     if (org_tline) {
2960         tline =
2961             new_Token(org_tline->next, org_tline->type, org_tline->text,
2962                       0);
2963         tline->mac = org_tline->mac;
2964         nasm_free(org_tline->text);
2965         org_tline->text = NULL;
2966     }
2967
2968   again:
2969     tail = &thead;
2970     thead = NULL;
2971
2972     while (tline) {             /* main token loop */
2973         if ((mname = tline->text)) {
2974             /* if this token is a local macro, look in local context */
2975             if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
2976                 ctx = get_ctx(mname, TRUE);
2977             else
2978                 ctx = NULL;
2979             if (!ctx) {
2980                 head = (SMacro *) hash_findix(smacros, mname);
2981             } else {
2982                 head = ctx->localmac;
2983             }
2984             /*
2985              * We've hit an identifier. As in is_mmacro below, we first
2986              * check whether the identifier is a single-line macro at
2987              * all, then think about checking for parameters if
2988              * necessary.
2989              */
2990             for (m = head; m; m = m->next)
2991                 if (!mstrcmp(m->name, mname, m->casesense))
2992                     break;
2993             if (m) {
2994                 mstart = tline;
2995                 params = NULL;
2996                 paramsize = NULL;
2997                 if (m->nparam == 0) {
2998                     /*
2999                      * Simple case: the macro is parameterless. Discard the
3000                      * one token that the macro call took, and push the
3001                      * expansion back on the to-do stack.
3002                      */
3003                     if (!m->expansion) {
3004                         if (!strcmp("__FILE__", m->name)) {
3005                             int32_t num = 0;
3006                             src_get(&num, &(tline->text));
3007                             nasm_quote(&(tline->text));
3008                             tline->type = TOK_STRING;
3009                             continue;
3010                         }
3011                         if (!strcmp("__LINE__", m->name)) {
3012                             nasm_free(tline->text);
3013                             make_tok_num(tline, src_get_linnum());
3014                             continue;
3015                         }
3016                         if (!strcmp("__BITS__", m->name)) {
3017                             nasm_free(tline->text);
3018                             make_tok_num(tline, globalbits);
3019                             continue;
3020                         }
3021                         tline = delete_Token(tline);
3022                         continue;
3023                     }
3024                 } else {
3025                     /*
3026                      * Complicated case: at least one macro with this name
3027                      * exists and takes parameters. We must find the
3028                      * parameters in the call, count them, find the SMacro
3029                      * that corresponds to that form of the macro call, and
3030                      * substitute for the parameters when we expand. What a
3031                      * pain.
3032                      */
3033                     /*tline = tline->next;
3034                        skip_white_(tline); */
3035                     do {
3036                         t = tline->next;
3037                         while (tok_type_(t, TOK_SMAC_END)) {
3038                             t->mac->in_progress = FALSE;
3039                             t->text = NULL;
3040                             t = tline->next = delete_Token(t);
3041                         }
3042                         tline = t;
3043                     } while (tok_type_(tline, TOK_WHITESPACE));
3044                     if (!tok_is_(tline, "(")) {
3045                         /*
3046                          * This macro wasn't called with parameters: ignore
3047                          * the call. (Behaviour borrowed from gnu cpp.)
3048                          */
3049                         tline = mstart;
3050                         m = NULL;
3051                     } else {
3052                         int paren = 0;
3053                         int white = 0;
3054                         brackets = 0;
3055                         nparam = 0;
3056                         sparam = PARAM_DELTA;
3057                         params = nasm_malloc(sparam * sizeof(Token *));
3058                         params[0] = tline->next;
3059                         paramsize = nasm_malloc(sparam * sizeof(int));
3060                         paramsize[0] = 0;
3061                         while (TRUE) {  /* parameter loop */
3062                             /*
3063                              * For some unusual expansions
3064                              * which concatenates function call
3065                              */
3066                             t = tline->next;
3067                             while (tok_type_(t, TOK_SMAC_END)) {
3068                                 t->mac->in_progress = FALSE;
3069                                 t->text = NULL;
3070                                 t = tline->next = delete_Token(t);
3071                             }
3072                             tline = t;
3073
3074                             if (!tline) {
3075                                 error(ERR_NONFATAL,
3076                                       "macro call expects terminating `)'");
3077                                 break;
3078                             }
3079                             if (tline->type == TOK_WHITESPACE
3080                                 && brackets <= 0) {
3081                                 if (paramsize[nparam])
3082                                     white++;
3083                                 else
3084                                     params[nparam] = tline->next;
3085                                 continue;       /* parameter loop */
3086                             }
3087                             if (tline->type == TOK_OTHER
3088                                 && tline->text[1] == 0) {
3089                                 char ch = tline->text[0];
3090                                 if (ch == ',' && !paren && brackets <= 0) {
3091                                     if (++nparam >= sparam) {
3092                                         sparam += PARAM_DELTA;
3093                                         params = nasm_realloc(params,
3094                                                               sparam *
3095                                                               sizeof(Token
3096                                                                      *));
3097                                         paramsize =
3098                                             nasm_realloc(paramsize,
3099                                                          sparam *
3100                                                          sizeof(int));
3101                                     }
3102                                     params[nparam] = tline->next;
3103                                     paramsize[nparam] = 0;
3104                                     white = 0;
3105                                     continue;   /* parameter loop */
3106                                 }
3107                                 if (ch == '{' &&
3108                                     (brackets > 0 || (brackets == 0 &&
3109                                                       !paramsize[nparam])))
3110                                 {
3111                                     if (!(brackets++)) {
3112                                         params[nparam] = tline->next;
3113                                         continue;       /* parameter loop */
3114                                     }
3115                                 }
3116                                 if (ch == '}' && brackets > 0)
3117                                     if (--brackets == 0) {
3118                                         brackets = -1;
3119                                         continue;       /* parameter loop */
3120                                     }
3121                                 if (ch == '(' && !brackets)
3122                                     paren++;
3123                                 if (ch == ')' && brackets <= 0)
3124                                     if (--paren < 0)
3125                                         break;
3126                             }
3127                             if (brackets < 0) {
3128                                 brackets = 0;
3129                                 error(ERR_NONFATAL, "braces do not "
3130                                       "enclose all of macro parameter");
3131                             }
3132                             paramsize[nparam] += white + 1;
3133                             white = 0;
3134                         }       /* parameter loop */
3135                         nparam++;
3136                         while (m && (m->nparam != nparam ||
3137                                      mstrcmp(m->name, mname,
3138                                              m->casesense)))
3139                             m = m->next;
3140                         if (!m)
3141                             error(ERR_WARNING | ERR_WARN_MNP,
3142                                   "macro `%s' exists, "
3143                                   "but not taking %d parameters",
3144                                   mstart->text, nparam);
3145                     }
3146                 }
3147                 if (m && m->in_progress)
3148                     m = NULL;
3149                 if (!m) {       /* in progess or didn't find '(' or wrong nparam */
3150                     /* 
3151                      * Design question: should we handle !tline, which
3152                      * indicates missing ')' here, or expand those
3153                      * macros anyway, which requires the (t) test a few
3154                      * lines down?  
3155                      */
3156                     nasm_free(params);
3157                     nasm_free(paramsize);
3158                     tline = mstart;
3159                 } else {
3160                     /*
3161                      * Expand the macro: we are placed on the last token of the
3162                      * call, so that we can easily split the call from the
3163                      * following tokens. We also start by pushing an SMAC_END
3164                      * token for the cycle removal.
3165                      */
3166                     t = tline;
3167                     if (t) {
3168                         tline = t->next;
3169                         t->next = NULL;
3170                     }
3171                     tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
3172                     tt->mac = m;
3173                     m->in_progress = TRUE;
3174                     tline = tt;
3175                     for (t = m->expansion; t; t = t->next) {
3176                         if (t->type >= TOK_SMAC_PARAM) {
3177                             Token *pcopy = tline, **ptail = &pcopy;
3178                             Token *ttt, *pt;
3179                             int i;
3180
3181                             ttt = params[t->type - TOK_SMAC_PARAM];
3182                             for (i = paramsize[t->type - TOK_SMAC_PARAM];
3183                                  --i >= 0;) {
3184                                 pt = *ptail =
3185                                     new_Token(tline, ttt->type, ttt->text,
3186                                               0);
3187                                 ptail = &pt->next;
3188                                 ttt = ttt->next;
3189                             }
3190                             tline = pcopy;
3191                         } else {
3192                             tt = new_Token(tline, t->type, t->text, 0);
3193                             tline = tt;
3194                         }
3195                     }
3196
3197                     /*
3198                      * Having done that, get rid of the macro call, and clean
3199                      * up the parameters.
3200                      */
3201                     nasm_free(params);
3202                     nasm_free(paramsize);
3203                     free_tlist(mstart);
3204                     continue;   /* main token loop */
3205                 }
3206             }
3207         }
3208
3209         if (tline->type == TOK_SMAC_END) {
3210             tline->mac->in_progress = FALSE;
3211             tline = delete_Token(tline);
3212         } else {
3213             t = *tail = tline;
3214             tline = tline->next;
3215             t->mac = NULL;
3216             t->next = NULL;
3217             tail = &t->next;
3218         }
3219     }
3220
3221     /*
3222      * Now scan the entire line and look for successive TOK_IDs that resulted
3223      * after expansion (they can't be produced by tokenize()). The successive
3224      * TOK_IDs should be concatenated.
3225      * Also we look for %+ tokens and concatenate the tokens before and after
3226      * them (without white spaces in between).
3227      */
3228     t = thead;
3229     rescan = 0;
3230     while (t) {
3231         while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
3232             t = t->next;
3233         if (!t || !t->next)
3234             break;
3235         if (t->next->type == TOK_ID ||
3236             t->next->type == TOK_PREPROC_ID ||
3237             t->next->type == TOK_NUMBER) {
3238             char *p = nasm_strcat(t->text, t->next->text);
3239             nasm_free(t->text);
3240             t->next = delete_Token(t->next);
3241             t->text = p;
3242             rescan = 1;
3243         } else if (t->next->type == TOK_WHITESPACE && t->next->next &&
3244                    t->next->next->type == TOK_PREPROC_ID &&
3245                    strcmp(t->next->next->text, "%+") == 0) {
3246             /* free the next whitespace, the %+ token and next whitespace */
3247             int i;
3248             for (i = 1; i <= 3; i++) {
3249                 if (!t->next
3250                     || (i != 2 && t->next->type != TOK_WHITESPACE))
3251                     break;
3252                 t->next = delete_Token(t->next);
3253             }                   /* endfor */
3254         } else
3255             t = t->next;
3256     }
3257     /* If we concatenaded something, re-scan the line for macros */
3258     if (rescan) {
3259         tline = thead;
3260         goto again;
3261     }
3262
3263     if (org_tline) {
3264         if (thead) {
3265             *org_tline = *thead;
3266             /* since we just gave text to org_line, don't free it */
3267             thead->text = NULL;
3268             delete_Token(thead);
3269         } else {
3270             /* the expression expanded to empty line;
3271                we can't return NULL for some reasons
3272                we just set the line to a single WHITESPACE token. */
3273             memset(org_tline, 0, sizeof(*org_tline));
3274             org_tline->text = NULL;
3275             org_tline->type = TOK_WHITESPACE;
3276         }
3277         thead = org_tline;
3278     }
3279
3280     return thead;
3281 }
3282
3283 /*
3284  * Similar to expand_smacro but used exclusively with macro identifiers
3285  * right before they are fetched in. The reason is that there can be
3286  * identifiers consisting of several subparts. We consider that if there
3287  * are more than one element forming the name, user wants a expansion,
3288  * otherwise it will be left as-is. Example:
3289  *
3290  *      %define %$abc cde
3291  *
3292  * the identifier %$abc will be left as-is so that the handler for %define
3293  * will suck it and define the corresponding value. Other case:
3294  *
3295  *      %define _%$abc cde
3296  *
3297  * In this case user wants name to be expanded *before* %define starts
3298  * working, so we'll expand %$abc into something (if it has a value;
3299  * otherwise it will be left as-is) then concatenate all successive
3300  * PP_IDs into one.
3301  */
3302 static Token *expand_id(Token * tline)
3303 {
3304     Token *cur, *oldnext = NULL;
3305
3306     if (!tline || !tline->next)
3307         return tline;
3308
3309     cur = tline;
3310     while (cur->next &&
3311            (cur->next->type == TOK_ID ||
3312             cur->next->type == TOK_PREPROC_ID
3313             || cur->next->type == TOK_NUMBER))
3314         cur = cur->next;
3315
3316     /* If identifier consists of just one token, don't expand */
3317     if (cur == tline)
3318         return tline;
3319
3320     if (cur) {
3321         oldnext = cur->next;    /* Detach the tail past identifier */
3322         cur->next = NULL;       /* so that expand_smacro stops here */
3323     }
3324
3325     tline = expand_smacro(tline);
3326
3327     if (cur) {
3328         /* expand_smacro possibly changhed tline; re-scan for EOL */
3329         cur = tline;
3330         while (cur && cur->next)
3331             cur = cur->next;
3332         if (cur)
3333             cur->next = oldnext;
3334     }
3335
3336     return tline;
3337 }
3338
3339 /*
3340  * Determine whether the given line constitutes a multi-line macro
3341  * call, and return the MMacro structure called if so. Doesn't have
3342  * to check for an initial label - that's taken care of in
3343  * expand_mmacro - but must check numbers of parameters. Guaranteed
3344  * to be called with tline->type == TOK_ID, so the putative macro
3345  * name is easy to find.
3346  */
3347 static MMacro *is_mmacro(Token * tline, Token *** params_array)
3348 {
3349     MMacro *head, *m;
3350     Token **params;
3351     int nparam;
3352
3353     head = (MMacro *) hash_findix(mmacros, tline->text);
3354
3355     /*
3356      * Efficiency: first we see if any macro exists with the given
3357      * name. If not, we can return NULL immediately. _Then_ we
3358      * count the parameters, and then we look further along the
3359      * list if necessary to find the proper MMacro.
3360      */
3361     for (m = head; m; m = m->next)
3362         if (!mstrcmp(m->name, tline->text, m->casesense))
3363             break;
3364     if (!m)
3365         return NULL;
3366
3367     /*
3368      * OK, we have a potential macro. Count and demarcate the
3369      * parameters.
3370      */
3371     count_mmac_params(tline->next, &nparam, &params);
3372
3373     /*
3374      * So we know how many parameters we've got. Find the MMacro
3375      * structure that handles this number.
3376      */
3377     while (m) {
3378         if (m->nparam_min <= nparam
3379             && (m->plus || nparam <= m->nparam_max)) {
3380             /*
3381              * This one is right. Just check if cycle removal
3382              * prohibits us using it before we actually celebrate...
3383              */
3384             if (m->in_progress) {
3385 #if 0
3386                 error(ERR_NONFATAL,
3387                       "self-reference in multi-line macro `%s'", m->name);
3388 #endif
3389                 nasm_free(params);
3390                 return NULL;
3391             }
3392             /*
3393              * It's right, and we can use it. Add its default
3394              * parameters to the end of our list if necessary.
3395              */
3396             if (m->defaults && nparam < m->nparam_min + m->ndefs) {
3397                 params =
3398                     nasm_realloc(params,
3399                                  ((m->nparam_min + m->ndefs +
3400                                    1) * sizeof(*params)));
3401                 while (nparam < m->nparam_min + m->ndefs) {
3402                     params[nparam] = m->defaults[nparam - m->nparam_min];
3403                     nparam++;
3404                 }
3405             }
3406             /*
3407              * If we've gone over the maximum parameter count (and
3408              * we're in Plus mode), ignore parameters beyond
3409              * nparam_max.
3410              */
3411             if (m->plus && nparam > m->nparam_max)
3412                 nparam = m->nparam_max;
3413             /*
3414              * Then terminate the parameter list, and leave.
3415              */
3416             if (!params) {      /* need this special case */
3417                 params = nasm_malloc(sizeof(*params));
3418                 nparam = 0;
3419             }
3420             params[nparam] = NULL;
3421             *params_array = params;
3422             return m;
3423         }
3424         /*
3425          * This one wasn't right: look for the next one with the
3426          * same name.
3427          */
3428         for (m = m->next; m; m = m->next)
3429             if (!mstrcmp(m->name, tline->text, m->casesense))
3430                 break;
3431     }
3432
3433     /*
3434      * After all that, we didn't find one with the right number of
3435      * parameters. Issue a warning, and fail to expand the macro.
3436      */
3437     error(ERR_WARNING | ERR_WARN_MNP,
3438           "macro `%s' exists, but not taking %d parameters",
3439           tline->text, nparam);
3440     nasm_free(params);
3441     return NULL;
3442 }
3443
3444 /*
3445  * Expand the multi-line macro call made by the given line, if
3446  * there is one to be expanded. If there is, push the expansion on
3447  * istk->expansion and return 1. Otherwise return 0.
3448  */
3449 static int expand_mmacro(Token * tline)
3450 {
3451     Token *startline = tline;
3452     Token *label = NULL;
3453     int dont_prepend = 0;
3454     Token **params, *t, *tt;
3455     MMacro *m;
3456     Line *l, *ll;
3457     int i, nparam, *paramlen;
3458
3459     t = tline;
3460     skip_white_(t);
3461 /*    if (!tok_type_(t, TOK_ID))  Lino 02/25/02 */
3462     if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID))
3463         return 0;
3464     m = is_mmacro(t, &params);
3465     if (!m) {
3466         Token *last;
3467         /*
3468          * We have an id which isn't a macro call. We'll assume
3469          * it might be a label; we'll also check to see if a
3470          * colon follows it. Then, if there's another id after
3471          * that lot, we'll check it again for macro-hood.
3472          */
3473         label = last = t;
3474         t = t->next;
3475         if (tok_type_(t, TOK_WHITESPACE))
3476             last = t, t = t->next;
3477         if (tok_is_(t, ":")) {
3478             dont_prepend = 1;
3479             last = t, t = t->next;
3480             if (tok_type_(t, TOK_WHITESPACE))
3481                 last = t, t = t->next;
3482         }
3483         if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, &params)) == NULL)
3484             return 0;
3485         last->next = NULL;
3486         tline = t;
3487     }
3488
3489     /*
3490      * Fix up the parameters: this involves stripping leading and
3491      * trailing whitespace, then stripping braces if they are
3492      * present.
3493      */
3494     for (nparam = 0; params[nparam]; nparam++) ;
3495     paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
3496
3497     for (i = 0; params[i]; i++) {
3498         int brace = FALSE;
3499         int comma = (!m->plus || i < nparam - 1);
3500
3501         t = params[i];
3502         skip_white_(t);
3503         if (tok_is_(t, "{"))
3504             t = t->next, brace = TRUE, comma = FALSE;
3505         params[i] = t;
3506         paramlen[i] = 0;
3507         while (t) {
3508             if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
3509                 break;          /* ... because we have hit a comma */
3510             if (comma && t->type == TOK_WHITESPACE
3511                 && tok_is_(t->next, ","))
3512                 break;          /* ... or a space then a comma */
3513             if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
3514                 break;          /* ... or a brace */
3515             t = t->next;
3516             paramlen[i]++;
3517         }
3518     }
3519
3520     /*
3521      * OK, we have a MMacro structure together with a set of
3522      * parameters. We must now go through the expansion and push
3523      * copies of each Line on to istk->expansion. Substitution of
3524      * parameter tokens and macro-local tokens doesn't get done
3525      * until the single-line macro substitution process; this is
3526      * because delaying them allows us to change the semantics
3527      * later through %rotate.
3528      *
3529      * First, push an end marker on to istk->expansion, mark this
3530      * macro as in progress, and set up its invocation-specific
3531      * variables.
3532      */
3533     ll = nasm_malloc(sizeof(Line));
3534     ll->next = istk->expansion;
3535     ll->finishes = m;
3536     ll->first = NULL;
3537     istk->expansion = ll;
3538
3539     m->in_progress = TRUE;
3540     m->params = params;
3541     m->iline = tline;
3542     m->nparam = nparam;
3543     m->rotate = 0;
3544     m->paramlen = paramlen;
3545     m->unique = unique++;
3546     m->lineno = 0;
3547
3548     m->next_active = istk->mstk;
3549     istk->mstk = m;
3550
3551     for (l = m->expansion; l; l = l->next) {
3552         Token **tail;
3553
3554         ll = nasm_malloc(sizeof(Line));
3555         ll->finishes = NULL;
3556         ll->next = istk->expansion;
3557         istk->expansion = ll;
3558         tail = &ll->first;
3559
3560         for (t = l->first; t; t = t->next) {
3561             Token *x = t;
3562             if (t->type == TOK_PREPROC_ID &&
3563                 t->text[1] == '0' && t->text[2] == '0') {
3564                 dont_prepend = -1;
3565                 x = label;
3566                 if (!x)
3567                     continue;
3568             }
3569             tt = *tail = new_Token(NULL, x->type, x->text, 0);
3570             tail = &tt->next;
3571         }
3572         *tail = NULL;
3573     }
3574
3575     /*
3576      * If we had a label, push it on as the first line of
3577      * the macro expansion.
3578      */
3579     if (label) {
3580         if (dont_prepend < 0)
3581             free_tlist(startline);
3582         else {
3583             ll = nasm_malloc(sizeof(Line));
3584             ll->finishes = NULL;
3585             ll->next = istk->expansion;
3586             istk->expansion = ll;
3587             ll->first = startline;
3588             if (!dont_prepend) {
3589                 while (label->next)
3590                     label = label->next;
3591                 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
3592             }
3593         }
3594     }
3595
3596     list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
3597
3598     return 1;
3599 }
3600
3601 /*
3602  * Since preprocessor always operate only on the line that didn't
3603  * arrived yet, we should always use ERR_OFFBY1. Also since user
3604  * won't want to see same error twice (preprocessing is done once
3605  * per pass) we will want to show errors only during pass one.
3606  */
3607 static void error(int severity, const char *fmt, ...)
3608 {
3609     va_list arg;
3610     char buff[1024];
3611
3612     /* If we're in a dead branch of IF or something like it, ignore the error */
3613     if (istk && istk->conds && !emitting(istk->conds->state))
3614         return;
3615
3616     va_start(arg, fmt);
3617     vsnprintf(buff, sizeof(buff), fmt, arg);
3618     va_end(arg);
3619
3620     if (istk && istk->mstk && istk->mstk->name)
3621         _error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
3622                istk->mstk->lineno, buff);
3623     else
3624         _error(severity | ERR_PASS1, "%s", buff);
3625 }
3626
3627 static void
3628 pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
3629          ListGen * listgen)
3630 {
3631     _error = errfunc;
3632     cstk = NULL;
3633     istk = nasm_malloc(sizeof(Include));
3634     istk->next = NULL;
3635     istk->conds = NULL;
3636     istk->expansion = NULL;
3637     istk->mstk = NULL;
3638     istk->fp = fopen(file, "r");
3639     istk->fname = NULL;
3640     src_set_fname(nasm_strdup(file));
3641     src_set_linnum(0);
3642     istk->lineinc = 1;
3643     if (!istk->fp)
3644         error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'",
3645               file);
3646     defining = NULL;
3647     init_macros();
3648     unique = 0;
3649     if (tasm_compatible_mode) {
3650         stdmacpos = stdmac;
3651     } else {
3652         stdmacpos = &stdmac[TASM_MACRO_COUNT];
3653     }
3654     any_extrastdmac = (extrastdmac != NULL);
3655     list = listgen;
3656     evaluate = eval;
3657     pass = apass;
3658 }
3659
3660 static char *pp_getline(void)
3661 {
3662     char *line;
3663     Token *tline;
3664
3665     while (1) {
3666         /*
3667          * Fetch a tokenized line, either from the macro-expansion
3668          * buffer or from the input file.
3669          */
3670         tline = NULL;
3671         while (istk->expansion && istk->expansion->finishes) {
3672             Line *l = istk->expansion;
3673             if (!l->finishes->name && l->finishes->in_progress > 1) {
3674                 Line *ll;
3675
3676                 /*
3677                  * This is a macro-end marker for a macro with no
3678                  * name, which means it's not really a macro at all
3679                  * but a %rep block, and the `in_progress' field is
3680                  * more than 1, meaning that we still need to
3681                  * repeat. (1 means the natural last repetition; 0
3682                  * means termination by %exitrep.) We have
3683                  * therefore expanded up to the %endrep, and must
3684                  * push the whole block on to the expansion buffer
3685                  * again. We don't bother to remove the macro-end
3686                  * marker: we'd only have to generate another one
3687                  * if we did.
3688                  */
3689                 l->finishes->in_progress--;
3690                 for (l = l->finishes->expansion; l; l = l->next) {
3691                     Token *t, *tt, **tail;
3692
3693                     ll = nasm_malloc(sizeof(Line));
3694                     ll->next = istk->expansion;
3695                     ll->finishes = NULL;
3696                     ll->first = NULL;
3697                     tail = &ll->first;
3698
3699                     for (t = l->first; t; t = t->next) {
3700                         if (t->text || t->type == TOK_WHITESPACE) {
3701                             tt = *tail =
3702                                 new_Token(NULL, t->type, t->text, 0);
3703                             tail = &tt->next;
3704                         }
3705                     }
3706
3707                     istk->expansion = ll;
3708                 }
3709             } else {
3710                 /*
3711                  * Check whether a `%rep' was started and not ended
3712                  * within this macro expansion. This can happen and
3713                  * should be detected. It's a fatal error because
3714                  * I'm too confused to work out how to recover
3715                  * sensibly from it.
3716                  */
3717                 if (defining) {
3718                     if (defining->name)
3719                         error(ERR_PANIC,
3720                               "defining with name in expansion");
3721                     else if (istk->mstk->name)
3722                         error(ERR_FATAL,
3723                               "`%%rep' without `%%endrep' within"
3724                               " expansion of macro `%s'",
3725                               istk->mstk->name);
3726                 }
3727
3728                 /*
3729                  * FIXME:  investigate the relationship at this point between
3730                  * istk->mstk and l->finishes
3731                  */
3732                 {
3733                     MMacro *m = istk->mstk;
3734                     istk->mstk = m->next_active;
3735                     if (m->name) {
3736                         /*
3737                          * This was a real macro call, not a %rep, and
3738                          * therefore the parameter information needs to
3739                          * be freed.
3740                          */
3741                         nasm_free(m->params);
3742                         free_tlist(m->iline);
3743                         nasm_free(m->paramlen);
3744                         l->finishes->in_progress = FALSE;
3745                     } else
3746                         free_mmacro(m);
3747                 }
3748                 istk->expansion = l->next;
3749                 nasm_free(l);
3750                 list->downlevel(LIST_MACRO);
3751             }
3752         }
3753         while (1) {             /* until we get a line we can use */
3754
3755             if (istk->expansion) {      /* from a macro expansion */
3756                 char *p;
3757                 Line *l = istk->expansion;
3758                 if (istk->mstk)
3759                     istk->mstk->lineno++;
3760                 tline = l->first;
3761                 istk->expansion = l->next;
3762                 nasm_free(l);
3763                 p = detoken(tline, FALSE);
3764                 list->line(LIST_MACRO, p);
3765                 nasm_free(p);
3766                 break;
3767             }
3768             line = read_line();
3769             if (line) {         /* from the current input file */
3770                 line = prepreproc(line);
3771                 tline = tokenize(line);
3772                 nasm_free(line);
3773                 break;
3774             }
3775             /*
3776              * The current file has ended; work down the istk
3777              */
3778             {
3779                 Include *i = istk;
3780                 fclose(i->fp);
3781                 if (i->conds)
3782                     error(ERR_FATAL,
3783                           "expected `%%endif' before end of file");
3784                 /* only set line and file name if there's a next node */
3785                 if (i->next) {
3786                     src_set_linnum(i->lineno);
3787                     nasm_free(src_set_fname(i->fname));
3788                 }
3789                 istk = i->next;
3790                 list->downlevel(LIST_INCLUDE);
3791                 nasm_free(i);
3792                 if (!istk)
3793                     return NULL;
3794             }
3795         }
3796
3797         /*
3798          * We must expand MMacro parameters and MMacro-local labels
3799          * _before_ we plunge into directive processing, to cope
3800          * with things like `%define something %1' such as STRUC
3801          * uses. Unless we're _defining_ a MMacro, in which case
3802          * those tokens should be left alone to go into the
3803          * definition; and unless we're in a non-emitting
3804          * condition, in which case we don't want to meddle with
3805          * anything.
3806          */
3807         if (!defining && !(istk->conds && !emitting(istk->conds->state)))
3808             tline = expand_mmac_params(tline);
3809
3810         /*
3811          * Check the line to see if it's a preprocessor directive.
3812          */
3813         if (do_directive(tline) == DIRECTIVE_FOUND) {
3814             continue;
3815         } else if (defining) {
3816             /*
3817              * We're defining a multi-line macro. We emit nothing
3818              * at all, and just
3819              * shove the tokenized line on to the macro definition.
3820              */
3821             Line *l = nasm_malloc(sizeof(Line));
3822             l->next = defining->expansion;
3823             l->first = tline;
3824             l->finishes = FALSE;
3825             defining->expansion = l;
3826             continue;
3827         } else if (istk->conds && !emitting(istk->conds->state)) {
3828             /*
3829              * We're in a non-emitting branch of a condition block.
3830              * Emit nothing at all, not even a blank line: when we
3831              * emerge from the condition we'll give a line-number
3832              * directive so we keep our place correctly.
3833              */
3834             free_tlist(tline);
3835             continue;
3836         } else if (istk->mstk && !istk->mstk->in_progress) {
3837             /*
3838              * We're in a %rep block which has been terminated, so
3839              * we're walking through to the %endrep without
3840              * emitting anything. Emit nothing at all, not even a
3841              * blank line: when we emerge from the %rep block we'll
3842              * give a line-number directive so we keep our place
3843              * correctly.
3844              */
3845             free_tlist(tline);
3846             continue;
3847         } else {
3848             tline = expand_smacro(tline);
3849             if (!expand_mmacro(tline)) {
3850                 /*
3851                  * De-tokenize the line again, and emit it.
3852                  */
3853                 line = detoken(tline, TRUE);
3854                 free_tlist(tline);
3855                 break;
3856             } else {
3857                 continue;       /* expand_mmacro calls free_tlist */
3858             }
3859         }
3860     }
3861
3862     return line;
3863 }
3864
3865 static void pp_cleanup(int pass)
3866 {
3867     if (defining) {
3868         error(ERR_NONFATAL, "end of file while still defining macro `%s'",
3869               defining->name);
3870         free_mmacro(defining);
3871     }
3872     while (cstk)
3873         ctx_pop();
3874     free_macros();
3875     while (istk) {
3876         Include *i = istk;
3877         istk = istk->next;
3878         fclose(i->fp);
3879         nasm_free(i->fname);
3880         nasm_free(i);
3881     }
3882     while (cstk)
3883         ctx_pop();
3884     if (pass == 0) {
3885         free_llist(predef);
3886         delete_Blocks();
3887     }
3888 }
3889
3890 void pp_include_path(char *path)
3891 {
3892     IncPath *i;
3893 /*  by alexfru: order of path inclusion fixed (was reverse order) */
3894     i = nasm_malloc(sizeof(IncPath));
3895     i->path = nasm_strdup(path);
3896     i->next = NULL;
3897
3898     if (ipath != NULL) {
3899         IncPath *j = ipath;
3900         while (j->next != NULL)
3901             j = j->next;
3902         j->next = i;
3903     } else {
3904         ipath = i;
3905     }
3906 }
3907
3908 /*
3909  * added by alexfru:
3910  *
3911  * This function is used to "export" the include paths, e.g.
3912  * the paths specified in the '-I' command switch.
3913  * The need for such exporting is due to the 'incbin' directive,
3914  * which includes raw binary files (unlike '%include', which
3915  * includes text source files). It would be real nice to be
3916  * able to specify paths to search for incbin'ned files also.
3917  * So, this is a simple workaround.
3918  *
3919  * The function use is simple:
3920  *
3921  * The 1st call (with NULL argument) returns a pointer to the 1st path
3922  * (char** type) or NULL if none include paths available.
3923  *
3924  * All subsequent calls take as argument the value returned by this
3925  * function last. The return value is either the next path
3926  * (char** type) or NULL if the end of the paths list is reached.
3927  *
3928  * It is maybe not the best way to do things, but I didn't want
3929  * to export too much, just one or two functions and no types or
3930  * variables exported.
3931  *
3932  * Can't say I like the current situation with e.g. this path list either,
3933  * it seems to be never deallocated after creation...
3934  */
3935 char **pp_get_include_path_ptr(char **pPrevPath)
3936 {
3937 /*   This macro returns offset of a member of a structure */
3938 #define GetMemberOffset(StructType,MemberName)\
3939   ((size_t)&((StructType*)0)->MemberName)
3940     IncPath *i;
3941
3942     if (pPrevPath == NULL) {
3943         if (ipath != NULL)
3944             return &ipath->path;
3945         else
3946             return NULL;
3947     }
3948     i = (IncPath *) ((char *)pPrevPath - GetMemberOffset(IncPath, path));
3949     i = i->next;
3950     if (i != NULL)
3951         return &i->path;
3952     else
3953         return NULL;
3954 #undef GetMemberOffset
3955 }
3956
3957 void pp_pre_include(char *fname)
3958 {
3959     Token *inc, *space, *name;
3960     Line *l;
3961
3962     name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
3963     space = new_Token(name, TOK_WHITESPACE, NULL, 0);
3964     inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
3965
3966     l = nasm_malloc(sizeof(Line));
3967     l->next = predef;
3968     l->first = inc;
3969     l->finishes = FALSE;
3970     predef = l;
3971 }
3972
3973 void pp_pre_define(char *definition)
3974 {
3975     Token *def, *space;
3976     Line *l;
3977     char *equals;
3978
3979     equals = strchr(definition, '=');
3980     space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
3981     def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
3982     if (equals)
3983         *equals = ' ';
3984     space->next = tokenize(definition);
3985     if (equals)
3986         *equals = '=';
3987
3988     l = nasm_malloc(sizeof(Line));
3989     l->next = predef;
3990     l->first = def;
3991     l->finishes = FALSE;
3992     predef = l;
3993 }
3994
3995 void pp_pre_undefine(char *definition)
3996 {
3997     Token *def, *space;
3998     Line *l;
3999
4000     space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4001     def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
4002     space->next = tokenize(definition);
4003
4004     l = nasm_malloc(sizeof(Line));
4005     l->next = predef;
4006     l->first = def;
4007     l->finishes = FALSE;
4008     predef = l;
4009 }
4010
4011 /*
4012  * Added by Keith Kanios:
4013  *
4014  * This function is used to assist with "runtime" preprocessor
4015  * directives. (e.g. pp_runtime("%define __BITS__ 64");)
4016  *
4017  * ERRORS ARE IGNORED HERE, SO MAKE COMPLETELY SURE THAT YOU
4018  * PASS A VALID STRING TO THIS FUNCTION!!!!!
4019  */
4020
4021 void pp_runtime(char *definition)
4022 {
4023     Token *def;
4024     
4025     def = tokenize(definition);
4026     if(do_directive(def) == NO_DIRECTIVE_FOUND)
4027         free_tlist(def);
4028         
4029 }
4030
4031 void pp_extra_stdmac(const char **macros)
4032 {
4033     extrastdmac = macros;
4034 }
4035
4036 static void make_tok_num(Token * tok, int32_t val)
4037 {
4038     char numbuf[20];
4039     snprintf(numbuf, sizeof(numbuf), "%"PRId32"", val);
4040     tok->text = nasm_strdup(numbuf);
4041     tok->type = TOK_NUMBER;
4042 }
4043
4044 Preproc nasmpp = {
4045     pp_reset,
4046     pp_getline,
4047     pp_cleanup
4048 };