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