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