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