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