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