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