br704736: handle deep context-local macros
[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 (isnumstart(*p)) {
877             bool is_hex = false;
878             bool is_float = false;
879             bool has_e = false;
880             char c, *r;
881
882             /*
883              * A numeric token.
884              */
885
886             if (*p == '$') {
887                 p++;
888                 is_hex = true;
889             }
890
891             for (;;) {
892                 c = *p++;
893
894                 if (!is_hex && (c == 'e' || c == 'E')) {
895                     has_e = true;
896                     if (*p == '+' || *p == '-') {
897                         /* e can only be followed by +/- if it is either a
898                            prefixed hex number or a floating-point number */
899                         p++;
900                         is_float = true;
901                     }
902                 } else if (c == 'H' || c == 'h' || c == 'X' || c == 'x') {
903                     is_hex = true;
904                 } else if (c == 'P' || c == 'p') {
905                     is_float = true;
906                     if (*p == '+' || *p == '-')
907                         p++;
908                 } else if (isnumchar(c) || c == '_')
909                     ; /* just advance */
910                 else if (c == '.') {
911                     /* we need to deal with consequences of the legacy
912                        parser, like "1.nolist" being two tokens
913                        (TOK_NUMBER, TOK_ID) here; at least give it
914                        a shot for now.  In the future, we probably need
915                        a flex-based scanner with proper pattern matching
916                        to do it as well as it can be done.  Nothing in
917                        the world is going to help the person who wants
918                        0x123.p16 interpreted as two tokens, though. */
919                     r = p;
920                     while (*r == '_')
921                         r++;
922
923                     if (nasm_isdigit(*r) || (is_hex && nasm_isxdigit(*r)) ||
924                         (!is_hex && (*r == 'e' || *r == 'E')) ||
925                         (*r == 'p' || *r == 'P')) {
926                         p = r;
927                         is_float = true;
928                     } else
929                         break;  /* Terminate the token */
930                 } else
931                     break;
932             }
933             p--;        /* Point to first character beyond number */
934
935             if (has_e && !is_hex) {
936                 /* 1e13 is floating-point, but 1e13h is not */
937                 is_float = true;
938             }
939
940             type = is_float ? TOK_FLOAT : TOK_NUMBER;
941         } else if (nasm_isspace(*p)) {
942             type = TOK_WHITESPACE;
943             p++;
944             while (*p && nasm_isspace(*p))
945                 p++;
946             /*
947              * Whitespace just before end-of-line is discarded by
948              * pretending it's a comment; whitespace just before a
949              * comment gets lumped into the comment.
950              */
951             if (!*p || *p == ';') {
952                 type = TOK_COMMENT;
953                 while (*p)
954                     p++;
955             }
956         } else if (*p == ';') {
957             type = TOK_COMMENT;
958             while (*p)
959                 p++;
960         } else {
961             /*
962              * Anything else is an operator of some kind. We check
963              * for all the double-character operators (>>, <<, //,
964              * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
965              * else is a single-character operator.
966              */
967             type = TOK_OTHER;
968             if ((p[0] == '>' && p[1] == '>') ||
969                 (p[0] == '<' && p[1] == '<') ||
970                 (p[0] == '/' && p[1] == '/') ||
971                 (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++;
980             }
981             p++;
982         }
983
984         /* Handling unterminated string by UNV */
985         /*if (type == -1)
986            {
987            *tail = t = new_Token(NULL, TOK_STRING, line, p-line+1);
988            t->text[p-line] = *line;
989            tail = &t->next;
990            }
991            else */
992         if (type != TOK_COMMENT) {
993             *tail = t = new_Token(NULL, type, line, p - line);
994             tail = &t->next;
995         }
996         line = p;
997     }
998     return list;
999 }
1000
1001 /*
1002  * this function allocates a new managed block of memory and
1003  * returns a pointer to the block.  The managed blocks are
1004  * deleted only all at once by the delete_Blocks function.
1005  */
1006 static void *new_Block(size_t size)
1007 {
1008     Blocks *b = &blocks;
1009
1010     /* first, get to the end of the linked list */
1011     while (b->next)
1012         b = b->next;
1013     /* now allocate the requested chunk */
1014     b->chunk = nasm_malloc(size);
1015
1016     /* now allocate a new block for the next request */
1017     b->next = nasm_malloc(sizeof(Blocks));
1018     /* and initialize the contents of the new block */
1019     b->next->next = NULL;
1020     b->next->chunk = NULL;
1021     return b->chunk;
1022 }
1023
1024 /*
1025  * this function deletes all managed blocks of memory
1026  */
1027 static void delete_Blocks(void)
1028 {
1029     Blocks *a, *b = &blocks;
1030
1031     /*
1032      * keep in mind that the first block, pointed to by blocks
1033      * is a static and not dynamically allocated, so we don't
1034      * free it.
1035      */
1036     while (b) {
1037         if (b->chunk)
1038             nasm_free(b->chunk);
1039         a = b;
1040         b = b->next;
1041         if (a != &blocks)
1042             nasm_free(a);
1043     }
1044 }
1045
1046 /*
1047  *  this function creates a new Token and passes a pointer to it
1048  *  back to the caller.  It sets the type and text elements, and
1049  *  also the a.mac and next elements to NULL.
1050  */
1051 static Token *new_Token(Token * next, enum pp_token_type type,
1052                         const char *text, int txtlen)
1053 {
1054     Token *t;
1055     int i;
1056
1057     if (freeTokens == NULL) {
1058         freeTokens = (Token *) new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
1059         for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
1060             freeTokens[i].next = &freeTokens[i + 1];
1061         freeTokens[i].next = NULL;
1062     }
1063     t = freeTokens;
1064     freeTokens = t->next;
1065     t->next = next;
1066     t->a.mac = NULL;
1067     t->type = type;
1068     if (type == TOK_WHITESPACE || text == NULL) {
1069         t->text = NULL;
1070     } else {
1071         if (txtlen == 0)
1072             txtlen = strlen(text);
1073         t->text = nasm_malloc(txtlen+1);
1074         memcpy(t->text, text, txtlen);
1075         t->text[txtlen] = '\0';
1076     }
1077     return t;
1078 }
1079
1080 static Token *delete_Token(Token * t)
1081 {
1082     Token *next = t->next;
1083     nasm_free(t->text);
1084     t->next = freeTokens;
1085     freeTokens = t;
1086     return next;
1087 }
1088
1089 /*
1090  * Convert a line of tokens back into text.
1091  * If expand_locals is not zero, identifiers of the form "%$*xxx"
1092  * will be transformed into ..@ctxnum.xxx
1093  */
1094 static char *detoken(Token * tlist, bool expand_locals)
1095 {
1096     Token *t;
1097     int len;
1098     char *line, *p;
1099     const char *q;
1100
1101     len = 0;
1102     for (t = tlist; t; t = t->next) {
1103         if (t->type == TOK_PREPROC_ID && t->text[1] == '!') {
1104             char *p = getenv(t->text + 2);
1105             nasm_free(t->text);
1106             if (p)
1107                 t->text = nasm_strdup(p);
1108             else
1109                 t->text = NULL;
1110         }
1111         /* Expand local macros here and not during preprocessing */
1112         if (expand_locals &&
1113             t->type == TOK_PREPROC_ID && t->text &&
1114             t->text[0] == '%' && t->text[1] == '$') {
1115             const char *q;
1116             char *p;
1117             Context *ctx = get_ctx(t->text, &q, false);
1118             if (ctx) {
1119                 char buffer[40];
1120                 snprintf(buffer, sizeof(buffer), "..@%"PRIu32".", ctx->number);
1121                 p = nasm_strcat(buffer, q);
1122                 nasm_free(t->text);
1123                 t->text = p;
1124             }
1125         }
1126         if (t->type == TOK_WHITESPACE) {
1127             len++;
1128         } else if (t->text) {
1129             len += strlen(t->text);
1130         }
1131     }
1132     p = line = nasm_malloc(len + 1);
1133     for (t = tlist; t; t = t->next) {
1134         if (t->type == TOK_WHITESPACE) {
1135             *p++ = ' ';
1136         } else if (t->text) {
1137             q = t->text;
1138             while (*q)
1139                 *p++ = *q++;
1140         }
1141     }
1142     *p = '\0';
1143     return line;
1144 }
1145
1146 /*
1147  * A scanner, suitable for use by the expression evaluator, which
1148  * operates on a line of Tokens. Expects a pointer to a pointer to
1149  * the first token in the line to be passed in as its private_data
1150  * field.
1151  *
1152  * FIX: This really needs to be unified with stdscan.
1153  */
1154 static int ppscan(void *private_data, struct tokenval *tokval)
1155 {
1156     Token **tlineptr = private_data;
1157     Token *tline;
1158     char ourcopy[MAX_KEYWORD+1], *p, *r, *s;
1159
1160     do {
1161         tline = *tlineptr;
1162         *tlineptr = tline ? tline->next : NULL;
1163     }
1164     while (tline && (tline->type == TOK_WHITESPACE ||
1165                      tline->type == TOK_COMMENT));
1166
1167     if (!tline)
1168         return tokval->t_type = TOKEN_EOS;
1169
1170     tokval->t_charptr = tline->text;
1171
1172     if (tline->text[0] == '$' && !tline->text[1])
1173         return tokval->t_type = TOKEN_HERE;
1174     if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[2])
1175         return tokval->t_type = TOKEN_BASE;
1176
1177     if (tline->type == TOK_ID) {
1178         p = tokval->t_charptr = tline->text;
1179         if (p[0] == '$') {
1180             tokval->t_charptr++;
1181             return tokval->t_type = TOKEN_ID;
1182         }
1183
1184         for (r = p, s = ourcopy; *r; r++) {
1185             if (r >= p+MAX_KEYWORD)
1186                 return tokval->t_type = TOKEN_ID; /* Not a keyword */
1187             *s++ = nasm_tolower(*r);
1188         }
1189         *s = '\0';
1190         /* right, so we have an identifier sitting in temp storage. now,
1191          * is it actually a register or instruction name, or what? */
1192         return nasm_token_hash(ourcopy, tokval);
1193     }
1194
1195     if (tline->type == TOK_NUMBER) {
1196         bool rn_error;
1197         tokval->t_integer = readnum(tline->text, &rn_error);
1198         tokval->t_charptr = tline->text;
1199         if (rn_error)
1200             return tokval->t_type = TOKEN_ERRNUM;
1201         else
1202             return tokval->t_type = TOKEN_NUM;
1203     }
1204
1205     if (tline->type == TOK_FLOAT) {
1206         return tokval->t_type = TOKEN_FLOAT;
1207     }
1208
1209     if (tline->type == TOK_STRING) {
1210         char bq, *ep;
1211
1212         bq = tline->text[0];
1213         tokval->t_charptr = tline->text;
1214         tokval->t_inttwo = nasm_unquote(tline->text, &ep);
1215
1216         if (ep[0] != bq || ep[1] != '\0')
1217             return tokval->t_type = TOKEN_ERRSTR;
1218         else
1219             return tokval->t_type = TOKEN_STR;
1220     }
1221
1222     if (tline->type == TOK_OTHER) {
1223         if (!strcmp(tline->text, "<<"))
1224             return tokval->t_type = TOKEN_SHL;
1225         if (!strcmp(tline->text, ">>"))
1226             return tokval->t_type = TOKEN_SHR;
1227         if (!strcmp(tline->text, "//"))
1228             return tokval->t_type = TOKEN_SDIV;
1229         if (!strcmp(tline->text, "%%"))
1230             return tokval->t_type = TOKEN_SMOD;
1231         if (!strcmp(tline->text, "=="))
1232             return tokval->t_type = TOKEN_EQ;
1233         if (!strcmp(tline->text, "<>"))
1234             return tokval->t_type = TOKEN_NE;
1235         if (!strcmp(tline->text, "!="))
1236             return tokval->t_type = TOKEN_NE;
1237         if (!strcmp(tline->text, "<="))
1238             return tokval->t_type = TOKEN_LE;
1239         if (!strcmp(tline->text, ">="))
1240             return tokval->t_type = TOKEN_GE;
1241         if (!strcmp(tline->text, "&&"))
1242             return tokval->t_type = TOKEN_DBL_AND;
1243         if (!strcmp(tline->text, "^^"))
1244             return tokval->t_type = TOKEN_DBL_XOR;
1245         if (!strcmp(tline->text, "||"))
1246             return tokval->t_type = TOKEN_DBL_OR;
1247     }
1248
1249     /*
1250      * We have no other options: just return the first character of
1251      * the token text.
1252      */
1253     return tokval->t_type = tline->text[0];
1254 }
1255
1256 /*
1257  * Compare a string to the name of an existing macro; this is a
1258  * simple wrapper which calls either strcmp or nasm_stricmp
1259  * depending on the value of the `casesense' parameter.
1260  */
1261 static int mstrcmp(const char *p, const char *q, bool casesense)
1262 {
1263     return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
1264 }
1265
1266 /*
1267  * Compare a string to the name of an existing macro; this is a
1268  * simple wrapper which calls either strcmp or nasm_stricmp
1269  * depending on the value of the `casesense' parameter.
1270  */
1271 static int mmemcmp(const char *p, const char *q, size_t l, bool casesense)
1272 {
1273     return casesense ? memcmp(p, q, l) : nasm_memicmp(p, q, l);
1274 }
1275
1276 /*
1277  * Return the Context structure associated with a %$ token. Return
1278  * NULL, having _already_ reported an error condition, if the
1279  * context stack isn't deep enough for the supplied number of $
1280  * signs.
1281  * If all_contexts == true, contexts that enclose current are
1282  * also scanned for such smacro, until it is found; if not -
1283  * only the context that directly results from the number of $'s
1284  * in variable's name.
1285  *
1286  * If "namep" is non-NULL, set it to the pointer to the macro name
1287  * tail, i.e. the part beyond %$...
1288  */
1289 static Context *get_ctx(const char *name, const char **namep,
1290                         bool all_contexts)
1291 {
1292     Context *ctx;
1293     SMacro *m;
1294     int i;
1295
1296     if (namep)
1297         *namep = name;
1298
1299     if (!name || name[0] != '%' || name[1] != '$')
1300         return NULL;
1301
1302     if (!cstk) {
1303         error(ERR_NONFATAL, "`%s': context stack is empty", name);
1304         return NULL;
1305     }
1306
1307     name += 2;
1308     ctx = cstk;
1309     i = 0;
1310     while (ctx && *name == '$') {
1311         name++;
1312         i++;
1313         ctx = ctx->next;
1314     }
1315     if (!ctx) {
1316         error(ERR_NONFATAL, "`%s': context stack is only"
1317               " %d level%s deep", name, i, (i == 1 ? "" : "s"));
1318         return NULL;
1319     }
1320
1321     if (namep)
1322         *namep = name;
1323
1324     if (!all_contexts)
1325         return ctx;
1326
1327     do {
1328         /* Search for this smacro in found context */
1329         m = hash_findix(&ctx->localmac, name);
1330         while (m) {
1331             if (!mstrcmp(m->name, name, m->casesense))
1332                 return ctx;
1333             m = m->next;
1334         }
1335         ctx = ctx->next;
1336     }
1337     while (ctx);
1338     return NULL;
1339 }
1340
1341 /*
1342  * Check to see if a file is already in a string list
1343  */
1344 static bool in_list(const StrList *list, const char *str)
1345 {
1346     while (list) {
1347         if (!strcmp(list->str, str))
1348             return true;
1349         list = list->next;
1350     }
1351     return false;
1352 }
1353
1354 /*
1355  * Open an include file. This routine must always return a valid
1356  * file pointer if it returns - it's responsible for throwing an
1357  * ERR_FATAL and bombing out completely if not. It should also try
1358  * the include path one by one until it finds the file or reaches
1359  * the end of the path.
1360  */
1361 static FILE *inc_fopen(const char *file, StrList **dhead, StrList ***dtail,
1362                        bool missing_ok)
1363 {
1364     FILE *fp;
1365     char *prefix = "";
1366     IncPath *ip = ipath;
1367     int len = strlen(file);
1368     size_t prefix_len = 0;
1369     StrList *sl;
1370
1371     while (1) {
1372         sl = nasm_malloc(prefix_len+len+1+sizeof sl->next);
1373         memcpy(sl->str, prefix, prefix_len);
1374         memcpy(sl->str+prefix_len, file, len+1);
1375         fp = fopen(sl->str, "r");
1376         if (fp && dhead && !in_list(*dhead, sl->str)) {
1377             sl->next = NULL;
1378             **dtail = sl;
1379             *dtail = &sl->next;
1380         } else {
1381             nasm_free(sl);
1382         }
1383         if (fp)
1384             return fp;
1385         if (!ip) {
1386             if (!missing_ok)
1387                 break;
1388             prefix = NULL;
1389         } else {
1390             prefix = ip->path;
1391             ip = ip->next;
1392         }
1393         if (prefix) {
1394             prefix_len = strlen(prefix);
1395         } else {
1396             /* -MG given and file not found */
1397             if (dhead && !in_list(*dhead, file)) {
1398                 sl = nasm_malloc(len+1+sizeof sl->next);
1399                 sl->next = NULL;
1400                 strcpy(sl->str, file);
1401                 **dtail = sl;
1402                 *dtail = &sl->next;
1403             }
1404             return NULL;
1405         }
1406     }
1407
1408     error(ERR_FATAL, "unable to open include file `%s'", file);
1409     return NULL;                /* never reached - placate compilers */
1410 }
1411
1412 /*
1413  * Determine if we should warn on defining a single-line macro of
1414  * name `name', with `nparam' parameters. If nparam is 0 or -1, will
1415  * return true if _any_ single-line macro of that name is defined.
1416  * Otherwise, will return true if a single-line macro with either
1417  * `nparam' or no parameters is defined.
1418  *
1419  * If a macro with precisely the right number of parameters is
1420  * defined, or nparam is -1, the address of the definition structure
1421  * will be returned in `defn'; otherwise NULL will be returned. If `defn'
1422  * is NULL, no action will be taken regarding its contents, and no
1423  * error will occur.
1424  *
1425  * Note that this is also called with nparam zero to resolve
1426  * `ifdef'.
1427  *
1428  * If you already know which context macro belongs to, you can pass
1429  * the context pointer as first parameter; if you won't but name begins
1430  * with %$ the context will be automatically computed. If all_contexts
1431  * is true, macro will be searched in outer contexts as well.
1432  */
1433 static bool
1434 smacro_defined(Context * ctx, const char *name, int nparam, SMacro ** defn,
1435                bool nocase)
1436 {
1437     struct hash_table *smtbl;
1438     SMacro *m;
1439
1440     if (ctx) {
1441         smtbl = &ctx->localmac;
1442     } else if (name[0] == '%' && name[1] == '$') {
1443         if (cstk)
1444             ctx = get_ctx(name, &name, false);
1445         if (!ctx)
1446             return false;       /* got to return _something_ */
1447         smtbl = &ctx->localmac;
1448     } else {
1449         smtbl = &smacros;
1450     }
1451     m = (SMacro *) hash_findix(smtbl, name);
1452
1453     while (m) {
1454         if (!mstrcmp(m->name, name, m->casesense && nocase) &&
1455             (nparam <= 0 || m->nparam == 0 || nparam == (int) m->nparam)) {
1456             if (defn) {
1457                 if (nparam == (int) m->nparam || nparam == -1)
1458                     *defn = m;
1459                 else
1460                     *defn = NULL;
1461             }
1462             return true;
1463         }
1464         m = m->next;
1465     }
1466
1467     return false;
1468 }
1469
1470 /*
1471  * Count and mark off the parameters in a multi-line macro call.
1472  * This is called both from within the multi-line macro expansion
1473  * code, and also to mark off the default parameters when provided
1474  * in a %macro definition line.
1475  */
1476 static void count_mmac_params(Token * t, int *nparam, Token *** params)
1477 {
1478     int paramsize, brace;
1479
1480     *nparam = paramsize = 0;
1481     *params = NULL;
1482     while (t) {
1483         /* +1: we need space for the final NULL */
1484         if (*nparam+1 >= paramsize) {
1485             paramsize += PARAM_DELTA;
1486             *params = nasm_realloc(*params, sizeof(**params) * paramsize);
1487         }
1488         skip_white_(t);
1489         brace = false;
1490         if (tok_is_(t, "{"))
1491             brace = true;
1492         (*params)[(*nparam)++] = t;
1493         while (tok_isnt_(t, brace ? "}" : ","))
1494             t = t->next;
1495         if (t) {                /* got a comma/brace */
1496             t = t->next;
1497             if (brace) {
1498                 /*
1499                  * Now we've found the closing brace, look further
1500                  * for the comma.
1501                  */
1502                 skip_white_(t);
1503                 if (tok_isnt_(t, ",")) {
1504                     error(ERR_NONFATAL,
1505                           "braces do not enclose all of macro parameter");
1506                     while (tok_isnt_(t, ","))
1507                         t = t->next;
1508                 }
1509                 if (t)
1510                     t = t->next;        /* eat the comma */
1511             }
1512         }
1513     }
1514 }
1515
1516 /*
1517  * Determine whether one of the various `if' conditions is true or
1518  * not.
1519  *
1520  * We must free the tline we get passed.
1521  */
1522 static bool if_condition(Token * tline, enum preproc_token ct)
1523 {
1524     enum pp_conditional i = PP_COND(ct);
1525     bool j;
1526     Token *t, *tt, **tptr, *origline;
1527     struct tokenval tokval;
1528     expr *evalresult;
1529     enum pp_token_type needtype;
1530
1531     origline = tline;
1532
1533     switch (i) {
1534     case PPC_IFCTX:
1535         j = false;              /* have we matched yet? */
1536         while (true) {
1537             skip_white_(tline);
1538             if (!tline)
1539                 break;
1540             if (tline->type != TOK_ID) {
1541                 error(ERR_NONFATAL,
1542                       "`%s' expects context identifiers", pp_directives[ct]);
1543                 free_tlist(origline);
1544                 return -1;
1545             }
1546             if (cstk && cstk->name && !nasm_stricmp(tline->text, cstk->name))
1547                 j = true;
1548             tline = tline->next;
1549         }
1550         break;
1551
1552     case PPC_IFDEF:
1553         j = false;              /* have we matched yet? */
1554         while (tline) {
1555             skip_white_(tline);
1556             if (!tline || (tline->type != TOK_ID &&
1557                            (tline->type != TOK_PREPROC_ID ||
1558                             tline->text[1] != '$'))) {
1559                 error(ERR_NONFATAL,
1560                       "`%s' expects macro identifiers", pp_directives[ct]);
1561                 goto fail;
1562             }
1563             if (smacro_defined(NULL, tline->text, 0, NULL, true))
1564                 j = true;
1565             tline = tline->next;
1566         }
1567         break;
1568
1569     case PPC_IFIDN:
1570     case PPC_IFIDNI:
1571         tline = expand_smacro(tline);
1572         t = tt = tline;
1573         while (tok_isnt_(tt, ","))
1574             tt = tt->next;
1575         if (!tt) {
1576             error(ERR_NONFATAL,
1577                   "`%s' expects two comma-separated arguments",
1578                   pp_directives[ct]);
1579             goto fail;
1580         }
1581         tt = tt->next;
1582         j = true;               /* assume equality unless proved not */
1583         while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt) {
1584             if (tt->type == TOK_OTHER && !strcmp(tt->text, ",")) {
1585                 error(ERR_NONFATAL, "`%s': more than one comma on line",
1586                       pp_directives[ct]);
1587                 goto fail;
1588             }
1589             if (t->type == TOK_WHITESPACE) {
1590                 t = t->next;
1591                 continue;
1592             }
1593             if (tt->type == TOK_WHITESPACE) {
1594                 tt = tt->next;
1595                 continue;
1596             }
1597             if (tt->type != t->type) {
1598                 j = false;      /* found mismatching tokens */
1599                 break;
1600             }
1601             /* When comparing strings, need to unquote them first */
1602             if (t->type == TOK_STRING) {
1603                 size_t l1 = nasm_unquote(t->text, NULL);
1604                 size_t l2 = nasm_unquote(tt->text, NULL);
1605
1606                 if (l1 != l2) {
1607                     j = false;
1608                     break;
1609                 }
1610                 if (mmemcmp(t->text, tt->text, l1, i == PPC_IFIDN)) {
1611                     j = false;
1612                     break;
1613                 }
1614             } else if (mstrcmp(tt->text, t->text, i == PPC_IFIDN) != 0) {
1615                 j = false;      /* found mismatching tokens */
1616                 break;
1617             }
1618
1619             t = t->next;
1620             tt = tt->next;
1621         }
1622         if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
1623             j = false;          /* trailing gunk on one end or other */
1624         break;
1625
1626     case PPC_IFMACRO:
1627         {
1628             bool found = false;
1629             MMacro searching, *mmac;
1630
1631             skip_white_(tline);
1632             tline = expand_id(tline);
1633             if (!tok_type_(tline, TOK_ID)) {
1634                 error(ERR_NONFATAL,
1635                       "`%s' expects a macro name", pp_directives[ct]);
1636                 goto fail;
1637             }
1638             searching.name = nasm_strdup(tline->text);
1639             searching.casesense = true;
1640             searching.plus = false;
1641             searching.nolist = false;
1642             searching.in_progress = 0;
1643             searching.rep_nest = NULL;
1644             searching.nparam_min = 0;
1645             searching.nparam_max = INT_MAX;
1646             tline = expand_smacro(tline->next);
1647             skip_white_(tline);
1648             if (!tline) {
1649             } else if (!tok_type_(tline, TOK_NUMBER)) {
1650                 error(ERR_NONFATAL,
1651                       "`%s' expects a parameter count or nothing",
1652                       pp_directives[ct]);
1653             } else {
1654                 searching.nparam_min = searching.nparam_max =
1655                     readnum(tline->text, &j);
1656                 if (j)
1657                     error(ERR_NONFATAL,
1658                           "unable to parse parameter count `%s'",
1659                           tline->text);
1660             }
1661             if (tline && tok_is_(tline->next, "-")) {
1662                 tline = tline->next->next;
1663                 if (tok_is_(tline, "*"))
1664                     searching.nparam_max = INT_MAX;
1665                 else if (!tok_type_(tline, TOK_NUMBER))
1666                     error(ERR_NONFATAL,
1667                           "`%s' expects a parameter count after `-'",
1668                           pp_directives[ct]);
1669                 else {
1670                     searching.nparam_max = readnum(tline->text, &j);
1671                     if (j)
1672                         error(ERR_NONFATAL,
1673                               "unable to parse parameter count `%s'",
1674                               tline->text);
1675                     if (searching.nparam_min > searching.nparam_max)
1676                         error(ERR_NONFATAL,
1677                               "minimum parameter count exceeds maximum");
1678                 }
1679             }
1680             if (tline && tok_is_(tline->next, "+")) {
1681                 tline = tline->next;
1682                 searching.plus = true;
1683             }
1684             mmac = (MMacro *) hash_findix(&mmacros, searching.name);
1685             while (mmac) {
1686                 if (!strcmp(mmac->name, searching.name) &&
1687                     (mmac->nparam_min <= searching.nparam_max
1688                      || searching.plus)
1689                     && (searching.nparam_min <= mmac->nparam_max
1690                         || mmac->plus)) {
1691                     found = true;
1692                     break;
1693                 }
1694                 mmac = mmac->next;
1695             }
1696             if(tline && tline->next)
1697                 error(ERR_WARNING|ERR_PASS1,
1698                       "trailing garbage after %%ifmacro ignored");
1699             nasm_free(searching.name);
1700             j = found;
1701             break;
1702         }
1703
1704     case PPC_IFID:
1705         needtype = TOK_ID;
1706         goto iftype;
1707     case PPC_IFNUM:
1708         needtype = TOK_NUMBER;
1709         goto iftype;
1710     case PPC_IFSTR:
1711         needtype = TOK_STRING;
1712         goto iftype;
1713
1714     iftype:
1715         t = tline = expand_smacro(tline);
1716
1717         while (tok_type_(t, TOK_WHITESPACE) ||
1718                (needtype == TOK_NUMBER &&
1719                 tok_type_(t, TOK_OTHER) &&
1720                 (t->text[0] == '-' || t->text[0] == '+') &&
1721                 !t->text[1]))
1722             t = t->next;
1723
1724         j = tok_type_(t, needtype);
1725         break;
1726
1727     case PPC_IFTOKEN:
1728         t = tline = expand_smacro(tline);
1729         while (tok_type_(t, TOK_WHITESPACE))
1730             t = t->next;
1731
1732         j = false;
1733         if (t) {
1734             t = t->next;        /* Skip the actual token */
1735             while (tok_type_(t, TOK_WHITESPACE))
1736                 t = t->next;
1737             j = !t;             /* Should be nothing left */
1738         }
1739         break;
1740
1741     case PPC_IFEMPTY:
1742         t = tline = expand_smacro(tline);
1743         while (tok_type_(t, TOK_WHITESPACE))
1744             t = t->next;
1745
1746         j = !t;                 /* Should be empty */
1747         break;
1748
1749     case PPC_IF:
1750         t = tline = expand_smacro(tline);
1751         tptr = &t;
1752         tokval.t_type = TOKEN_INVALID;
1753         evalresult = evaluate(ppscan, tptr, &tokval,
1754                               NULL, pass | CRITICAL, error, NULL);
1755         if (!evalresult)
1756             return -1;
1757         if (tokval.t_type)
1758             error(ERR_WARNING|ERR_PASS1,
1759                   "trailing garbage after expression ignored");
1760         if (!is_simple(evalresult)) {
1761             error(ERR_NONFATAL,
1762                   "non-constant value given to `%s'", pp_directives[ct]);
1763             goto fail;
1764         }
1765         j = reloc_value(evalresult) != 0;
1766         break;
1767
1768     default:
1769         error(ERR_FATAL,
1770               "preprocessor directive `%s' not yet implemented",
1771               pp_directives[ct]);
1772         goto fail;
1773     }
1774
1775     free_tlist(origline);
1776     return j ^ PP_NEGATIVE(ct);
1777
1778 fail:
1779     free_tlist(origline);
1780     return -1;
1781 }
1782
1783 /*
1784  * Common code for defining an smacro
1785  */
1786 static bool define_smacro(Context *ctx, const char *mname, bool casesense,
1787                           int nparam, Token *expansion)
1788 {
1789     SMacro *smac, **smhead;
1790     struct hash_table *smtbl;
1791
1792     if (smacro_defined(ctx, mname, nparam, &smac, casesense)) {
1793         if (!smac) {
1794             error(ERR_WARNING|ERR_PASS1,
1795                   "single-line macro `%s' defined both with and"
1796                   " without parameters", mname);
1797
1798             /* Some instances of the old code considered this a failure,
1799                some others didn't.  What is the right thing to do here? */
1800             free_tlist(expansion);
1801             return false;       /* Failure */
1802         } else {
1803             /*
1804              * We're redefining, so we have to take over an
1805              * existing SMacro structure. This means freeing
1806              * what was already in it.
1807              */
1808             nasm_free(smac->name);
1809             free_tlist(smac->expansion);
1810         }
1811     } else {
1812         smtbl  = ctx ? &ctx->localmac : &smacros;
1813         smhead = (SMacro **) hash_findi_add(smtbl, mname);
1814         smac = nasm_malloc(sizeof(SMacro));
1815         smac->next = *smhead;
1816         *smhead = smac;
1817     }
1818     smac->name = nasm_strdup(mname);
1819     smac->casesense = casesense;
1820     smac->nparam = nparam;
1821     smac->expansion = expansion;
1822     smac->in_progress = false;
1823     return true;                /* Success */
1824 }
1825
1826 /*
1827  * Undefine an smacro
1828  */
1829 static void undef_smacro(Context *ctx, const char *mname)
1830 {
1831     SMacro **smhead, *s, **sp;
1832     struct hash_table *smtbl;
1833
1834     smtbl = ctx ? &ctx->localmac : &smacros;
1835     smhead = (SMacro **)hash_findi(smtbl, mname, NULL);
1836
1837     if (smhead) {
1838         /*
1839          * We now have a macro name... go hunt for it.
1840          */
1841         sp = smhead;
1842         while ((s = *sp) != NULL) {
1843             if (!mstrcmp(s->name, mname, s->casesense)) {
1844                 *sp = s->next;
1845                 nasm_free(s->name);
1846                 free_tlist(s->expansion);
1847                 nasm_free(s);
1848             } else {
1849                 sp = &s->next;
1850             }
1851         }
1852     }
1853 }
1854
1855 /*
1856  * Parse a mmacro specification.
1857  */
1858 static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive)
1859 {
1860     bool err;
1861
1862     tline = tline->next;
1863     skip_white_(tline);
1864     tline = expand_id(tline);
1865     if (!tok_type_(tline, TOK_ID)) {
1866         error(ERR_NONFATAL, "`%s' expects a macro name", directive);
1867         return false;
1868     }
1869
1870     def->name = nasm_strdup(tline->text);
1871     def->plus = false;
1872     def->nolist = false;
1873     def->in_progress = 0;
1874     def->rep_nest = NULL;
1875     def->nparam_min = 0;
1876     def->nparam_max = 0;
1877
1878     tline = expand_smacro(tline->next);
1879     skip_white_(tline);
1880     if (!tok_type_(tline, TOK_NUMBER)) {
1881         error(ERR_NONFATAL, "`%s' expects a parameter count", directive);
1882     } else {
1883         def->nparam_min = def->nparam_max =
1884             readnum(tline->text, &err);
1885         if (err)
1886             error(ERR_NONFATAL,
1887                   "unable to parse parameter count `%s'", tline->text);
1888     }
1889     if (tline && tok_is_(tline->next, "-")) {
1890         tline = tline->next->next;
1891         if (tok_is_(tline, "*")) {
1892             def->nparam_max = INT_MAX;
1893         } else if (!tok_type_(tline, TOK_NUMBER)) {
1894             error(ERR_NONFATAL,
1895                   "`%s' expects a parameter count after `-'", directive);
1896         } else {
1897             def->nparam_max = readnum(tline->text, &err);
1898             if (err) {
1899                 error(ERR_NONFATAL, "unable to parse parameter count `%s'",
1900                       tline->text);
1901             }
1902             if (def->nparam_min > def->nparam_max) {
1903                 error(ERR_NONFATAL, "minimum parameter count exceeds maximum");
1904             }
1905         }
1906     }
1907     if (tline && tok_is_(tline->next, "+")) {
1908         tline = tline->next;
1909         def->plus = true;
1910     }
1911     if (tline && tok_type_(tline->next, TOK_ID) &&
1912         !nasm_stricmp(tline->next->text, ".nolist")) {
1913         tline = tline->next;
1914         def->nolist = true;
1915     }
1916
1917     /*
1918      * Handle default parameters.
1919      */
1920     if (tline && tline->next) {
1921         def->dlist = tline->next;
1922         tline->next = NULL;
1923         count_mmac_params(def->dlist, &def->ndefs, &def->defaults);
1924     } else {
1925         def->dlist = NULL;
1926         def->defaults = NULL;
1927     }
1928     def->expansion = NULL;
1929
1930         if(def->defaults &&
1931            def->ndefs > def->nparam_max - def->nparam_min &&
1932            !def->plus)
1933          error(ERR_WARNING|ERR_PASS1|ERR_WARN_MDP,
1934                "too many default macro parameters");
1935
1936     return true;
1937 }
1938
1939
1940 /*
1941  * Decode a size directive
1942  */
1943 static int parse_size(const char *str) {
1944     static const char *size_names[] =
1945         { "byte", "dword", "oword", "qword", "tword", "word", "yword" };
1946     static const int sizes[] =
1947         { 0, 1, 4, 16, 8, 10, 2, 32 };
1948
1949     return sizes[bsii(str, size_names, elements(size_names))+1];
1950 }
1951
1952 /**
1953  * find and process preprocessor directive in passed line
1954  * Find out if a line contains a preprocessor directive, and deal
1955  * with it if so.
1956  *
1957  * If a directive _is_ found, it is the responsibility of this routine
1958  * (and not the caller) to free_tlist() the line.
1959  *
1960  * @param tline a pointer to the current tokeninzed line linked list
1961  * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND
1962  *
1963  */
1964 static int do_directive(Token * tline)
1965 {
1966     enum preproc_token i;
1967     int j;
1968     bool err;
1969     int nparam;
1970     bool nolist;
1971     bool casesense;
1972     int k, m;
1973     int offset;
1974     char *p, *pp;
1975     const char *mname;
1976     Include *inc;
1977     Context *ctx;
1978     Cond *cond;
1979     MMacro *mmac, **mmhead;
1980     Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
1981     Line *l;
1982     struct tokenval tokval;
1983     expr *evalresult;
1984     MMacro *tmp_defining;       /* Used when manipulating rep_nest */
1985     int64_t count;
1986     size_t len;
1987     int severity;
1988
1989     origline = tline;
1990
1991     skip_white_(tline);
1992     if (!tline || !tok_type_(tline, TOK_PREPROC_ID) ||
1993         (tline->text[1] == '%' || tline->text[1] == '$'
1994          || tline->text[1] == '!'))
1995         return NO_DIRECTIVE_FOUND;
1996
1997     i = pp_token_hash(tline->text);
1998
1999     /*
2000      * If we're in a non-emitting branch of a condition construct,
2001      * or walking to the end of an already terminated %rep block,
2002      * we should ignore all directives except for condition
2003      * directives.
2004      */
2005     if (((istk->conds && !emitting(istk->conds->state)) ||
2006          (istk->mstk && !istk->mstk->in_progress)) && !is_condition(i)) {
2007         return NO_DIRECTIVE_FOUND;
2008     }
2009
2010     /*
2011      * If we're defining a macro or reading a %rep block, we should
2012      * ignore all directives except for %macro/%imacro (which nest),
2013      * %endm/%endmacro, and (only if we're in a %rep block) %endrep.
2014      * If we're in a %rep block, another %rep nests, so should be let through.
2015      */
2016     if (defining && i != PP_MACRO && i != PP_IMACRO &&
2017         i != PP_ENDMACRO && i != PP_ENDM &&
2018         (defining->name || (i != PP_ENDREP && i != PP_REP))) {
2019         return NO_DIRECTIVE_FOUND;
2020     }
2021
2022     if (defining) {
2023         if (i == PP_MACRO || i == PP_IMACRO) {
2024             nested_mac_count++;
2025             return NO_DIRECTIVE_FOUND;
2026         } else if (nested_mac_count > 0) {
2027             if (i == PP_ENDMACRO) {
2028                 nested_mac_count--;
2029                 return NO_DIRECTIVE_FOUND;
2030             }
2031         }
2032         if (!defining->name) {
2033             if (i == PP_REP) {
2034                 nested_rep_count++;
2035                 return NO_DIRECTIVE_FOUND;
2036             } else if (nested_rep_count > 0) {
2037                 if (i == PP_ENDREP) {
2038                     nested_rep_count--;
2039                     return NO_DIRECTIVE_FOUND;
2040                 }
2041             }
2042         }
2043     }
2044
2045     switch (i) {
2046     case PP_INVALID:
2047         error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
2048               tline->text);
2049         return NO_DIRECTIVE_FOUND;      /* didn't get it */
2050
2051     case PP_STACKSIZE:
2052         /* Directive to tell NASM what the default stack size is. The
2053          * default is for a 16-bit stack, and this can be overriden with
2054          * %stacksize large.
2055          * the following form:
2056          *
2057          *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD
2058          */
2059         tline = tline->next;
2060         if (tline && tline->type == TOK_WHITESPACE)
2061             tline = tline->next;
2062         if (!tline || tline->type != TOK_ID) {
2063             error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
2064             free_tlist(origline);
2065             return DIRECTIVE_FOUND;
2066         }
2067         if (nasm_stricmp(tline->text, "flat") == 0) {
2068             /* All subsequent ARG directives are for a 32-bit stack */
2069             StackSize = 4;
2070             StackPointer = "ebp";
2071             ArgOffset = 8;
2072             LocalOffset = 0;
2073         } else if (nasm_stricmp(tline->text, "flat64") == 0) {
2074             /* All subsequent ARG directives are for a 64-bit stack */
2075             StackSize = 8;
2076             StackPointer = "rbp";
2077             ArgOffset = 8;
2078             LocalOffset = 0;
2079         } else if (nasm_stricmp(tline->text, "large") == 0) {
2080             /* All subsequent ARG directives are for a 16-bit stack,
2081              * far function call.
2082              */
2083             StackSize = 2;
2084             StackPointer = "bp";
2085             ArgOffset = 4;
2086             LocalOffset = 0;
2087         } else if (nasm_stricmp(tline->text, "small") == 0) {
2088             /* All subsequent ARG directives are for a 16-bit stack,
2089              * far function call. We don't support near functions.
2090              */
2091             StackSize = 2;
2092             StackPointer = "bp";
2093             ArgOffset = 6;
2094             LocalOffset = 0;
2095         } else {
2096             error(ERR_NONFATAL, "`%%stacksize' invalid size type");
2097             free_tlist(origline);
2098             return DIRECTIVE_FOUND;
2099         }
2100         free_tlist(origline);
2101         return DIRECTIVE_FOUND;
2102
2103     case PP_ARG:
2104         /* TASM like ARG directive to define arguments to functions, in
2105          * the following form:
2106          *
2107          *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD
2108          */
2109         offset = ArgOffset;
2110         do {
2111             char *arg, directive[256];
2112             int size = StackSize;
2113
2114             /* Find the argument name */
2115             tline = tline->next;
2116             if (tline && tline->type == TOK_WHITESPACE)
2117                 tline = tline->next;
2118             if (!tline || tline->type != TOK_ID) {
2119                 error(ERR_NONFATAL, "`%%arg' missing argument parameter");
2120                 free_tlist(origline);
2121                 return DIRECTIVE_FOUND;
2122             }
2123             arg = tline->text;
2124
2125             /* Find the argument size type */
2126             tline = tline->next;
2127             if (!tline || tline->type != TOK_OTHER
2128                 || tline->text[0] != ':') {
2129                 error(ERR_NONFATAL,
2130                       "Syntax error processing `%%arg' directive");
2131                 free_tlist(origline);
2132                 return DIRECTIVE_FOUND;
2133             }
2134             tline = tline->next;
2135             if (!tline || tline->type != TOK_ID) {
2136                 error(ERR_NONFATAL, "`%%arg' missing size type parameter");
2137                 free_tlist(origline);
2138                 return DIRECTIVE_FOUND;
2139             }
2140
2141             /* Allow macro expansion of type parameter */
2142             tt = tokenize(tline->text);
2143             tt = expand_smacro(tt);
2144             size = parse_size(tt->text);
2145             if (!size) {
2146                 error(ERR_NONFATAL,
2147                       "Invalid size type for `%%arg' missing directive");
2148                 free_tlist(tt);
2149                 free_tlist(origline);
2150                 return DIRECTIVE_FOUND;
2151             }
2152             free_tlist(tt);
2153
2154             /* Round up to even stack slots */
2155             size = (size+StackSize-1) & ~(StackSize-1);
2156
2157             /* Now define the macro for the argument */
2158             snprintf(directive, sizeof(directive), "%%define %s (%s+%d)",
2159                      arg, StackPointer, offset);
2160             do_directive(tokenize(directive));
2161             offset += size;
2162
2163             /* Move to the next argument in the list */
2164             tline = tline->next;
2165             if (tline && tline->type == TOK_WHITESPACE)
2166                 tline = tline->next;
2167         } while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
2168         ArgOffset = offset;
2169         free_tlist(origline);
2170         return DIRECTIVE_FOUND;
2171
2172     case PP_LOCAL:
2173         /* TASM like LOCAL directive to define local variables for a
2174          * function, in the following form:
2175          *
2176          *      LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
2177          *
2178          * The '= LocalSize' at the end is ignored by NASM, but is
2179          * required by TASM to define the local parameter size (and used
2180          * by the TASM macro package).
2181          */
2182         offset = LocalOffset;
2183         do {
2184             char *local, directive[256];
2185             int size = StackSize;
2186
2187             /* Find the argument name */
2188             tline = tline->next;
2189             if (tline && tline->type == TOK_WHITESPACE)
2190                 tline = tline->next;
2191             if (!tline || tline->type != TOK_ID) {
2192                 error(ERR_NONFATAL,
2193                       "`%%local' missing argument parameter");
2194                 free_tlist(origline);
2195                 return DIRECTIVE_FOUND;
2196             }
2197             local = tline->text;
2198
2199             /* Find the argument size type */
2200             tline = tline->next;
2201             if (!tline || tline->type != TOK_OTHER
2202                 || tline->text[0] != ':') {
2203                 error(ERR_NONFATAL,
2204                       "Syntax error processing `%%local' directive");
2205                 free_tlist(origline);
2206                 return DIRECTIVE_FOUND;
2207             }
2208             tline = tline->next;
2209             if (!tline || tline->type != TOK_ID) {
2210                 error(ERR_NONFATAL,
2211                       "`%%local' missing size type parameter");
2212                 free_tlist(origline);
2213                 return DIRECTIVE_FOUND;
2214             }
2215
2216             /* Allow macro expansion of type parameter */
2217             tt = tokenize(tline->text);
2218             tt = expand_smacro(tt);
2219             size = parse_size(tt->text);
2220             if (!size) {
2221                 error(ERR_NONFATAL,
2222                       "Invalid size type for `%%local' missing directive");
2223                 free_tlist(tt);
2224                 free_tlist(origline);
2225                 return DIRECTIVE_FOUND;
2226             }
2227             free_tlist(tt);
2228
2229             /* Round up to even stack slots */
2230             size = (size+StackSize-1) & ~(StackSize-1);
2231
2232             offset += size;     /* Negative offset, increment before */
2233
2234             /* Now define the macro for the argument */
2235             snprintf(directive, sizeof(directive), "%%define %s (%s-%d)",
2236                      local, StackPointer, offset);
2237             do_directive(tokenize(directive));
2238
2239             /* Now define the assign to setup the enter_c macro correctly */
2240             snprintf(directive, sizeof(directive),
2241                      "%%assign %%$localsize %%$localsize+%d", size);
2242             do_directive(tokenize(directive));
2243
2244             /* Move to the next argument in the list */
2245             tline = tline->next;
2246             if (tline && tline->type == TOK_WHITESPACE)
2247                 tline = tline->next;
2248         } while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
2249         LocalOffset = offset;
2250         free_tlist(origline);
2251         return DIRECTIVE_FOUND;
2252
2253     case PP_CLEAR:
2254         if (tline->next)
2255             error(ERR_WARNING|ERR_PASS1,
2256                   "trailing garbage after `%%clear' ignored");
2257         free_macros();
2258         init_macros();
2259         free_tlist(origline);
2260         return DIRECTIVE_FOUND;
2261
2262     case PP_DEPEND:
2263         t = tline->next = expand_smacro(tline->next);
2264         skip_white_(t);
2265         if (!t || (t->type != TOK_STRING &&
2266                        t->type != TOK_INTERNAL_STRING)) {
2267             error(ERR_NONFATAL, "`%%depend' expects a file name");
2268             free_tlist(origline);
2269             return DIRECTIVE_FOUND;     /* but we did _something_ */
2270         }
2271         if (t->next)
2272             error(ERR_WARNING|ERR_PASS1,
2273                   "trailing garbage after `%%depend' ignored");
2274         p = t->text;
2275         if (t->type != TOK_INTERNAL_STRING)
2276             nasm_unquote(p, NULL);
2277         if (dephead && !in_list(*dephead, p)) {
2278             StrList *sl = nasm_malloc(strlen(p)+1+sizeof sl->next);
2279             sl->next = NULL;
2280             strcpy(sl->str, p);
2281             *deptail = sl;
2282             deptail = &sl->next;
2283         }
2284         free_tlist(origline);
2285         return DIRECTIVE_FOUND;
2286
2287     case PP_INCLUDE:
2288         t = tline->next = expand_smacro(tline->next);
2289         skip_white_(t);
2290
2291         if (!t || (t->type != TOK_STRING &&
2292                        t->type != TOK_INTERNAL_STRING)) {
2293             error(ERR_NONFATAL, "`%%include' expects a file name");
2294             free_tlist(origline);
2295             return DIRECTIVE_FOUND;     /* but we did _something_ */
2296         }
2297         if (t->next)
2298             error(ERR_WARNING|ERR_PASS1,
2299                   "trailing garbage after `%%include' ignored");
2300         p = t->text;
2301         if (t->type != TOK_INTERNAL_STRING)
2302             nasm_unquote(p, NULL);
2303         inc = nasm_malloc(sizeof(Include));
2304         inc->next = istk;
2305         inc->conds = NULL;
2306         inc->fp = inc_fopen(p, dephead, &deptail, pass == 0);
2307         if (!inc->fp) {
2308             /* -MG given but file not found */
2309             nasm_free(inc);
2310         } else {
2311             inc->fname = src_set_fname(nasm_strdup(p));
2312             inc->lineno = src_set_linnum(0);
2313             inc->lineinc = 1;
2314             inc->expansion = NULL;
2315             inc->mstk = NULL;
2316             istk = inc;
2317             list->uplevel(LIST_INCLUDE);
2318         }
2319         free_tlist(origline);
2320         return DIRECTIVE_FOUND;
2321
2322     case PP_USE:
2323     {
2324         static macros_t *use_pkg;
2325         const char *pkg_macro;
2326
2327         tline = tline->next;
2328         skip_white_(tline);
2329         tline = expand_id(tline);
2330
2331         if (!tline || (tline->type != TOK_STRING &&
2332                        tline->type != TOK_INTERNAL_STRING &&
2333                        tline->type != TOK_ID)) {
2334             error(ERR_NONFATAL, "`%%use' expects a package name");
2335             free_tlist(origline);
2336             return DIRECTIVE_FOUND;     /* but we did _something_ */
2337         }
2338         if (tline->next)
2339             error(ERR_WARNING|ERR_PASS1,
2340                   "trailing garbage after `%%use' ignored");
2341         if (tline->type == TOK_STRING)
2342             nasm_unquote(tline->text, NULL);
2343         use_pkg = nasm_stdmac_find_package(tline->text);
2344         if (!use_pkg)
2345             error(ERR_NONFATAL, "unknown `%%use' package: %s", tline->text);
2346         /* The first string will be <%define>__USE_*__ */
2347         pkg_macro = (char *)use_pkg + 1;
2348         if (!smacro_defined(NULL, pkg_macro, 0, NULL, true)) {
2349             /* Not already included, go ahead and include it */
2350             stdmacpos = use_pkg;
2351         }
2352         free_tlist(origline);
2353         return DIRECTIVE_FOUND;
2354     }
2355     case PP_PUSH:
2356     case PP_REPL:
2357     case PP_POP:
2358         tline = tline->next;
2359         skip_white_(tline);
2360         tline = expand_id(tline);
2361         if (tline) {
2362             if (!tok_type_(tline, TOK_ID)) {
2363                 error(ERR_NONFATAL, "`%s' expects a context identifier",
2364                       pp_directives[i]);
2365                 free_tlist(origline);
2366                 return DIRECTIVE_FOUND;     /* but we did _something_ */
2367             }
2368             if (tline->next)
2369                 error(ERR_WARNING|ERR_PASS1,
2370                       "trailing garbage after `%s' ignored",
2371                       pp_directives[i]);
2372             p = nasm_strdup(tline->text);
2373         } else {
2374             p = NULL;           /* Anonymous */
2375         }
2376
2377         if (i == PP_PUSH) {
2378             ctx = nasm_malloc(sizeof(Context));
2379             ctx->next = cstk;
2380             hash_init(&ctx->localmac, HASH_SMALL);
2381             ctx->name = p;
2382             ctx->number = unique++;
2383             cstk = ctx;
2384         } else {
2385             /* %pop or %repl */
2386             if (!cstk) {
2387                 error(ERR_NONFATAL, "`%s': context stack is empty",
2388                       pp_directives[i]);
2389             } else if (i == PP_POP) {
2390                 if (p && (!cstk->name || nasm_stricmp(p, cstk->name)))
2391                     error(ERR_NONFATAL, "`%%pop' in wrong context: %s, "
2392                           "expected %s",
2393                           cstk->name ? cstk->name : "anonymous", p);
2394                 else
2395                     ctx_pop();
2396             } else {
2397                 /* i == PP_REPL */
2398                 nasm_free(cstk->name);
2399                 cstk->name = p;
2400                 p = NULL;
2401             }
2402             nasm_free(p);
2403         }
2404         free_tlist(origline);
2405         return DIRECTIVE_FOUND;
2406     case PP_FATAL:
2407         severity = ERR_FATAL|ERR_NO_SEVERITY;
2408         goto issue_error;
2409     case PP_ERROR:
2410         severity = ERR_NONFATAL|ERR_NO_SEVERITY;
2411         goto issue_error;
2412     case PP_WARNING:
2413         severity = ERR_WARNING|ERR_NO_SEVERITY|ERR_WARN_USER;
2414         goto issue_error;
2415
2416     issue_error:
2417     {
2418         /* Only error out if this is the final pass */
2419         if (pass != 2 && i != PP_FATAL)
2420             return DIRECTIVE_FOUND;
2421
2422         tline->next = expand_smacro(tline->next);
2423         tline = tline->next;
2424         skip_white_(tline);
2425         t = tline ? tline->next : NULL;
2426         skip_white_(t);
2427         if (tok_type_(tline, TOK_STRING) && !t) {
2428             /* The line contains only a quoted string */
2429             p = tline->text;
2430             nasm_unquote(p, NULL);
2431             error(severity, "%s: %s",  pp_directives[i], p);
2432         } else {
2433             /* Not a quoted string, or more than a quoted string */
2434             p = detoken(tline, false);
2435             error(severity, "%s: %s",  pp_directives[i], p);
2436             nasm_free(p);
2437         }
2438         free_tlist(origline);
2439         return DIRECTIVE_FOUND;
2440     }
2441
2442     CASE_PP_IF:
2443         if (istk->conds && !emitting(istk->conds->state))
2444             j = COND_NEVER;
2445         else {
2446             j = if_condition(tline->next, i);
2447             tline->next = NULL; /* it got freed */
2448             j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2449         }
2450         cond = nasm_malloc(sizeof(Cond));
2451         cond->next = istk->conds;
2452         cond->state = j;
2453         istk->conds = cond;
2454         free_tlist(origline);
2455         return DIRECTIVE_FOUND;
2456
2457     CASE_PP_ELIF:
2458         if (!istk->conds)
2459             error(ERR_FATAL, "`%s': no matching `%%if'", pp_directives[i]);
2460         switch(istk->conds->state) {
2461             case COND_IF_TRUE:
2462                 istk->conds->state = COND_DONE;
2463                 break;
2464
2465             case COND_DONE:
2466             case COND_NEVER:
2467                 break;
2468
2469             case COND_ELSE_TRUE:
2470             case COND_ELSE_FALSE:
2471                 error_precond(ERR_WARNING|ERR_PASS1,
2472                               "`%%elif' after `%%else' ignored");
2473                 istk->conds->state = COND_NEVER;
2474                 break;
2475
2476             case COND_IF_FALSE:
2477                 /*
2478                  * IMPORTANT: In the case of %if, we will already have
2479                  * called expand_mmac_params(); however, if we're
2480                  * processing an %elif we must have been in a
2481                  * non-emitting mode, which would have inhibited
2482                  * the normal invocation of expand_mmac_params().
2483                  * Therefore, we have to do it explicitly here.
2484                  */
2485                 j = if_condition(expand_mmac_params(tline->next), i);
2486                 tline->next = NULL; /* it got freed */
2487                 istk->conds->state =
2488                     j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2489                 break;
2490         }
2491         free_tlist(origline);
2492         return DIRECTIVE_FOUND;
2493
2494     case PP_ELSE:
2495         if (tline->next)
2496             error_precond(ERR_WARNING|ERR_PASS1,
2497                           "trailing garbage after `%%else' ignored");
2498         if (!istk->conds)
2499             error(ERR_FATAL, "`%%else': no matching `%%if'");
2500         switch(istk->conds->state) {
2501             case COND_IF_TRUE:
2502             case COND_DONE:
2503                 istk->conds->state = COND_ELSE_FALSE;
2504                 break;
2505
2506             case COND_NEVER:
2507                 break;
2508
2509             case COND_IF_FALSE:
2510                 istk->conds->state = COND_ELSE_TRUE;
2511                 break;
2512
2513             case COND_ELSE_TRUE:
2514             case COND_ELSE_FALSE:
2515                 error_precond(ERR_WARNING|ERR_PASS1,
2516                               "`%%else' after `%%else' ignored.");
2517                 istk->conds->state = COND_NEVER;
2518                 break;
2519         }
2520         free_tlist(origline);
2521         return DIRECTIVE_FOUND;
2522
2523     case PP_ENDIF:
2524         if (tline->next)
2525             error_precond(ERR_WARNING|ERR_PASS1,
2526                           "trailing garbage after `%%endif' ignored");
2527         if (!istk->conds)
2528             error(ERR_FATAL, "`%%endif': no matching `%%if'");
2529         cond = istk->conds;
2530         istk->conds = cond->next;
2531         nasm_free(cond);
2532         free_tlist(origline);
2533         return DIRECTIVE_FOUND;
2534
2535     case PP_MACRO:
2536     case PP_IMACRO:
2537         if (defining) {
2538             error(ERR_FATAL,
2539                   "`%%%smacro': already defining a macro",
2540                   (i == PP_IMACRO ? "i" : ""));
2541             return DIRECTIVE_FOUND;
2542         }
2543         defining = nasm_malloc(sizeof(MMacro));
2544         defining->casesense = (i == PP_MACRO);
2545         if (!parse_mmacro_spec(tline, defining, pp_directives[i])) {
2546             nasm_free(defining);
2547             defining = NULL;
2548             return DIRECTIVE_FOUND;
2549         }
2550
2551         mmac = (MMacro *) hash_findix(&mmacros, defining->name);
2552         while (mmac) {
2553             if (!strcmp(mmac->name, defining->name) &&
2554                 (mmac->nparam_min <= defining->nparam_max
2555                  || defining->plus)
2556                 && (defining->nparam_min <= mmac->nparam_max
2557                     || mmac->plus)) {
2558                 error(ERR_WARNING|ERR_PASS1,
2559                       "redefining multi-line macro `%s'", defining->name);
2560                 return DIRECTIVE_FOUND;
2561             }
2562             mmac = mmac->next;
2563         }
2564         free_tlist(origline);
2565         return DIRECTIVE_FOUND;
2566
2567     case PP_ENDM:
2568     case PP_ENDMACRO:
2569         if (! (defining && defining->name)) {
2570             error(ERR_NONFATAL, "`%s': not defining a macro", tline->text);
2571             return DIRECTIVE_FOUND;
2572         }
2573         mmhead = (MMacro **) hash_findi_add(&mmacros, defining->name);
2574         defining->next = *mmhead;
2575         *mmhead = defining;
2576         defining = NULL;
2577         free_tlist(origline);
2578         return DIRECTIVE_FOUND;
2579
2580     case PP_UNMACRO:
2581     case PP_UNIMACRO:
2582     {
2583         MMacro **mmac_p;
2584         MMacro spec;
2585
2586         spec.casesense = (i == PP_UNMACRO);
2587         if (!parse_mmacro_spec(tline, &spec, pp_directives[i])) {
2588             return DIRECTIVE_FOUND;
2589         }
2590         mmac_p = (MMacro **) hash_findi(&mmacros, spec.name, NULL);
2591         while (mmac_p && *mmac_p) {
2592             mmac = *mmac_p;
2593             if (mmac->casesense == spec.casesense &&
2594                 !mstrcmp(mmac->name, spec.name, spec.casesense) &&
2595                 mmac->nparam_min == spec.nparam_min &&
2596                 mmac->nparam_max == spec.nparam_max &&
2597                 mmac->plus == spec.plus) {
2598                 *mmac_p = mmac->next;
2599                 free_mmacro(mmac);
2600             } else {
2601                 mmac_p = &mmac->next;
2602             }
2603         }
2604         free_tlist(origline);
2605         free_tlist(spec.dlist);
2606         return DIRECTIVE_FOUND;
2607     }
2608
2609     case PP_ROTATE:
2610         if (tline->next && tline->next->type == TOK_WHITESPACE)
2611             tline = tline->next;
2612         if (tline->next == NULL) {
2613             free_tlist(origline);
2614             error(ERR_NONFATAL, "`%%rotate' missing rotate count");
2615             return DIRECTIVE_FOUND;
2616         }
2617         t = expand_smacro(tline->next);
2618         tline->next = NULL;
2619         free_tlist(origline);
2620         tline = t;
2621         tptr = &t;
2622         tokval.t_type = TOKEN_INVALID;
2623         evalresult =
2624             evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2625         free_tlist(tline);
2626         if (!evalresult)
2627             return DIRECTIVE_FOUND;
2628         if (tokval.t_type)
2629             error(ERR_WARNING|ERR_PASS1,
2630                   "trailing garbage after expression ignored");
2631         if (!is_simple(evalresult)) {
2632             error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
2633             return DIRECTIVE_FOUND;
2634         }
2635         mmac = istk->mstk;
2636         while (mmac && !mmac->name)     /* avoid mistaking %reps for macros */
2637             mmac = mmac->next_active;
2638         if (!mmac) {
2639             error(ERR_NONFATAL, "`%%rotate' invoked outside a macro call");
2640         } else if (mmac->nparam == 0) {
2641             error(ERR_NONFATAL,
2642                   "`%%rotate' invoked within macro without parameters");
2643         } else {
2644             int rotate = mmac->rotate + reloc_value(evalresult);
2645
2646             rotate %= (int)mmac->nparam;
2647             if (rotate < 0)
2648                 rotate += mmac->nparam;
2649
2650             mmac->rotate = rotate;
2651         }
2652         return DIRECTIVE_FOUND;
2653
2654     case PP_REP:
2655         nolist = false;
2656         do {
2657             tline = tline->next;
2658         } while (tok_type_(tline, TOK_WHITESPACE));
2659
2660         if (tok_type_(tline, TOK_ID) &&
2661             nasm_stricmp(tline->text, ".nolist") == 0) {
2662             nolist = true;
2663             do {
2664                 tline = tline->next;
2665             } while (tok_type_(tline, TOK_WHITESPACE));
2666         }
2667
2668         if (tline) {
2669             t = expand_smacro(tline);
2670             tptr = &t;
2671             tokval.t_type = TOKEN_INVALID;
2672             evalresult =
2673                 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2674             if (!evalresult) {
2675                 free_tlist(origline);
2676                 return DIRECTIVE_FOUND;
2677             }
2678             if (tokval.t_type)
2679                 error(ERR_WARNING|ERR_PASS1,
2680                       "trailing garbage after expression ignored");
2681             if (!is_simple(evalresult)) {
2682                 error(ERR_NONFATAL, "non-constant value given to `%%rep'");
2683                 return DIRECTIVE_FOUND;
2684             }
2685             count = reloc_value(evalresult) + 1;
2686         } else {
2687             error(ERR_NONFATAL, "`%%rep' expects a repeat count");
2688             count = 0;
2689         }
2690         free_tlist(origline);
2691
2692         tmp_defining = defining;
2693         defining = nasm_malloc(sizeof(MMacro));
2694         defining->name = NULL;  /* flags this macro as a %rep block */
2695         defining->casesense = false;
2696         defining->plus = false;
2697         defining->nolist = nolist;
2698         defining->in_progress = count;
2699         defining->nparam_min = defining->nparam_max = 0;
2700         defining->defaults = NULL;
2701         defining->dlist = NULL;
2702         defining->expansion = NULL;
2703         defining->next_active = istk->mstk;
2704         defining->rep_nest = tmp_defining;
2705         return DIRECTIVE_FOUND;
2706
2707     case PP_ENDREP:
2708         if (!defining || defining->name) {
2709             error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
2710             return DIRECTIVE_FOUND;
2711         }
2712
2713         /*
2714          * Now we have a "macro" defined - although it has no name
2715          * and we won't be entering it in the hash tables - we must
2716          * push a macro-end marker for it on to istk->expansion.
2717          * After that, it will take care of propagating itself (a
2718          * macro-end marker line for a macro which is really a %rep
2719          * block will cause the macro to be re-expanded, complete
2720          * with another macro-end marker to ensure the process
2721          * continues) until the whole expansion is forcibly removed
2722          * from istk->expansion by a %exitrep.
2723          */
2724         l = nasm_malloc(sizeof(Line));
2725         l->next = istk->expansion;
2726         l->finishes = defining;
2727         l->first = NULL;
2728         istk->expansion = l;
2729
2730         istk->mstk = defining;
2731
2732         list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
2733         tmp_defining = defining;
2734         defining = defining->rep_nest;
2735         free_tlist(origline);
2736         return DIRECTIVE_FOUND;
2737
2738     case PP_EXITREP:
2739         /*
2740          * We must search along istk->expansion until we hit a
2741          * macro-end marker for a macro with no name. Then we set
2742          * its `in_progress' flag to 0.
2743          */
2744         for (l = istk->expansion; l; l = l->next)
2745             if (l->finishes && !l->finishes->name)
2746                 break;
2747
2748         if (l)
2749             l->finishes->in_progress = 1;
2750         else
2751             error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
2752         free_tlist(origline);
2753         return DIRECTIVE_FOUND;
2754
2755     case PP_XDEFINE:
2756     case PP_IXDEFINE:
2757     case PP_DEFINE:
2758     case PP_IDEFINE:
2759         casesense = (i == PP_DEFINE || i == PP_XDEFINE);
2760
2761         tline = tline->next;
2762         skip_white_(tline);
2763         tline = expand_id(tline);
2764         if (!tline || (tline->type != TOK_ID &&
2765                        (tline->type != TOK_PREPROC_ID ||
2766                         tline->text[1] != '$'))) {
2767             error(ERR_NONFATAL, "`%s' expects a macro identifier",
2768                   pp_directives[i]);
2769             free_tlist(origline);
2770             return DIRECTIVE_FOUND;
2771         }
2772
2773         ctx = get_ctx(tline->text, &mname, false);
2774         last = tline;
2775         param_start = tline = tline->next;
2776         nparam = 0;
2777
2778         /* Expand the macro definition now for %xdefine and %ixdefine */
2779         if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
2780             tline = expand_smacro(tline);
2781
2782         if (tok_is_(tline, "(")) {
2783             /*
2784              * This macro has parameters.
2785              */
2786
2787             tline = tline->next;
2788             while (1) {
2789                 skip_white_(tline);
2790                 if (!tline) {
2791                     error(ERR_NONFATAL, "parameter identifier expected");
2792                     free_tlist(origline);
2793                     return DIRECTIVE_FOUND;
2794                 }
2795                 if (tline->type != TOK_ID) {
2796                     error(ERR_NONFATAL,
2797                           "`%s': parameter identifier expected",
2798                           tline->text);
2799                     free_tlist(origline);
2800                     return DIRECTIVE_FOUND;
2801                 }
2802                 tline->type = TOK_SMAC_PARAM + nparam++;
2803                 tline = tline->next;
2804                 skip_white_(tline);
2805                 if (tok_is_(tline, ",")) {
2806                     tline = tline->next;
2807                 } else {
2808                     if (!tok_is_(tline, ")")) {
2809                         error(ERR_NONFATAL,
2810                               "`)' expected to terminate macro template");
2811                         free_tlist(origline);
2812                         return DIRECTIVE_FOUND;
2813                     }
2814                     break;
2815                 }
2816             }
2817             last = tline;
2818             tline = tline->next;
2819         }
2820         if (tok_type_(tline, TOK_WHITESPACE))
2821             last = tline, tline = tline->next;
2822         macro_start = NULL;
2823         last->next = NULL;
2824         t = tline;
2825         while (t) {
2826             if (t->type == TOK_ID) {
2827                 for (tt = param_start; tt; tt = tt->next)
2828                     if (tt->type >= TOK_SMAC_PARAM &&
2829                         !strcmp(tt->text, t->text))
2830                         t->type = tt->type;
2831             }
2832             tt = t->next;
2833             t->next = macro_start;
2834             macro_start = t;
2835             t = tt;
2836         }
2837         /*
2838          * Good. We now have a macro name, a parameter count, and a
2839          * token list (in reverse order) for an expansion. We ought
2840          * to be OK just to create an SMacro, store it, and let
2841          * free_tlist have the rest of the line (which we have
2842          * carefully re-terminated after chopping off the expansion
2843          * from the end).
2844          */
2845         define_smacro(ctx, mname, casesense, nparam, macro_start);
2846         free_tlist(origline);
2847         return DIRECTIVE_FOUND;
2848
2849     case PP_UNDEF:
2850         tline = tline->next;
2851         skip_white_(tline);
2852         tline = expand_id(tline);
2853         if (!tline || (tline->type != TOK_ID &&
2854                        (tline->type != TOK_PREPROC_ID ||
2855                         tline->text[1] != '$'))) {
2856             error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
2857             free_tlist(origline);
2858             return DIRECTIVE_FOUND;
2859         }
2860         if (tline->next) {
2861             error(ERR_WARNING|ERR_PASS1,
2862                   "trailing garbage after macro name ignored");
2863         }
2864
2865         /* Find the context that symbol belongs to */
2866         ctx = get_ctx(tline->text, &mname, false);
2867         undef_smacro(ctx, mname);
2868         free_tlist(origline);
2869         return DIRECTIVE_FOUND;
2870
2871     case PP_DEFSTR:
2872     case PP_IDEFSTR:
2873         casesense = (i == PP_DEFSTR);
2874
2875         tline = tline->next;
2876         skip_white_(tline);
2877         tline = expand_id(tline);
2878         if (!tline || (tline->type != TOK_ID &&
2879                        (tline->type != TOK_PREPROC_ID ||
2880                         tline->text[1] != '$'))) {
2881             error(ERR_NONFATAL, "`%s' expects a macro identifier",
2882                   pp_directives[i]);
2883             free_tlist(origline);
2884             return DIRECTIVE_FOUND;
2885         }
2886
2887         ctx = get_ctx(tline->text, &mname, false);
2888         last = tline;
2889         tline = expand_smacro(tline->next);
2890         last->next = NULL;
2891
2892         while (tok_type_(tline, TOK_WHITESPACE))
2893             tline = delete_Token(tline);
2894
2895         p = detoken(tline, false);
2896         macro_start = nasm_malloc(sizeof(*macro_start));
2897         macro_start->next = NULL;
2898         macro_start->text = nasm_quote(p, strlen(p));
2899         macro_start->type = TOK_STRING;
2900         macro_start->a.mac = NULL;
2901         nasm_free(p);
2902
2903         /*
2904          * We now have a macro name, an implicit parameter count of
2905          * zero, and a string token to use as an expansion. Create
2906          * and store an SMacro.
2907          */
2908         define_smacro(ctx, mname, casesense, 0, macro_start);
2909         free_tlist(origline);
2910         return DIRECTIVE_FOUND;
2911
2912     case PP_PATHSEARCH:
2913     {
2914         FILE *fp;
2915         StrList *xsl = NULL;
2916         StrList **xst = &xsl;
2917
2918         casesense = true;
2919
2920         tline = tline->next;
2921         skip_white_(tline);
2922         tline = expand_id(tline);
2923         if (!tline || (tline->type != TOK_ID &&
2924                        (tline->type != TOK_PREPROC_ID ||
2925                         tline->text[1] != '$'))) {
2926             error(ERR_NONFATAL,
2927                   "`%%pathsearch' expects a macro identifier as first parameter");
2928             free_tlist(origline);
2929             return DIRECTIVE_FOUND;
2930         }
2931         ctx = get_ctx(tline->text, &mname, false);
2932         last = tline;
2933         tline = expand_smacro(tline->next);
2934         last->next = NULL;
2935
2936         t = tline;
2937         while (tok_type_(t, TOK_WHITESPACE))
2938             t = t->next;
2939
2940         if (!t || (t->type != TOK_STRING &&
2941                    t->type != TOK_INTERNAL_STRING)) {
2942             error(ERR_NONFATAL, "`%%pathsearch' expects a file name");
2943             free_tlist(tline);
2944             free_tlist(origline);
2945             return DIRECTIVE_FOUND;     /* but we did _something_ */
2946         }
2947         if (t->next)
2948             error(ERR_WARNING|ERR_PASS1,
2949                   "trailing garbage after `%%pathsearch' ignored");
2950         p = t->text;
2951         if (t->type != TOK_INTERNAL_STRING)
2952             nasm_unquote(p, NULL);
2953
2954         fp = inc_fopen(p, &xsl, &xst, true);
2955         if (fp) {
2956             p = xsl->str;
2957             fclose(fp);         /* Don't actually care about the file */
2958         }
2959         macro_start = nasm_malloc(sizeof(*macro_start));
2960         macro_start->next = NULL;
2961         macro_start->text = nasm_quote(p, strlen(p));
2962         macro_start->type = TOK_STRING;
2963         macro_start->a.mac = NULL;
2964         if (xsl)
2965             nasm_free(xsl);
2966
2967         /*
2968          * We now have a macro name, an implicit parameter count of
2969          * zero, and a string token to use as an expansion. Create
2970          * and store an SMacro.
2971          */
2972         define_smacro(ctx, mname, casesense, 0, macro_start);
2973         free_tlist(tline);
2974         free_tlist(origline);
2975         return DIRECTIVE_FOUND;
2976     }
2977
2978     case PP_STRLEN:
2979         casesense = true;
2980
2981         tline = tline->next;
2982         skip_white_(tline);
2983         tline = expand_id(tline);
2984         if (!tline || (tline->type != TOK_ID &&
2985                        (tline->type != TOK_PREPROC_ID ||
2986                         tline->text[1] != '$'))) {
2987             error(ERR_NONFATAL,
2988                   "`%%strlen' expects a macro identifier as first parameter");
2989             free_tlist(origline);
2990             return DIRECTIVE_FOUND;
2991         }
2992         ctx = get_ctx(tline->text, &mname, false);
2993         last = tline;
2994         tline = expand_smacro(tline->next);
2995         last->next = NULL;
2996
2997         t = tline;
2998         while (tok_type_(t, TOK_WHITESPACE))
2999             t = t->next;
3000         /* t should now point to the string */
3001         if (t->type != TOK_STRING) {
3002             error(ERR_NONFATAL,
3003                   "`%%strlen` requires string as second parameter");
3004             free_tlist(tline);
3005             free_tlist(origline);
3006             return DIRECTIVE_FOUND;
3007         }
3008
3009         macro_start = nasm_malloc(sizeof(*macro_start));
3010         macro_start->next = NULL;
3011         make_tok_num(macro_start, nasm_unquote(t->text, NULL));
3012         macro_start->a.mac = NULL;
3013
3014         /*
3015          * We now have a macro name, an implicit parameter count of
3016          * zero, and a numeric token to use as an expansion. Create
3017          * and store an SMacro.
3018          */
3019         define_smacro(ctx, mname, casesense, 0, macro_start);
3020         free_tlist(tline);
3021         free_tlist(origline);
3022         return DIRECTIVE_FOUND;
3023
3024     case PP_STRCAT:
3025         casesense = true;
3026
3027         tline = tline->next;
3028         skip_white_(tline);
3029         tline = expand_id(tline);
3030         if (!tline || (tline->type != TOK_ID &&
3031                        (tline->type != TOK_PREPROC_ID ||
3032                         tline->text[1] != '$'))) {
3033             error(ERR_NONFATAL,
3034                   "`%%strcat' expects a macro identifier as first parameter");
3035             free_tlist(origline);
3036             return DIRECTIVE_FOUND;
3037         }
3038         ctx = get_ctx(tline->text, &mname, false);
3039         last = tline;
3040         tline = expand_smacro(tline->next);
3041         last->next = NULL;
3042
3043         len = 0;
3044         for (t = tline; t; t = t->next) {
3045             switch (t->type) {
3046             case TOK_WHITESPACE:
3047                 break;
3048             case TOK_STRING:
3049                 len += t->a.len = nasm_unquote(t->text, NULL);
3050                 break;
3051             case TOK_OTHER:
3052                 if (!strcmp(t->text, ",")) /* permit comma separators */
3053                     break;
3054                 /* else fall through */
3055             default:
3056                 error(ERR_NONFATAL,
3057                       "non-string passed to `%%strcat' (%d)", t->type);
3058                 free_tlist(tline);
3059                 free_tlist(origline);
3060                 return DIRECTIVE_FOUND;
3061             }
3062         }
3063
3064         p = pp = nasm_malloc(len);
3065         t = tline;
3066         for (t = tline; t; t = t->next) {
3067             if (t->type == TOK_STRING) {
3068                 memcpy(p, t->text, t->a.len);
3069                 p += t->a.len;
3070             }
3071         }
3072
3073         /*
3074          * We now have a macro name, an implicit parameter count of
3075          * zero, and a numeric token to use as an expansion. Create
3076          * and store an SMacro.
3077          */
3078         macro_start = new_Token(NULL, TOK_STRING, NULL, 0);
3079         macro_start->text = nasm_quote(pp, len);
3080         nasm_free(pp);
3081         define_smacro(ctx, mname, casesense, 0, macro_start);
3082         free_tlist(tline);
3083         free_tlist(origline);
3084         return DIRECTIVE_FOUND;
3085
3086     case PP_SUBSTR:
3087     {
3088         int64_t a1, a2;
3089         size_t len;
3090
3091         casesense = true;
3092
3093         tline = tline->next;
3094         skip_white_(tline);
3095         tline = expand_id(tline);
3096         if (!tline || (tline->type != TOK_ID &&
3097                        (tline->type != TOK_PREPROC_ID ||
3098                         tline->text[1] != '$'))) {
3099             error(ERR_NONFATAL,
3100                   "`%%substr' expects a macro identifier as first parameter");
3101             free_tlist(origline);
3102             return DIRECTIVE_FOUND;
3103         }
3104         ctx = get_ctx(tline->text, &mname, false);
3105         last = tline;
3106         tline = expand_smacro(tline->next);
3107         last->next = NULL;
3108
3109         t = tline->next;
3110         while (tok_type_(t, TOK_WHITESPACE))
3111             t = t->next;
3112
3113         /* t should now point to the string */
3114         if (t->type != TOK_STRING) {
3115             error(ERR_NONFATAL,
3116                   "`%%substr` requires string as second parameter");
3117             free_tlist(tline);
3118             free_tlist(origline);
3119             return DIRECTIVE_FOUND;
3120         }
3121
3122         tt = t->next;
3123         tptr = &tt;
3124         tokval.t_type = TOKEN_INVALID;
3125         evalresult = evaluate(ppscan, tptr, &tokval, NULL,
3126                               pass, error, NULL);
3127         if (!evalresult) {
3128             free_tlist(tline);
3129             free_tlist(origline);
3130             return DIRECTIVE_FOUND;
3131         } else if (!is_simple(evalresult)) {
3132             error(ERR_NONFATAL, "non-constant value given to `%%substr`");
3133             free_tlist(tline);
3134             free_tlist(origline);
3135             return DIRECTIVE_FOUND;
3136         }
3137         a1 = evalresult->value-1;
3138
3139         while (tok_type_(tt, TOK_WHITESPACE))
3140             tt = tt->next;
3141         if (!tt) {
3142             a2 = 1;             /* Backwards compatibility: one character */
3143         } else {
3144             tokval.t_type = TOKEN_INVALID;
3145             evalresult = evaluate(ppscan, tptr, &tokval, NULL,
3146                                   pass, error, NULL);
3147             if (!evalresult) {
3148                 free_tlist(tline);
3149                 free_tlist(origline);
3150                 return DIRECTIVE_FOUND;
3151             } else if (!is_simple(evalresult)) {
3152                 error(ERR_NONFATAL, "non-constant value given to `%%substr`");
3153                 free_tlist(tline);
3154                 free_tlist(origline);
3155                 return DIRECTIVE_FOUND;
3156             }
3157             a2 = evalresult->value;
3158         }
3159
3160         len = nasm_unquote(t->text, NULL);
3161         if (a2 < 0)
3162             a2 = a2+1+len-a1;
3163         if (a1+a2 > (int64_t)len)
3164             a2 = len-a1;
3165
3166         macro_start = nasm_malloc(sizeof(*macro_start));
3167         macro_start->next = NULL;
3168         macro_start->text = nasm_quote((a1 < 0) ? "" : t->text+a1, a2);
3169         macro_start->type = TOK_STRING;
3170         macro_start->a.mac = NULL;
3171
3172         /*
3173          * We now have a macro name, an implicit parameter count of
3174          * zero, and a numeric token to use as an expansion. Create
3175          * and store an SMacro.
3176          */
3177         define_smacro(ctx, mname, casesense, 0, macro_start);
3178         free_tlist(tline);
3179         free_tlist(origline);
3180         return DIRECTIVE_FOUND;
3181     }
3182
3183     case PP_ASSIGN:
3184     case PP_IASSIGN:
3185         casesense = (i == PP_ASSIGN);
3186
3187         tline = tline->next;
3188         skip_white_(tline);
3189         tline = expand_id(tline);
3190         if (!tline || (tline->type != TOK_ID &&
3191                        (tline->type != TOK_PREPROC_ID ||
3192                         tline->text[1] != '$'))) {
3193             error(ERR_NONFATAL,
3194                   "`%%%sassign' expects a macro identifier",
3195                   (i == PP_IASSIGN ? "i" : ""));
3196             free_tlist(origline);
3197             return DIRECTIVE_FOUND;
3198         }
3199         ctx = get_ctx(tline->text, &mname, false);
3200         last = tline;
3201         tline = expand_smacro(tline->next);
3202         last->next = NULL;
3203
3204         t = tline;
3205         tptr = &t;
3206         tokval.t_type = TOKEN_INVALID;
3207         evalresult =
3208             evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
3209         free_tlist(tline);
3210         if (!evalresult) {
3211             free_tlist(origline);
3212             return DIRECTIVE_FOUND;
3213         }
3214
3215         if (tokval.t_type)
3216             error(ERR_WARNING|ERR_PASS1,
3217                   "trailing garbage after expression ignored");
3218
3219         if (!is_simple(evalresult)) {
3220             error(ERR_NONFATAL,
3221                   "non-constant value given to `%%%sassign'",
3222                   (i == PP_IASSIGN ? "i" : ""));
3223             free_tlist(origline);
3224             return DIRECTIVE_FOUND;
3225         }
3226
3227         macro_start = nasm_malloc(sizeof(*macro_start));
3228         macro_start->next = NULL;
3229         make_tok_num(macro_start, reloc_value(evalresult));
3230         macro_start->a.mac = NULL;
3231
3232         /*
3233          * We now have a macro name, an implicit parameter count of
3234          * zero, and a numeric token to use as an expansion. Create
3235          * and store an SMacro.
3236          */
3237         define_smacro(ctx, mname, casesense, 0, macro_start);
3238         free_tlist(origline);
3239         return DIRECTIVE_FOUND;
3240
3241     case PP_LINE:
3242         /*
3243          * Syntax is `%line nnn[+mmm] [filename]'
3244          */
3245         tline = tline->next;
3246         skip_white_(tline);
3247         if (!tok_type_(tline, TOK_NUMBER)) {
3248             error(ERR_NONFATAL, "`%%line' expects line number");
3249             free_tlist(origline);
3250             return DIRECTIVE_FOUND;
3251         }
3252         k = readnum(tline->text, &err);
3253         m = 1;
3254         tline = tline->next;
3255         if (tok_is_(tline, "+")) {
3256             tline = tline->next;
3257             if (!tok_type_(tline, TOK_NUMBER)) {
3258                 error(ERR_NONFATAL, "`%%line' expects line increment");
3259                 free_tlist(origline);
3260                 return DIRECTIVE_FOUND;
3261             }
3262             m = readnum(tline->text, &err);
3263             tline = tline->next;
3264         }
3265         skip_white_(tline);
3266         src_set_linnum(k);
3267         istk->lineinc = m;
3268         if (tline) {
3269             nasm_free(src_set_fname(detoken(tline, false)));
3270         }
3271         free_tlist(origline);
3272         return DIRECTIVE_FOUND;
3273
3274     default:
3275         error(ERR_FATAL,
3276               "preprocessor directive `%s' not yet implemented",
3277               pp_directives[i]);
3278         return DIRECTIVE_FOUND;
3279     }
3280 }
3281
3282 /*
3283  * Ensure that a macro parameter contains a condition code and
3284  * nothing else. Return the condition code index if so, or -1
3285  * otherwise.
3286  */
3287 static int find_cc(Token * t)
3288 {
3289     Token *tt;
3290     int i, j, k, m;
3291
3292     if (!t)
3293             return -1;          /* Probably a %+ without a space */
3294
3295     skip_white_(t);
3296     if (t->type != TOK_ID)
3297         return -1;
3298     tt = t->next;
3299     skip_white_(tt);
3300     if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
3301         return -1;
3302
3303     i = -1;
3304     j = elements(conditions);
3305     while (j - i > 1) {
3306         k = (j + i) / 2;
3307         m = nasm_stricmp(t->text, conditions[k]);
3308         if (m == 0) {
3309             i = k;
3310             j = -2;
3311             break;
3312         } else if (m < 0) {
3313             j = k;
3314         } else
3315             i = k;
3316     }
3317     if (j != -2)
3318         return -1;
3319     return i;
3320 }
3321
3322 /*
3323  * Expand MMacro-local things: parameter references (%0, %n, %+n,
3324  * %-n) and MMacro-local identifiers (%%foo) as well as
3325  * macro indirection (%[...]).
3326  */
3327 static Token *expand_mmac_params(Token * tline)
3328 {
3329     Token *t, *tt, **tail, *thead;
3330
3331     tail = &thead;
3332     thead = NULL;
3333
3334     while (tline) {
3335         if (tline->type == TOK_PREPROC_ID &&
3336             (((tline->text[1] == '+' || tline->text[1] == '-')
3337               && tline->text[2]) || tline->text[1] == '%'
3338              || (tline->text[1] >= '0' && tline->text[1] <= '9'))) {
3339             char *text = NULL;
3340             int type = 0, cc;   /* type = 0 to placate optimisers */
3341             char tmpbuf[30];
3342             unsigned int n;
3343             int i;
3344             MMacro *mac;
3345
3346             t = tline;
3347             tline = tline->next;
3348
3349             mac = istk->mstk;
3350             while (mac && !mac->name)   /* avoid mistaking %reps for macros */
3351                 mac = mac->next_active;
3352             if (!mac)
3353                 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
3354             else
3355                 switch (t->text[1]) {
3356                     /*
3357                      * We have to make a substitution of one of the
3358                      * forms %1, %-1, %+1, %%foo, %0.
3359                      */
3360                 case '0':
3361                     type = TOK_NUMBER;
3362                     snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam);
3363                     text = nasm_strdup(tmpbuf);
3364                     break;
3365                 case '%':
3366                     type = TOK_ID;
3367                     snprintf(tmpbuf, sizeof(tmpbuf), "..@%"PRIu64".",
3368                              mac->unique);
3369                     text = nasm_strcat(tmpbuf, t->text + 2);
3370                     break;
3371                 case '-':
3372                     n = atoi(t->text + 2) - 1;
3373                     if (n >= mac->nparam)
3374                         tt = NULL;
3375                     else {
3376                         if (mac->nparam > 1)
3377                             n = (n + mac->rotate) % mac->nparam;
3378                         tt = mac->params[n];
3379                     }
3380                     cc = find_cc(tt);
3381                     if (cc == -1) {
3382                         error(ERR_NONFATAL,
3383                               "macro parameter %d is not a condition code",
3384                               n + 1);
3385                         text = NULL;
3386                     } else {
3387                         type = TOK_ID;
3388                         if (inverse_ccs[cc] == -1) {
3389                             error(ERR_NONFATAL,
3390                                   "condition code `%s' is not invertible",
3391                                   conditions[cc]);
3392                             text = NULL;
3393                         } else
3394                             text = nasm_strdup(conditions[inverse_ccs[cc]]);
3395                     }
3396                     break;
3397                 case '+':
3398                     n = atoi(t->text + 2) - 1;
3399                     if (n >= mac->nparam)
3400                         tt = NULL;
3401                     else {
3402                         if (mac->nparam > 1)
3403                             n = (n + mac->rotate) % mac->nparam;
3404                         tt = mac->params[n];
3405                     }
3406                     cc = find_cc(tt);
3407                     if (cc == -1) {
3408                         error(ERR_NONFATAL,
3409                               "macro parameter %d is not a condition code",
3410                               n + 1);
3411                         text = NULL;
3412                     } else {
3413                         type = TOK_ID;
3414                         text = nasm_strdup(conditions[cc]);
3415                     }
3416                     break;
3417                 default:
3418                     n = atoi(t->text + 1) - 1;
3419                     if (n >= mac->nparam)
3420                         tt = NULL;
3421                     else {
3422                         if (mac->nparam > 1)
3423                             n = (n + mac->rotate) % mac->nparam;
3424                         tt = mac->params[n];
3425                     }
3426                     if (tt) {
3427                         for (i = 0; i < mac->paramlen[n]; i++) {
3428                             *tail = new_Token(NULL, tt->type, tt->text, 0);
3429                             tail = &(*tail)->next;
3430                             tt = tt->next;
3431                         }
3432                     }
3433                     text = NULL;        /* we've done it here */
3434                     break;
3435                 }
3436             if (!text) {
3437                 delete_Token(t);
3438             } else {
3439                 *tail = t;
3440                 tail = &t->next;
3441                 t->type = type;
3442                 nasm_free(t->text);
3443                 t->text = text;
3444                 t->a.mac = NULL;
3445             }
3446             continue;
3447         } else if (tline->type == TOK_INDIRECT) {
3448             t = tline;
3449             tline = tline->next;
3450             tt = tokenize(t->text);
3451             tt = expand_mmac_params(tt);
3452             tt = expand_smacro(tt);
3453             *tail = tt;
3454             while (tt) {
3455                 tt->a.mac = NULL; /* Necessary? */
3456                 tail = &tt->next;
3457                 tt = tt->next;
3458             }
3459             delete_Token(t);
3460         } else {
3461             t = *tail = tline;
3462             tline = tline->next;
3463             t->a.mac = NULL;
3464             tail = &t->next;
3465         }
3466     }
3467     *tail = NULL;
3468
3469     /* Now handle token pasting... */
3470     t = thead;
3471     while (t && (tt = t->next)) {
3472         switch (t->type) {
3473         case TOK_WHITESPACE:
3474             if (tt->type == TOK_WHITESPACE) {
3475                 t->next = delete_Token(tt);
3476             } else {
3477                 t = tt;
3478             }
3479             break;
3480         case TOK_ID:
3481         case TOK_NUMBER:
3482             if (tt->type == t->type || tt->type == TOK_NUMBER) {
3483                 char *tmp = nasm_strcat(t->text, tt->text);
3484                 nasm_free(t->text);
3485                 t->text = tmp;
3486                 t->next = delete_Token(tt);
3487             } else {
3488                 t = tt;
3489             }
3490             break;
3491         default:
3492             t = tt;
3493             break;
3494         }
3495     }
3496     return thead;
3497 }
3498
3499 /*
3500  * Expand all single-line macro calls made in the given line.
3501  * Return the expanded version of the line. The original is deemed
3502  * to be destroyed in the process. (In reality we'll just move
3503  * Tokens from input to output a lot of the time, rather than
3504  * actually bothering to destroy and replicate.)
3505  */
3506 #define DEADMAN_LIMIT (1 << 20)
3507
3508 static Token *expand_smacro(Token * tline)
3509 {
3510     Token *t, *tt, *mstart, **tail, *thead;
3511     struct hash_table *smtbl;
3512     SMacro *head = NULL, *m;
3513     Token **params;
3514     int *paramsize;
3515     unsigned int nparam, sparam;
3516     int brackets, rescan;
3517     Token *org_tline = tline;
3518     Context *ctx;
3519     const char *mname;
3520     int deadman = DEADMAN_LIMIT;
3521
3522     /*
3523      * Trick: we should avoid changing the start token pointer since it can
3524      * be contained in "next" field of other token. Because of this
3525      * we allocate a copy of first token and work with it; at the end of
3526      * routine we copy it back
3527      */
3528     if (org_tline) {
3529         tline =
3530             new_Token(org_tline->next, org_tline->type, org_tline->text,
3531                       0);
3532         tline->a.mac = org_tline->a.mac;
3533         nasm_free(org_tline->text);
3534         org_tline->text = NULL;
3535     }
3536
3537 again:
3538     tail = &thead;
3539     thead = NULL;
3540
3541     while (tline) {             /* main token loop */
3542         if (!--deadman) {
3543             error(ERR_NONFATAL, "interminable macro recursion");
3544             break;
3545         }
3546
3547         if ((mname = tline->text)) {
3548             /* if this token is a local macro, look in local context */
3549             if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
3550                 ctx = get_ctx(mname, &mname, true);
3551             else
3552                 ctx = NULL;
3553             smtbl = ctx ? &ctx->localmac : &smacros;
3554             head = (SMacro *) hash_findix(smtbl, mname);
3555
3556             /*
3557              * We've hit an identifier. As in is_mmacro below, we first
3558              * check whether the identifier is a single-line macro at
3559              * all, then think about checking for parameters if
3560              * necessary.
3561              */
3562             for (m = head; m; m = m->next)
3563                 if (!mstrcmp(m->name, mname, m->casesense))
3564                     break;
3565             if (m) {
3566                 mstart = tline;
3567                 params = NULL;
3568                 paramsize = NULL;
3569                 if (m->nparam == 0) {
3570                     /*
3571                      * Simple case: the macro is parameterless. Discard the
3572                      * one token that the macro call took, and push the
3573                      * expansion back on the to-do stack.
3574                      */
3575                     if (!m->expansion) {
3576                         if (!strcmp("__FILE__", m->name)) {
3577                             int32_t num = 0;
3578                             char *file = NULL;
3579                             src_get(&num, &file);
3580                             tline->text = nasm_quote(file, strlen(file));
3581                             tline->type = TOK_STRING;
3582                             nasm_free(file);
3583                             continue;
3584                         }
3585                         if (!strcmp("__LINE__", m->name)) {
3586                             nasm_free(tline->text);
3587                             make_tok_num(tline, src_get_linnum());
3588                             continue;
3589                         }
3590                         if (!strcmp("__BITS__", m->name)) {
3591                             nasm_free(tline->text);
3592                             make_tok_num(tline, globalbits);
3593                             continue;
3594                         }
3595                         tline = delete_Token(tline);
3596                         continue;
3597                     }
3598                 } else {
3599                     /*
3600                      * Complicated case: at least one macro with this name
3601                      * exists and takes parameters. We must find the
3602                      * parameters in the call, count them, find the SMacro
3603                      * that corresponds to that form of the macro call, and
3604                      * substitute for the parameters when we expand. What a
3605                      * pain.
3606                      */
3607                     /*tline = tline->next;
3608                        skip_white_(tline); */
3609                     do {
3610                         t = tline->next;
3611                         while (tok_type_(t, TOK_SMAC_END)) {
3612                             t->a.mac->in_progress = false;
3613                             t->text = NULL;
3614                             t = tline->next = delete_Token(t);
3615                         }
3616                         tline = t;
3617                     } while (tok_type_(tline, TOK_WHITESPACE));
3618                     if (!tok_is_(tline, "(")) {
3619                         /*
3620                          * This macro wasn't called with parameters: ignore
3621                          * the call. (Behaviour borrowed from gnu cpp.)
3622                          */
3623                         tline = mstart;
3624                         m = NULL;
3625                     } else {
3626                         int paren = 0;
3627                         int white = 0;
3628                         brackets = 0;
3629                         nparam = 0;
3630                         sparam = PARAM_DELTA;
3631                         params = nasm_malloc(sparam * sizeof(Token *));
3632                         params[0] = tline->next;
3633                         paramsize = nasm_malloc(sparam * sizeof(int));
3634                         paramsize[0] = 0;
3635                         while (true) {  /* parameter loop */
3636                             /*
3637                              * For some unusual expansions
3638                              * which concatenates function call
3639                              */
3640                             t = tline->next;
3641                             while (tok_type_(t, TOK_SMAC_END)) {
3642                                 t->a.mac->in_progress = false;
3643                                 t->text = NULL;
3644                                 t = tline->next = delete_Token(t);
3645                             }
3646                             tline = t;
3647
3648                             if (!tline) {
3649                                 error(ERR_NONFATAL,
3650                                       "macro call expects terminating `)'");
3651                                 break;
3652                             }
3653                             if (tline->type == TOK_WHITESPACE
3654                                 && brackets <= 0) {
3655                                 if (paramsize[nparam])
3656                                     white++;
3657                                 else
3658                                     params[nparam] = tline->next;
3659                                 continue;       /* parameter loop */
3660                             }
3661                             if (tline->type == TOK_OTHER
3662                                 && tline->text[1] == 0) {
3663                                 char ch = tline->text[0];
3664                                 if (ch == ',' && !paren && brackets <= 0) {
3665                                     if (++nparam >= sparam) {
3666                                         sparam += PARAM_DELTA;
3667                                         params = nasm_realloc(params,
3668                                                               sparam *
3669                                                               sizeof(Token
3670                                                                      *));
3671                                         paramsize =
3672                                             nasm_realloc(paramsize,
3673                                                          sparam *
3674                                                          sizeof(int));
3675                                     }
3676                                     params[nparam] = tline->next;
3677                                     paramsize[nparam] = 0;
3678                                     white = 0;
3679                                     continue;   /* parameter loop */
3680                                 }
3681                                 if (ch == '{' &&
3682                                     (brackets > 0 || (brackets == 0 &&
3683                                                       !paramsize[nparam])))
3684                                 {
3685                                     if (!(brackets++)) {
3686                                         params[nparam] = tline->next;
3687                                         continue;       /* parameter loop */
3688                                     }
3689                                 }
3690                                 if (ch == '}' && brackets > 0)
3691                                     if (--brackets == 0) {
3692                                         brackets = -1;
3693                                         continue;       /* parameter loop */
3694                                     }
3695                                 if (ch == '(' && !brackets)
3696                                     paren++;
3697                                 if (ch == ')' && brackets <= 0)
3698                                     if (--paren < 0)
3699                                         break;
3700                             }
3701                             if (brackets < 0) {
3702                                 brackets = 0;
3703                                 error(ERR_NONFATAL, "braces do not "
3704                                       "enclose all of macro parameter");
3705                             }
3706                             paramsize[nparam] += white + 1;
3707                             white = 0;
3708                         }       /* parameter loop */
3709                         nparam++;
3710                         while (m && (m->nparam != nparam ||
3711                                      mstrcmp(m->name, mname,
3712                                              m->casesense)))
3713                             m = m->next;
3714                         if (!m)
3715                             error(ERR_WARNING|ERR_PASS1|ERR_WARN_MNP,
3716                                   "macro `%s' exists, "
3717                                   "but not taking %d parameters",
3718                                   mstart->text, nparam);
3719                     }
3720                 }
3721                 if (m && m->in_progress)
3722                     m = NULL;
3723                 if (!m) {       /* in progess or didn't find '(' or wrong nparam */
3724                     /*
3725                      * Design question: should we handle !tline, which
3726                      * indicates missing ')' here, or expand those
3727                      * macros anyway, which requires the (t) test a few
3728                      * lines down?
3729                      */
3730                     nasm_free(params);
3731                     nasm_free(paramsize);
3732                     tline = mstart;
3733                 } else {
3734                     /*
3735                      * Expand the macro: we are placed on the last token of the
3736                      * call, so that we can easily split the call from the
3737                      * following tokens. We also start by pushing an SMAC_END
3738                      * token for the cycle removal.
3739                      */
3740                     t = tline;
3741                     if (t) {
3742                         tline = t->next;
3743                         t->next = NULL;
3744                     }
3745                     tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
3746                     tt->a.mac = m;
3747                     m->in_progress = true;
3748                     tline = tt;
3749                     for (t = m->expansion; t; t = t->next) {
3750                         if (t->type >= TOK_SMAC_PARAM) {
3751                             Token *pcopy = tline, **ptail = &pcopy;
3752                             Token *ttt, *pt;
3753                             int i;
3754
3755                             ttt = params[t->type - TOK_SMAC_PARAM];
3756                             for (i = paramsize[t->type - TOK_SMAC_PARAM];
3757                                  --i >= 0;) {
3758                                 pt = *ptail =
3759                                     new_Token(tline, ttt->type, ttt->text,
3760                                               0);
3761                                 ptail = &pt->next;
3762                                 ttt = ttt->next;
3763                             }
3764                             tline = pcopy;
3765                         } else if (t->type == TOK_PREPROC_Q) {
3766                             tt = new_Token(tline, TOK_ID, mname, 0);
3767                             tline = tt;
3768                         } else if (t->type == TOK_PREPROC_QQ) {
3769                             tt = new_Token(tline, TOK_ID, m->name, 0);
3770                             tline = tt;
3771                         } else {
3772                             tt = new_Token(tline, t->type, t->text, 0);
3773                             tline = tt;
3774                         }
3775                     }
3776
3777                     /*
3778                      * Having done that, get rid of the macro call, and clean
3779                      * up the parameters.
3780                      */
3781                     nasm_free(params);
3782                     nasm_free(paramsize);
3783                     free_tlist(mstart);
3784                     continue;   /* main token loop */
3785                 }
3786             }
3787         }
3788
3789         if (tline->type == TOK_SMAC_END) {
3790             tline->a.mac->in_progress = false;
3791             tline = delete_Token(tline);
3792         } else {
3793             t = *tail = tline;
3794             tline = tline->next;
3795             t->a.mac = NULL;
3796             t->next = NULL;
3797             tail = &t->next;
3798         }
3799     }
3800
3801     /*
3802      * Now scan the entire line and look for successive TOK_IDs that resulted
3803      * after expansion (they can't be produced by tokenize()). The successive
3804      * TOK_IDs should be concatenated.
3805      * Also we look for %+ tokens and concatenate the tokens before and after
3806      * them (without white spaces in between).
3807      */
3808     t = thead;
3809     rescan = 0;
3810     while (t) {
3811         while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
3812             t = t->next;
3813         if (!t || !t->next)
3814             break;
3815         if (t->next->type == TOK_ID ||
3816             t->next->type == TOK_PREPROC_ID ||
3817             t->next->type == TOK_NUMBER) {
3818             char *p = nasm_strcat(t->text, t->next->text);
3819             nasm_free(t->text);
3820             t->next = delete_Token(t->next);
3821             t->text = p;
3822             rescan = 1;
3823         } else if (t->next->type == TOK_WHITESPACE && t->next->next &&
3824                    t->next->next->type == TOK_PREPROC_ID &&
3825                    strcmp(t->next->next->text, "%+") == 0) {
3826             /* free the next whitespace, the %+ token and next whitespace */
3827             int i;
3828             for (i = 1; i <= 3; i++) {
3829                 if (!t->next
3830                     || (i != 2 && t->next->type != TOK_WHITESPACE))
3831                     break;
3832                 t->next = delete_Token(t->next);
3833             }                   /* endfor */
3834         } else
3835             t = t->next;
3836     }
3837     /* If we concatenaded something, re-scan the line for macros */
3838     if (rescan) {
3839         tline = thead;
3840         goto again;
3841     }
3842
3843     if (org_tline) {
3844         if (thead) {
3845             *org_tline = *thead;
3846             /* since we just gave text to org_line, don't free it */
3847             thead->text = NULL;
3848             delete_Token(thead);
3849         } else {
3850             /* the expression expanded to empty line;
3851                we can't return NULL for some reasons
3852                we just set the line to a single WHITESPACE token. */
3853             memset(org_tline, 0, sizeof(*org_tline));
3854             org_tline->text = NULL;
3855             org_tline->type = TOK_WHITESPACE;
3856         }
3857         thead = org_tline;
3858     }
3859
3860     return thead;
3861 }
3862
3863 /*
3864  * Similar to expand_smacro but used exclusively with macro identifiers
3865  * right before they are fetched in. The reason is that there can be
3866  * identifiers consisting of several subparts. We consider that if there
3867  * are more than one element forming the name, user wants a expansion,
3868  * otherwise it will be left as-is. Example:
3869  *
3870  *      %define %$abc cde
3871  *
3872  * the identifier %$abc will be left as-is so that the handler for %define
3873  * will suck it and define the corresponding value. Other case:
3874  *
3875  *      %define _%$abc cde
3876  *
3877  * In this case user wants name to be expanded *before* %define starts
3878  * working, so we'll expand %$abc into something (if it has a value;
3879  * otherwise it will be left as-is) then concatenate all successive
3880  * PP_IDs into one.
3881  */
3882 static Token *expand_id(Token * tline)
3883 {
3884     Token *cur, *oldnext = NULL;
3885
3886     if (!tline || !tline->next)
3887         return tline;
3888
3889     cur = tline;
3890     while (cur->next &&
3891            (cur->next->type == TOK_ID ||
3892             cur->next->type == TOK_PREPROC_ID
3893             || cur->next->type == TOK_NUMBER))
3894         cur = cur->next;
3895
3896     /* If identifier consists of just one token, don't expand */
3897     if (cur == tline)
3898         return tline;
3899
3900     if (cur) {
3901         oldnext = cur->next;    /* Detach the tail past identifier */
3902         cur->next = NULL;       /* so that expand_smacro stops here */
3903     }
3904
3905     tline = expand_smacro(tline);
3906
3907     if (cur) {
3908         /* expand_smacro possibly changhed tline; re-scan for EOL */
3909         cur = tline;
3910         while (cur && cur->next)
3911             cur = cur->next;
3912         if (cur)
3913             cur->next = oldnext;
3914     }
3915
3916     return tline;
3917 }
3918
3919 /*
3920  * Determine whether the given line constitutes a multi-line macro
3921  * call, and return the MMacro structure called if so. Doesn't have
3922  * to check for an initial label - that's taken care of in
3923  * expand_mmacro - but must check numbers of parameters. Guaranteed
3924  * to be called with tline->type == TOK_ID, so the putative macro
3925  * name is easy to find.
3926  */
3927 static MMacro *is_mmacro(Token * tline, Token *** params_array)
3928 {
3929     MMacro *head, *m;
3930     Token **params;
3931     int nparam;
3932
3933     head = (MMacro *) hash_findix(&mmacros, tline->text);
3934
3935     /*
3936      * Efficiency: first we see if any macro exists with the given
3937      * name. If not, we can return NULL immediately. _Then_ we
3938      * count the parameters, and then we look further along the
3939      * list if necessary to find the proper MMacro.
3940      */
3941     for (m = head; m; m = m->next)
3942         if (!mstrcmp(m->name, tline->text, m->casesense))
3943             break;
3944     if (!m)
3945         return NULL;
3946
3947     /*
3948      * OK, we have a potential macro. Count and demarcate the
3949      * parameters.
3950      */
3951     count_mmac_params(tline->next, &nparam, &params);
3952
3953     /*
3954      * So we know how many parameters we've got. Find the MMacro
3955      * structure that handles this number.
3956      */
3957     while (m) {
3958         if (m->nparam_min <= nparam
3959             && (m->plus || nparam <= m->nparam_max)) {
3960             /*
3961              * This one is right. Just check if cycle removal
3962              * prohibits us using it before we actually celebrate...
3963              */
3964             if (m->in_progress) {
3965 #if 0
3966                 error(ERR_NONFATAL,
3967                       "self-reference in multi-line macro `%s'", m->name);
3968 #endif
3969                 nasm_free(params);
3970                 return NULL;
3971             }
3972             /*
3973              * It's right, and we can use it. Add its default
3974              * parameters to the end of our list if necessary.
3975              */
3976             if (m->defaults && nparam < m->nparam_min + m->ndefs) {
3977                 params =
3978                     nasm_realloc(params,
3979                                  ((m->nparam_min + m->ndefs +
3980                                    1) * sizeof(*params)));
3981                 while (nparam < m->nparam_min + m->ndefs) {
3982                     params[nparam] = m->defaults[nparam - m->nparam_min];
3983                     nparam++;
3984                 }
3985             }
3986             /*
3987              * If we've gone over the maximum parameter count (and
3988              * we're in Plus mode), ignore parameters beyond
3989              * nparam_max.
3990              */
3991             if (m->plus && nparam > m->nparam_max)
3992                 nparam = m->nparam_max;
3993             /*
3994              * Then terminate the parameter list, and leave.
3995              */
3996             if (!params) {      /* need this special case */
3997                 params = nasm_malloc(sizeof(*params));
3998                 nparam = 0;
3999             }
4000             params[nparam] = NULL;
4001             *params_array = params;
4002             return m;
4003         }
4004         /*
4005          * This one wasn't right: look for the next one with the
4006          * same name.
4007          */
4008         for (m = m->next; m; m = m->next)
4009             if (!mstrcmp(m->name, tline->text, m->casesense))
4010                 break;
4011     }
4012
4013     /*
4014      * After all that, we didn't find one with the right number of
4015      * parameters. Issue a warning, and fail to expand the macro.
4016      */
4017     error(ERR_WARNING|ERR_PASS1|ERR_WARN_MNP,
4018           "macro `%s' exists, but not taking %d parameters",
4019           tline->text, nparam);
4020     nasm_free(params);
4021     return NULL;
4022 }
4023
4024 /*
4025  * Expand the multi-line macro call made by the given line, if
4026  * there is one to be expanded. If there is, push the expansion on
4027  * istk->expansion and return 1. Otherwise return 0.
4028  */
4029 static int expand_mmacro(Token * tline)
4030 {
4031     Token *startline = tline;
4032     Token *label = NULL;
4033     int dont_prepend = 0;
4034     Token **params, *t, *mtok, *tt;
4035     MMacro *m;
4036     Line *l, *ll;
4037     int i, nparam, *paramlen;
4038     const char *mname;
4039
4040     t = tline;
4041     skip_white_(t);
4042     /*    if (!tok_type_(t, TOK_ID))  Lino 02/25/02 */
4043     if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID))
4044         return 0;
4045     mtok = t;
4046     m = is_mmacro(t, &params);
4047     if (m) {
4048         mname = t->text;
4049     } else {
4050         Token *last;
4051         /*
4052          * We have an id which isn't a macro call. We'll assume
4053          * it might be a label; we'll also check to see if a
4054          * colon follows it. Then, if there's another id after
4055          * that lot, we'll check it again for macro-hood.
4056          */
4057         label = last = t;
4058         t = t->next;
4059         if (tok_type_(t, TOK_WHITESPACE))
4060             last = t, t = t->next;
4061         if (tok_is_(t, ":")) {
4062             dont_prepend = 1;
4063             last = t, t = t->next;
4064             if (tok_type_(t, TOK_WHITESPACE))
4065                 last = t, t = t->next;
4066         }
4067         if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, &params)) == NULL)
4068             return 0;
4069         last->next = NULL;
4070         mname = t->text;
4071         tline = t;
4072     }
4073
4074     /*
4075      * Fix up the parameters: this involves stripping leading and
4076      * trailing whitespace, then stripping braces if they are
4077      * present.
4078      */
4079     for (nparam = 0; params[nparam]; nparam++) ;
4080     paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
4081
4082     for (i = 0; params[i]; i++) {
4083         int brace = false;
4084         int comma = (!m->plus || i < nparam - 1);
4085
4086         t = params[i];
4087         skip_white_(t);
4088         if (tok_is_(t, "{"))
4089             t = t->next, brace = true, comma = false;
4090         params[i] = t;
4091         paramlen[i] = 0;
4092         while (t) {
4093             if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
4094                 break;          /* ... because we have hit a comma */
4095             if (comma && t->type == TOK_WHITESPACE
4096                 && tok_is_(t->next, ","))
4097                 break;          /* ... or a space then a comma */
4098             if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
4099                 break;          /* ... or a brace */
4100             t = t->next;
4101             paramlen[i]++;
4102         }
4103     }
4104
4105     /*
4106      * OK, we have a MMacro structure together with a set of
4107      * parameters. We must now go through the expansion and push
4108      * copies of each Line on to istk->expansion. Substitution of
4109      * parameter tokens and macro-local tokens doesn't get done
4110      * until the single-line macro substitution process; this is
4111      * because delaying them allows us to change the semantics
4112      * later through %rotate.
4113      *
4114      * First, push an end marker on to istk->expansion, mark this
4115      * macro as in progress, and set up its invocation-specific
4116      * variables.
4117      */
4118     ll = nasm_malloc(sizeof(Line));
4119     ll->next = istk->expansion;
4120     ll->finishes = m;
4121     ll->first = NULL;
4122     istk->expansion = ll;
4123
4124     m->in_progress = true;
4125     m->params = params;
4126     m->iline = tline;
4127     m->nparam = nparam;
4128     m->rotate = 0;
4129     m->paramlen = paramlen;
4130     m->unique = unique++;
4131     m->lineno = 0;
4132
4133     m->next_active = istk->mstk;
4134     istk->mstk = m;
4135
4136     for (l = m->expansion; l; l = l->next) {
4137         Token **tail;
4138
4139         ll = nasm_malloc(sizeof(Line));
4140         ll->finishes = NULL;
4141         ll->next = istk->expansion;
4142         istk->expansion = ll;
4143         tail = &ll->first;
4144
4145         for (t = l->first; t; t = t->next) {
4146             Token *x = t;
4147             switch (t->type) {
4148             case TOK_PREPROC_Q:
4149                 tt = *tail = new_Token(NULL, TOK_ID, mname, 0);
4150                 break;
4151             case TOK_PREPROC_QQ:
4152                 tt = *tail = new_Token(NULL, TOK_ID, m->name, 0);
4153                 break;
4154             case TOK_PREPROC_ID:
4155                 if (t->text[1] == '0' && t->text[2] == '0') {
4156                     dont_prepend = -1;
4157                     x = label;
4158                     if (!x)
4159                         continue;
4160                 }
4161                 /* fall through */
4162             default:
4163                 tt = *tail = new_Token(NULL, x->type, x->text, 0);
4164                 break;
4165             }
4166             tail = &tt->next;
4167         }
4168         *tail = NULL;
4169     }
4170
4171     /*
4172      * If we had a label, push it on as the first line of
4173      * the macro expansion.
4174      */
4175     if (label) {
4176         if (dont_prepend < 0)
4177             free_tlist(startline);
4178         else {
4179             ll = nasm_malloc(sizeof(Line));
4180             ll->finishes = NULL;
4181             ll->next = istk->expansion;
4182             istk->expansion = ll;
4183             ll->first = startline;
4184             if (!dont_prepend) {
4185                 while (label->next)
4186                     label = label->next;
4187                 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
4188             }
4189         }
4190     }
4191
4192     list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
4193
4194     return 1;
4195 }
4196
4197 /* The function that actually does the error reporting */
4198 static void verror(int severity, const char *fmt, va_list arg)
4199 {
4200     char buff[1024];
4201
4202     vsnprintf(buff, sizeof(buff), fmt, arg);
4203
4204     if (istk && istk->mstk && istk->mstk->name)
4205         _error(severity, "(%s:%d) %s", istk->mstk->name,
4206                istk->mstk->lineno, buff);
4207     else
4208         _error(severity, "%s", buff);
4209 }
4210
4211 /*
4212  * Since preprocessor always operate only on the line that didn't
4213  * arrived yet, we should always use ERR_OFFBY1.
4214  */
4215 static void error(int severity, const char *fmt, ...)
4216 {
4217     va_list arg;
4218
4219     /* If we're in a dead branch of IF or something like it, ignore the error */
4220     if (istk && istk->conds && !emitting(istk->conds->state))
4221         return;
4222
4223     va_start(arg, fmt);
4224     verror(severity, fmt, arg);
4225     va_end(arg);
4226 }
4227
4228 /*
4229  * Because %else etc are evaluated in the state context
4230  * of the previous branch, errors might get lost with error():
4231  *   %if 0 ... %else trailing garbage ... %endif
4232  * So %else etc should report errors with this function.
4233  */
4234 static void error_precond(int severity, const char *fmt, ...)
4235 {
4236     va_list arg;
4237
4238     /* Only ignore the error if it's really in a dead branch */
4239     if (istk && istk->conds && istk->conds->state == COND_NEVER)
4240         return;
4241
4242     va_start(arg, fmt);
4243     verror(severity, fmt, arg);
4244     va_end(arg);
4245 }
4246
4247 static void
4248 pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
4249          ListGen * listgen, StrList **deplist)
4250 {
4251     Token *t;
4252
4253     _error = errfunc;
4254     cstk = NULL;
4255     istk = nasm_malloc(sizeof(Include));
4256     istk->next = NULL;
4257     istk->conds = NULL;
4258     istk->expansion = NULL;
4259     istk->mstk = NULL;
4260     istk->fp = fopen(file, "r");
4261     istk->fname = NULL;
4262     src_set_fname(nasm_strdup(file));
4263     src_set_linnum(0);
4264     istk->lineinc = 1;
4265     if (!istk->fp)
4266         error(ERR_FATAL|ERR_NOFILE, "unable to open input file `%s'",
4267               file);
4268     defining = NULL;
4269     nested_mac_count = 0;
4270     nested_rep_count = 0;
4271     init_macros();
4272     unique = 0;
4273     if (tasm_compatible_mode) {
4274         stdmacpos = nasm_stdmac;
4275     } else {
4276         stdmacpos = nasm_stdmac_after_tasm;
4277     }
4278     any_extrastdmac = extrastdmac && *extrastdmac;
4279     do_predef = true;
4280     list = listgen;
4281     evaluate = eval;
4282
4283     /*
4284      * 0 for dependencies, 1 for preparatory passes, 2 for final pass.
4285      * The caller, however, will also pass in 3 for preprocess-only so
4286      * we can set __PASS__ accordingly.
4287      */
4288     pass = apass > 2 ? 2 : apass;
4289
4290     dephead = deptail = deplist;
4291     if (deplist) {
4292         StrList *sl = nasm_malloc(strlen(file)+1+sizeof sl->next);
4293         sl->next = NULL;
4294         strcpy(sl->str, file);
4295         *deptail = sl;
4296         deptail = &sl->next;
4297     }
4298
4299     /*
4300      * Define the __PASS__ macro.  This is defined here unlike
4301      * all the other builtins, because it is special -- it varies between
4302      * passes.
4303      */
4304     t = nasm_malloc(sizeof(*t));
4305     t->next = NULL;
4306     make_tok_num(t, apass);
4307     t->a.mac = NULL;
4308     define_smacro(NULL, "__PASS__", true, 0, t);
4309 }
4310
4311 static char *pp_getline(void)
4312 {
4313     char *line;
4314     Token *tline;
4315
4316     while (1) {
4317         /*
4318          * Fetch a tokenized line, either from the macro-expansion
4319          * buffer or from the input file.
4320          */
4321         tline = NULL;
4322         while (istk->expansion && istk->expansion->finishes) {
4323             Line *l = istk->expansion;
4324             if (!l->finishes->name && l->finishes->in_progress > 1) {
4325                 Line *ll;
4326
4327                 /*
4328                  * This is a macro-end marker for a macro with no
4329                  * name, which means it's not really a macro at all
4330                  * but a %rep block, and the `in_progress' field is
4331                  * more than 1, meaning that we still need to
4332                  * repeat. (1 means the natural last repetition; 0
4333                  * means termination by %exitrep.) We have
4334                  * therefore expanded up to the %endrep, and must
4335                  * push the whole block on to the expansion buffer
4336                  * again. We don't bother to remove the macro-end
4337                  * marker: we'd only have to generate another one
4338                  * if we did.
4339                  */
4340                 l->finishes->in_progress--;
4341                 for (l = l->finishes->expansion; l; l = l->next) {
4342                     Token *t, *tt, **tail;
4343
4344                     ll = nasm_malloc(sizeof(Line));
4345                     ll->next = istk->expansion;
4346                     ll->finishes = NULL;
4347                     ll->first = NULL;
4348                     tail = &ll->first;
4349
4350                     for (t = l->first; t; t = t->next) {
4351                         if (t->text || t->type == TOK_WHITESPACE) {
4352                             tt = *tail =
4353                                 new_Token(NULL, t->type, t->text, 0);
4354                             tail = &tt->next;
4355                         }
4356                     }
4357
4358                     istk->expansion = ll;
4359                 }
4360             } else {
4361                 /*
4362                  * Check whether a `%rep' was started and not ended
4363                  * within this macro expansion. This can happen and
4364                  * should be detected. It's a fatal error because
4365                  * I'm too confused to work out how to recover
4366                  * sensibly from it.
4367                  */
4368                 if (defining) {
4369                     if (defining->name)
4370                         error(ERR_PANIC,
4371                               "defining with name in expansion");
4372                     else if (istk->mstk->name)
4373                         error(ERR_FATAL,
4374                               "`%%rep' without `%%endrep' within"
4375                               " expansion of macro `%s'",
4376                               istk->mstk->name);
4377                 }
4378
4379                 /*
4380                  * FIXME:  investigate the relationship at this point between
4381                  * istk->mstk and l->finishes
4382                  */
4383                 {
4384                     MMacro *m = istk->mstk;
4385                     istk->mstk = m->next_active;
4386                     if (m->name) {
4387                         /*
4388                          * This was a real macro call, not a %rep, and
4389                          * therefore the parameter information needs to
4390                          * be freed.
4391                          */
4392                         nasm_free(m->params);
4393                         free_tlist(m->iline);
4394                         nasm_free(m->paramlen);
4395                         l->finishes->in_progress = false;
4396                     } else
4397                         free_mmacro(m);
4398                 }
4399                 istk->expansion = l->next;
4400                 nasm_free(l);
4401                 list->downlevel(LIST_MACRO);
4402             }
4403         }
4404         while (1) {             /* until we get a line we can use */
4405
4406             if (istk->expansion) {      /* from a macro expansion */
4407                 char *p;
4408                 Line *l = istk->expansion;
4409                 if (istk->mstk)
4410                     istk->mstk->lineno++;
4411                 tline = l->first;
4412                 istk->expansion = l->next;
4413                 nasm_free(l);
4414                 p = detoken(tline, false);
4415                 list->line(LIST_MACRO, p);
4416                 nasm_free(p);
4417                 break;
4418             }
4419             line = read_line();
4420             if (line) {         /* from the current input file */
4421                 line = prepreproc(line);
4422                 tline = tokenize(line);
4423                 nasm_free(line);
4424                 break;
4425             }
4426             /*
4427              * The current file has ended; work down the istk
4428              */
4429             {
4430                 Include *i = istk;
4431                 fclose(i->fp);
4432                 if (i->conds)
4433                     error(ERR_FATAL,
4434                           "expected `%%endif' before end of file");
4435                 /* only set line and file name if there's a next node */
4436                 if (i->next) {
4437                     src_set_linnum(i->lineno);
4438                     nasm_free(src_set_fname(i->fname));
4439                 }
4440                 istk = i->next;
4441                 list->downlevel(LIST_INCLUDE);
4442                 nasm_free(i);
4443                 if (!istk)
4444                     return NULL;
4445                 if (istk->expansion && istk->expansion->finishes)
4446                     break;
4447             }
4448         }
4449
4450         /*
4451          * We must expand MMacro parameters and MMacro-local labels
4452          * _before_ we plunge into directive processing, to cope
4453          * with things like `%define something %1' such as STRUC
4454          * uses. Unless we're _defining_ a MMacro, in which case
4455          * those tokens should be left alone to go into the
4456          * definition; and unless we're in a non-emitting
4457          * condition, in which case we don't want to meddle with
4458          * anything.
4459          */
4460         if (!defining && !(istk->conds && !emitting(istk->conds->state))
4461             && !(istk->mstk && !istk->mstk->in_progress)) {
4462             tline = expand_mmac_params(tline);
4463         }
4464
4465         /*
4466          * Check the line to see if it's a preprocessor directive.
4467          */
4468         if (do_directive(tline) == DIRECTIVE_FOUND) {
4469             continue;
4470         } else if (defining) {
4471             /*
4472              * We're defining a multi-line macro. We emit nothing
4473              * at all, and just
4474              * shove the tokenized line on to the macro definition.
4475              */
4476             Line *l = nasm_malloc(sizeof(Line));
4477             l->next = defining->expansion;
4478             l->first = tline;
4479             l->finishes = NULL;
4480             defining->expansion = l;
4481             continue;
4482         } else if (istk->conds && !emitting(istk->conds->state)) {
4483             /*
4484              * We're in a non-emitting branch of a condition block.
4485              * Emit nothing at all, not even a blank line: when we
4486              * emerge from the condition we'll give a line-number
4487              * directive so we keep our place correctly.
4488              */
4489             free_tlist(tline);
4490             continue;
4491         } else if (istk->mstk && !istk->mstk->in_progress) {
4492             /*
4493              * We're in a %rep block which has been terminated, so
4494              * we're walking through to the %endrep without
4495              * emitting anything. Emit nothing at all, not even a
4496              * blank line: when we emerge from the %rep block we'll
4497              * give a line-number directive so we keep our place
4498              * correctly.
4499              */
4500             free_tlist(tline);
4501             continue;
4502         } else {
4503             tline = expand_smacro(tline);
4504             if (!expand_mmacro(tline)) {
4505                 /*
4506                  * De-tokenize the line again, and emit it.
4507                  */
4508                 line = detoken(tline, true);
4509                 free_tlist(tline);
4510                 break;
4511             } else {
4512                 continue;       /* expand_mmacro calls free_tlist */
4513             }
4514         }
4515     }
4516
4517     return line;
4518 }
4519
4520 static void pp_cleanup(int pass)
4521 {
4522     if (defining) {
4523         if(defining->name) {
4524             error(ERR_NONFATAL,
4525                   "end of file while still defining macro `%s'",
4526                   defining->name);
4527         } else {
4528             error(ERR_NONFATAL, "end of file while still in %%rep");
4529         }
4530
4531         free_mmacro(defining);
4532     }
4533     while (cstk)
4534         ctx_pop();
4535     free_macros();
4536     while (istk) {
4537         Include *i = istk;
4538         istk = istk->next;
4539         fclose(i->fp);
4540         nasm_free(i->fname);
4541         nasm_free(i);
4542     }
4543     while (cstk)
4544         ctx_pop();
4545     nasm_free(src_set_fname(NULL));
4546     if (pass == 0) {
4547         IncPath *i;
4548         free_llist(predef);
4549         delete_Blocks();
4550         while ((i = ipath)) {
4551             ipath = i->next;
4552             if (i->path)
4553                 nasm_free(i->path);
4554             nasm_free(i);
4555         }
4556     }
4557 }
4558
4559 void pp_include_path(char *path)
4560 {
4561     IncPath *i;
4562
4563     i = nasm_malloc(sizeof(IncPath));
4564     i->path = path ? nasm_strdup(path) : NULL;
4565     i->next = NULL;
4566
4567     if (ipath != NULL) {
4568         IncPath *j = ipath;
4569         while (j->next != NULL)
4570             j = j->next;
4571         j->next = i;
4572     } else {
4573         ipath = i;
4574     }
4575 }
4576
4577 void pp_pre_include(char *fname)
4578 {
4579     Token *inc, *space, *name;
4580     Line *l;
4581
4582     name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
4583     space = new_Token(name, TOK_WHITESPACE, NULL, 0);
4584     inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
4585
4586     l = nasm_malloc(sizeof(Line));
4587     l->next = predef;
4588     l->first = inc;
4589     l->finishes = NULL;
4590     predef = l;
4591 }
4592
4593 void pp_pre_define(char *definition)
4594 {
4595     Token *def, *space;
4596     Line *l;
4597     char *equals;
4598
4599     equals = strchr(definition, '=');
4600     space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4601     def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
4602     if (equals)
4603         *equals = ' ';
4604     space->next = tokenize(definition);
4605     if (equals)
4606         *equals = '=';
4607
4608     l = nasm_malloc(sizeof(Line));
4609     l->next = predef;
4610     l->first = def;
4611     l->finishes = NULL;
4612     predef = l;
4613 }
4614
4615 void pp_pre_undefine(char *definition)
4616 {
4617     Token *def, *space;
4618     Line *l;
4619
4620     space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4621     def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
4622     space->next = tokenize(definition);
4623
4624     l = nasm_malloc(sizeof(Line));
4625     l->next = predef;
4626     l->first = def;
4627     l->finishes = NULL;
4628     predef = l;
4629 }
4630
4631 /*
4632  * Added by Keith Kanios:
4633  *
4634  * This function is used to assist with "runtime" preprocessor
4635  * directives. (e.g. pp_runtime("%define __BITS__ 64");)
4636  *
4637  * ERRORS ARE IGNORED HERE, SO MAKE COMPLETELY SURE THAT YOU
4638  * PASS A VALID STRING TO THIS FUNCTION!!!!!
4639  */
4640
4641 void pp_runtime(char *definition)
4642 {
4643     Token *def;
4644
4645     def = tokenize(definition);
4646     if(do_directive(def) == NO_DIRECTIVE_FOUND)
4647         free_tlist(def);
4648
4649 }
4650
4651 void pp_extra_stdmac(macros_t *macros)
4652 {
4653     extrastdmac = macros;
4654 }
4655
4656 static void make_tok_num(Token * tok, int64_t val)
4657 {
4658     char numbuf[20];
4659     snprintf(numbuf, sizeof(numbuf), "%"PRId64"", val);
4660     tok->text = nasm_strdup(numbuf);
4661     tok->type = TOK_NUMBER;
4662 }
4663
4664 Preproc nasmpp = {
4665     pp_reset,
4666     pp_getline,
4667     pp_cleanup
4668 };