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