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