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