BR3392253: Fix potential buffer overflow in number conversion
[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 #define PP_CONCAT_MATCH(t, mask) (PP_CONCAT_MASK((t)->type) & mask)
217
218 struct tokseq_match {
219     int mask_head;
220     int mask_tail;
221 };
222
223 struct Token {
224     Token *next;
225     char *text;
226     union {
227         SMacro *mac;        /* associated macro for TOK_SMAC_END */
228         size_t len;         /* scratch length field */
229     } a;                    /* Auxiliary data */
230     enum pp_token_type type;
231 };
232
233 /*
234  * Multi-line macro definitions are stored as a linked list of
235  * these, which is essentially a container to allow several linked
236  * lists of Tokens.
237  *
238  * Note that in this module, linked lists are treated as stacks
239  * wherever possible. For this reason, Lines are _pushed_ on to the
240  * `expansion' field in MMacro structures, so that the linked list,
241  * if walked, would give the macro lines in reverse order; this
242  * means that we can walk the list when expanding a macro, and thus
243  * push the lines on to the `expansion' field in _istk_ in reverse
244  * order (so that when popped back off they are in the right
245  * order). It may seem cockeyed, and it relies on my design having
246  * an even number of steps in, but it works...
247  *
248  * Some of these structures, rather than being actual lines, are
249  * markers delimiting the end of the expansion of a given macro.
250  * This is for use in the cycle-tracking and %rep-handling code.
251  * Such structures have `finishes' non-NULL, and `first' NULL. All
252  * others have `finishes' NULL, but `first' may still be NULL if
253  * the line is blank.
254  */
255 struct Line {
256     Line *next;
257     MMacro *finishes;
258     Token *first;
259 };
260
261 /*
262  * To handle an arbitrary level of file inclusion, we maintain a
263  * stack (ie linked list) of these things.
264  */
265 struct Include {
266     Include *next;
267     FILE *fp;
268     Cond *conds;
269     Line *expansion;
270     char *fname;
271     int lineno, lineinc;
272     MMacro *mstk;       /* stack of active macros/reps */
273 };
274
275 /*
276  * Include search path. This is simply a list of strings which get
277  * prepended, in turn, to the name of an include file, in an
278  * attempt to find the file if it's not in the current directory.
279  */
280 struct IncPath {
281     IncPath *next;
282     char *path;
283 };
284
285 /*
286  * Conditional assembly: we maintain a separate stack of these for
287  * each level of file inclusion. (The only reason we keep the
288  * stacks separate is to ensure that a stray `%endif' in a file
289  * included from within the true branch of a `%if' won't terminate
290  * it and cause confusion: instead, rightly, it'll cause an error.)
291  */
292 struct Cond {
293     Cond *next;
294     int state;
295 };
296 enum {
297     /*
298      * These states are for use just after %if or %elif: IF_TRUE
299      * means the condition has evaluated to truth so we are
300      * currently emitting, whereas IF_FALSE means we are not
301      * currently emitting but will start doing so if a %else comes
302      * up. In these states, all directives are admissible: %elif,
303      * %else and %endif. (And of course %if.)
304      */
305     COND_IF_TRUE, COND_IF_FALSE,
306     /*
307      * These states come up after a %else: ELSE_TRUE means we're
308      * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
309      * any %elif or %else will cause an error.
310      */
311     COND_ELSE_TRUE, COND_ELSE_FALSE,
312     /*
313      * These states mean that we're not emitting now, and also that
314      * nothing until %endif will be emitted at all. COND_DONE is
315      * used when we've had our moment of emission
316      * and have now started seeing %elifs. COND_NEVER is used when
317      * the condition construct in question is contained within a
318      * non-emitting branch of a larger condition construct,
319      * or if there is an error.
320      */
321     COND_DONE, COND_NEVER
322 };
323 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
324
325 /*
326  * These defines are used as the possible return values for do_directive
327  */
328 #define NO_DIRECTIVE_FOUND  0
329 #define DIRECTIVE_FOUND     1
330
331 /*
332  * This define sets the upper limit for smacro and recursive mmacro
333  * expansions
334  */
335 #define DEADMAN_LIMIT (1 << 20)
336
337 /* max reps */
338 #define REP_LIMIT ((INT64_C(1) << 62))
339
340 /*
341  * Condition codes. Note that we use c_ prefix not C_ because C_ is
342  * used in nasm.h for the "real" condition codes. At _this_ level,
343  * we treat CXZ and ECXZ as condition codes, albeit non-invertible
344  * ones, so we need a different enum...
345  */
346 static const char * const conditions[] = {
347     "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
348     "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
349     "np", "ns", "nz", "o", "p", "pe", "po", "rcxz", "s", "z"
350 };
351 enum pp_conds {
352     c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE,
353     c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO,
354     c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_RCXZ, c_S, c_Z,
355     c_none = -1
356 };
357 static const enum pp_conds inverse_ccs[] = {
358     c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE,
359     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,
360     c_Z, c_NO, c_NP, c_PO, c_PE, -1, c_NS, c_NZ
361 };
362
363 /*
364  * Directive names.
365  */
366 /* If this is a an IF, ELIF, ELSE or ENDIF keyword */
367 static int is_condition(enum preproc_token arg)
368 {
369     return PP_IS_COND(arg) || (arg == PP_ELSE) || (arg == PP_ENDIF);
370 }
371
372 /* For TASM compatibility we need to be able to recognise TASM compatible
373  * conditional compilation directives. Using the NASM pre-processor does
374  * not work, so we look for them specifically from the following list and
375  * then jam in the equivalent NASM directive into the input stream.
376  */
377
378 enum {
379     TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
380     TM_IFNDEF, TM_INCLUDE, TM_LOCAL
381 };
382
383 static const char * const tasm_directives[] = {
384     "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
385     "ifndef", "include", "local"
386 };
387
388 static int StackSize = 4;
389 static char *StackPointer = "ebp";
390 static int ArgOffset = 8;
391 static int LocalOffset = 0;
392
393 static Context *cstk;
394 static Include *istk;
395 static IncPath *ipath = NULL;
396
397 static int pass;            /* HACK: pass 0 = generate dependencies only */
398 static StrList **dephead, **deptail; /* Dependency list */
399
400 static uint64_t unique;     /* unique identifier numbers */
401
402 static Line *predef = NULL;
403 static bool do_predef;
404
405 static ListGen *list;
406
407 /*
408  * The current set of multi-line macros we have defined.
409  */
410 static struct hash_table mmacros;
411
412 /*
413  * The current set of single-line macros we have defined.
414  */
415 static struct hash_table smacros;
416
417 /*
418  * The multi-line macro we are currently defining, or the %rep
419  * block we are currently reading, if any.
420  */
421 static MMacro *defining;
422
423 static uint64_t nested_mac_count;
424 static uint64_t nested_rep_count;
425
426 /*
427  * The number of macro parameters to allocate space for at a time.
428  */
429 #define PARAM_DELTA 16
430
431 /*
432  * The standard macro set: defined in macros.c in the array nasm_stdmac.
433  * This gives our position in the macro set, when we're processing it.
434  */
435 static macros_t *stdmacpos;
436
437 /*
438  * The extra standard macros that come from the object format, if
439  * any.
440  */
441 static macros_t *extrastdmac = NULL;
442 static bool any_extrastdmac;
443
444 /*
445  * Tokens are allocated in blocks to improve speed
446  */
447 #define TOKEN_BLOCKSIZE 4096
448 static Token *freeTokens = NULL;
449 struct Blocks {
450     Blocks *next;
451     void *chunk;
452 };
453
454 static Blocks blocks = { NULL, NULL };
455
456 /*
457  * Forward declarations.
458  */
459 static Token *expand_mmac_params(Token * tline);
460 static Token *expand_smacro(Token * tline);
461 static Token *expand_id(Token * tline);
462 static Context *get_ctx(const char *name, const char **namep);
463 static void make_tok_num(Token * tok, int64_t val);
464 static void error(int severity, const char *fmt, ...);
465 static void error_precond(int severity, const char *fmt, ...);
466 static void *new_Block(size_t size);
467 static void delete_Blocks(void);
468 static Token *new_Token(Token * next, enum pp_token_type type,
469                         const char *text, int txtlen);
470 static Token *delete_Token(Token * t);
471
472 /*
473  * Macros for safe checking of token pointers, avoid *(NULL)
474  */
475 #define tok_type_(x,t)  ((x) && (x)->type == (t))
476 #define skip_white_(x)  if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
477 #define tok_is_(x,v)    (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
478 #define tok_isnt_(x,v)  ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
479
480 /*
481  * nasm_unquote with error if the string contains NUL characters.
482  * If the string contains NUL characters, issue an error and return
483  * the C len, i.e. truncate at the NUL.
484  */
485 static size_t nasm_unquote_cstr(char *qstr, enum preproc_token directive)
486 {
487     size_t len = nasm_unquote(qstr, NULL);
488     size_t clen = strlen(qstr);
489
490     if (len != clen)
491         error(ERR_NONFATAL, "NUL character in `%s' directive",
492               pp_directives[directive]);
493
494     return clen;
495 }
496
497 /*
498  * In-place reverse a list of tokens.
499  */
500 static Token *reverse_tokens(Token *t)
501 {
502     Token *prev = NULL;
503     Token *next;
504
505     while (t) {
506         next = t->next;
507         t->next = prev;
508         prev = t;
509         t = next;
510     }
511
512     return prev;
513 }
514
515 /*
516  * Handle TASM specific directives, which do not contain a % in
517  * front of them. We do it here because I could not find any other
518  * place to do it for the moment, and it is a hack (ideally it would
519  * be nice to be able to use the NASM pre-processor to do it).
520  */
521 static char *check_tasm_directive(char *line)
522 {
523     int32_t i, j, k, m, len;
524     char *p, *q, *oldline, oldchar;
525
526     p = nasm_skip_spaces(line);
527
528     /* Binary search for the directive name */
529     i = -1;
530     j = ARRAY_SIZE(tasm_directives);
531     q = nasm_skip_word(p);
532     len = q - p;
533     if (len) {
534         oldchar = p[len];
535         p[len] = 0;
536         while (j - i > 1) {
537             k = (j + i) / 2;
538             m = nasm_stricmp(p, tasm_directives[k]);
539             if (m == 0) {
540                 /* We have found a directive, so jam a % in front of it
541                  * so that NASM will then recognise it as one if it's own.
542                  */
543                 p[len] = oldchar;
544                 len = strlen(p);
545                 oldline = line;
546                 line = nasm_malloc(len + 2);
547                 line[0] = '%';
548                 if (k == TM_IFDIFI) {
549                     /*
550                      * NASM does not recognise IFDIFI, so we convert
551                      * it to %if 0. This is not used in NASM
552                      * compatible code, but does need to parse for the
553                      * TASM macro package.
554                      */
555                     strcpy(line + 1, "if 0");
556                 } else {
557                     memcpy(line + 1, p, len + 1);
558                 }
559                 nasm_free(oldline);
560                 return line;
561             } else if (m < 0) {
562                 j = k;
563             } else
564                 i = k;
565         }
566         p[len] = oldchar;
567     }
568     return line;
569 }
570
571 /*
572  * The pre-preprocessing stage... This function translates line
573  * number indications as they emerge from GNU cpp (`# lineno "file"
574  * flags') into NASM preprocessor line number indications (`%line
575  * lineno file').
576  */
577 static char *prepreproc(char *line)
578 {
579     int lineno, fnlen;
580     char *fname, *oldline;
581
582     if (line[0] == '#' && line[1] == ' ') {
583         oldline = line;
584         fname = oldline + 2;
585         lineno = atoi(fname);
586         fname += strspn(fname, "0123456789 ");
587         if (*fname == '"')
588             fname++;
589         fnlen = strcspn(fname, "\"");
590         line = nasm_malloc(20 + fnlen);
591         snprintf(line, 20 + fnlen, "%%line %d %.*s", lineno, fnlen, fname);
592         nasm_free(oldline);
593     }
594     if (tasm_compatible_mode)
595         return check_tasm_directive(line);
596     return line;
597 }
598
599 /*
600  * Free a linked list of tokens.
601  */
602 static void free_tlist(Token * list)
603 {
604     while (list)
605         list = delete_Token(list);
606 }
607
608 /*
609  * Free a linked list of lines.
610  */
611 static void free_llist(Line * list)
612 {
613     Line *l, *tmp;
614     list_for_each_safe(l, tmp, list) {
615         free_tlist(l->first);
616         nasm_free(l);
617     }
618 }
619
620 /*
621  * Free an MMacro
622  */
623 static void free_mmacro(MMacro * m)
624 {
625     nasm_free(m->name);
626     free_tlist(m->dlist);
627     nasm_free(m->defaults);
628     free_llist(m->expansion);
629     nasm_free(m);
630 }
631
632 /*
633  * Free all currently defined macros, and free the hash tables
634  */
635 static void free_smacro_table(struct hash_table *smt)
636 {
637     SMacro *s, *tmp;
638     const char *key;
639     struct hash_tbl_node *it = NULL;
640
641     while ((s = hash_iterate(smt, &it, &key)) != NULL) {
642         nasm_free((void *)key);
643         list_for_each_safe(s, tmp, s) {
644             nasm_free(s->name);
645             free_tlist(s->expansion);
646             nasm_free(s);
647         }
648     }
649     hash_free(smt);
650 }
651
652 static void free_mmacro_table(struct hash_table *mmt)
653 {
654     MMacro *m, *tmp;
655     const char *key;
656     struct hash_tbl_node *it = NULL;
657
658     it = NULL;
659     while ((m = hash_iterate(mmt, &it, &key)) != NULL) {
660         nasm_free((void *)key);
661         list_for_each_safe(m ,tmp, m)
662             free_mmacro(m);
663     }
664     hash_free(mmt);
665 }
666
667 static void free_macros(void)
668 {
669     free_smacro_table(&smacros);
670     free_mmacro_table(&mmacros);
671 }
672
673 /*
674  * Initialize the hash tables
675  */
676 static void init_macros(void)
677 {
678     hash_init(&smacros, HASH_LARGE);
679     hash_init(&mmacros, HASH_LARGE);
680 }
681
682 /*
683  * Pop the context stack.
684  */
685 static void ctx_pop(void)
686 {
687     Context *c = cstk;
688
689     cstk = cstk->next;
690     free_smacro_table(&c->localmac);
691     nasm_free(c->name);
692     nasm_free(c);
693 }
694
695 /*
696  * Search for a key in the hash index; adding it if necessary
697  * (in which case we initialize the data pointer to NULL.)
698  */
699 static void **
700 hash_findi_add(struct hash_table *hash, const char *str)
701 {
702     struct hash_insert hi;
703     void **r;
704     char *strx;
705
706     r = hash_findi(hash, str, &hi);
707     if (r)
708         return r;
709
710     strx = nasm_strdup(str);    /* Use a more efficient allocator here? */
711     return hash_add(&hi, strx, NULL);
712 }
713
714 /*
715  * Like hash_findi, but returns the data element rather than a pointer
716  * to it.  Used only when not adding a new element, hence no third
717  * argument.
718  */
719 static void *
720 hash_findix(struct hash_table *hash, const char *str)
721 {
722     void **p;
723
724     p = hash_findi(hash, str, NULL);
725     return p ? *p : NULL;
726 }
727
728 /*
729  * read line from standart macros set,
730  * if there no more left -- return NULL
731  */
732 static char *line_from_stdmac(void)
733 {
734     unsigned char c;
735     const unsigned char *p = stdmacpos;
736     char *line, *q;
737     size_t len = 0;
738
739     if (!stdmacpos)
740         return NULL;
741
742     while ((c = *p++)) {
743         if (c >= 0x80)
744             len += pp_directives_len[c - 0x80] + 1;
745         else
746             len++;
747     }
748
749     line = nasm_malloc(len + 1);
750     q = line;
751     while ((c = *stdmacpos++)) {
752         if (c >= 0x80) {
753             memcpy(q, pp_directives[c - 0x80], pp_directives_len[c - 0x80]);
754             q += pp_directives_len[c - 0x80];
755             *q++ = ' ';
756         } else {
757             *q++ = c;
758         }
759     }
760     stdmacpos = p;
761     *q = '\0';
762
763     if (!*stdmacpos) {
764         /* This was the last of the standard macro chain... */
765         stdmacpos = NULL;
766         if (any_extrastdmac) {
767             stdmacpos = extrastdmac;
768             any_extrastdmac = false;
769         } else if (do_predef) {
770             Line *pd, *l;
771             Token *head, **tail, *t;
772
773             /*
774              * Nasty hack: here we push the contents of
775              * `predef' on to the top-level expansion stack,
776              * since this is the most convenient way to
777              * implement the pre-include and pre-define
778              * features.
779              */
780             list_for_each(pd, predef) {
781                 head = NULL;
782                 tail = &head;
783                 list_for_each(t, pd->first) {
784                     *tail = new_Token(NULL, t->type, t->text, 0);
785                     tail = &(*tail)->next;
786                 }
787
788                 l           = nasm_malloc(sizeof(Line));
789                 l->next     = istk->expansion;
790                 l->first    = head;
791                 l->finishes = NULL;
792
793                 istk->expansion = l;
794             }
795             do_predef = false;
796         }
797     }
798
799     return line;
800 }
801
802 static char *read_line(void)
803 {
804     unsigned int size, c, next;
805     const unsigned int delta = 512;
806     const unsigned int pad = 8;
807     unsigned int nr_cont = 0;
808     bool cont = false;
809     char *buffer, *p;
810
811     /* Standart macros set (predefined) goes first */
812     p = line_from_stdmac();
813     if (p)
814         return p;
815
816     size = delta;
817     p = buffer = nasm_malloc(size);
818
819     for (;;) {
820         c = fgetc(istk->fp);
821         if ((int)(c) == EOF) {
822             p[0] = 0;
823             break;
824         }
825
826         switch (c) {
827         case '\r':
828             next = fgetc(istk->fp);
829             if (next != '\n')
830                 ungetc(next, istk->fp);
831             if (cont) {
832                 cont = false;
833                 continue;
834             }
835             break;
836
837         case '\n':
838             if (cont) {
839                 cont = false;
840                 continue;
841             }
842             break;
843
844         case '\\':
845             next = fgetc(istk->fp);
846             ungetc(next, istk->fp);
847             if (next == '\r' || next == '\n') {
848                 cont = true;
849                 nr_cont++;
850                 continue;
851             }
852             break;
853         }
854
855         if (c == '\r' || c == '\n') {
856             *p++ = 0;
857             break;
858         }
859
860         if (p >= (buffer + size - pad)) {
861             buffer = nasm_realloc(buffer, size + delta);
862             p = buffer + size - pad;
863             size += delta;
864         }
865
866         *p++ = (unsigned char)c;
867     }
868
869     if (p == buffer) {
870         nasm_free(buffer);
871         return NULL;
872     }
873
874     src_set_linnum(src_get_linnum() + istk->lineinc +
875                    (nr_cont * istk->lineinc));
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_IRMACRO || 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 /*
3589  * This routines walks over tokens strem and hadnles tokens
3590  * pasting, if @handle_explicit passed then explicit pasting
3591  * term is handled, otherwise -- implicit pastings only.
3592  */
3593 static bool paste_tokens(Token **head, const struct tokseq_match *m,
3594                          size_t mnum, bool handle_explicit)
3595 {
3596     Token *tok, *next, **prev_next, **prev_nonspace;
3597     bool pasted = false;
3598     char *buf, *p;
3599     size_t len, i;
3600
3601     /*
3602      * The last token before pasting. We need it
3603      * to be able to connect new handled tokens.
3604      * In other words if there were a tokens stream
3605      *
3606      * A -> B -> C -> D
3607      *
3608      * and we've joined tokens B and C, the resulting
3609      * stream should be
3610      *
3611      * A -> BC -> D
3612      */
3613     tok = *head;
3614     prev_next = NULL;
3615
3616     if (!tok_type_(tok, TOK_WHITESPACE) && !tok_type_(tok, TOK_PASTE))
3617         prev_nonspace = head;
3618     else
3619         prev_nonspace = NULL;
3620
3621     while (tok && (next = tok->next)) {
3622
3623         switch (tok->type) {
3624         case TOK_WHITESPACE:
3625             /* Zap redundant whitespaces */
3626             while (tok_type_(next, TOK_WHITESPACE))
3627                 next = delete_Token(next);
3628             tok->next = next;
3629             break;
3630
3631         case TOK_PASTE:
3632             /* Explicit pasting */
3633             if (!handle_explicit)
3634                 break;
3635             next = delete_Token(tok);
3636
3637             while (tok_type_(next, TOK_WHITESPACE))
3638                 next = delete_Token(next);
3639
3640             if (!pasted)
3641                 pasted = true;
3642
3643             /* Left pasting token is start of line */
3644             if (!prev_nonspace)
3645                 error(ERR_FATAL, "No lvalue found on pasting");
3646
3647             /*
3648              * No ending token, this might happen in two
3649              * cases
3650              *
3651              *  1) There indeed no right token at all
3652              *  2) There is a bare "%define ID" statement,
3653              *     and @ID does expand to whitespace.
3654              *
3655              * So technically we need to do a grammar analysis
3656              * in another stage of parsing, but for now lets don't
3657              * change the behaviour people used to. Simply allow
3658              * whitespace after paste token.
3659              */
3660             if (!next) {
3661                 /*
3662                  * Zap ending space tokens and that's all.
3663                  */
3664                 tok = (*prev_nonspace)->next;
3665                 while (tok_type_(tok, TOK_WHITESPACE))
3666                     tok = delete_Token(tok);
3667                 tok = *prev_nonspace;
3668                 tok->next = NULL;
3669                 break;
3670             }
3671
3672             tok = *prev_nonspace;
3673             while (tok_type_(tok, TOK_WHITESPACE))
3674                 tok = delete_Token(tok);
3675             len  = strlen(tok->text);
3676             len += strlen(next->text);
3677
3678             p = buf = nasm_malloc(len + 1);
3679             strcpy(p, tok->text);
3680             p = strchr(p, '\0');
3681             strcpy(p, next->text);
3682
3683             delete_Token(tok);
3684
3685             tok = tokenize(buf);
3686             nasm_free(buf);
3687
3688             *prev_nonspace = tok;
3689             while (tok && tok->next)
3690                 tok = tok->next;
3691
3692             tok->next = delete_Token(next);
3693
3694             /* Restart from pasted tokens head */
3695             tok = *prev_nonspace;
3696             break;
3697
3698         default:
3699             /* implicit pasting */
3700             for (i = 0; i < mnum; i++) {
3701                 if (!(PP_CONCAT_MATCH(tok, m[i].mask_head)))
3702                     continue;
3703
3704                 len = 0;
3705                 while (next && PP_CONCAT_MATCH(next, m[i].mask_tail)) {
3706                     len += strlen(next->text);
3707                     next = next->next;
3708                 }
3709
3710                 /* No match */
3711                 if (tok == next)
3712                     break;
3713
3714                 len += strlen(tok->text);
3715                 p = buf = nasm_malloc(len + 1);
3716
3717                 while (tok != next) {
3718                     strcpy(p, tok->text);
3719                     p = strchr(p, '\0');
3720                     tok = delete_Token(tok);
3721                 }
3722
3723                 tok = tokenize(buf);
3724                 nasm_free(buf);
3725
3726                 if (prev_next)
3727                     *prev_next = tok;
3728                 else
3729                     *head = tok;
3730
3731                 /*
3732                  * Connect pasted into original stream,
3733                  * ie A -> new-tokens -> B
3734                  */
3735                 while (tok && tok->next)
3736                     tok = tok->next;
3737                 tok->next = next;
3738
3739                 if (!pasted)
3740                     pasted = true;
3741
3742                 /* Restart from pasted tokens head */
3743                 tok = prev_next ? *prev_next : *head;
3744             }
3745
3746             break;
3747         }
3748
3749         prev_next = &tok->next;
3750
3751         if (tok->next &&
3752             !tok_type_(tok->next, TOK_WHITESPACE) &&
3753             !tok_type_(tok->next, TOK_PASTE))
3754             prev_nonspace = prev_next;
3755
3756         tok = tok->next;
3757     }
3758
3759     return pasted;
3760 }
3761
3762 /*
3763  * expands to a list of tokens from %{x:y}
3764  */
3765 static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last)
3766 {
3767     Token *t = tline, **tt, *tm, *head;
3768     char *pos;
3769     int fst, lst, j, i;
3770
3771     pos = strchr(tline->text, ':');
3772     nasm_assert(pos);
3773
3774     lst = atoi(pos + 1);
3775     fst = atoi(tline->text + 1);
3776
3777     /*
3778      * only macros params are accounted so
3779      * if someone passes %0 -- we reject such
3780      * value(s)
3781      */
3782     if (lst == 0 || fst == 0)
3783         goto err;
3784
3785     /* the values should be sane */
3786     if ((fst > (int)mac->nparam || fst < (-(int)mac->nparam)) ||
3787         (lst > (int)mac->nparam || lst < (-(int)mac->nparam)))
3788         goto err;
3789
3790     fst = fst < 0 ? fst + (int)mac->nparam + 1: fst;
3791     lst = lst < 0 ? lst + (int)mac->nparam + 1: lst;
3792
3793     /* counted from zero */
3794     fst--, lst--;
3795
3796     /*
3797      * it will be at least one token
3798      */
3799     tm = mac->params[(fst + mac->rotate) % mac->nparam];
3800     t = new_Token(NULL, tm->type, tm->text, 0);
3801     head = t, tt = &t->next;
3802     if (fst < lst) {
3803         for (i = fst + 1; i <= lst; i++) {
3804             t = new_Token(NULL, TOK_OTHER, ",", 0);
3805             *tt = t, tt = &t->next;
3806             j = (i + mac->rotate) % mac->nparam;
3807             tm = mac->params[j];
3808             t = new_Token(NULL, tm->type, tm->text, 0);
3809             *tt = t, tt = &t->next;
3810         }
3811     } else {
3812         for (i = fst - 1; i >= lst; i--) {
3813             t = new_Token(NULL, TOK_OTHER, ",", 0);
3814             *tt = t, tt = &t->next;
3815             j = (i + mac->rotate) % mac->nparam;
3816             tm = mac->params[j];
3817             t = new_Token(NULL, tm->type, tm->text, 0);
3818             *tt = t, tt = &t->next;
3819         }
3820     }
3821
3822     *last = tt;
3823     return head;
3824
3825 err:
3826     error(ERR_NONFATAL, "`%%{%s}': macro parameters out of range",
3827           &tline->text[1]);
3828     return tline;
3829 }
3830
3831 /*
3832  * Expand MMacro-local things: parameter references (%0, %n, %+n,
3833  * %-n) and MMacro-local identifiers (%%foo) as well as
3834  * macro indirection (%[...]) and range (%{..:..}).
3835  */
3836 static Token *expand_mmac_params(Token * tline)
3837 {
3838     Token *t, *tt, **tail, *thead;
3839     bool changed = false;
3840     char *pos;
3841
3842     tail = &thead;
3843     thead = NULL;
3844
3845     while (tline) {
3846         if (tline->type == TOK_PREPROC_ID &&
3847             (((tline->text[1] == '+' || tline->text[1] == '-') && tline->text[2])   ||
3848               (tline->text[1] >= '0' && tline->text[1] <= '9')                      ||
3849                tline->text[1] == '%')) {
3850             char *text = NULL;
3851             int type = 0, cc;   /* type = 0 to placate optimisers */
3852             char tmpbuf[30];
3853             unsigned int n;
3854             int i;
3855             MMacro *mac;
3856
3857             t = tline;
3858             tline = tline->next;
3859
3860             mac = istk->mstk;
3861             while (mac && !mac->name)   /* avoid mistaking %reps for macros */
3862                 mac = mac->next_active;
3863             if (!mac) {
3864                 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
3865             } else {
3866                 pos = strchr(t->text, ':');
3867                 if (!pos) {
3868                     switch (t->text[1]) {
3869                         /*
3870                          * We have to make a substitution of one of the
3871                          * forms %1, %-1, %+1, %%foo, %0.
3872                          */
3873                     case '0':
3874                         type = TOK_NUMBER;
3875                         snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam);
3876                         text = nasm_strdup(tmpbuf);
3877                         break;
3878                     case '%':
3879                         type = TOK_ID;
3880                         snprintf(tmpbuf, sizeof(tmpbuf), "..@%"PRIu64".",
3881                                  mac->unique);
3882                         text = nasm_strcat(tmpbuf, t->text + 2);
3883                         break;
3884                     case '-':
3885                         n = atoi(t->text + 2) - 1;
3886                         if (n >= mac->nparam)
3887                             tt = NULL;
3888                         else {
3889                             if (mac->nparam > 1)
3890                                 n = (n + mac->rotate) % mac->nparam;
3891                             tt = mac->params[n];
3892                         }
3893                         cc = find_cc(tt);
3894                         if (cc == -1) {
3895                             error(ERR_NONFATAL,
3896                                   "macro parameter %d is not a condition code",
3897                                   n + 1);
3898                             text = NULL;
3899                         } else {
3900                             type = TOK_ID;
3901                             if (inverse_ccs[cc] == -1) {
3902                                 error(ERR_NONFATAL,
3903                                       "condition code `%s' is not invertible",
3904                                       conditions[cc]);
3905                                 text = NULL;
3906                             } else
3907                                 text = nasm_strdup(conditions[inverse_ccs[cc]]);
3908                         }
3909                         break;
3910                     case '+':
3911                         n = atoi(t->text + 2) - 1;
3912                         if (n >= mac->nparam)
3913                             tt = NULL;
3914                         else {
3915                             if (mac->nparam > 1)
3916                                 n = (n + mac->rotate) % mac->nparam;
3917                             tt = mac->params[n];
3918                         }
3919                         cc = find_cc(tt);
3920                         if (cc == -1) {
3921                             error(ERR_NONFATAL,
3922                                   "macro parameter %d is not a condition code",
3923                                   n + 1);
3924                             text = NULL;
3925                         } else {
3926                             type = TOK_ID;
3927                             text = nasm_strdup(conditions[cc]);
3928                         }
3929                         break;
3930                     default:
3931                         n = atoi(t->text + 1) - 1;
3932                         if (n >= mac->nparam)
3933                             tt = NULL;
3934                         else {
3935                             if (mac->nparam > 1)
3936                                 n = (n + mac->rotate) % mac->nparam;
3937                             tt = mac->params[n];
3938                         }
3939                         if (tt) {
3940                             for (i = 0; i < mac->paramlen[n]; i++) {
3941                                 *tail = new_Token(NULL, tt->type, tt->text, 0);
3942                                 tail = &(*tail)->next;
3943                                 tt = tt->next;
3944                             }
3945                         }
3946                         text = NULL;        /* we've done it here */
3947                         break;
3948                     }
3949                 } else {
3950                     /*
3951                      * seems we have a parameters range here
3952                      */
3953                     Token *head, **last;
3954                     head = expand_mmac_params_range(mac, t, &last);
3955                     if (head != t) {
3956                         *tail = head;
3957                         *last = tline;
3958                         tline = head;
3959                         text = NULL;
3960                     }
3961                 }
3962             }
3963             if (!text) {
3964                 delete_Token(t);
3965             } else {
3966                 *tail = t;
3967                 tail = &t->next;
3968                 t->type = type;
3969                 nasm_free(t->text);
3970                 t->text = text;
3971                 t->a.mac = NULL;
3972             }
3973             changed = true;
3974             continue;
3975         } else if (tline->type == TOK_INDIRECT) {
3976             t = tline;
3977             tline = tline->next;
3978             tt = tokenize(t->text);
3979             tt = expand_mmac_params(tt);
3980             tt = expand_smacro(tt);
3981             *tail = tt;
3982             while (tt) {
3983                 tt->a.mac = NULL; /* Necessary? */
3984                 tail = &tt->next;
3985                 tt = tt->next;
3986             }
3987             delete_Token(t);
3988             changed = true;
3989         } else {
3990             t = *tail = tline;
3991             tline = tline->next;
3992             t->a.mac = NULL;
3993             tail = &t->next;
3994         }
3995     }
3996     *tail = NULL;
3997
3998     if (changed) {
3999         const struct tokseq_match t[] = {
4000             {
4001                 PP_CONCAT_MASK(TOK_ID)          |
4002                 PP_CONCAT_MASK(TOK_FLOAT),          /* head */
4003                 PP_CONCAT_MASK(TOK_ID)          |
4004                 PP_CONCAT_MASK(TOK_NUMBER)      |
4005                 PP_CONCAT_MASK(TOK_FLOAT)       |
4006                 PP_CONCAT_MASK(TOK_OTHER)           /* tail */
4007             },
4008             {
4009                 PP_CONCAT_MASK(TOK_NUMBER),         /* head */
4010                 PP_CONCAT_MASK(TOK_NUMBER)          /* tail */
4011             }
4012         };
4013         paste_tokens(&thead, t, ARRAY_SIZE(t), false);
4014     }
4015
4016     return thead;
4017 }
4018
4019 /*
4020  * Expand all single-line macro calls made in the given line.
4021  * Return the expanded version of the line. The original is deemed
4022  * to be destroyed in the process. (In reality we'll just move
4023  * Tokens from input to output a lot of the time, rather than
4024  * actually bothering to destroy and replicate.)
4025  */
4026
4027 static Token *expand_smacro(Token * tline)
4028 {
4029     Token *t, *tt, *mstart, **tail, *thead;
4030     SMacro *head = NULL, *m;
4031     Token **params;
4032     int *paramsize;
4033     unsigned int nparam, sparam;
4034     int brackets;
4035     Token *org_tline = tline;
4036     Context *ctx;
4037     const char *mname;
4038     int deadman = DEADMAN_LIMIT;
4039     bool expanded;
4040
4041     /*
4042      * Trick: we should avoid changing the start token pointer since it can
4043      * be contained in "next" field of other token. Because of this
4044      * we allocate a copy of first token and work with it; at the end of
4045      * routine we copy it back
4046      */
4047     if (org_tline) {
4048         tline = new_Token(org_tline->next, org_tline->type,
4049                           org_tline->text, 0);
4050         tline->a.mac = org_tline->a.mac;
4051         nasm_free(org_tline->text);
4052         org_tline->text = NULL;
4053     }
4054
4055     expanded = true;            /* Always expand %+ at least once */
4056
4057 again:
4058     thead = NULL;
4059     tail = &thead;
4060
4061     while (tline) {             /* main token loop */
4062         if (!--deadman) {
4063             error(ERR_NONFATAL, "interminable macro recursion");
4064             goto err;
4065         }
4066
4067         if ((mname = tline->text)) {
4068             /* if this token is a local macro, look in local context */
4069             if (tline->type == TOK_ID) {
4070                 head = (SMacro *)hash_findix(&smacros, mname);
4071             } else if (tline->type == TOK_PREPROC_ID) {
4072                 ctx = get_ctx(mname, &mname);
4073                 head = ctx ? (SMacro *)hash_findix(&ctx->localmac, mname) : NULL;
4074             } else
4075                 head = NULL;
4076
4077             /*
4078              * We've hit an identifier. As in is_mmacro below, we first
4079              * check whether the identifier is a single-line macro at
4080              * all, then think about checking for parameters if
4081              * necessary.
4082              */
4083             list_for_each(m, head)
4084                 if (!mstrcmp(m->name, mname, m->casesense))
4085                     break;
4086             if (m) {
4087                 mstart = tline;
4088                 params = NULL;
4089                 paramsize = NULL;
4090                 if (m->nparam == 0) {
4091                     /*
4092                      * Simple case: the macro is parameterless. Discard the
4093                      * one token that the macro call took, and push the
4094                      * expansion back on the to-do stack.
4095                      */
4096                     if (!m->expansion) {
4097                         if (!strcmp("__FILE__", m->name)) {
4098                             int32_t num = 0;
4099                             char *file = NULL;
4100                             src_get(&num, &file);
4101                             tline->text = nasm_quote(file, strlen(file));
4102                             tline->type = TOK_STRING;
4103                             nasm_free(file);
4104                             continue;
4105                         }
4106                         if (!strcmp("__LINE__", m->name)) {
4107                             nasm_free(tline->text);
4108                             make_tok_num(tline, src_get_linnum());
4109                             continue;
4110                         }
4111                         if (!strcmp("__BITS__", m->name)) {
4112                             nasm_free(tline->text);
4113                             make_tok_num(tline, globalbits);
4114                             continue;
4115                         }
4116                         tline = delete_Token(tline);
4117                         continue;
4118                     }
4119                 } else {
4120                     /*
4121                      * Complicated case: at least one macro with this name
4122                      * exists and takes parameters. We must find the
4123                      * parameters in the call, count them, find the SMacro
4124                      * that corresponds to that form of the macro call, and
4125                      * substitute for the parameters when we expand. What a
4126                      * pain.
4127                      */
4128                     /*tline = tline->next;
4129                       skip_white_(tline); */
4130                     do {
4131                         t = tline->next;
4132                         while (tok_type_(t, TOK_SMAC_END)) {
4133                             t->a.mac->in_progress = false;
4134                             t->text = NULL;
4135                             t = tline->next = delete_Token(t);
4136                         }
4137                         tline = t;
4138                     } while (tok_type_(tline, TOK_WHITESPACE));
4139                     if (!tok_is_(tline, "(")) {
4140                         /*
4141                          * This macro wasn't called with parameters: ignore
4142                          * the call. (Behaviour borrowed from gnu cpp.)
4143                          */
4144                         tline = mstart;
4145                         m = NULL;
4146                     } else {
4147                         int paren = 0;
4148                         int white = 0;
4149                         brackets = 0;
4150                         nparam = 0;
4151                         sparam = PARAM_DELTA;
4152                         params = nasm_malloc(sparam * sizeof(Token *));
4153                         params[0] = tline->next;
4154                         paramsize = nasm_malloc(sparam * sizeof(int));
4155                         paramsize[0] = 0;
4156                         while (true) {  /* parameter loop */
4157                             /*
4158                              * For some unusual expansions
4159                              * which concatenates function call
4160                              */
4161                             t = tline->next;
4162                             while (tok_type_(t, TOK_SMAC_END)) {
4163                                 t->a.mac->in_progress = false;
4164                                 t->text = NULL;
4165                                 t = tline->next = delete_Token(t);
4166                             }
4167                             tline = t;
4168
4169                             if (!tline) {
4170                                 error(ERR_NONFATAL,
4171                                       "macro call expects terminating `)'");
4172                                 break;
4173                             }
4174                             if (tline->type == TOK_WHITESPACE
4175                                 && brackets <= 0) {
4176                                 if (paramsize[nparam])
4177                                     white++;
4178                                 else
4179                                     params[nparam] = tline->next;
4180                                 continue;       /* parameter loop */
4181                             }
4182                             if (tline->type == TOK_OTHER
4183                                 && tline->text[1] == 0) {
4184                                 char ch = tline->text[0];
4185                                 if (ch == ',' && !paren && brackets <= 0) {
4186                                     if (++nparam >= sparam) {
4187                                         sparam += PARAM_DELTA;
4188                                         params = nasm_realloc(params,
4189                                                         sparam * sizeof(Token *));
4190                                         paramsize = nasm_realloc(paramsize,
4191                                                         sparam * sizeof(int));
4192                                     }
4193                                     params[nparam] = tline->next;
4194                                     paramsize[nparam] = 0;
4195                                     white = 0;
4196                                     continue;   /* parameter loop */
4197                                 }
4198                                 if (ch == '{' &&
4199                                     (brackets > 0 || (brackets == 0 &&
4200                                                       !paramsize[nparam])))
4201                                 {
4202                                     if (!(brackets++)) {
4203                                         params[nparam] = tline->next;
4204                                         continue;       /* parameter loop */
4205                                     }
4206                                 }
4207                                 if (ch == '}' && brackets > 0)
4208                                     if (--brackets == 0) {
4209                                         brackets = -1;
4210                                         continue;       /* parameter loop */
4211                                     }
4212                                 if (ch == '(' && !brackets)
4213                                     paren++;
4214                                 if (ch == ')' && brackets <= 0)
4215                                     if (--paren < 0)
4216                                         break;
4217                             }
4218                             if (brackets < 0) {
4219                                 brackets = 0;
4220                                 error(ERR_NONFATAL, "braces do not "
4221                                       "enclose all of macro parameter");
4222                             }
4223                             paramsize[nparam] += white + 1;
4224                             white = 0;
4225                         }       /* parameter loop */
4226                         nparam++;
4227                         while (m && (m->nparam != nparam ||
4228                                      mstrcmp(m->name, mname,
4229                                              m->casesense)))
4230                             m = m->next;
4231                         if (!m)
4232                             error(ERR_WARNING|ERR_PASS1|ERR_WARN_MNP,
4233                                   "macro `%s' exists, "
4234                                   "but not taking %d parameters",
4235                                   mstart->text, nparam);
4236                     }
4237                 }
4238                 if (m && m->in_progress)
4239                     m = NULL;
4240                 if (!m) {       /* in progess or didn't find '(' or wrong nparam */
4241                     /*
4242                      * Design question: should we handle !tline, which
4243                      * indicates missing ')' here, or expand those
4244                      * macros anyway, which requires the (t) test a few
4245                      * lines down?
4246                      */
4247                     nasm_free(params);
4248                     nasm_free(paramsize);
4249                     tline = mstart;
4250                 } else {
4251                     /*
4252                      * Expand the macro: we are placed on the last token of the
4253                      * call, so that we can easily split the call from the
4254                      * following tokens. We also start by pushing an SMAC_END
4255                      * token for the cycle removal.
4256                      */
4257                     t = tline;
4258                     if (t) {
4259                         tline = t->next;
4260                         t->next = NULL;
4261                     }
4262                     tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
4263                     tt->a.mac = m;
4264                     m->in_progress = true;
4265                     tline = tt;
4266                     list_for_each(t, m->expansion) {
4267                         if (t->type >= TOK_SMAC_PARAM) {
4268                             Token *pcopy = tline, **ptail = &pcopy;
4269                             Token *ttt, *pt;
4270                             int i;
4271
4272                             ttt = params[t->type - TOK_SMAC_PARAM];
4273                             i = paramsize[t->type - TOK_SMAC_PARAM];
4274                             while (--i >= 0) {
4275                                 pt = *ptail = new_Token(tline, ttt->type,
4276                                                         ttt->text, 0);
4277                                 ptail = &pt->next;
4278                                 ttt = ttt->next;
4279                             }
4280                             tline = pcopy;
4281                         } else if (t->type == TOK_PREPROC_Q) {
4282                             tt = new_Token(tline, TOK_ID, mname, 0);
4283                             tline = tt;
4284                         } else if (t->type == TOK_PREPROC_QQ) {
4285                             tt = new_Token(tline, TOK_ID, m->name, 0);
4286                             tline = tt;
4287                         } else {
4288                             tt = new_Token(tline, t->type, t->text, 0);
4289                             tline = tt;
4290                         }
4291                     }
4292
4293                     /*
4294                      * Having done that, get rid of the macro call, and clean
4295                      * up the parameters.
4296                      */
4297                     nasm_free(params);
4298                     nasm_free(paramsize);
4299                     free_tlist(mstart);
4300                     expanded = true;
4301                     continue;   /* main token loop */
4302                 }
4303             }
4304         }
4305
4306         if (tline->type == TOK_SMAC_END) {
4307             tline->a.mac->in_progress = false;
4308             tline = delete_Token(tline);
4309         } else {
4310             t = *tail = tline;
4311             tline = tline->next;
4312             t->a.mac = NULL;
4313             t->next = NULL;
4314             tail = &t->next;
4315         }
4316     }
4317
4318     /*
4319      * Now scan the entire line and look for successive TOK_IDs that resulted
4320      * after expansion (they can't be produced by tokenize()). The successive
4321      * TOK_IDs should be concatenated.
4322      * Also we look for %+ tokens and concatenate the tokens before and after
4323      * them (without white spaces in between).
4324      */
4325     if (expanded) {
4326         const struct tokseq_match t[] = {
4327             {
4328                 PP_CONCAT_MASK(TOK_ID)          |
4329                 PP_CONCAT_MASK(TOK_PREPROC_ID),     /* head */
4330                 PP_CONCAT_MASK(TOK_ID)          |
4331                 PP_CONCAT_MASK(TOK_PREPROC_ID)  |
4332                 PP_CONCAT_MASK(TOK_NUMBER)          /* tail */
4333             }
4334         };
4335         if (paste_tokens(&thead, t, ARRAY_SIZE(t), true)) {
4336             /*
4337              * If we concatenated something, *and* we had previously expanded
4338              * an actual macro, scan the lines again for macros...
4339              */
4340             tline = thead;
4341             expanded = false;
4342             goto again;
4343         }
4344     }
4345
4346 err:
4347     if (org_tline) {
4348         if (thead) {
4349             *org_tline = *thead;
4350             /* since we just gave text to org_line, don't free it */
4351             thead->text = NULL;
4352             delete_Token(thead);
4353         } else {
4354             /* the expression expanded to empty line;
4355                we can't return NULL for some reasons
4356                we just set the line to a single WHITESPACE token. */
4357             memset(org_tline, 0, sizeof(*org_tline));
4358             org_tline->text = NULL;
4359             org_tline->type = TOK_WHITESPACE;
4360         }
4361         thead = org_tline;
4362     }
4363
4364     return thead;
4365 }
4366
4367 /*
4368  * Similar to expand_smacro but used exclusively with macro identifiers
4369  * right before they are fetched in. The reason is that there can be
4370  * identifiers consisting of several subparts. We consider that if there
4371  * are more than one element forming the name, user wants a expansion,
4372  * otherwise it will be left as-is. Example:
4373  *
4374  *      %define %$abc cde
4375  *
4376  * the identifier %$abc will be left as-is so that the handler for %define
4377  * will suck it and define the corresponding value. Other case:
4378  *
4379  *      %define _%$abc cde
4380  *
4381  * In this case user wants name to be expanded *before* %define starts
4382  * working, so we'll expand %$abc into something (if it has a value;
4383  * otherwise it will be left as-is) then concatenate all successive
4384  * PP_IDs into one.
4385  */
4386 static Token *expand_id(Token * tline)
4387 {
4388     Token *cur, *oldnext = NULL;
4389
4390     if (!tline || !tline->next)
4391         return tline;
4392
4393     cur = tline;
4394     while (cur->next &&
4395            (cur->next->type == TOK_ID ||
4396             cur->next->type == TOK_PREPROC_ID
4397             || cur->next->type == TOK_NUMBER))
4398         cur = cur->next;
4399
4400     /* If identifier consists of just one token, don't expand */
4401     if (cur == tline)
4402         return tline;
4403
4404     if (cur) {
4405         oldnext = cur->next;    /* Detach the tail past identifier */
4406         cur->next = NULL;       /* so that expand_smacro stops here */
4407     }
4408
4409     tline = expand_smacro(tline);
4410
4411     if (cur) {
4412         /* expand_smacro possibly changhed tline; re-scan for EOL */
4413         cur = tline;
4414         while (cur && cur->next)
4415             cur = cur->next;
4416         if (cur)
4417             cur->next = oldnext;
4418     }
4419
4420     return tline;
4421 }
4422
4423 /*
4424  * Determine whether the given line constitutes a multi-line macro
4425  * call, and return the MMacro structure called if so. Doesn't have
4426  * to check for an initial label - that's taken care of in
4427  * expand_mmacro - but must check numbers of parameters. Guaranteed
4428  * to be called with tline->type == TOK_ID, so the putative macro
4429  * name is easy to find.
4430  */
4431 static MMacro *is_mmacro(Token * tline, Token *** params_array)
4432 {
4433     MMacro *head, *m;
4434     Token **params;
4435     int nparam;
4436
4437     head = (MMacro *) hash_findix(&mmacros, tline->text);
4438
4439     /*
4440      * Efficiency: first we see if any macro exists with the given
4441      * name. If not, we can return NULL immediately. _Then_ we
4442      * count the parameters, and then we look further along the
4443      * list if necessary to find the proper MMacro.
4444      */
4445     list_for_each(m, head)
4446         if (!mstrcmp(m->name, tline->text, m->casesense))
4447             break;
4448     if (!m)
4449         return NULL;
4450
4451     /*
4452      * OK, we have a potential macro. Count and demarcate the
4453      * parameters.
4454      */
4455     count_mmac_params(tline->next, &nparam, &params);
4456
4457     /*
4458      * So we know how many parameters we've got. Find the MMacro
4459      * structure that handles this number.
4460      */
4461     while (m) {
4462         if (m->nparam_min <= nparam
4463             && (m->plus || nparam <= m->nparam_max)) {
4464             /*
4465              * This one is right. Just check if cycle removal
4466              * prohibits us using it before we actually celebrate...
4467              */
4468             if (m->in_progress > m->max_depth) {
4469                 if (m->max_depth > 0) {
4470                     error(ERR_WARNING,
4471                           "reached maximum recursion depth of %i",
4472                           m->max_depth);
4473                 }
4474                 nasm_free(params);
4475                 return NULL;
4476             }
4477             /*
4478              * It's right, and we can use it. Add its default
4479              * parameters to the end of our list if necessary.
4480              */
4481             if (m->defaults && nparam < m->nparam_min + m->ndefs) {
4482                 params =
4483                     nasm_realloc(params,
4484                                  ((m->nparam_min + m->ndefs +
4485                                    1) * sizeof(*params)));
4486                 while (nparam < m->nparam_min + m->ndefs) {
4487                     params[nparam] = m->defaults[nparam - m->nparam_min];
4488                     nparam++;
4489                 }
4490             }
4491             /*
4492              * If we've gone over the maximum parameter count (and
4493              * we're in Plus mode), ignore parameters beyond
4494              * nparam_max.
4495              */
4496             if (m->plus && nparam > m->nparam_max)
4497                 nparam = m->nparam_max;
4498             /*
4499              * Then terminate the parameter list, and leave.
4500              */
4501             if (!params) {      /* need this special case */
4502                 params = nasm_malloc(sizeof(*params));
4503                 nparam = 0;
4504             }
4505             params[nparam] = NULL;
4506             *params_array = params;
4507             return m;
4508         }
4509         /*
4510          * This one wasn't right: look for the next one with the
4511          * same name.
4512          */
4513         list_for_each(m, m->next)
4514             if (!mstrcmp(m->name, tline->text, m->casesense))
4515                 break;
4516     }
4517
4518     /*
4519      * After all that, we didn't find one with the right number of
4520      * parameters. Issue a warning, and fail to expand the macro.
4521      */
4522     error(ERR_WARNING|ERR_PASS1|ERR_WARN_MNP,
4523           "macro `%s' exists, but not taking %d parameters",
4524           tline->text, nparam);
4525     nasm_free(params);
4526     return NULL;
4527 }
4528
4529
4530 /*
4531  * Save MMacro invocation specific fields in
4532  * preparation for a recursive macro expansion
4533  */
4534 static void push_mmacro(MMacro *m)
4535 {
4536     MMacroInvocation *i;
4537
4538     i = nasm_malloc(sizeof(MMacroInvocation));
4539     i->prev = m->prev;
4540     i->params = m->params;
4541     i->iline = m->iline;
4542     i->nparam = m->nparam;
4543     i->rotate = m->rotate;
4544     i->paramlen = m->paramlen;
4545     i->unique = m->unique;
4546     i->condcnt = m->condcnt;
4547     m->prev = i;
4548 }
4549
4550
4551 /*
4552  * Restore MMacro invocation specific fields that were
4553  * saved during a previous recursive macro expansion
4554  */
4555 static void pop_mmacro(MMacro *m)
4556 {
4557     MMacroInvocation *i;
4558
4559     if (m->prev) {
4560         i = m->prev;
4561         m->prev = i->prev;
4562         m->params = i->params;
4563         m->iline = i->iline;
4564         m->nparam = i->nparam;
4565         m->rotate = i->rotate;
4566         m->paramlen = i->paramlen;
4567         m->unique = i->unique;
4568         m->condcnt = i->condcnt;
4569         nasm_free(i);
4570     }
4571 }
4572
4573
4574 /*
4575  * Expand the multi-line macro call made by the given line, if
4576  * there is one to be expanded. If there is, push the expansion on
4577  * istk->expansion and return 1. Otherwise return 0.
4578  */
4579 static int expand_mmacro(Token * tline)
4580 {
4581     Token *startline = tline;
4582     Token *label = NULL;
4583     int dont_prepend = 0;
4584     Token **params, *t, *tt;
4585     MMacro *m;
4586     Line *l, *ll;
4587     int i, nparam, *paramlen;
4588     const char *mname;
4589
4590     t = tline;
4591     skip_white_(t);
4592     /*    if (!tok_type_(t, TOK_ID))  Lino 02/25/02 */
4593     if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID))
4594         return 0;
4595     m = is_mmacro(t, &params);
4596     if (m) {
4597         mname = t->text;
4598     } else {
4599         Token *last;
4600         /*
4601          * We have an id which isn't a macro call. We'll assume
4602          * it might be a label; we'll also check to see if a
4603          * colon follows it. Then, if there's another id after
4604          * that lot, we'll check it again for macro-hood.
4605          */
4606         label = last = t;
4607         t = t->next;
4608         if (tok_type_(t, TOK_WHITESPACE))
4609             last = t, t = t->next;
4610         if (tok_is_(t, ":")) {
4611             dont_prepend = 1;
4612             last = t, t = t->next;
4613             if (tok_type_(t, TOK_WHITESPACE))
4614                 last = t, t = t->next;
4615         }
4616         if (!tok_type_(t, TOK_ID) || !(m = is_mmacro(t, &params)))
4617             return 0;
4618         last->next = NULL;
4619         mname = t->text;
4620         tline = t;
4621     }
4622
4623     /*
4624      * Fix up the parameters: this involves stripping leading and
4625      * trailing whitespace, then stripping braces if they are
4626      * present.
4627      */
4628     for (nparam = 0; params[nparam]; nparam++) ;
4629     paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
4630
4631     for (i = 0; params[i]; i++) {
4632         int brace = false;
4633         int comma = (!m->plus || i < nparam - 1);
4634
4635         t = params[i];
4636         skip_white_(t);
4637         if (tok_is_(t, "{"))
4638             t = t->next, brace = true, comma = false;
4639         params[i] = t;
4640         paramlen[i] = 0;
4641         while (t) {
4642             if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
4643                 break;          /* ... because we have hit a comma */
4644             if (comma && t->type == TOK_WHITESPACE
4645                 && tok_is_(t->next, ","))
4646                 break;          /* ... or a space then a comma */
4647             if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
4648                 break;          /* ... or a brace */
4649             t = t->next;
4650             paramlen[i]++;
4651         }
4652     }
4653
4654     /*
4655      * OK, we have a MMacro structure together with a set of
4656      * parameters. We must now go through the expansion and push
4657      * copies of each Line on to istk->expansion. Substitution of
4658      * parameter tokens and macro-local tokens doesn't get done
4659      * until the single-line macro substitution process; this is
4660      * because delaying them allows us to change the semantics
4661      * later through %rotate.
4662      *
4663      * First, push an end marker on to istk->expansion, mark this
4664      * macro as in progress, and set up its invocation-specific
4665      * variables.
4666      */
4667     ll = nasm_malloc(sizeof(Line));
4668     ll->next = istk->expansion;
4669     ll->finishes = m;
4670     ll->first = NULL;
4671     istk->expansion = ll;
4672
4673     /*
4674      * Save the previous MMacro expansion in the case of
4675      * macro recursion
4676      */
4677     if (m->max_depth && m->in_progress)
4678         push_mmacro(m);
4679
4680     m->in_progress ++;
4681     m->params = params;
4682     m->iline = tline;
4683     m->nparam = nparam;
4684     m->rotate = 0;
4685     m->paramlen = paramlen;
4686     m->unique = unique++;
4687     m->lineno = 0;
4688     m->condcnt = 0;
4689
4690     m->next_active = istk->mstk;
4691     istk->mstk = m;
4692
4693     list_for_each(l, m->expansion) {
4694         Token **tail;
4695
4696         ll = nasm_malloc(sizeof(Line));
4697         ll->finishes = NULL;
4698         ll->next = istk->expansion;
4699         istk->expansion = ll;
4700         tail = &ll->first;
4701
4702         list_for_each(t, l->first) {
4703             Token *x = t;
4704             switch (t->type) {
4705             case TOK_PREPROC_Q:
4706                 tt = *tail = new_Token(NULL, TOK_ID, mname, 0);
4707                 break;
4708             case TOK_PREPROC_QQ:
4709                 tt = *tail = new_Token(NULL, TOK_ID, m->name, 0);
4710                 break;
4711             case TOK_PREPROC_ID:
4712                 if (t->text[1] == '0' && t->text[2] == '0') {
4713                     dont_prepend = -1;
4714                     x = label;
4715                     if (!x)
4716                         continue;
4717                 }
4718                 /* fall through */
4719             default:
4720                 tt = *tail = new_Token(NULL, x->type, x->text, 0);
4721                 break;
4722             }
4723             tail = &tt->next;
4724         }
4725         *tail = NULL;
4726     }
4727
4728     /*
4729      * If we had a label, push it on as the first line of
4730      * the macro expansion.
4731      */
4732     if (label) {
4733         if (dont_prepend < 0)
4734             free_tlist(startline);
4735         else {
4736             ll = nasm_malloc(sizeof(Line));
4737             ll->finishes = NULL;
4738             ll->next = istk->expansion;
4739             istk->expansion = ll;
4740             ll->first = startline;
4741             if (!dont_prepend) {
4742                 while (label->next)
4743                     label = label->next;
4744                 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
4745             }
4746         }
4747     }
4748
4749     list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
4750
4751     return 1;
4752 }
4753
4754 /* The function that actually does the error reporting */
4755 static void verror(int severity, const char *fmt, va_list arg)
4756 {
4757     char buff[1024];
4758     MMacro *mmac = NULL;
4759     int delta = 0;
4760
4761     vsnprintf(buff, sizeof(buff), fmt, arg);
4762
4763     /* get %macro name */
4764     if (istk && istk->mstk) {
4765         mmac = istk->mstk;
4766         /* but %rep blocks should be skipped */
4767         while (mmac && !mmac->name)
4768             mmac = mmac->next_active, delta++;
4769     }
4770
4771     if (mmac)
4772         nasm_error(severity, "(%s:%d) %s",
4773                    mmac->name, mmac->lineno - delta, buff);
4774     else
4775         nasm_error(severity, "%s", buff);
4776 }
4777
4778 /*
4779  * Since preprocessor always operate only on the line that didn't
4780  * arrived yet, we should always use ERR_OFFBY1.
4781  */
4782 static void error(int severity, const char *fmt, ...)
4783 {
4784     va_list arg;
4785
4786     /* If we're in a dead branch of IF or something like it, ignore the error */
4787     if (istk && istk->conds && !emitting(istk->conds->state))
4788         return;
4789
4790     va_start(arg, fmt);
4791     verror(severity, fmt, arg);
4792     va_end(arg);
4793 }
4794
4795 /*
4796  * Because %else etc are evaluated in the state context
4797  * of the previous branch, errors might get lost with error():
4798  *   %if 0 ... %else trailing garbage ... %endif
4799  * So %else etc should report errors with this function.
4800  */
4801 static void error_precond(int severity, const char *fmt, ...)
4802 {
4803     va_list arg;
4804
4805     /* Only ignore the error if it's really in a dead branch */
4806     if (istk && istk->conds && istk->conds->state == COND_NEVER)
4807         return;
4808
4809     va_start(arg, fmt);
4810     verror(severity, fmt, arg);
4811     va_end(arg);
4812 }
4813
4814 static void
4815 pp_reset(char *file, int apass, ListGen * listgen, StrList **deplist)
4816 {
4817     Token *t;
4818
4819     cstk = NULL;
4820     istk = nasm_malloc(sizeof(Include));
4821     istk->next = NULL;
4822     istk->conds = NULL;
4823     istk->expansion = NULL;
4824     istk->mstk = NULL;
4825     istk->fp = fopen(file, "r");
4826     istk->fname = NULL;
4827     src_set_fname(nasm_strdup(file));
4828     src_set_linnum(0);
4829     istk->lineinc = 1;
4830     if (!istk->fp)
4831         error(ERR_FATAL|ERR_NOFILE, "unable to open input file `%s'",
4832               file);
4833     defining = NULL;
4834     nested_mac_count = 0;
4835     nested_rep_count = 0;
4836     init_macros();
4837     unique = 0;
4838     if (tasm_compatible_mode) {
4839         stdmacpos = nasm_stdmac;
4840     } else {
4841         stdmacpos = nasm_stdmac_after_tasm;
4842     }
4843     any_extrastdmac = extrastdmac && *extrastdmac;
4844     do_predef = true;
4845     list = listgen;
4846
4847     /*
4848      * 0 for dependencies, 1 for preparatory passes, 2 for final pass.
4849      * The caller, however, will also pass in 3 for preprocess-only so
4850      * we can set __PASS__ accordingly.
4851      */
4852     pass = apass > 2 ? 2 : apass;
4853
4854     dephead = deptail = deplist;
4855     if (deplist) {
4856         StrList *sl = nasm_malloc(strlen(file)+1+sizeof sl->next);
4857         sl->next = NULL;
4858         strcpy(sl->str, file);
4859         *deptail = sl;
4860         deptail = &sl->next;
4861     }
4862
4863     /*
4864      * Define the __PASS__ macro.  This is defined here unlike
4865      * all the other builtins, because it is special -- it varies between
4866      * passes.
4867      */
4868     t = nasm_malloc(sizeof(*t));
4869     t->next = NULL;
4870     make_tok_num(t, apass);
4871     t->a.mac = NULL;
4872     define_smacro(NULL, "__PASS__", true, 0, t);
4873 }
4874
4875 static char *pp_getline(void)
4876 {
4877     char *line;
4878     Token *tline;
4879
4880     while (1) {
4881         /*
4882          * Fetch a tokenized line, either from the macro-expansion
4883          * buffer or from the input file.
4884          */
4885         tline = NULL;
4886         while (istk->expansion && istk->expansion->finishes) {
4887             Line *l = istk->expansion;
4888             if (!l->finishes->name && l->finishes->in_progress > 1) {
4889                 Line *ll;
4890
4891                 /*
4892                  * This is a macro-end marker for a macro with no
4893                  * name, which means it's not really a macro at all
4894                  * but a %rep block, and the `in_progress' field is
4895                  * more than 1, meaning that we still need to
4896                  * repeat. (1 means the natural last repetition; 0
4897                  * means termination by %exitrep.) We have
4898                  * therefore expanded up to the %endrep, and must
4899                  * push the whole block on to the expansion buffer
4900                  * again. We don't bother to remove the macro-end
4901                  * marker: we'd only have to generate another one
4902                  * if we did.
4903                  */
4904                 l->finishes->in_progress--;
4905                 list_for_each(l, l->finishes->expansion) {
4906                     Token *t, *tt, **tail;
4907
4908                     ll = nasm_malloc(sizeof(Line));
4909                     ll->next = istk->expansion;
4910                     ll->finishes = NULL;
4911                     ll->first = NULL;
4912                     tail = &ll->first;
4913
4914                     list_for_each(t, l->first) {
4915                         if (t->text || t->type == TOK_WHITESPACE) {
4916                             tt = *tail = new_Token(NULL, t->type, t->text, 0);
4917                             tail = &tt->next;
4918                         }
4919                     }
4920
4921                     istk->expansion = ll;
4922                 }
4923             } else {
4924                 /*
4925                  * Check whether a `%rep' was started and not ended
4926                  * within this macro expansion. This can happen and
4927                  * should be detected. It's a fatal error because
4928                  * I'm too confused to work out how to recover
4929                  * sensibly from it.
4930                  */
4931                 if (defining) {
4932                     if (defining->name)
4933                         error(ERR_PANIC,
4934                               "defining with name in expansion");
4935                     else if (istk->mstk->name)
4936                         error(ERR_FATAL,
4937                               "`%%rep' without `%%endrep' within"
4938                               " expansion of macro `%s'",
4939                               istk->mstk->name);
4940                 }
4941
4942                 /*
4943                  * FIXME:  investigate the relationship at this point between
4944                  * istk->mstk and l->finishes
4945                  */
4946                 {
4947                     MMacro *m = istk->mstk;
4948                     istk->mstk = m->next_active;
4949                     if (m->name) {
4950                         /*
4951                          * This was a real macro call, not a %rep, and
4952                          * therefore the parameter information needs to
4953                          * be freed.
4954                          */
4955                         if (m->prev) {
4956                             pop_mmacro(m);
4957                             l->finishes->in_progress --;
4958                         } else {
4959                             nasm_free(m->params);
4960                             free_tlist(m->iline);
4961                             nasm_free(m->paramlen);
4962                             l->finishes->in_progress = 0;
4963                         }
4964                     } else
4965                         free_mmacro(m);
4966                 }
4967                 istk->expansion = l->next;
4968                 nasm_free(l);
4969                 list->downlevel(LIST_MACRO);
4970             }
4971         }
4972         while (1) {             /* until we get a line we can use */
4973
4974             if (istk->expansion) {      /* from a macro expansion */
4975                 char *p;
4976                 Line *l = istk->expansion;
4977                 if (istk->mstk)
4978                     istk->mstk->lineno++;
4979                 tline = l->first;
4980                 istk->expansion = l->next;
4981                 nasm_free(l);
4982                 p = detoken(tline, false);
4983                 list->line(LIST_MACRO, p);
4984                 nasm_free(p);
4985                 break;
4986             }
4987             line = read_line();
4988             if (line) {         /* from the current input file */
4989                 line = prepreproc(line);
4990                 tline = tokenize(line);
4991                 nasm_free(line);
4992                 break;
4993             }
4994             /*
4995              * The current file has ended; work down the istk
4996              */
4997             {
4998                 Include *i = istk;
4999                 fclose(i->fp);
5000                 if (i->conds) {
5001                     /* nasm_error can't be conditionally suppressed */
5002                     nasm_error(ERR_FATAL,
5003                                "expected `%%endif' before end of file");
5004                 }
5005                 /* only set line and file name if there's a next node */
5006                 if (i->next) {
5007                     src_set_linnum(i->lineno);
5008                     nasm_free(src_set_fname(nasm_strdup(i->fname)));
5009                 }
5010                 istk = i->next;
5011                 list->downlevel(LIST_INCLUDE);
5012                 nasm_free(i);
5013                 if (!istk)
5014                     return NULL;
5015                 if (istk->expansion && istk->expansion->finishes)
5016                     break;
5017             }
5018         }
5019
5020         /*
5021          * We must expand MMacro parameters and MMacro-local labels
5022          * _before_ we plunge into directive processing, to cope
5023          * with things like `%define something %1' such as STRUC
5024          * uses. Unless we're _defining_ a MMacro, in which case
5025          * those tokens should be left alone to go into the
5026          * definition; and unless we're in a non-emitting
5027          * condition, in which case we don't want to meddle with
5028          * anything.
5029          */
5030         if (!defining && !(istk->conds && !emitting(istk->conds->state))
5031             && !(istk->mstk && !istk->mstk->in_progress)) {
5032             tline = expand_mmac_params(tline);
5033         }
5034
5035         /*
5036          * Check the line to see if it's a preprocessor directive.
5037          */
5038         if (do_directive(tline) == DIRECTIVE_FOUND) {
5039             continue;
5040         } else if (defining) {
5041             /*
5042              * We're defining a multi-line macro. We emit nothing
5043              * at all, and just
5044              * shove the tokenized line on to the macro definition.
5045              */
5046             Line *l = nasm_malloc(sizeof(Line));
5047             l->next = defining->expansion;
5048             l->first = tline;
5049             l->finishes = NULL;
5050             defining->expansion = l;
5051             continue;
5052         } else if (istk->conds && !emitting(istk->conds->state)) {
5053             /*
5054              * We're in a non-emitting branch of a condition block.
5055              * Emit nothing at all, not even a blank line: when we
5056              * emerge from the condition we'll give a line-number
5057              * directive so we keep our place correctly.
5058              */
5059             free_tlist(tline);
5060             continue;
5061         } else if (istk->mstk && !istk->mstk->in_progress) {
5062             /*
5063              * We're in a %rep block which has been terminated, so
5064              * we're walking through to the %endrep without
5065              * emitting anything. Emit nothing at all, not even a
5066              * blank line: when we emerge from the %rep block we'll
5067              * give a line-number directive so we keep our place
5068              * correctly.
5069              */
5070             free_tlist(tline);
5071             continue;
5072         } else {
5073             tline = expand_smacro(tline);
5074             if (!expand_mmacro(tline)) {
5075                 /*
5076                  * De-tokenize the line again, and emit it.
5077                  */
5078                 line = detoken(tline, true);
5079                 free_tlist(tline);
5080                 break;
5081             } else {
5082                 continue;       /* expand_mmacro calls free_tlist */
5083             }
5084         }
5085     }
5086
5087     return line;
5088 }
5089
5090 static void pp_cleanup(int pass)
5091 {
5092     if (defining) {
5093         if (defining->name) {
5094             error(ERR_NONFATAL,
5095                   "end of file while still defining macro `%s'",
5096                   defining->name);
5097         } else {
5098             error(ERR_NONFATAL, "end of file while still in %%rep");
5099         }
5100
5101         free_mmacro(defining);
5102         defining = NULL;
5103     }
5104     while (cstk)
5105         ctx_pop();
5106     free_macros();
5107     while (istk) {
5108         Include *i = istk;
5109         istk = istk->next;
5110         fclose(i->fp);
5111         nasm_free(i->fname);
5112         nasm_free(i);
5113     }
5114     while (cstk)
5115         ctx_pop();
5116     nasm_free(src_set_fname(NULL));
5117     if (pass == 0) {
5118         IncPath *i;
5119         free_llist(predef);
5120         delete_Blocks();
5121         while ((i = ipath)) {
5122             ipath = i->next;
5123             if (i->path)
5124                 nasm_free(i->path);
5125             nasm_free(i);
5126         }
5127     }
5128 }
5129
5130 static void pp_include_path(char *path)
5131 {
5132     IncPath *i;
5133
5134     i = nasm_malloc(sizeof(IncPath));
5135     i->path = path ? nasm_strdup(path) : NULL;
5136     i->next = NULL;
5137
5138     if (ipath) {
5139         IncPath *j = ipath;
5140         while (j->next)
5141             j = j->next;
5142         j->next = i;
5143     } else {
5144         ipath = i;
5145     }
5146 }
5147
5148 static void pp_pre_include(char *fname)
5149 {
5150     Token *inc, *space, *name;
5151     Line *l;
5152
5153     name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
5154     space = new_Token(name, TOK_WHITESPACE, NULL, 0);
5155     inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
5156
5157     l = nasm_malloc(sizeof(Line));
5158     l->next = predef;
5159     l->first = inc;
5160     l->finishes = NULL;
5161     predef = l;
5162 }
5163
5164 static void pp_pre_define(char *definition)
5165 {
5166     Token *def, *space;
5167     Line *l;
5168     char *equals;
5169
5170     equals = strchr(definition, '=');
5171     space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
5172     def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
5173     if (equals)
5174         *equals = ' ';
5175     space->next = tokenize(definition);
5176     if (equals)
5177         *equals = '=';
5178
5179     l = nasm_malloc(sizeof(Line));
5180     l->next = predef;
5181     l->first = def;
5182     l->finishes = NULL;
5183     predef = l;
5184 }
5185
5186 static void pp_pre_undefine(char *definition)
5187 {
5188     Token *def, *space;
5189     Line *l;
5190
5191     space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
5192     def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
5193     space->next = tokenize(definition);
5194
5195     l = nasm_malloc(sizeof(Line));
5196     l->next = predef;
5197     l->first = def;
5198     l->finishes = NULL;
5199     predef = l;
5200 }
5201
5202 static void pp_extra_stdmac(macros_t *macros)
5203 {
5204     extrastdmac = macros;
5205 }
5206
5207 static void make_tok_num(Token * tok, int64_t val)
5208 {
5209     char numbuf[32];
5210     snprintf(numbuf, sizeof(numbuf), "%"PRId64"", val);
5211     tok->text = nasm_strdup(numbuf);
5212     tok->type = TOK_NUMBER;
5213 }
5214
5215 struct preproc_ops nasmpp = {
5216     pp_reset,
5217     pp_getline,
5218     pp_cleanup,
5219     pp_extra_stdmac,
5220     pp_pre_define,
5221     pp_pre_undefine,
5222     pp_pre_include,
5223     pp_include_path
5224 };