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