Create dummy file to test nasm-cvs list
[platform/upstream/nasm.git] / preproc.c
1 /* preproc.c   macro preprocessor for the Netwide Assembler
2  *
3  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4  * Julian Hall. All rights reserved. The software is
5  * redistributable under the licence given in the file "Licence"
6  * distributed in the NASM archive.
7  *
8  * initial version 18/iii/97 by Simon Tatham
9  */
10
11 /* Typical flow of text through preproc
12  *
13  * pp_getline gets tokenised lines, either
14  *
15  *   from a macro expansion
16  *
17  * or
18  *   {
19  *   read_line  gets raw text from stdmacpos, or predef, or current input file
20  *   tokenise   converts to tokens
21  *   }
22  *
23  * expand_mmac_params is used to expand %1 etc., unless a macro is being
24  * defined or a false conditional is being processed
25  * (%0, %1, %+1, %-1, %%foo
26  *
27  * do_directive checks for directives
28  *
29  * expand_smacro is used to expand single line macros
30  *
31  * expand_mmacro is used to expand multi-line macros
32  *
33  * detoken is used to convert the line back to text
34  */
35
36 #include <stdio.h>
37 #include <stdarg.h>
38 #include <stdlib.h>
39 #include <stddef.h>
40 #include <string.h>
41 #include <ctype.h>
42 #include <limits.h>
43
44 #include "nasm.h"
45 #include "nasmlib.h"
46
47 typedef struct SMacro SMacro;
48 typedef struct MMacro MMacro;
49 typedef struct Context Context;
50 typedef struct Token Token;
51 typedef struct Blocks Blocks;
52 typedef struct Line Line;
53 typedef struct Include Include;
54 typedef struct Cond Cond;
55 typedef struct IncPath IncPath;
56
57 /*
58  * Store the definition of a single-line macro.
59  */
60 struct SMacro
61 {
62     SMacro *next;
63     char *name;
64     int casesense;
65     int nparam;
66     int in_progress;
67     Token *expansion;
68 };
69
70 /*
71  * Store the definition of a multi-line macro. This is also used to
72  * store the interiors of `%rep...%endrep' blocks, which are
73  * effectively self-re-invoking multi-line macros which simply
74  * don't have a name or bother to appear in the hash tables. %rep
75  * blocks are signified by having a NULL `name' field.
76  *
77  * In a MMacro describing a `%rep' block, the `in_progress' field
78  * isn't merely boolean, but gives the number of repeats left to
79  * run.
80  *
81  * The `next' field is used for storing MMacros in hash tables; the
82  * `next_active' field is for stacking them on istk entries.
83  *
84  * When a MMacro is being expanded, `params', `iline', `nparam',
85  * `paramlen', `rotate' and `unique' are local to the invocation.
86  */
87 struct MMacro
88 {
89     MMacro *next;
90     char *name;
91     int casesense;
92     int nparam_min, nparam_max;
93     int plus;                   /* is the last parameter greedy? */
94     int nolist;                 /* is this macro listing-inhibited? */
95     int in_progress;
96     Token *dlist;               /* All defaults as one list */
97     Token **defaults;           /* Parameter default pointers */
98     int ndefs;                  /* number of default parameters */
99     Line *expansion;
100
101     MMacro *next_active;
102     MMacro *rep_nest;           /* used for nesting %rep */
103     Token **params;             /* actual parameters */
104     Token *iline;               /* invocation line */
105     int nparam, rotate, *paramlen;
106     unsigned long unique;
107     int lineno;                 /* Current line number on expansion */
108 };
109
110 /*
111  * The context stack is composed of a linked list of these.
112  */
113 struct Context
114 {
115     Context *next;
116     SMacro *localmac;
117     char *name;
118     unsigned long number;
119 };
120
121 /*
122  * This is the internal form which we break input lines up into.
123  * Typically stored in linked lists.
124  *
125  * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
126  * necessarily used as-is, but is intended to denote the number of
127  * the substituted parameter. So in the definition
128  *
129  *     %define a(x,y) ( (x) & ~(y) )
130  * 
131  * the token representing `x' will have its type changed to
132  * TOK_SMAC_PARAM, but the one representing `y' will be
133  * TOK_SMAC_PARAM+1.
134  *
135  * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
136  * which doesn't need quotes around it. Used in the pre-include
137  * mechanism as an alternative to trying to find a sensible type of
138  * quote to use on the filename we were passed.
139  */
140 struct Token
141 {
142     Token *next;
143     char *text;
144     SMacro *mac;                /* associated macro for TOK_SMAC_END */
145     int type;
146 };
147 enum
148 {
149     TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING,
150     TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM,
151     TOK_INTERNAL_STRING
152 };
153
154 /*
155  * Multi-line macro definitions are stored as a linked list of
156  * these, which is essentially a container to allow several linked
157  * lists of Tokens.
158  * 
159  * Note that in this module, linked lists are treated as stacks
160  * wherever possible. For this reason, Lines are _pushed_ on to the
161  * `expansion' field in MMacro structures, so that the linked list,
162  * if walked, would give the macro lines in reverse order; this
163  * means that we can walk the list when expanding a macro, and thus
164  * push the lines on to the `expansion' field in _istk_ in reverse
165  * order (so that when popped back off they are in the right
166  * order). It may seem cockeyed, and it relies on my design having
167  * an even number of steps in, but it works...
168  *
169  * Some of these structures, rather than being actual lines, are
170  * markers delimiting the end of the expansion of a given macro.
171  * This is for use in the cycle-tracking and %rep-handling code.
172  * Such structures have `finishes' non-NULL, and `first' NULL. All
173  * others have `finishes' NULL, but `first' may still be NULL if
174  * the line is blank.
175  */
176 struct Line
177 {
178     Line *next;
179     MMacro *finishes;
180     Token *first;
181 };
182
183 /*
184  * To handle an arbitrary level of file inclusion, we maintain a
185  * stack (ie linked list) of these things.
186  */
187 struct Include
188 {
189     Include *next;
190     FILE *fp;
191     Cond *conds;
192     Line *expansion;
193     char *fname;
194     int lineno, lineinc;
195     MMacro *mstk;               /* stack of active macros/reps */
196 };
197
198 /*
199  * Include search path. This is simply a list of strings which get
200  * prepended, in turn, to the name of an include file, in an
201  * attempt to find the file if it's not in the current directory.
202  */
203 struct IncPath
204 {
205     IncPath *next;
206     char *path;
207 };
208
209 /*
210  * Conditional assembly: we maintain a separate stack of these for
211  * each level of file inclusion. (The only reason we keep the
212  * stacks separate is to ensure that a stray `%endif' in a file
213  * included from within the true branch of a `%if' won't terminate
214  * it and cause confusion: instead, rightly, it'll cause an error.)
215  */
216 struct Cond
217 {
218     Cond *next;
219     int state;
220 };
221 enum
222 {
223     /*
224      * These states are for use just after %if or %elif: IF_TRUE
225      * means the condition has evaluated to truth so we are
226      * currently emitting, whereas IF_FALSE means we are not
227      * currently emitting but will start doing so if a %else comes
228      * up. In these states, all directives are admissible: %elif,
229      * %else and %endif. (And of course %if.)
230      */
231     COND_IF_TRUE, COND_IF_FALSE,
232     /*
233      * These states come up after a %else: ELSE_TRUE means we're
234      * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
235      * any %elif or %else will cause an error.
236      */
237     COND_ELSE_TRUE, COND_ELSE_FALSE,
238     /*
239      * This state means that we're not emitting now, and also that
240      * nothing until %endif will be emitted at all. It's for use in
241      * two circumstances: (i) when we've had our moment of emission
242      * and have now started seeing %elifs, and (ii) when the
243      * condition construct in question is contained within a
244      * non-emitting branch of a larger condition construct.
245      */
246     COND_NEVER
247 };
248 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
249
250 /*
251  * Condition codes. Note that we use c_ prefix not C_ because C_ is
252  * used in nasm.h for the "real" condition codes. At _this_ level,
253  * we treat CXZ and ECXZ as condition codes, albeit non-invertible
254  * ones, so we need a different enum...
255  */
256 static char *conditions[] = {
257     "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
258     "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
259     "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
260 };
261 enum
262 {
263     c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE,
264     c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO,
265     c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_S, c_Z
266 };
267 static int inverse_ccs[] = {
268     c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE,
269     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,
270     c_Z, c_NO, c_NP, c_PO, c_PE, c_NS, c_NZ
271 };
272
273 /*
274  * Directive names.
275  */
276 static char *directives[] = {
277     "%arg",
278     "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
279     "%elifid", "%elifidn", "%elifidni", "%elifnctx", "%elifndef",
280     "%elifnid", "%elifnidn", "%elifnidni", "%elifnnum", "%elifnstr",
281     "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
282     "%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
283     "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifnctx",
284     "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnnum",
285     "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
286     "%ixdefine", "%line",
287     "%local",
288     "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
289     "%stacksize",
290     "%strlen", "%substr", "%undef", "%xdefine"
291 };
292 enum
293 {
294     PP_ARG,
295     PP_ASSIGN, PP_CLEAR, PP_DEFINE, PP_ELIF, PP_ELIFCTX, PP_ELIFDEF,
296     PP_ELIFID, PP_ELIFIDN, PP_ELIFIDNI, PP_ELIFNCTX, PP_ELIFNDEF,
297     PP_ELIFNID, PP_ELIFNIDN, PP_ELIFNIDNI, PP_ELIFNNUM, PP_ELIFNSTR,
298     PP_ELIFNUM, PP_ELIFSTR, PP_ELSE, PP_ENDIF, PP_ENDM, PP_ENDMACRO,
299     PP_ENDREP, PP_ERROR, PP_EXITREP, PP_IASSIGN, PP_IDEFINE, PP_IF,
300     PP_IFCTX, PP_IFDEF, PP_IFID, PP_IFIDN, PP_IFIDNI, PP_IFNCTX,
301     PP_IFNDEF, PP_IFNID, PP_IFNIDN, PP_IFNIDNI, PP_IFNNUM,
302     PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE,
303     PP_IXDEFINE, PP_LINE,
304     PP_LOCAL,
305     PP_MACRO, PP_POP, PP_PUSH, PP_REP, PP_REPL, PP_ROTATE,
306     PP_STACKSIZE,
307     PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
308 };
309
310
311 /* For TASM compatibility we need to be able to recognise TASM compatible
312  * conditional compilation directives. Using the NASM pre-processor does
313  * not work, so we look for them specifically from the following list and
314  * then jam in the equivalent NASM directive into the input stream.
315  */
316
317 #ifndef MAX
318 #       define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
319 #endif
320
321 enum
322 {
323     TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
324     TM_IFNDEF, TM_INCLUDE, TM_LOCAL
325 };
326
327 static char *tasm_directives[] = {
328     "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
329     "ifndef", "include", "local"
330 };
331
332 static int StackSize = 4;
333 static char *StackPointer = "ebp";
334 static int ArgOffset = 8;
335 static int LocalOffset = 4;
336
337
338 static Context *cstk;
339 static Include *istk;
340 static IncPath *ipath = NULL;
341
342 static efunc __error;           /* Pointer to client-provided error reporting function */
343 static evalfunc evaluate;
344
345 static int pass;                /* HACK: pass 0 = generate dependencies only */
346
347 static unsigned long unique;    /* unique identifier numbers */
348
349 static Line *predef = NULL;
350
351 static ListGen *list;
352
353 /*
354  * The number of hash values we use for the macro lookup tables.
355  * FIXME: We should *really* be able to configure this at run time,
356  * or even have the hash table automatically expanding when necessary.
357  */
358 #define NHASH 31
359
360 /*
361  * The current set of multi-line macros we have defined.
362  */
363 static MMacro *mmacros[NHASH];
364
365 /*
366  * The current set of single-line macros we have defined.
367  */
368 static SMacro *smacros[NHASH];
369
370 /*
371  * The multi-line macro we are currently defining, or the %rep
372  * block we are currently reading, if any.
373  */
374 static MMacro *defining;
375
376 /*
377  * The number of macro parameters to allocate space for at a time.
378  */
379 #define PARAM_DELTA 16
380
381 /*
382  * The standard macro set: defined as `static char *stdmac[]'. Also
383  * gives our position in the macro set, when we're processing it.
384  */
385 #include "macros.c"
386 static char **stdmacpos;
387
388 /*
389  * The extra standard macros that come from the object format, if
390  * any.
391  */
392 static char **extrastdmac = NULL;
393 int any_extrastdmac;
394
395 /*
396  * Tokens are allocated in blocks to improve speed
397  */
398 #define TOKEN_BLOCKSIZE 4096
399 static Token *freeTokens = NULL;
400 struct Blocks {
401         Blocks *next;
402         void *chunk;
403 };
404
405 static Blocks blocks = { NULL, NULL };
406
407 /*
408  * Forward declarations.
409  */
410 static Token *expand_mmac_params(Token * tline);
411 static Token *expand_smacro(Token * tline);
412 static Token *expand_id(Token * tline);
413 static Context *get_ctx(char *name, int all_contexts);
414 static void make_tok_num(Token * tok, long val);
415 static void error(int severity, char *fmt, ...);
416 static void *new_Block(size_t size);
417 static void delete_Blocks(void);
418 static Token *new_Token(Token * next, int type, char *text, int txtlen);
419 static Token *delete_Token(Token * t);
420
421 /*
422  * Macros for safe checking of token pointers, avoid *(NULL)
423  */
424 #define tok_type_(x,t) ((x) && (x)->type == (t))
425 #define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
426 #define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
427 #define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
428
429 /* Handle TASM specific directives, which do not contain a % in
430  * front of them. We do it here because I could not find any other
431  * place to do it for the moment, and it is a hack (ideally it would
432  * be nice to be able to use the NASM pre-processor to do it).
433  */
434 static char *
435 check_tasm_directive(char *line)
436 {
437     int i, j, k, m, len;
438     char *p = line, *oldline, oldchar;
439
440     /* Skip whitespace */
441     while (isspace(*p) && *p != 0)
442         p++;
443
444     /* Binary search for the directive name */
445     i = -1;
446     j = sizeof(tasm_directives) / sizeof(*tasm_directives);
447     len = 0;
448     while (!isspace(p[len]) && p[len] != 0)
449         len++;
450     if (len)
451     {
452         oldchar = p[len];
453         p[len] = 0;
454         while (j - i > 1)
455         {
456             k = (j + i) / 2;
457             m = nasm_stricmp(p, tasm_directives[k]);
458             if (m == 0)
459             {
460                 /* We have found a directive, so jam a % in front of it
461                  * so that NASM will then recognise it as one if it's own.
462                  */
463                 p[len] = oldchar;
464                 len = strlen(p);
465                 oldline = line;
466                 line = nasm_malloc(len + 2);
467                 line[0] = '%';
468                 if (k == TM_IFDIFI)
469                 {
470                     /* NASM does not recognise IFDIFI, so we convert it to
471                      * %ifdef BOGUS. This is not used in NASM comaptible
472                      * code, but does need to parse for the TASM macro
473                      * package.
474                      */
475                     strcpy(line + 1, "ifdef BOGUS");
476                 }
477                 else
478                 {
479                     memcpy(line + 1, p, len + 1);
480                 }
481                 nasm_free(oldline);
482                 return line;
483             }
484             else if (m < 0)
485             {
486                 j = k;
487             }
488             else
489                 i = k;
490         }
491         p[len] = oldchar;
492     }
493     return line;
494 }
495
496 /*
497  * The pre-preprocessing stage... This function translates line
498  * number indications as they emerge from GNU cpp (`# lineno "file"
499  * flags') into NASM preprocessor line number indications (`%line
500  * lineno file').
501  */
502 static char *
503 prepreproc(char *line)
504 {
505     int lineno, fnlen;
506     char *fname, *oldline;
507
508     if (line[0] == '#' && line[1] == ' ')
509     {
510         oldline = line;
511         fname = oldline + 2;
512         lineno = atoi(fname);
513         fname += strspn(fname, "0123456789 ");
514         if (*fname == '"')
515             fname++;
516         fnlen = strcspn(fname, "\"");
517         line = nasm_malloc(20 + fnlen);
518         sprintf(line, "%%line %d %.*s", lineno, fnlen, fname);
519         nasm_free(oldline);
520     }
521     if (tasm_compatible_mode)
522         return check_tasm_directive(line);
523     return line;
524 }
525
526 /*
527  * The hash function for macro lookups. Note that due to some
528  * macros having case-insensitive names, the hash function must be
529  * invariant under case changes. We implement this by applying a
530  * perfectly normal hash function to the uppercase of the string.
531  */
532 static int
533 hash(char *s)
534 {
535     unsigned int h = 0;
536     int i = 0;
537     /*
538      * Powers of three, mod 31.
539      */
540     static const int multipliers[] = {
541         1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
542         30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
543     };
544
545
546     while (*s)
547     {
548         h += multipliers[i] * (unsigned char) (toupper(*s));
549         s++;
550         if (++i >= sizeof(multipliers) / sizeof(*multipliers))
551             i = 0;
552     }
553     h %= NHASH;
554     return h;
555 }
556
557 /*
558  * Free a linked list of tokens.
559  */
560 static void
561 free_tlist(Token * list)
562 {
563     while (list)
564     {
565         list = delete_Token(list);
566     }
567 }
568
569 /*
570  * Free a linked list of lines.
571  */
572 static void
573 free_llist(Line * list)
574 {
575     Line *l;
576     while (list)
577     {
578         l = list;
579         list = list->next;
580         free_tlist(l->first);
581         nasm_free(l);
582     }
583 }
584
585 /*
586  * Free an MMacro
587  */
588 static void
589 free_mmacro(MMacro * m)
590 {
591     nasm_free(m->name);
592     free_tlist(m->dlist);
593     nasm_free(m->defaults);
594     free_llist(m->expansion);
595     nasm_free(m);
596 }
597
598 /*
599  * Pop the context stack.
600  */
601 static void
602 ctx_pop(void)
603 {
604     Context *c = cstk;
605     SMacro *smac, *s;
606
607     cstk = cstk->next;
608     smac = c->localmac;
609     while (smac)
610     {
611         s = smac;
612         smac = smac->next;
613         nasm_free(s->name);
614         free_tlist(s->expansion);
615         nasm_free(s);
616     }
617     nasm_free(c->name);
618     nasm_free(c);
619 }
620
621 #define BUF_DELTA 512
622 /*
623  * Read a line from the top file in istk, handling multiple CR/LFs
624  * at the end of the line read, and handling spurious ^Zs. Will
625  * return lines from the standard macro set if this has not already
626  * been done.
627  */
628 static char *
629 read_line(void)
630 {
631     char *buffer, *p, *q;
632     int bufsize, continued_count;
633
634     if (stdmacpos)
635     {
636         if (*stdmacpos)
637         {
638             char *ret = nasm_strdup(*stdmacpos++);
639             if (!*stdmacpos && any_extrastdmac)
640             {
641                 stdmacpos = extrastdmac;
642                 any_extrastdmac = FALSE;
643                 return ret;
644             }
645             /*
646              * Nasty hack: here we push the contents of `predef' on
647              * to the top-level expansion stack, since this is the
648              * most convenient way to implement the pre-include and
649              * pre-define features.
650              */
651             if (!*stdmacpos)
652             {
653                 Line *pd, *l;
654                 Token *head, **tail, *t;
655
656                 for (pd = predef; pd; pd = pd->next)
657                 {
658                     head = NULL;
659                     tail = &head;
660                     for (t = pd->first; t; t = t->next)
661                     {
662                         *tail = new_Token(NULL, t->type, t->text, 0);
663                         tail = &(*tail)->next;
664                     }
665                     l = nasm_malloc(sizeof(Line));
666                     l->next = istk->expansion;
667                     l->first = head;
668                     l->finishes = FALSE;
669                     istk->expansion = l;
670                 }
671             }
672             return ret;
673         }
674         else
675         {
676             stdmacpos = NULL;
677         }
678     }
679
680     bufsize = BUF_DELTA;
681     buffer = nasm_malloc(BUF_DELTA);
682     p = buffer;
683     continued_count = 0;
684     while (1)
685     {
686         q = fgets(p, bufsize - (p - buffer), istk->fp);
687         if (!q)
688             break;
689         p += strlen(p);
690         if (p > buffer && p[-1] == '\n')
691         {
692            /* Convert backslash-CRLF line continuation sequences into
693               nothing at all (for DOS and Windows) */
694            if (((p - 2) > buffer) && (p[-3] == '\\') && (p[-2] == '\r')) {
695                p -= 3;
696                *p = 0;
697                continued_count++;
698            }
699            /* Also convert backslash-LF line continuation sequences into
700               nothing at all (for Unix) */
701            else if (((p - 1) > buffer) && (p[-2] == '\\')) {
702                p -= 2;
703                *p = 0;
704                continued_count++;
705            }
706            else {
707                break;
708            }
709         }
710         if (p - buffer > bufsize - 10)
711         {
712             long offset = p - buffer;
713             bufsize += BUF_DELTA;
714             buffer = nasm_realloc(buffer, bufsize);
715             p = buffer + offset;        /* prevent stale-pointer problems */
716         }
717     }
718
719     if (!q && p == buffer)
720     {
721         nasm_free(buffer);
722         return NULL;
723     }
724
725     src_set_linnum(src_get_linnum() + istk->lineinc + (continued_count * istk->lineinc));
726
727     /*
728      * Play safe: remove CRs as well as LFs, if any of either are
729      * present at the end of the line.
730      */
731     while (--p >= buffer && (*p == '\n' || *p == '\r'))
732         *p = '\0';
733
734     /*
735      * Handle spurious ^Z, which may be inserted into source files
736      * by some file transfer utilities.
737      */
738     buffer[strcspn(buffer, "\032")] = '\0';
739
740     list->line(LIST_READ, buffer);
741
742     return buffer;
743 }
744
745 /*
746  * Tokenise a line of text. This is a very simple process since we
747  * don't need to parse the value out of e.g. numeric tokens: we
748  * simply split one string into many.
749  */
750 static Token *
751 tokenise(char *line)
752 {
753     char *p = line;
754     int type;
755     Token *list = NULL;
756     Token *t, **tail = &list;
757
758     while (*line)
759     {
760         p = line;
761         if (*p == '%')
762         {
763                 p++;
764                 if ( isdigit(*p) ||
765                         ((*p == '-' || *p == '+') && isdigit(p[1])) ||
766                         ((*p == '+') && (isspace(p[1]) || !p[1])))
767                                 {
768                         do
769                         {
770                         p++;
771                         }
772                         while (isdigit(*p));
773                         type = TOK_PREPROC_ID;
774                 }
775                 else if (*p == '{')
776                 {
777                         p++;
778                         while (*p && *p != '}')
779                         {
780                         p[-1] = *p;
781                         p++;
782                         }
783                         p[-1] = '\0';
784                         if (*p)
785                         p++;
786                         type = TOK_PREPROC_ID;
787                 }
788                 else if (isidchar(*p) ||
789                                 ((*p == '!' || *p == '%' || *p == '$') &&
790                                         isidchar(p[1])))
791                 {
792                         do
793                         {
794                         p++;
795                         }
796                         while (isidchar(*p));
797                         type = TOK_PREPROC_ID;
798                 }
799                 else
800                 {
801                         type = TOK_OTHER;
802                         if (*p == '%')
803                                 p++;
804                 }
805         }
806         else if (isidstart(*p) || (*p == '$' && isidstart(p[1])))
807         {
808             type = TOK_ID;
809             p++;
810             while (*p && isidchar(*p))
811                 p++;
812         }
813         else if (*p == '\'' || *p == '"')
814         {
815             /*
816              * A string token.
817              */
818             char c = *p;
819             p++;
820             type = TOK_STRING;
821             while (*p && *p != c)
822                 p++;
823             if (*p)
824             {
825                 p++;
826             }
827             else
828             {
829                 error(ERR_WARNING, "unterminated string");
830             }
831         }
832         else if (isnumstart(*p))
833         {
834             /*
835              * A number token.
836              */
837             type = TOK_NUMBER;
838             p++;
839             while (*p && isnumchar(*p))
840                 p++;
841         }
842         else if (isspace(*p))
843         {
844             type = TOK_WHITESPACE;
845             p++;
846             while (*p && isspace(*p))
847                 p++;
848             /*
849              * Whitespace just before end-of-line is discarded by
850              * pretending it's a comment; whitespace just before a
851              * comment gets lumped into the comment.
852              */
853             if (!*p || *p == ';')
854             {
855                 type = TOK_COMMENT;
856                 while (*p)
857                     p++;
858             }
859         }
860         else if (*p == ';')
861         {
862             type = TOK_COMMENT;
863             while (*p)
864                 p++;
865         }
866         else
867         {
868             /*
869              * Anything else is an operator of some kind. We check
870              * for all the double-character operators (>>, <<, //,
871              * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
872              * else is a single-character operator.
873              */
874             type = TOK_OTHER;
875             if ((p[0] == '>' && p[1] == '>') ||
876                     (p[0] == '<' && p[1] == '<') ||
877                     (p[0] == '/' && p[1] == '/') ||
878                     (p[0] == '<' && p[1] == '=') ||
879                     (p[0] == '>' && p[1] == '=') ||
880                     (p[0] == '=' && p[1] == '=') ||
881                     (p[0] == '!' && p[1] == '=') ||
882                     (p[0] == '<' && p[1] == '>') ||
883                     (p[0] == '&' && p[1] == '&') ||
884                     (p[0] == '|' && p[1] == '|') ||
885                     (p[0] == '^' && p[1] == '^'))
886             {
887                 p++;
888             }
889             p++;
890         }
891         if (type != TOK_COMMENT)
892         {
893             *tail = t = new_Token(NULL, type, line, p - line);
894             tail = &t->next;
895         }
896         line = p;
897     }
898     return list;
899 }
900
901 /*
902  * this function allocates a new managed block of memory and
903  * returns a pointer to the block.  The managed blocks are 
904  * deleted only all at once by the delete_Blocks function.
905  */
906 static void *
907 new_Block(size_t size)
908 {
909         Blocks *b = &blocks;
910         
911         /* first, get to the end of the linked list      */
912         while (b->next)
913                 b = b->next;
914         /* now allocate the requested chunk */
915         b->chunk = nasm_malloc(size);
916         
917         /* now allocate a new block for the next request */
918         b->next = nasm_malloc(sizeof(Blocks));
919         /* and initialize the contents of the new block */
920         b->next->next = NULL;
921         b->next->chunk = NULL;
922         return b->chunk;
923 }
924
925 /*
926  * this function deletes all managed blocks of memory
927  */
928 static void
929 delete_Blocks(void)
930 {
931         Blocks *a,*b = &blocks;
932
933         /* 
934          * keep in mind that the first block, pointed to by blocks
935          * is a static and not dynamically allocated, so we don't 
936          * free it.
937          */
938         while (b)
939         {
940                 if (b->chunk)
941                         nasm_free(b->chunk);
942                 a = b;
943                 b = b->next;
944                 if (a != &blocks)
945                         nasm_free(a);
946         }
947 }       
948
949 /*
950  *  this function creates a new Token and passes a pointer to it 
951  *  back to the caller.  It sets the type and text elements, and
952  *  also the mac and next elements to NULL.
953  */
954 static Token *
955 new_Token(Token * next, int type, char *text, int txtlen)
956 {
957     Token *t;
958     int i;
959
960     if (freeTokens == NULL)
961     {
962         freeTokens = (Token *)new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
963         for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
964             freeTokens[i].next = &freeTokens[i + 1];
965         freeTokens[i].next = NULL;
966     }
967     t = freeTokens;
968     freeTokens = t->next;
969     t->next = next;
970     t->mac = NULL;
971     t->type = type;
972     if (type == TOK_WHITESPACE || text == NULL)
973     {
974         t->text = NULL;
975     }
976     else
977     {
978         if (txtlen == 0)
979             txtlen = strlen(text);
980         t->text = nasm_malloc(1 + txtlen);
981         strncpy(t->text, text, txtlen);
982         t->text[txtlen] = '\0';
983     }
984     return t;
985 }
986
987 static Token *
988 delete_Token(Token * t)
989 {
990     Token *next = t->next;
991     nasm_free(t->text);
992     t->next = freeTokens;
993     freeTokens = t;
994     return next;
995 }
996
997 /*
998  * Convert a line of tokens back into text.
999  * If expand_locals is not zero, identifiers of the form "%$*xxx"
1000  * will be transformed into ..@ctxnum.xxx
1001  */
1002 static char *
1003 detoken(Token * tlist, int expand_locals)
1004 {
1005     Token *t;
1006     int len;
1007     char *line, *p;
1008
1009     len = 0;
1010     for (t = tlist; t; t = t->next)
1011     {
1012         if (t->type == TOK_PREPROC_ID && t->text[1] == '!')
1013         {
1014             char *p = getenv(t->text + 2);
1015             nasm_free(t->text);
1016             if (p)
1017                 t->text = nasm_strdup(p);
1018             else
1019                 t->text = NULL;
1020         }
1021         /* Expand local macros here and not during preprocessing */
1022         if (expand_locals &&
1023                 t->type == TOK_PREPROC_ID && t->text &&
1024                 t->text[0] == '%' && t->text[1] == '$')
1025         {
1026             Context *ctx = get_ctx(t->text, FALSE);
1027             if (ctx)
1028             {
1029                 char buffer[40];
1030                 char *p, *q = t->text + 2;
1031
1032                 q += strspn(q, "$");
1033                 sprintf(buffer, "..@%lu.", ctx->number);
1034                 p = nasm_strcat(buffer, q);
1035                 nasm_free(t->text);
1036                 t->text = p;
1037             }
1038         }
1039         if (t->type == TOK_WHITESPACE)
1040         {
1041             len++;
1042         }
1043         else if (t->text)
1044         {
1045             len += strlen(t->text);
1046         }
1047     }
1048     p = line = nasm_malloc(len + 1);
1049     for (t = tlist; t; t = t->next)
1050     {
1051         if (t->type == TOK_WHITESPACE)
1052         {
1053             *p = ' ';
1054                 p++;
1055                 *p = '\0';
1056         }
1057         else if (t->text)
1058         {
1059             strcpy(p, t->text);
1060             p += strlen(p);
1061         }
1062     }
1063     *p = '\0';
1064     return line;
1065 }
1066
1067 /*
1068  * A scanner, suitable for use by the expression evaluator, which
1069  * operates on a line of Tokens. Expects a pointer to a pointer to
1070  * the first token in the line to be passed in as its private_data
1071  * field.
1072  */
1073 static int
1074 ppscan(void *private_data, struct tokenval *tokval)
1075 {
1076     Token **tlineptr = private_data;
1077     Token *tline;
1078
1079     do
1080     {
1081         tline = *tlineptr;
1082         *tlineptr = tline ? tline->next : NULL;
1083     }
1084     while (tline && (tline->type == TOK_WHITESPACE ||
1085                     tline->type == TOK_COMMENT));
1086
1087     if (!tline)
1088         return tokval->t_type = TOKEN_EOS;
1089
1090     if (tline->text[0] == '$' && !tline->text[1])
1091         return tokval->t_type = TOKEN_HERE;
1092     if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[1])
1093         return tokval->t_type = TOKEN_BASE;
1094
1095     if (tline->type == TOK_ID)
1096     {
1097         tokval->t_charptr = tline->text;
1098         if (tline->text[0] == '$')
1099         {
1100             tokval->t_charptr++;
1101             return tokval->t_type = TOKEN_ID;
1102         }
1103
1104         /*
1105          * This is the only special case we actually need to worry
1106          * about in this restricted context.
1107          */
1108         if (!nasm_stricmp(tline->text, "seg"))
1109             return tokval->t_type = TOKEN_SEG;
1110
1111         return tokval->t_type = TOKEN_ID;
1112     }
1113
1114     if (tline->type == TOK_NUMBER)
1115     {
1116         int rn_error;
1117
1118         tokval->t_integer = readnum(tline->text, &rn_error);
1119         if (rn_error)
1120             return tokval->t_type = TOKEN_ERRNUM;
1121         tokval->t_charptr = NULL;
1122         return tokval->t_type = TOKEN_NUM;
1123     }
1124
1125     if (tline->type == TOK_STRING)
1126     {
1127         int rn_warn;
1128         char q, *r;
1129         int l;
1130
1131         r = tline->text;
1132         q = *r++;
1133         l = strlen(r);
1134
1135         if (l == 0 || r[l - 1] != q)
1136             return tokval->t_type = TOKEN_ERRNUM;
1137         tokval->t_integer = readstrnum(r, l - 1, &rn_warn);
1138         if (rn_warn)
1139             error(ERR_WARNING | ERR_PASS1, "character constant too long");
1140         tokval->t_charptr = NULL;
1141         return tokval->t_type = TOKEN_NUM;
1142     }
1143
1144     if (tline->type == TOK_OTHER)
1145     {
1146         if (!strcmp(tline->text, "<<"))
1147             return tokval->t_type = TOKEN_SHL;
1148         if (!strcmp(tline->text, ">>"))
1149             return tokval->t_type = TOKEN_SHR;
1150         if (!strcmp(tline->text, "//"))
1151             return tokval->t_type = TOKEN_SDIV;
1152         if (!strcmp(tline->text, "%%"))
1153             return tokval->t_type = TOKEN_SMOD;
1154         if (!strcmp(tline->text, "=="))
1155             return tokval->t_type = TOKEN_EQ;
1156         if (!strcmp(tline->text, "<>"))
1157             return tokval->t_type = TOKEN_NE;
1158         if (!strcmp(tline->text, "!="))
1159             return tokval->t_type = TOKEN_NE;
1160         if (!strcmp(tline->text, "<="))
1161             return tokval->t_type = TOKEN_LE;
1162         if (!strcmp(tline->text, ">="))
1163             return tokval->t_type = TOKEN_GE;
1164         if (!strcmp(tline->text, "&&"))
1165             return tokval->t_type = TOKEN_DBL_AND;
1166         if (!strcmp(tline->text, "^^"))
1167             return tokval->t_type = TOKEN_DBL_XOR;
1168         if (!strcmp(tline->text, "||"))
1169             return tokval->t_type = TOKEN_DBL_OR;
1170     }
1171
1172     /*
1173      * We have no other options: just return the first character of
1174      * the token text.
1175      */
1176     return tokval->t_type = tline->text[0];
1177 }
1178
1179 /*
1180  * Compare a string to the name of an existing macro; this is a
1181  * simple wrapper which calls either strcmp or nasm_stricmp
1182  * depending on the value of the `casesense' parameter.
1183  */
1184 static int
1185 mstrcmp(char *p, char *q, int casesense)
1186 {
1187     return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
1188 }
1189
1190 /*
1191  * Return the Context structure associated with a %$ token. Return
1192  * NULL, having _already_ reported an error condition, if the
1193  * context stack isn't deep enough for the supplied number of $
1194  * signs.
1195  * If all_contexts == TRUE, contexts that enclose current are
1196  * also scanned for such smacro, until it is found; if not -
1197  * only the context that directly results from the number of $'s
1198  * in variable's name.
1199  */
1200 static Context *
1201 get_ctx(char *name, int all_contexts)
1202 {
1203     Context *ctx;
1204     SMacro *m;
1205     int i;
1206
1207     if (!name || name[0] != '%' || name[1] != '$')
1208         return NULL;
1209
1210     if (!cstk)
1211     {
1212         error(ERR_NONFATAL, "`%s': context stack is empty", name);
1213         return NULL;
1214     }
1215
1216     for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--)
1217     {
1218         ctx = ctx->next;
1219 /*        i--;  Lino - 02/25/02 */
1220     }
1221     if (!ctx)
1222     {
1223         error(ERR_NONFATAL, "`%s': context stack is only"
1224                 " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
1225         return NULL;
1226     }
1227     if (!all_contexts)
1228         return ctx;
1229
1230     do
1231     {
1232         /* Search for this smacro in found context */
1233         m = ctx->localmac;
1234         while (m)
1235         {
1236             if (!mstrcmp(m->name, name, m->casesense))
1237                 return ctx;
1238             m = m->next;
1239         }
1240         ctx = ctx->next;
1241     }
1242     while (ctx);
1243     return NULL;
1244 }
1245
1246 /* Add a slash to the end of a path if it is missing. We use the
1247  * forward slash to make it compatible with Unix systems.
1248  */
1249 static void
1250 backslash(char *s)
1251 {
1252     int pos = strlen(s);
1253     if (s[pos - 1] != '\\' && s[pos - 1] != '/')
1254     {
1255         s[pos] = '/';
1256         s[pos + 1] = '\0';
1257     }
1258 }
1259
1260 /*
1261  * Open an include file. This routine must always return a valid
1262  * file pointer if it returns - it's responsible for throwing an
1263  * ERR_FATAL and bombing out completely if not. It should also try
1264  * the include path one by one until it finds the file or reaches
1265  * the end of the path.
1266  */
1267 static FILE *
1268 inc_fopen(char *file)
1269 {
1270     FILE *fp;
1271     char *prefix = "", *combine;
1272     IncPath *ip = ipath;
1273     static int namelen = 0;
1274     int len = strlen(file);
1275
1276     while (1)
1277     {
1278         combine = nasm_malloc(strlen(prefix) + 1 + len + 1);
1279         strcpy(combine, prefix);
1280         if (prefix[0] != 0)
1281             backslash(combine);
1282         strcat(combine, file);
1283         fp = fopen(combine, "r");
1284         if (pass == 0 && fp)
1285         {
1286             namelen += strlen(combine) + 1;
1287             if (namelen > 62)
1288             {
1289                 printf(" \\\n  ");
1290                 namelen = 2;
1291             }
1292             printf(" %s", combine);
1293         }
1294         nasm_free(combine);
1295         if (fp)
1296             return fp;
1297         if (!ip)
1298             break;
1299         prefix = ip->path;
1300         ip = ip->next;
1301     }
1302
1303     error(ERR_FATAL, "unable to open include file `%s'", file);
1304     return NULL;                /* never reached - placate compilers */
1305 }
1306
1307 /*
1308  * Determine if we should warn on defining a single-line macro of
1309  * name `name', with `nparam' parameters. If nparam is 0 or -1, will
1310  * return TRUE if _any_ single-line macro of that name is defined.
1311  * Otherwise, will return TRUE if a single-line macro with either
1312  * `nparam' or no parameters is defined.
1313  *
1314  * If a macro with precisely the right number of parameters is
1315  * defined, or nparam is -1, the address of the definition structure
1316  * will be returned in `defn'; otherwise NULL will be returned. If `defn'
1317  * is NULL, no action will be taken regarding its contents, and no
1318  * error will occur.
1319  *
1320  * Note that this is also called with nparam zero to resolve
1321  * `ifdef'.
1322  *
1323  * If you already know which context macro belongs to, you can pass
1324  * the context pointer as first parameter; if you won't but name begins
1325  * with %$ the context will be automatically computed. If all_contexts
1326  * is true, macro will be searched in outer contexts as well.
1327  */
1328 static int
1329 smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
1330         int nocase)
1331 {
1332     SMacro *m;
1333
1334     if (ctx)
1335         m = ctx->localmac;
1336     else if (name[0] == '%' && name[1] == '$')
1337     {
1338         if (cstk)
1339             ctx = get_ctx(name, FALSE);
1340         if (!ctx)
1341             return FALSE;       /* got to return _something_ */
1342         m = ctx->localmac;
1343     }
1344     else
1345         m = smacros[hash(name)];
1346
1347     while (m)
1348     {
1349         if (!mstrcmp(m->name, name, m->casesense && nocase) &&
1350                 (nparam <= 0 || m->nparam == 0 || nparam == m->nparam))
1351         {
1352             if (defn)
1353             {
1354                 if (nparam == m->nparam || nparam == -1)
1355                     *defn = m;
1356                 else
1357                     *defn = NULL;
1358             }
1359             return TRUE;
1360         }
1361         m = m->next;
1362     }
1363
1364     return FALSE;
1365 }
1366
1367 /*
1368  * Count and mark off the parameters in a multi-line macro call.
1369  * This is called both from within the multi-line macro expansion
1370  * code, and also to mark off the default parameters when provided
1371  * in a %macro definition line.
1372  */
1373 static void
1374 count_mmac_params(Token * t, int *nparam, Token *** params)
1375 {
1376     int paramsize, brace;
1377
1378     *nparam = paramsize = 0;
1379     *params = NULL;
1380     while (t)
1381     {
1382         if (*nparam >= paramsize)
1383         {
1384             paramsize += PARAM_DELTA;
1385             *params = nasm_realloc(*params, sizeof(**params) * paramsize);
1386         }
1387         skip_white_(t);
1388         brace = FALSE;
1389         if (tok_is_(t, "{"))
1390             brace = TRUE;
1391         (*params)[(*nparam)++] = t;
1392         while (tok_isnt_(t, brace ? "}" : ","))
1393             t = t->next;
1394         if (t)
1395         {                       /* got a comma/brace */
1396             t = t->next;
1397             if (brace)
1398             {
1399                 /*
1400                  * Now we've found the closing brace, look further
1401                  * for the comma.
1402                  */
1403                 skip_white_(t);
1404                 if (tok_isnt_(t, ","))
1405                 {
1406                     error(ERR_NONFATAL,
1407                             "braces do not enclose all of macro parameter");
1408                     while (tok_isnt_(t, ","))
1409                         t = t->next;
1410                 }
1411                 if (t)
1412                     t = t->next;        /* eat the comma */
1413             }
1414         }
1415     }
1416 }
1417
1418 /*
1419  * Determine whether one of the various `if' conditions is true or
1420  * not.
1421  *
1422  * We must free the tline we get passed.
1423  */
1424 static int
1425 if_condition(Token * tline, int i)
1426 {
1427     int j, casesense;
1428     Token *t, *tt, **tptr, *origline;
1429     struct tokenval tokval;
1430     expr *evalresult;
1431
1432     origline = tline;
1433
1434     switch (i)
1435     {
1436         case PP_IFCTX:
1437         case PP_ELIFCTX:
1438         case PP_IFNCTX:
1439         case PP_ELIFNCTX:
1440             j = FALSE;          /* have we matched yet? */
1441             while (cstk && tline)
1442             {
1443                 skip_white_(tline);
1444                 if (!tline || tline->type != TOK_ID)
1445                 {
1446                     error(ERR_NONFATAL,
1447                             "`%s' expects context identifiers",
1448                             directives[i]);
1449                     free_tlist(origline);
1450                     return -1;
1451                 }
1452                 if (!nasm_stricmp(tline->text, cstk->name))
1453                     j = TRUE;
1454                 tline = tline->next;
1455             }
1456             if (i == PP_IFNCTX || i == PP_ELIFNCTX)
1457                 j = !j;
1458             free_tlist(origline);
1459             return j;
1460
1461         case PP_IFDEF:
1462         case PP_ELIFDEF:
1463         case PP_IFNDEF:
1464         case PP_ELIFNDEF:
1465             j = FALSE;          /* have we matched yet? */
1466             while (tline)
1467             {
1468                 skip_white_(tline);
1469                 if (!tline || (tline->type != TOK_ID &&
1470                                 (tline->type != TOK_PREPROC_ID ||
1471                                         tline->text[1] != '$')))
1472                 {
1473                     error(ERR_NONFATAL,
1474                             "`%%if%sdef' expects macro identifiers",
1475                             (i == PP_ELIFNDEF ? "n" : ""));
1476                     free_tlist(origline);
1477                     return -1;
1478                 }
1479                 if (smacro_defined(NULL, tline->text, 0, NULL, 1))
1480                     j = TRUE;
1481                 tline = tline->next;
1482             }
1483             if (i == PP_IFNDEF || i == PP_ELIFNDEF)
1484                 j = !j;
1485             free_tlist(origline);
1486             return j;
1487
1488         case PP_IFIDN:
1489         case PP_ELIFIDN:
1490         case PP_IFNIDN:
1491         case PP_ELIFNIDN:
1492         case PP_IFIDNI:
1493         case PP_ELIFIDNI:
1494         case PP_IFNIDNI:
1495         case PP_ELIFNIDNI:
1496             tline = expand_smacro(tline);
1497             t = tt = tline;
1498             while (tok_isnt_(tt, ","))
1499                 tt = tt->next;
1500             if (!tt)
1501             {
1502                 error(ERR_NONFATAL,
1503                         "`%s' expects two comma-separated arguments",
1504                         directives[i]);
1505                 free_tlist(tline);
1506                 return -1;
1507             }
1508             tt = tt->next;
1509             casesense = (i == PP_IFIDN || i == PP_ELIFIDN ||
1510                     i == PP_IFNIDN || i == PP_ELIFNIDN);
1511             j = TRUE;           /* assume equality unless proved not */
1512             while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt)
1513             {
1514                 if (tt->type == TOK_OTHER && !strcmp(tt->text, ","))
1515                 {
1516                     error(ERR_NONFATAL, "`%s': more than one comma on line",
1517                             directives[i]);
1518                     free_tlist(tline);
1519                     return -1;
1520                 }
1521                 if (t->type == TOK_WHITESPACE)
1522                 {
1523                     t = t->next;
1524                     continue;
1525                 }
1526                 else if (tt->type == TOK_WHITESPACE)
1527                 {
1528                     tt = tt->next;
1529                     continue;
1530                 }
1531                 else if (tt->type != t->type ||
1532                         mstrcmp(tt->text, t->text, casesense))
1533                 {
1534                     j = FALSE;  /* found mismatching tokens */
1535                     break;
1536                 }
1537                 else
1538                 {
1539                     t = t->next;
1540                     tt = tt->next;
1541                     continue;
1542                 }
1543             }
1544             if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
1545                 j = FALSE;      /* trailing gunk on one end or other */
1546             if (i == PP_IFNIDN || i == PP_ELIFNIDN ||
1547                     i == PP_IFNIDNI || i == PP_ELIFNIDNI)
1548                 j = !j;
1549             free_tlist(tline);
1550             return j;
1551
1552         case PP_IFID:
1553         case PP_ELIFID:
1554         case PP_IFNID:
1555         case PP_ELIFNID:
1556         case PP_IFNUM:
1557         case PP_ELIFNUM:
1558         case PP_IFNNUM:
1559         case PP_ELIFNNUM:
1560         case PP_IFSTR:
1561         case PP_ELIFSTR:
1562         case PP_IFNSTR:
1563         case PP_ELIFNSTR:
1564             tline = expand_smacro(tline);
1565             t = tline;
1566             while (tok_type_(t, TOK_WHITESPACE))
1567                 t = t->next;
1568             j = FALSE;          /* placate optimiser */
1569             if (t)
1570                 switch (i)
1571                 {
1572                     case PP_IFID:
1573                     case PP_ELIFID:
1574                     case PP_IFNID:
1575                     case PP_ELIFNID:
1576                         j = (t->type == TOK_ID);
1577                         break;
1578                     case PP_IFNUM:
1579                     case PP_ELIFNUM:
1580                     case PP_IFNNUM:
1581                     case PP_ELIFNNUM:
1582                         j = (t->type == TOK_NUMBER);
1583                         break;
1584                     case PP_IFSTR:
1585                     case PP_ELIFSTR:
1586                     case PP_IFNSTR:
1587                     case PP_ELIFNSTR:
1588                         j = (t->type == TOK_STRING);
1589                         break;
1590                 }
1591             if (i == PP_IFNID || i == PP_ELIFNID ||
1592                     i == PP_IFNNUM || i == PP_ELIFNNUM ||
1593                     i == PP_IFNSTR || i == PP_ELIFNSTR)
1594                 j = !j;
1595             free_tlist(tline);
1596             return j;
1597
1598         case PP_IF:
1599         case PP_ELIF:
1600             t = tline = expand_smacro(tline);
1601             tptr = &t;
1602             tokval.t_type = TOKEN_INVALID;
1603             evalresult = evaluate(ppscan, tptr, &tokval,
1604                     NULL, pass | CRITICAL, error, NULL);
1605             free_tlist(tline);
1606             if (!evalresult)
1607                 return -1;
1608             if (tokval.t_type)
1609                 error(ERR_WARNING,
1610                         "trailing garbage after expression ignored");
1611             if (!is_simple(evalresult))
1612             {
1613                 error(ERR_NONFATAL,
1614                         "non-constant value given to `%s'", directives[i]);
1615                 return -1;
1616             }
1617             return reloc_value(evalresult) != 0;
1618
1619         default:
1620             error(ERR_FATAL,
1621                     "preprocessor directive `%s' not yet implemented",
1622                     directives[i]);
1623             free_tlist(origline);
1624             return -1;          /* yeah, right */
1625     }
1626 }
1627
1628 /*
1629  * Expand macros in a string. Used in %error and %include directives.
1630  * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
1631  * The returned variable should ALWAYS be freed after usage.
1632  */
1633 void
1634 expand_macros_in_string(char **p)
1635 {
1636     Token *line = tokenise(*p);
1637     line = expand_smacro(line);
1638     *p = detoken(line, FALSE);
1639 }
1640
1641 /*
1642  * Find out if a line contains a preprocessor directive, and deal
1643  * with it if so.
1644  * 
1645  * If a directive _is_ found, we are expected to free_tlist() the
1646  * line.
1647  *
1648  * Return values go like this:
1649  * 
1650  * bit 0 is set if a directive was found (so the line gets freed)
1651  */
1652 static int
1653 do_directive(Token * tline)
1654 {
1655     int i, j, k, m, nparam, nolist;
1656     int offset;
1657     char *p, *mname;
1658     Include *inc;
1659     Context *ctx;
1660     Cond *cond;
1661     SMacro *smac, **smhead;
1662     MMacro *mmac;
1663     Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
1664     Line *l;
1665     struct tokenval tokval;
1666     expr *evalresult;
1667     MMacro *tmp_defining;       /* Used when manipulating rep_nest */
1668
1669     origline = tline;
1670
1671     skip_white_(tline);
1672     if (!tok_type_(tline, TOK_PREPROC_ID) ||
1673             (tline->text[1] == '%' || tline->text[1] == '$'
1674                     || tline->text[1] == '!'))
1675         return 0;
1676
1677     i = -1;
1678     j = sizeof(directives) / sizeof(*directives);
1679     while (j - i > 1)
1680     {
1681         k = (j + i) / 2;
1682         m = nasm_stricmp(tline->text, directives[k]);
1683         if (m == 0) {
1684                 if (tasm_compatible_mode) {
1685                 i = k;
1686                 j = -2;
1687                 } else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) {
1688                     i = k;
1689                 j = -2;
1690                 }
1691             break;
1692         }
1693         else if (m < 0) {
1694             j = k;
1695         }
1696         else
1697             i = k;
1698     }
1699
1700     /*
1701      * If we're in a non-emitting branch of a condition construct,
1702      * or walking to the end of an already terminated %rep block,
1703      * we should ignore all directives except for condition
1704      * directives.
1705      */
1706     if (((istk->conds && !emitting(istk->conds->state)) ||
1707                     (istk->mstk && !istk->mstk->in_progress)) &&
1708             i != PP_IF && i != PP_ELIF &&
1709             i != PP_IFCTX && i != PP_ELIFCTX &&
1710             i != PP_IFDEF && i != PP_ELIFDEF &&
1711             i != PP_IFID && i != PP_ELIFID &&
1712             i != PP_IFIDN && i != PP_ELIFIDN &&
1713             i != PP_IFIDNI && i != PP_ELIFIDNI &&
1714             i != PP_IFNCTX && i != PP_ELIFNCTX &&
1715             i != PP_IFNDEF && i != PP_ELIFNDEF &&
1716             i != PP_IFNID && i != PP_ELIFNID &&
1717             i != PP_IFNIDN && i != PP_ELIFNIDN &&
1718             i != PP_IFNIDNI && i != PP_ELIFNIDNI &&
1719             i != PP_IFNNUM && i != PP_ELIFNNUM &&
1720             i != PP_IFNSTR && i != PP_ELIFNSTR &&
1721             i != PP_IFNUM && i != PP_ELIFNUM &&
1722             i != PP_IFSTR && i != PP_ELIFSTR && i != PP_ELSE && i != PP_ENDIF)
1723     {
1724         return 0;
1725     }
1726
1727     /*
1728      * If we're defining a macro or reading a %rep block, we should
1729      * ignore all directives except for %macro/%imacro (which
1730      * generate an error), %endm/%endmacro, and (only if we're in a
1731      * %rep block) %endrep. If we're in a %rep block, another %rep
1732      * causes an error, so should be let through.
1733      */
1734     if (defining && i != PP_MACRO && i != PP_IMACRO &&
1735             i != PP_ENDMACRO && i != PP_ENDM &&
1736             (defining->name || (i != PP_ENDREP && i != PP_REP)))
1737     {
1738         return 0;
1739     }
1740
1741     if (j != -2)
1742     {
1743         error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
1744                 tline->text);
1745         return 0;               /* didn't get it */
1746     }
1747
1748     switch (i)
1749     {
1750         case PP_STACKSIZE:
1751             /* Directive to tell NASM what the default stack size is. The
1752              * default is for a 16-bit stack, and this can be overriden with
1753              * %stacksize large.
1754              * the following form:
1755              *
1756              *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1757              */
1758             tline = tline->next;
1759             if (tline && tline->type == TOK_WHITESPACE)
1760                 tline = tline->next;
1761             if (!tline || tline->type != TOK_ID)
1762             {
1763                 error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
1764                 free_tlist(origline);
1765                 return 3;
1766             }
1767             if (nasm_stricmp(tline->text, "flat") == 0)
1768             {
1769                 /* All subsequent ARG directives are for a 32-bit stack */
1770                 StackSize = 4;
1771                 StackPointer = "ebp";
1772                 ArgOffset = 8;
1773                 LocalOffset = 4;
1774             }
1775             else if (nasm_stricmp(tline->text, "large") == 0)
1776             {
1777                 /* All subsequent ARG directives are for a 16-bit stack,
1778                  * far function call.
1779                  */
1780                 StackSize = 2;
1781                 StackPointer = "bp";
1782                 ArgOffset = 4;
1783                 LocalOffset = 2;
1784             }
1785             else if (nasm_stricmp(tline->text, "small") == 0)
1786             {
1787                 /* All subsequent ARG directives are for a 16-bit stack,
1788                    * far function call. We don't support near functions.
1789                  */
1790                 StackSize = 2;
1791                 StackPointer = "bp";
1792                 ArgOffset = 6;
1793                 LocalOffset = 2;
1794             }
1795             else
1796             {
1797                 error(ERR_NONFATAL, "`%%stacksize' invalid size type");
1798                 free_tlist(origline);
1799                 return 3;
1800             }
1801             free_tlist(origline);
1802             return 3;
1803
1804         case PP_ARG:
1805             /* TASM like ARG directive to define arguments to functions, in
1806              * the following form:
1807              *
1808              *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1809              */
1810             offset = ArgOffset;
1811             do
1812             {
1813                 char *arg, directive[256];
1814                 int size = StackSize;
1815
1816                 /* Find the argument name */
1817                 tline = tline->next;
1818                 if (tline && tline->type == TOK_WHITESPACE)
1819                     tline = tline->next;
1820                 if (!tline || tline->type != TOK_ID)
1821                 {
1822                     error(ERR_NONFATAL, "`%%arg' missing argument parameter");
1823                     free_tlist(origline);
1824                     return 3;
1825                 }
1826                 arg = tline->text;
1827
1828                 /* Find the argument size type */
1829                 tline = tline->next;
1830                 if (!tline || tline->type != TOK_OTHER
1831                         || tline->text[0] != ':')
1832                 {
1833                     error(ERR_NONFATAL,
1834                             "Syntax error processing `%%arg' directive");
1835                     free_tlist(origline);
1836                     return 3;
1837                 }
1838                 tline = tline->next;
1839                 if (!tline || tline->type != TOK_ID)
1840                 {
1841                     error(ERR_NONFATAL,
1842                             "`%%arg' missing size type parameter");
1843                     free_tlist(origline);
1844                     return 3;
1845                 }
1846
1847                 /* Allow macro expansion of type parameter */
1848                 tt = tokenise(tline->text);
1849                 tt = expand_smacro(tt);
1850                 if (nasm_stricmp(tt->text, "byte") == 0)
1851                 {
1852                     size = MAX(StackSize, 1);
1853                 }
1854                 else if (nasm_stricmp(tt->text, "word") == 0)
1855                 {
1856                     size = MAX(StackSize, 2);
1857                 }
1858                 else if (nasm_stricmp(tt->text, "dword") == 0)
1859                 {
1860                     size = MAX(StackSize, 4);
1861                 }
1862                 else if (nasm_stricmp(tt->text, "qword") == 0)
1863                 {
1864                     size = MAX(StackSize, 8);
1865                 }
1866                 else if (nasm_stricmp(tt->text, "tword") == 0)
1867                 {
1868                     size = MAX(StackSize, 10);
1869                 }
1870                 else
1871                 {
1872                     error(ERR_NONFATAL,
1873                             "Invalid size type for `%%arg' missing directive");
1874                     free_tlist(tt);
1875                     free_tlist(origline);
1876                     return 3;
1877                 }
1878                 free_tlist(tt);
1879
1880                 /* Now define the macro for the argument */
1881                 sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer,
1882                         offset);
1883                 do_directive(tokenise(directive));
1884                 offset += size;
1885
1886                 /* Move to the next argument in the list */
1887                 tline = tline->next;
1888                 if (tline && tline->type == TOK_WHITESPACE)
1889                     tline = tline->next;
1890             }
1891             while (tline && tline->type == TOK_OTHER
1892                     && tline->text[0] == ',');
1893             free_tlist(origline);
1894             return 3;
1895
1896         case PP_LOCAL:
1897             /* TASM like LOCAL directive to define local variables for a
1898              * function, in the following form:
1899              *
1900              *      LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1901              *
1902              * The '= LocalSize' at the end is ignored by NASM, but is
1903              * required by TASM to define the local parameter size (and used
1904              * by the TASM macro package).
1905              */
1906             offset = LocalOffset;
1907             do
1908             {
1909                 char *local, directive[256];
1910                 int size = StackSize;
1911
1912                 /* Find the argument name */
1913                 tline = tline->next;
1914                 if (tline && tline->type == TOK_WHITESPACE)
1915                     tline = tline->next;
1916                 if (!tline || tline->type != TOK_ID)
1917                 {
1918                     error(ERR_NONFATAL,
1919                             "`%%local' missing argument parameter");
1920                     free_tlist(origline);
1921                     return 3;
1922                 }
1923                 local = tline->text;
1924
1925                 /* Find the argument size type */
1926                 tline = tline->next;
1927                 if (!tline || tline->type != TOK_OTHER
1928                         || tline->text[0] != ':')
1929                 {
1930                     error(ERR_NONFATAL,
1931                             "Syntax error processing `%%local' directive");
1932                     free_tlist(origline);
1933                     return 3;
1934                 }
1935                 tline = tline->next;
1936                 if (!tline || tline->type != TOK_ID)
1937                 {
1938                     error(ERR_NONFATAL,
1939                             "`%%local' missing size type parameter");
1940                     free_tlist(origline);
1941                     return 3;
1942                 }
1943
1944                 /* Allow macro expansion of type parameter */
1945                 tt = tokenise(tline->text);
1946                 tt = expand_smacro(tt);
1947                 if (nasm_stricmp(tt->text, "byte") == 0)
1948                 {
1949                     size = MAX(StackSize, 1);
1950                 }
1951                 else if (nasm_stricmp(tt->text, "word") == 0)
1952                 {
1953                     size = MAX(StackSize, 2);
1954                 }
1955                 else if (nasm_stricmp(tt->text, "dword") == 0)
1956                 {
1957                     size = MAX(StackSize, 4);
1958                 }
1959                 else if (nasm_stricmp(tt->text, "qword") == 0)
1960                 {
1961                     size = MAX(StackSize, 8);
1962                 }
1963                 else if (nasm_stricmp(tt->text, "tword") == 0)
1964                 {
1965                     size = MAX(StackSize, 10);
1966                 }
1967                 else
1968                 {
1969                     error(ERR_NONFATAL,
1970                             "Invalid size type for `%%local' missing directive");
1971                     free_tlist(tt);
1972                     free_tlist(origline);
1973                     return 3;
1974                 }
1975                 free_tlist(tt);
1976
1977                 /* Now define the macro for the argument */
1978                 sprintf(directive, "%%define %s (%s-%d)", local, StackPointer,
1979                         offset);
1980                 do_directive(tokenise(directive));
1981                 offset += size;
1982
1983                 /* Now define the assign to setup the enter_c macro correctly */
1984                 sprintf(directive, "%%assign %%$localsize %%$localsize+%d",
1985                         size);
1986                 do_directive(tokenise(directive));
1987
1988                 /* Move to the next argument in the list */
1989                 tline = tline->next;
1990                 if (tline && tline->type == TOK_WHITESPACE)
1991                     tline = tline->next;
1992             }
1993             while (tline && tline->type == TOK_OTHER
1994                     && tline->text[0] == ',');
1995             free_tlist(origline);
1996             return 3;
1997
1998         case PP_CLEAR:
1999             if (tline->next)
2000                 error(ERR_WARNING,
2001                         "trailing garbage after `%%clear' ignored");
2002             for (j = 0; j < NHASH; j++)
2003             {
2004                 while (mmacros[j])
2005                 {
2006                     MMacro *m = mmacros[j];
2007                     mmacros[j] = m->next;
2008                     free_mmacro(m);
2009                 }
2010                 while (smacros[j])
2011                 {
2012                     SMacro *s = smacros[j];
2013                     smacros[j] = smacros[j]->next;
2014                     nasm_free(s->name);
2015                     free_tlist(s->expansion);
2016                     nasm_free(s);
2017                 }
2018             }
2019             free_tlist(origline);
2020             return 3;
2021
2022         case PP_INCLUDE:
2023             tline = tline->next;
2024             skip_white_(tline);
2025             if (!tline || (tline->type != TOK_STRING &&
2026                             tline->type != TOK_INTERNAL_STRING))
2027             {
2028                 error(ERR_NONFATAL, "`%%include' expects a file name");
2029                 free_tlist(origline);
2030                 return 3;       /* but we did _something_ */
2031             }
2032             if (tline->next)
2033                 error(ERR_WARNING,
2034                         "trailing garbage after `%%include' ignored");
2035             if (tline->type != TOK_INTERNAL_STRING)
2036             {
2037                 p = tline->text + 1;    /* point past the quote to the name */
2038                 p[strlen(p) - 1] = '\0';        /* remove the trailing quote */
2039             }
2040             else
2041                 p = tline->text;        /* internal_string is easier */
2042             expand_macros_in_string(&p);
2043             inc = nasm_malloc(sizeof(Include));
2044             inc->next = istk;
2045             inc->conds = NULL;
2046             inc->fp = inc_fopen(p);
2047             inc->fname = src_set_fname(p);
2048             inc->lineno = src_set_linnum(0);
2049             inc->lineinc = 1;
2050             inc->expansion = NULL;
2051             inc->mstk = NULL;
2052             istk = inc;
2053             list->uplevel(LIST_INCLUDE);
2054             free_tlist(origline);
2055             return 5;
2056
2057         case PP_PUSH:
2058             tline = tline->next;
2059             skip_white_(tline);
2060             tline = expand_id(tline);
2061             if (!tok_type_(tline, TOK_ID))
2062             {
2063                 error(ERR_NONFATAL, "`%%push' expects a context identifier");
2064                 free_tlist(origline);
2065                 return 3;       /* but we did _something_ */
2066             }
2067             if (tline->next)
2068                 error(ERR_WARNING, "trailing garbage after `%%push' ignored");
2069             ctx = nasm_malloc(sizeof(Context));
2070             ctx->next = cstk;
2071             ctx->localmac = NULL;
2072             ctx->name = nasm_strdup(tline->text);
2073             ctx->number = unique++;
2074             cstk = ctx;
2075             free_tlist(origline);
2076             break;
2077
2078         case PP_REPL:
2079             tline = tline->next;
2080             skip_white_(tline);
2081             tline = expand_id(tline);
2082             if (!tok_type_(tline, TOK_ID))
2083             {
2084                 error(ERR_NONFATAL, "`%%repl' expects a context identifier");
2085                 free_tlist(origline);
2086                 return 3;       /* but we did _something_ */
2087             }
2088             if (tline->next)
2089                 error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
2090             if (!cstk)
2091                 error(ERR_NONFATAL, "`%%repl': context stack is empty");
2092             else
2093             {
2094                 nasm_free(cstk->name);
2095                 cstk->name = nasm_strdup(tline->text);
2096             }
2097             free_tlist(origline);
2098             break;
2099
2100         case PP_POP:
2101             if (tline->next)
2102                 error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
2103             if (!cstk)
2104                 error(ERR_NONFATAL,
2105                         "`%%pop': context stack is already empty");
2106             else
2107                 ctx_pop();
2108             free_tlist(origline);
2109             break;
2110
2111         case PP_ERROR:
2112             tline->next = expand_smacro(tline->next);
2113             tline = tline->next;
2114             skip_white_(tline);
2115             if (tok_type_(tline, TOK_STRING))
2116             {
2117                 p = tline->text + 1;    /* point past the quote to the name */
2118                 p[strlen(p) - 1] = '\0';        /* remove the trailing quote */
2119                 expand_macros_in_string(&p);
2120                 error(ERR_NONFATAL, "%s", p);
2121                 nasm_free(p);
2122             }
2123             else
2124             {
2125                 p = detoken(tline, FALSE);
2126                 error(ERR_WARNING, "%s", p);
2127                 nasm_free(p);
2128             }
2129             free_tlist(origline);
2130             break;
2131
2132         case PP_IF:
2133         case PP_IFCTX:
2134         case PP_IFDEF:
2135         case PP_IFID:
2136         case PP_IFIDN:
2137         case PP_IFIDNI:
2138         case PP_IFNCTX:
2139         case PP_IFNDEF:
2140         case PP_IFNID:
2141         case PP_IFNIDN:
2142         case PP_IFNIDNI:
2143         case PP_IFNNUM:
2144         case PP_IFNSTR:
2145         case PP_IFNUM:
2146         case PP_IFSTR:
2147             if (istk->conds && !emitting(istk->conds->state))
2148                 j = COND_NEVER;
2149             else
2150             {
2151                 j = if_condition(tline->next, i);
2152                 tline->next = NULL;     /* it got freed */
2153                 free_tlist(origline);
2154                 j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2155             }
2156             cond = nasm_malloc(sizeof(Cond));
2157             cond->next = istk->conds;
2158             cond->state = j;
2159             istk->conds = cond;
2160             return (j == COND_IF_TRUE ? 3 : 1);
2161
2162         case PP_ELIF:
2163         case PP_ELIFCTX:
2164         case PP_ELIFDEF:
2165         case PP_ELIFID:
2166         case PP_ELIFIDN:
2167         case PP_ELIFIDNI:
2168         case PP_ELIFNCTX:
2169         case PP_ELIFNDEF:
2170         case PP_ELIFNID:
2171         case PP_ELIFNIDN:
2172         case PP_ELIFNIDNI:
2173         case PP_ELIFNNUM:
2174         case PP_ELIFNSTR:
2175         case PP_ELIFNUM:
2176         case PP_ELIFSTR:
2177             if (!istk->conds)
2178                 error(ERR_FATAL, "`%s': no matching `%%if'", directives[i]);
2179             if (emitting(istk->conds->state)
2180                     || istk->conds->state == COND_NEVER)
2181                 istk->conds->state = COND_NEVER;
2182             else
2183             {
2184                 j = if_condition(expand_mmac_params(tline->next), i);
2185                 tline->next = NULL;     /* it got freed */
2186                 free_tlist(origline);
2187                 istk->conds->state =
2188                         j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2189             }
2190             return (istk->conds->state == COND_IF_TRUE ? 5 : 1);
2191
2192         case PP_ELSE:
2193             if (tline->next)
2194                 error(ERR_WARNING, "trailing garbage after `%%else' ignored");
2195             if (!istk->conds)
2196                 error(ERR_FATAL, "`%%else': no matching `%%if'");
2197             if (emitting(istk->conds->state)
2198                     || istk->conds->state == COND_NEVER)
2199                 istk->conds->state = COND_ELSE_FALSE;
2200             else
2201                 istk->conds->state = COND_ELSE_TRUE;
2202             free_tlist(origline);
2203             return 5;
2204
2205         case PP_ENDIF:
2206             if (tline->next)
2207                 error(ERR_WARNING,
2208                         "trailing garbage after `%%endif' ignored");
2209             if (!istk->conds)
2210                 error(ERR_FATAL, "`%%endif': no matching `%%if'");
2211             cond = istk->conds;
2212             istk->conds = cond->next;
2213             nasm_free(cond);
2214             free_tlist(origline);
2215             return 5;
2216
2217         case PP_MACRO:
2218         case PP_IMACRO:
2219             if (defining)
2220                 error(ERR_FATAL,
2221                         "`%%%smacro': already defining a macro",
2222                         (i == PP_IMACRO ? "i" : ""));
2223             tline = tline->next;
2224             skip_white_(tline);
2225             tline = expand_id(tline);
2226             if (!tok_type_(tline, TOK_ID))
2227             {
2228                 error(ERR_NONFATAL,
2229                         "`%%%smacro' expects a macro name",
2230                         (i == PP_IMACRO ? "i" : ""));
2231                 return 3;
2232             }
2233             defining = nasm_malloc(sizeof(MMacro));
2234             defining->name = nasm_strdup(tline->text);
2235             defining->casesense = (i == PP_MACRO);
2236             defining->plus = FALSE;
2237             defining->nolist = FALSE;
2238             defining->in_progress = FALSE;
2239             defining->rep_nest = NULL;
2240             tline = expand_smacro(tline->next);
2241             skip_white_(tline);
2242             if (!tok_type_(tline, TOK_NUMBER))
2243             {
2244                 error(ERR_NONFATAL,
2245                         "`%%%smacro' expects a parameter count",
2246                         (i == PP_IMACRO ? "i" : ""));
2247                 defining->nparam_min = defining->nparam_max = 0;
2248             }
2249             else
2250             {
2251                 defining->nparam_min = defining->nparam_max =
2252                         readnum(tline->text, &j);
2253                 if (j)
2254                     error(ERR_NONFATAL,
2255                             "unable to parse parameter count `%s'",
2256                             tline->text);
2257             }
2258             if (tline && tok_is_(tline->next, "-"))
2259             {
2260                 tline = tline->next->next;
2261                 if (tok_is_(tline, "*"))
2262                     defining->nparam_max = INT_MAX;
2263                 else if (!tok_type_(tline, TOK_NUMBER))
2264                     error(ERR_NONFATAL,
2265                             "`%%%smacro' expects a parameter count after `-'",
2266                             (i == PP_IMACRO ? "i" : ""));
2267                 else
2268                 {
2269                     defining->nparam_max = readnum(tline->text, &j);
2270                     if (j)
2271                         error(ERR_NONFATAL,
2272                                 "unable to parse parameter count `%s'",
2273                                 tline->text);
2274                     if (defining->nparam_min > defining->nparam_max)
2275                         error(ERR_NONFATAL,
2276                                 "minimum parameter count exceeds maximum");
2277                 }
2278             }
2279             if (tline && tok_is_(tline->next, "+"))
2280             {
2281                 tline = tline->next;
2282                 defining->plus = TRUE;
2283             }
2284             if (tline && tok_type_(tline->next, TOK_ID) &&
2285                     !nasm_stricmp(tline->next->text, ".nolist"))
2286             {
2287                 tline = tline->next;
2288                 defining->nolist = TRUE;
2289             }
2290             mmac = mmacros[hash(defining->name)];
2291             while (mmac)
2292             {
2293                 if (!strcmp(mmac->name, defining->name) &&
2294                         (mmac->nparam_min <= defining->nparam_max
2295                                 || defining->plus)
2296                         && (defining->nparam_min <= mmac->nparam_max
2297                                 || mmac->plus))
2298                 {
2299                     error(ERR_WARNING,
2300                             "redefining multi-line macro `%s'",
2301                             defining->name);
2302                     break;
2303                 }
2304                 mmac = mmac->next;
2305             }
2306             /*
2307              * Handle default parameters.
2308              */
2309             if (tline && tline->next)
2310             {
2311                 defining->dlist = tline->next;
2312                 tline->next = NULL;
2313                 count_mmac_params(defining->dlist, &defining->ndefs,
2314                         &defining->defaults);
2315             }
2316             else
2317             {
2318                 defining->dlist = NULL;
2319                 defining->defaults = NULL;
2320             }
2321             defining->expansion = NULL;
2322             free_tlist(origline);
2323             return 1;
2324
2325         case PP_ENDM:
2326         case PP_ENDMACRO:
2327             if (!defining)
2328             {
2329                 error(ERR_NONFATAL, "`%s': not defining a macro",
2330                         tline->text);
2331                 return 3;
2332             }
2333             k = hash(defining->name);
2334             defining->next = mmacros[k];
2335             mmacros[k] = defining;
2336             defining = NULL;
2337             free_tlist(origline);
2338             return 5;
2339
2340         case PP_ROTATE:
2341             if (tline->next && tline->next->type == TOK_WHITESPACE)
2342                 tline = tline->next;
2343             t = expand_smacro(tline->next);
2344             tline->next = NULL;
2345             free_tlist(origline);
2346             tline = t;
2347             tptr = &t;
2348             tokval.t_type = TOKEN_INVALID;
2349             evalresult =
2350                     evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2351             free_tlist(tline);
2352             if (!evalresult)
2353                 return 3;
2354             if (tokval.t_type)
2355                 error(ERR_WARNING,
2356                         "trailing garbage after expression ignored");
2357             if (!is_simple(evalresult))
2358             {
2359                 error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
2360                 return 3;
2361             }
2362             mmac = istk->mstk;
2363             while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
2364                 mmac = mmac->next_active;
2365             if (!mmac)
2366                 error(ERR_NONFATAL,
2367                         "`%%rotate' invoked outside a macro call");
2368             mmac->rotate = mmac->rotate + reloc_value(evalresult);
2369             if (mmac->rotate < 0)
2370                 mmac->rotate = mmac->nparam - (-mmac->rotate) % mmac->nparam;
2371             mmac->rotate %= mmac->nparam;
2372             return 1;
2373
2374         case PP_REP:
2375             nolist = FALSE;
2376             tline = tline->next;
2377             if (tline->next && tline->next->type == TOK_WHITESPACE)
2378                 tline = tline->next;
2379             if (tline->next && tline->next->type == TOK_ID &&
2380                     !nasm_stricmp(tline->next->text, ".nolist"))
2381             {
2382                 tline = tline->next;
2383                 nolist = TRUE;
2384             }
2385             t = expand_smacro(tline->next);
2386             tline->next = NULL;
2387             free_tlist(origline);
2388             tline = t;
2389             tptr = &t;
2390             tokval.t_type = TOKEN_INVALID;
2391             evalresult =
2392                     evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2393             free_tlist(tline);
2394             if (!evalresult)
2395                 return 3;
2396             if (tokval.t_type)
2397                 error(ERR_WARNING,
2398                         "trailing garbage after expression ignored");
2399             if (!is_simple(evalresult))
2400             {
2401                 error(ERR_NONFATAL, "non-constant value given to `%%rep'");
2402                 return 3;
2403             }
2404             tmp_defining = defining;
2405             defining = nasm_malloc(sizeof(MMacro));
2406             defining->name = NULL;      /* flags this macro as a %rep block */
2407             defining->casesense = 0;
2408             defining->plus = FALSE;
2409             defining->nolist = nolist;
2410             defining->in_progress = reloc_value(evalresult) + 1;
2411             defining->nparam_min = defining->nparam_max = 0;
2412             defining->defaults = NULL;
2413             defining->dlist = NULL;
2414             defining->expansion = NULL;
2415             defining->next_active = istk->mstk;
2416             defining->rep_nest = tmp_defining;
2417             return 1;
2418
2419         case PP_ENDREP:
2420             if (!defining || defining->name)
2421             {
2422                 error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
2423                 return 3;
2424             }
2425
2426             /*
2427              * Now we have a "macro" defined - although it has no name
2428              * and we won't be entering it in the hash tables - we must
2429              * push a macro-end marker for it on to istk->expansion.
2430              * After that, it will take care of propagating itself (a
2431              * macro-end marker line for a macro which is really a %rep
2432              * block will cause the macro to be re-expanded, complete
2433              * with another macro-end marker to ensure the process
2434              * continues) until the whole expansion is forcibly removed
2435              * from istk->expansion by a %exitrep.
2436              */
2437             l = nasm_malloc(sizeof(Line));
2438             l->next = istk->expansion;
2439             l->finishes = defining;
2440             l->first = NULL;
2441             istk->expansion = l;
2442
2443             istk->mstk = defining;
2444
2445             list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
2446             tmp_defining = defining;
2447             defining = defining->rep_nest;
2448             free_tlist(origline);
2449             return 1;
2450
2451         case PP_EXITREP:
2452             /*
2453              * We must search along istk->expansion until we hit a
2454              * macro-end marker for a macro with no name. Then we set
2455              * its `in_progress' flag to 0.
2456              */
2457             for (l = istk->expansion; l; l = l->next)
2458                 if (l->finishes && !l->finishes->name)
2459                     break;
2460
2461             if (l)
2462                 l->finishes->in_progress = 0;
2463             else
2464                 error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
2465             free_tlist(origline);
2466             return 1;
2467
2468         case PP_XDEFINE:
2469         case PP_IXDEFINE:
2470         case PP_DEFINE:
2471         case PP_IDEFINE:
2472             tline = tline->next;
2473             skip_white_(tline);
2474             tline = expand_id(tline);
2475             if (!tline || (tline->type != TOK_ID &&
2476                             (tline->type != TOK_PREPROC_ID ||
2477                                     tline->text[1] != '$')))
2478             {
2479                 error(ERR_NONFATAL,
2480                         "`%%%s%sdefine' expects a macro identifier",
2481                         ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""),
2482                         ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : ""));
2483                 free_tlist(origline);
2484                 return 3;
2485             }
2486
2487             ctx = get_ctx(tline->text, FALSE);
2488             if (!ctx)
2489                 smhead = &smacros[hash(tline->text)];
2490             else
2491                 smhead = &ctx->localmac;
2492             mname = tline->text;
2493             last = tline;
2494             param_start = tline = tline->next;
2495             nparam = 0;
2496
2497             /* Expand the macro definition now for %xdefine and %ixdefine */
2498             if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
2499                 tline = expand_smacro(tline);
2500
2501             if (tok_is_(tline, "("))
2502             {
2503                 /*
2504                  * This macro has parameters.
2505                  */
2506
2507                 tline = tline->next;
2508                 while (1)
2509                 {
2510                     skip_white_(tline);
2511                     if (!tline)
2512                     {
2513                         error(ERR_NONFATAL, "parameter identifier expected");
2514                         free_tlist(origline);
2515                         return 3;
2516                     }
2517                     if (tline->type != TOK_ID)
2518                     {
2519                         error(ERR_NONFATAL,
2520                                 "`%s': parameter identifier expected",
2521                                 tline->text);
2522                         free_tlist(origline);
2523                         return 3;
2524                     }
2525                     tline->type = TOK_SMAC_PARAM + nparam++;
2526                     tline = tline->next;
2527                     skip_white_(tline);
2528                     if (tok_is_(tline, ","))
2529                     {
2530                         tline = tline->next;
2531                         continue;
2532                     }
2533                     if (!tok_is_(tline, ")"))
2534                     {
2535                         error(ERR_NONFATAL,
2536                                 "`)' expected to terminate macro template");
2537                         free_tlist(origline);
2538                         return 3;
2539                     }
2540                     break;
2541                 }
2542                 last = tline;
2543                 tline = tline->next;
2544             }
2545             if (tok_type_(tline, TOK_WHITESPACE))
2546                 last = tline, tline = tline->next;
2547             macro_start = NULL;
2548             last->next = NULL;
2549             t = tline;
2550             while (t)
2551             {
2552                 if (t->type == TOK_ID)
2553                 {
2554                     for (tt = param_start; tt; tt = tt->next)
2555                         if (tt->type >= TOK_SMAC_PARAM &&
2556                                 !strcmp(tt->text, t->text))
2557                             t->type = tt->type;
2558                 }
2559                 tt = t->next;
2560                 t->next = macro_start;
2561                 macro_start = t;
2562                 t = tt;
2563             }
2564             /*
2565              * Good. We now have a macro name, a parameter count, and a
2566              * token list (in reverse order) for an expansion. We ought
2567              * to be OK just to create an SMacro, store it, and let
2568              * free_tlist have the rest of the line (which we have
2569              * carefully re-terminated after chopping off the expansion
2570              * from the end).
2571              */
2572             if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE))
2573             {
2574                 if (!smac)
2575                 {
2576                     error(ERR_WARNING,
2577                             "single-line macro `%s' defined both with and"
2578                             " without parameters", mname);
2579                     free_tlist(origline);
2580                     free_tlist(macro_start);
2581                     return 3;
2582                 }
2583                 else
2584                 {
2585                     /*
2586                      * We're redefining, so we have to take over an
2587                      * existing SMacro structure. This means freeing
2588                      * what was already in it.
2589                      */
2590                     nasm_free(smac->name);
2591                     free_tlist(smac->expansion);
2592                 }
2593             }
2594             else
2595             {
2596                 smac = nasm_malloc(sizeof(SMacro));
2597                 smac->next = *smhead;
2598                 *smhead = smac;
2599             }
2600             smac->name = nasm_strdup(mname);
2601             smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE));
2602             smac->nparam = nparam;
2603             smac->expansion = macro_start;
2604             smac->in_progress = FALSE;
2605             free_tlist(origline);
2606             return 3;
2607
2608         case PP_UNDEF:
2609             tline = tline->next;
2610             skip_white_(tline);
2611             tline = expand_id(tline);
2612             if (!tline || (tline->type != TOK_ID &&
2613                             (tline->type != TOK_PREPROC_ID ||
2614                                     tline->text[1] != '$')))
2615             {
2616                 error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
2617                 free_tlist(origline);
2618                 return 3;
2619             }
2620             if (tline->next)
2621             {
2622                 error(ERR_WARNING,
2623                         "trailing garbage after macro name ignored");
2624             }
2625
2626             /* Find the context that symbol belongs to */
2627             ctx = get_ctx(tline->text, FALSE);
2628             if (!ctx)
2629                 smhead = &smacros[hash(tline->text)];
2630             else
2631                 smhead = &ctx->localmac;
2632
2633             mname = tline->text;
2634             last = tline;
2635             last->next = NULL;
2636
2637             /*
2638              * We now have a macro name... go hunt for it.
2639              */
2640             while (smacro_defined(ctx, mname, -1, &smac, 1))
2641             {
2642                 /* Defined, so we need to find its predecessor and nuke it */
2643                 SMacro **s;
2644                 for (s = smhead; *s && *s != smac; s = &(*s)->next);
2645                 if (*s)
2646                 {
2647                     *s = smac->next;
2648                     nasm_free(smac->name);
2649                     free_tlist(smac->expansion);
2650                     nasm_free(smac);
2651                 }
2652             }
2653             free_tlist(origline);
2654             return 3;
2655
2656         case PP_STRLEN:
2657             tline = tline->next;
2658             skip_white_(tline);
2659             tline = expand_id(tline);
2660             if (!tline || (tline->type != TOK_ID &&
2661                             (tline->type != TOK_PREPROC_ID ||
2662                                     tline->text[1] != '$')))
2663             {
2664                 error(ERR_NONFATAL,
2665                         "`%%strlen' expects a macro identifier as first parameter");
2666                 free_tlist(origline);
2667                 return 3;
2668             }
2669             ctx = get_ctx(tline->text, FALSE);
2670             if (!ctx)
2671                 smhead = &smacros[hash(tline->text)];
2672             else
2673                 smhead = &ctx->localmac;
2674             mname = tline->text;
2675             last = tline;
2676             tline = expand_smacro(tline->next);
2677             last->next = NULL;
2678
2679             t = tline;
2680             while (tok_type_(t, TOK_WHITESPACE))
2681                 t = t->next;
2682             /* t should now point to the string */
2683             if (t->type != TOK_STRING)
2684             {
2685                 error(ERR_NONFATAL,
2686                         "`%%strlen` requires string as second parameter");
2687                 free_tlist(tline);
2688                 free_tlist(origline);
2689                 return 3;
2690             }
2691
2692             macro_start = nasm_malloc(sizeof(*macro_start));
2693             macro_start->next = NULL;
2694             make_tok_num(macro_start, strlen(t->text) - 2);
2695             macro_start->mac = NULL;
2696
2697             /*
2698              * We now have a macro name, an implicit parameter count of
2699              * zero, and a numeric token to use as an expansion. Create
2700              * and store an SMacro.
2701              */
2702             if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN))
2703             {
2704                 if (!smac)
2705                     error(ERR_WARNING,
2706                             "single-line macro `%s' defined both with and"
2707                             " without parameters", mname);
2708                 else
2709                 {
2710                     /*
2711                      * We're redefining, so we have to take over an
2712                      * existing SMacro structure. This means freeing
2713                      * what was already in it.
2714                      */
2715                     nasm_free(smac->name);
2716                     free_tlist(smac->expansion);
2717                 }
2718             }
2719             else
2720             {
2721                 smac = nasm_malloc(sizeof(SMacro));
2722                 smac->next = *smhead;
2723                 *smhead = smac;
2724             }
2725             smac->name = nasm_strdup(mname);
2726             smac->casesense = (i == PP_STRLEN);
2727             smac->nparam = 0;
2728             smac->expansion = macro_start;
2729             smac->in_progress = FALSE;
2730             free_tlist(tline);
2731             free_tlist(origline);
2732             return 3;
2733
2734         case PP_SUBSTR:
2735             tline = tline->next;
2736             skip_white_(tline);
2737             tline = expand_id(tline);
2738             if (!tline || (tline->type != TOK_ID &&
2739                             (tline->type != TOK_PREPROC_ID ||
2740                                     tline->text[1] != '$')))
2741             {
2742                 error(ERR_NONFATAL,
2743                         "`%%substr' expects a macro identifier as first parameter");
2744                 free_tlist(origline);
2745                 return 3;
2746             }
2747             ctx = get_ctx(tline->text, FALSE);
2748             if (!ctx)
2749                 smhead = &smacros[hash(tline->text)];
2750             else
2751                 smhead = &ctx->localmac;
2752             mname = tline->text;
2753             last = tline;
2754             tline = expand_smacro(tline->next);
2755             last->next = NULL;
2756
2757             t = tline->next;
2758             while (tok_type_(t, TOK_WHITESPACE))
2759                 t = t->next;
2760
2761             /* t should now point to the string */
2762             if (t->type != TOK_STRING)
2763             {
2764                 error(ERR_NONFATAL,
2765                         "`%%substr` requires string as second parameter");
2766                 free_tlist(tline);
2767                 free_tlist(origline);
2768                 return 3;
2769             }
2770
2771             tt = t->next;
2772             tptr = &tt;
2773             tokval.t_type = TOKEN_INVALID;
2774             evalresult =
2775                     evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2776             if (!evalresult)
2777             {
2778                 free_tlist(tline);
2779                 free_tlist(origline);
2780                 return 3;
2781             }
2782             if (!is_simple(evalresult))
2783             {
2784                 error(ERR_NONFATAL, "non-constant value given to `%%substr`");
2785                 free_tlist(tline);
2786                 free_tlist(origline);
2787                 return 3;
2788             }
2789
2790             macro_start = nasm_malloc(sizeof(*macro_start));
2791             macro_start->next = NULL;
2792             macro_start->text = nasm_strdup("'''");
2793             if (evalresult->value > 0
2794                     && evalresult->value < strlen(t->text) - 1)
2795             {
2796                 macro_start->text[1] = t->text[evalresult->value];
2797             }
2798             else
2799             {
2800                 macro_start->text[2] = '\0';
2801             }
2802             macro_start->type = TOK_STRING;
2803             macro_start->mac = NULL;
2804
2805             /*
2806              * We now have a macro name, an implicit parameter count of
2807              * zero, and a numeric token to use as an expansion. Create
2808              * and store an SMacro.
2809              */
2810             if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR))
2811             {
2812                 if (!smac)
2813                     error(ERR_WARNING,
2814                             "single-line macro `%s' defined both with and"
2815                             " without parameters", mname);
2816                 else
2817                 {
2818                     /*
2819                      * We're redefining, so we have to take over an
2820                      * existing SMacro structure. This means freeing
2821                      * what was already in it.
2822                      */
2823                     nasm_free(smac->name);
2824                     free_tlist(smac->expansion);
2825                 }
2826             }
2827             else
2828             {
2829                 smac = nasm_malloc(sizeof(SMacro));
2830                 smac->next = *smhead;
2831                 *smhead = smac;
2832             }
2833             smac->name = nasm_strdup(mname);
2834             smac->casesense = (i == PP_SUBSTR);
2835             smac->nparam = 0;
2836             smac->expansion = macro_start;
2837             smac->in_progress = FALSE;
2838             free_tlist(tline);
2839             free_tlist(origline);
2840             return 3;
2841
2842
2843         case PP_ASSIGN:
2844         case PP_IASSIGN:
2845             tline = tline->next;
2846             skip_white_(tline);
2847             tline = expand_id(tline);
2848             if (!tline || (tline->type != TOK_ID &&
2849                             (tline->type != TOK_PREPROC_ID ||
2850                                     tline->text[1] != '$')))
2851             {
2852                 error(ERR_NONFATAL,
2853                         "`%%%sassign' expects a macro identifier",
2854                         (i == PP_IASSIGN ? "i" : ""));
2855                 free_tlist(origline);
2856                 return 3;
2857             }
2858             ctx = get_ctx(tline->text, FALSE);
2859             if (!ctx)
2860                 smhead = &smacros[hash(tline->text)];
2861             else
2862                 smhead = &ctx->localmac;
2863             mname = tline->text;
2864             last = tline;
2865             tline = expand_smacro(tline->next);
2866             last->next = NULL;
2867
2868             t = tline;
2869             tptr = &t;
2870             tokval.t_type = TOKEN_INVALID;
2871             evalresult =
2872                     evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2873             free_tlist(tline);
2874             if (!evalresult)
2875             {
2876                 free_tlist(origline);
2877                 return 3;
2878             }
2879
2880             if (tokval.t_type)
2881                 error(ERR_WARNING,
2882                         "trailing garbage after expression ignored");
2883
2884             if (!is_simple(evalresult))
2885             {
2886                 error(ERR_NONFATAL,
2887                         "non-constant value given to `%%%sassign'",
2888                         (i == PP_IASSIGN ? "i" : ""));
2889                 free_tlist(origline);
2890                 return 3;
2891             }
2892
2893             macro_start = nasm_malloc(sizeof(*macro_start));
2894             macro_start->next = NULL;
2895             make_tok_num(macro_start, reloc_value(evalresult));
2896             macro_start->mac = NULL;
2897
2898             /*
2899              * We now have a macro name, an implicit parameter count of
2900              * zero, and a numeric token to use as an expansion. Create
2901              * and store an SMacro.
2902              */
2903             if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN))
2904             {
2905                 if (!smac)
2906                     error(ERR_WARNING,
2907                             "single-line macro `%s' defined both with and"
2908                             " without parameters", mname);
2909                 else
2910                 {
2911                     /*
2912                      * We're redefining, so we have to take over an
2913                      * existing SMacro structure. This means freeing
2914                      * what was already in it.
2915                      */
2916                     nasm_free(smac->name);
2917                     free_tlist(smac->expansion);
2918                 }
2919             }
2920             else
2921             {
2922                 smac = nasm_malloc(sizeof(SMacro));
2923                 smac->next = *smhead;
2924                 *smhead = smac;
2925             }
2926             smac->name = nasm_strdup(mname);
2927             smac->casesense = (i == PP_ASSIGN);
2928             smac->nparam = 0;
2929             smac->expansion = macro_start;
2930             smac->in_progress = FALSE;
2931             free_tlist(origline);
2932             return 3;
2933
2934         case PP_LINE:
2935             /*
2936              * Syntax is `%line nnn[+mmm] [filename]'
2937              */
2938             tline = tline->next;
2939             skip_white_(tline);
2940             if (!tok_type_(tline, TOK_NUMBER))
2941             {
2942                 error(ERR_NONFATAL, "`%%line' expects line number");
2943                 free_tlist(origline);
2944                 return 3;
2945             }
2946             k = readnum(tline->text, &j);
2947             m = 1;
2948             tline = tline->next;
2949             if (tok_is_(tline, "+"))
2950             {
2951                 tline = tline->next;
2952                 if (!tok_type_(tline, TOK_NUMBER))
2953                 {
2954                     error(ERR_NONFATAL, "`%%line' expects line increment");
2955                     free_tlist(origline);
2956                     return 3;
2957                 }
2958                 m = readnum(tline->text, &j);
2959                 tline = tline->next;
2960             }
2961             skip_white_(tline);
2962             src_set_linnum(k);
2963             istk->lineinc = m;
2964             if (tline)
2965             {
2966                 nasm_free(src_set_fname(detoken(tline, FALSE)));
2967             }
2968             free_tlist(origline);
2969             return 5;
2970
2971         default:
2972             error(ERR_FATAL,
2973                     "preprocessor directive `%s' not yet implemented",
2974                     directives[i]);
2975             break;
2976     }
2977     return 3;
2978 }
2979
2980 /*
2981  * Ensure that a macro parameter contains a condition code and
2982  * nothing else. Return the condition code index if so, or -1
2983  * otherwise.
2984  */
2985 static int
2986 find_cc(Token * t)
2987 {
2988     Token *tt;
2989     int i, j, k, m;
2990
2991     skip_white_(t);
2992     if (t->type != TOK_ID)
2993         return -1;
2994     tt = t->next;
2995     skip_white_(tt);
2996     if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
2997         return -1;
2998
2999     i = -1;
3000     j = sizeof(conditions) / sizeof(*conditions);
3001     while (j - i > 1)
3002     {
3003         k = (j + i) / 2;
3004         m = nasm_stricmp(t->text, conditions[k]);
3005         if (m == 0)
3006         {
3007             i = k;
3008             j = -2;
3009             break;
3010         }
3011         else if (m < 0)
3012         {
3013             j = k;
3014         }
3015         else
3016             i = k;
3017     }
3018     if (j != -2)
3019         return -1;
3020     return i;
3021 }
3022
3023 /*
3024  * Expand MMacro-local things: parameter references (%0, %n, %+n,
3025  * %-n) and MMacro-local identifiers (%%foo).
3026  */
3027 static Token *
3028 expand_mmac_params(Token * tline)
3029 {
3030     Token *t, *tt, **tail, *thead;
3031
3032     tail = &thead;
3033     thead = NULL;
3034
3035     while (tline)
3036     {
3037         if (tline->type == TOK_PREPROC_ID &&
3038                 (((tline->text[1] == '+' || tline->text[1] == '-')
3039                                 && tline->text[2]) || tline->text[1] == '%'
3040                         || (tline->text[1] >= '0' && tline->text[1] <= '9')))
3041         {
3042             char *text = NULL;
3043             int type = 0, cc;   /* type = 0 to placate optimisers */
3044             char tmpbuf[30];
3045             int n, i;
3046             MMacro *mac;
3047
3048             t = tline;
3049             tline = tline->next;
3050
3051             mac = istk->mstk;
3052             while (mac && !mac->name)   /* avoid mistaking %reps for macros */
3053                 mac = mac->next_active;
3054             if (!mac)
3055                 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
3056             else
3057                 switch (t->text[1])
3058                 {
3059                         /*
3060                          * We have to make a substitution of one of the
3061                          * forms %1, %-1, %+1, %%foo, %0.
3062                          */
3063                     case '0':
3064                         type = TOK_NUMBER;
3065                         sprintf(tmpbuf, "%d", mac->nparam);
3066                         text = nasm_strdup(tmpbuf);
3067                         break;
3068                     case '%':
3069                         type = TOK_ID;
3070                         sprintf(tmpbuf, "..@%lu.", mac->unique);
3071                         text = nasm_strcat(tmpbuf, t->text + 2);
3072                         break;
3073                     case '-':
3074                         n = atoi(t->text + 2) - 1;
3075                         if (n >= mac->nparam)
3076                             tt = NULL;
3077                         else
3078                         {
3079                             if (mac->nparam > 1)
3080                                 n = (n + mac->rotate) % mac->nparam;
3081                             tt = mac->params[n];
3082                         }
3083                         cc = find_cc(tt);
3084                         if (cc == -1)
3085                         {
3086                             error(ERR_NONFATAL,
3087                                     "macro parameter %d is not a condition code",
3088                                     n + 1);
3089                             text = NULL;
3090                         }
3091                         else
3092                         {
3093                             type = TOK_ID;
3094                             if (inverse_ccs[cc] == -1)
3095                             {
3096                                 error(ERR_NONFATAL,
3097                                         "condition code `%s' is not invertible",
3098                                         conditions[cc]);
3099                                 text = NULL;
3100                             }
3101                             else
3102                                 text =
3103                                         nasm_strdup(conditions[inverse_ccs
3104                                                  [cc]]);
3105                         }
3106                         break;
3107                     case '+':
3108                         n = atoi(t->text + 2) - 1;
3109                         if (n >= mac->nparam)
3110                             tt = NULL;
3111                         else
3112                         {
3113                             if (mac->nparam > 1)
3114                                 n = (n + mac->rotate) % mac->nparam;
3115                             tt = mac->params[n];
3116                         }
3117                         cc = find_cc(tt);
3118                         if (cc == -1)
3119                         {
3120                             error(ERR_NONFATAL,
3121                                     "macro parameter %d is not a condition code",
3122                                     n + 1);
3123                             text = NULL;
3124                         }
3125                         else
3126                         {
3127                             type = TOK_ID;
3128                             text = nasm_strdup(conditions[cc]);
3129                         }
3130                         break;
3131                     default:
3132                         n = atoi(t->text + 1) - 1;
3133                         if (n >= mac->nparam)
3134                             tt = NULL;
3135                         else
3136                         {
3137                             if (mac->nparam > 1)
3138                                 n = (n + mac->rotate) % mac->nparam;
3139                             tt = mac->params[n];
3140                         }
3141                         if (tt)
3142                         {
3143                             for (i = 0; i < mac->paramlen[n]; i++)
3144                             {
3145                                 *tail =
3146                                         new_Token(NULL, tt->type, tt->text,
3147                                         0);
3148                                 tail = &(*tail)->next;
3149                                 tt = tt->next;
3150                             }
3151                         }
3152                         text = NULL;    /* we've done it here */
3153                         break;
3154                 }
3155             if (!text)
3156             {
3157                 delete_Token(t);
3158             }
3159             else
3160             {
3161                 *tail = t;
3162                 tail = &t->next;
3163                 t->type = type;
3164                 nasm_free(t->text);
3165                 t->text = text;
3166                 t->mac = NULL;
3167             }
3168             continue;
3169         }
3170         else
3171         {
3172             t = *tail = tline;
3173             tline = tline->next;
3174             t->mac = NULL;
3175             tail = &t->next;
3176         }
3177     }
3178     *tail = NULL;
3179     t = thead;
3180     for (; t && (tt = t->next) != NULL; t = t->next)
3181         switch (t->type)
3182         {
3183             case TOK_WHITESPACE:
3184                 if (tt->type == TOK_WHITESPACE)
3185                 {
3186                     t->next = delete_Token(tt);
3187                 }
3188                 break;
3189             case TOK_ID:
3190                 if (tt->type == TOK_ID || tt->type == TOK_NUMBER)
3191                 {
3192                     char *tmp = nasm_strcat(t->text, tt->text);
3193                     nasm_free(t->text);
3194                     t->text = tmp;
3195                     t->next = delete_Token(tt);
3196                 }
3197                 break;
3198             case TOK_NUMBER:
3199                 if (tt->type == TOK_NUMBER)
3200                 {
3201                     char *tmp = nasm_strcat(t->text, tt->text);
3202                     nasm_free(t->text);
3203                     t->text = tmp;
3204                     t->next = delete_Token(tt);
3205                 }
3206                 break;
3207         }
3208
3209     return thead;
3210 }
3211
3212 /*
3213  * Expand all single-line macro calls made in the given line.
3214  * Return the expanded version of the line. The original is deemed
3215  * to be destroyed in the process. (In reality we'll just move
3216  * Tokens from input to output a lot of the time, rather than
3217  * actually bothering to destroy and replicate.)
3218  */
3219 static Token *
3220 expand_smacro(Token * tline)
3221 {
3222     Token *t, *tt, *mstart, **tail, *thead;
3223     SMacro *head = NULL, *m;
3224     Token **params;
3225     int *paramsize;
3226     int nparam, sparam, brackets, rescan;
3227     Token *org_tline = tline;
3228     Context *ctx;
3229     char *mname;
3230
3231     /*
3232      * Trick: we should avoid changing the start token pointer since it can
3233      * be contained in "next" field of other token. Because of this
3234      * we allocate a copy of first token and work with it; at the end of
3235      * routine we copy it back
3236      */
3237     if (org_tline)
3238     {
3239         tline =
3240                 new_Token(org_tline->next, org_tline->type, org_tline->text,
3241                 0);
3242         tline->mac = org_tline->mac;
3243         nasm_free(org_tline->text);
3244         org_tline->text = NULL;
3245     }
3246
3247   again:
3248     tail = &thead;
3249     thead = NULL;
3250
3251     while (tline)
3252     {                           /* main token loop */
3253         if ((mname = tline->text))
3254         {
3255             /* if this token is a local macro, look in local context */
3256             if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
3257                 ctx = get_ctx(mname, TRUE);
3258             else
3259                 ctx = NULL;
3260             if (!ctx)
3261                 head = smacros[hash(mname)];
3262             else
3263                 head = ctx->localmac;
3264             /*
3265              * We've hit an identifier. As in is_mmacro below, we first
3266              * check whether the identifier is a single-line macro at
3267              * all, then think about checking for parameters if
3268              * necessary.
3269              */
3270             for (m = head; m; m = m->next)
3271                 if (!mstrcmp(m->name, mname, m->casesense))
3272                     break;
3273             if (m)
3274             {
3275                 mstart = tline;
3276                 params = NULL;
3277                 paramsize = NULL;
3278                 if (m->nparam == 0)
3279                 {
3280                     /*
3281                      * Simple case: the macro is parameterless. Discard the
3282                      * one token that the macro call took, and push the
3283                      * expansion back on the to-do stack.
3284                      */
3285                     if (!m->expansion)
3286                     {
3287                         if (!strcmp("__FILE__", m->name))
3288                         {
3289                             long num = 0;
3290                             src_get(&num, &(tline->text));
3291                             nasm_quote(&(tline->text));
3292                             tline->type = TOK_STRING;
3293                             continue;
3294                         }
3295                         if (!strcmp("__LINE__", m->name))
3296                         {
3297                             nasm_free(tline->text);
3298                             make_tok_num(tline, src_get_linnum());
3299                             continue;
3300                         }
3301                         tline = delete_Token(tline);
3302                         continue;
3303                     }
3304                 }
3305                 else
3306                 {
3307                     /*
3308                      * Complicated case: at least one macro with this name
3309                      * exists and takes parameters. We must find the
3310                      * parameters in the call, count them, find the SMacro
3311                      * that corresponds to that form of the macro call, and
3312                      * substitute for the parameters when we expand. What a
3313                      * pain.
3314                      */
3315                     tline = tline->next;
3316                     skip_white_(tline);
3317                     if (!tok_is_(tline, "("))
3318                     {
3319                         /*
3320                          * This macro wasn't called with parameters: ignore
3321                          * the call. (Behaviour borrowed from gnu cpp.)
3322                          */
3323                         tline = mstart;
3324                         m = NULL;
3325                     }
3326                     else
3327                     {
3328                         int paren = 0;
3329                         int white = 0;
3330                         brackets = 0;
3331                         nparam = 0;
3332                         tline = tline->next;
3333                         sparam = PARAM_DELTA;
3334                         params = nasm_malloc(sparam * sizeof(Token *));
3335                         params[0] = tline;
3336                         paramsize = nasm_malloc(sparam * sizeof(int));
3337                         paramsize[0] = 0;
3338                         for (;; tline = tline->next)
3339                         {       /* parameter loop */
3340                             if (!tline)
3341                             {
3342                                 error(ERR_NONFATAL,
3343                                         "macro call expects terminating `)'");
3344                                 break;
3345                             }
3346                             if (tline->type == TOK_WHITESPACE
3347                                     && brackets <= 0)
3348                             {
3349                                 if (paramsize[nparam])
3350                                     white++;
3351                                 else
3352                                     params[nparam] = tline->next;
3353                                 continue;       /* parameter loop */
3354                             }
3355                             if (tline->type == TOK_OTHER
3356                                     && tline->text[1] == 0)
3357                             {
3358                                 char ch = tline->text[0];
3359                                 if (ch == ',' && !paren && brackets <= 0)
3360                                 {
3361                                     if (++nparam >= sparam)
3362                                     {
3363                                         sparam += PARAM_DELTA;
3364                                         params = nasm_realloc(params,
3365                                                 sparam * sizeof(Token *));
3366                                         paramsize = nasm_realloc(paramsize,
3367                                                 sparam * sizeof(int));
3368                                     }
3369                                     params[nparam] = tline->next;
3370                                     paramsize[nparam] = 0;
3371                                     white = 0;
3372                                     continue;   /* parameter loop */
3373                                 }
3374                                 if (ch == '{' &&
3375                                         (brackets > 0 || (brackets == 0 &&
3376                                                         !paramsize[nparam])))
3377                                 {
3378                                     if (!(brackets++))
3379                                     {
3380                                         params[nparam] = tline->next;
3381                                         continue;       /* parameter loop */
3382                                     }
3383                                 }
3384                                 if (ch == '}' && brackets > 0)
3385                                     if (--brackets == 0)
3386                                     {
3387                                         brackets = -1;
3388                                         continue;       /* parameter loop */
3389                                     }
3390                                 if (ch == '(' && !brackets)
3391                                     paren++;
3392                                 if (ch == ')' && brackets <= 0)
3393                                     if (--paren < 0)
3394                                         break;
3395                             }
3396                             if (brackets < 0)
3397                             {
3398                                 brackets = 0;
3399                                 error(ERR_NONFATAL, "braces do not "
3400                                         "enclose all of macro parameter");
3401                             }
3402                             paramsize[nparam] += white + 1;
3403                             white = 0;
3404                         }       /* parameter loop */
3405                         nparam++;
3406                         while (m && (m->nparam != nparam ||
3407                                         mstrcmp(m->name, mname,
3408                                                 m->casesense)))
3409                             m = m->next;
3410                         if (!m)
3411                             error(ERR_WARNING | ERR_WARN_MNP,
3412                                     "macro `%s' exists, "
3413                                     "but not taking %d parameters",
3414                                     mstart->text, nparam);
3415                     }
3416                 }
3417                 if (m && m->in_progress)
3418                     m = NULL;
3419                 if (!m)         /* in progess or didn't find '(' or wrong nparam */
3420                 {
3421                     /* 
3422                      * Design question: should we handle !tline, which
3423                      * indicates missing ')' here, or expand those
3424                      * macros anyway, which requires the (t) test a few
3425                      * lines down?  
3426                      */
3427                     nasm_free(params);
3428                     nasm_free(paramsize);
3429                     tline = mstart;
3430                 }
3431                 else
3432                 {
3433                     /*
3434                      * Expand the macro: we are placed on the last token of the
3435                      * call, so that we can easily split the call from the
3436                      * following tokens. We also start by pushing an SMAC_END
3437                      * token for the cycle removal.
3438                      */
3439                     t = tline;
3440                     if (t)
3441                     {
3442                         tline = t->next;
3443                         t->next = NULL;
3444                     }
3445                     tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
3446                     tt->mac = m;
3447                     m->in_progress = TRUE;
3448                     tline = tt;
3449                     for (t = m->expansion; t; t = t->next)
3450                     {
3451                         if (t->type >= TOK_SMAC_PARAM)
3452                         {
3453                             Token *pcopy = tline, **ptail = &pcopy;
3454                             Token *ttt, *pt;
3455                             int i;
3456
3457                             ttt = params[t->type - TOK_SMAC_PARAM];
3458                             for (i = paramsize[t->type - TOK_SMAC_PARAM];
3459                                     --i >= 0;)
3460                             {
3461                                 pt = *ptail =
3462                                         new_Token(tline, ttt->type, ttt->text,
3463                                         0);
3464                                 ptail = &pt->next;
3465                                 ttt = ttt->next;
3466                             }
3467                             tline = pcopy;
3468                         }
3469                         else
3470                         {
3471                             tt = new_Token(tline, t->type, t->text, 0);
3472                             tline = tt;
3473                         }
3474                     }
3475
3476                     /*
3477                      * Having done that, get rid of the macro call, and clean
3478                      * up the parameters.
3479                      */
3480                     nasm_free(params);
3481                     nasm_free(paramsize);
3482                     free_tlist(mstart);
3483                     continue;   /* main token loop */
3484                 }
3485             }
3486         }
3487
3488         if (tline->type == TOK_SMAC_END)
3489         {
3490             tline->mac->in_progress = FALSE;
3491             tline = delete_Token(tline);
3492         }
3493         else
3494         {
3495             t = *tail = tline;
3496             tline = tline->next;
3497             t->mac = NULL;
3498             t->next = NULL;
3499             tail = &t->next;
3500         }
3501     }
3502
3503     /*
3504      * Now scan the entire line and look for successive TOK_IDs that resulted
3505      * after expansion (they can't be produced by tokenise()). The successive
3506      * TOK_IDs should be concatenated.
3507      * Also we look for %+ tokens and concatenate the tokens before and after
3508      * them (without white spaces in between).
3509      */
3510     t = thead;
3511     rescan = 0;
3512     while (t)
3513     {
3514         while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
3515             t = t->next;
3516         if (!t || !t->next)
3517             break;
3518         if (t->next->type == TOK_ID ||
3519                 t->next->type == TOK_PREPROC_ID ||
3520                 t->next->type == TOK_NUMBER)
3521         {
3522             char *p = nasm_strcat(t->text, t->next->text);
3523             nasm_free(t->text);
3524             t->next = delete_Token(t->next);
3525             t->text = p;
3526             rescan = 1;
3527         }
3528         else if (t->next->type == TOK_WHITESPACE && t->next->next &&
3529                 t->next->next->type == TOK_PREPROC_ID &&
3530                 strcmp(t->next->next->text, "%+") == 0)
3531         {
3532             /* free the next whitespace, the %+ token and next whitespace */
3533             int i;
3534             for (i = 1; i <= 3; i++)
3535             {
3536                 if (!t->next || (i != 2 && t->next->type != TOK_WHITESPACE))
3537                     break;
3538                 t->next = delete_Token(t->next);
3539             }                   /* endfor */
3540         }
3541         else
3542             t = t->next;
3543     }
3544     /* If we concatenaded something, re-scan the line for macros */
3545     if (rescan)
3546     {
3547         tline = thead;
3548         goto again;
3549     }
3550
3551     if (org_tline)
3552     {
3553         if (thead)
3554         {
3555             *org_tline = *thead;
3556             /* since we just gave text to org_line, don't free it */
3557             thead->text = NULL;
3558             delete_Token(thead);
3559         }
3560         else
3561         {
3562             /* the expression expanded to empty line;
3563                we can't return NULL for some reasons
3564                we just set the line to a single WHITESPACE token. */
3565             memset(org_tline, 0, sizeof(*org_tline));
3566             org_tline->text = NULL;
3567             org_tline->type = TOK_WHITESPACE;
3568         }
3569         thead = org_tline;
3570     }
3571
3572     return thead;
3573 }
3574
3575 /*
3576  * Similar to expand_smacro but used exclusively with macro identifiers
3577  * right before they are fetched in. The reason is that there can be
3578  * identifiers consisting of several subparts. We consider that if there
3579  * are more than one element forming the name, user wants a expansion,
3580  * otherwise it will be left as-is. Example:
3581  *
3582  *      %define %$abc cde
3583  *
3584  * the identifier %$abc will be left as-is so that the handler for %define
3585  * will suck it and define the corresponding value. Other case:
3586  *
3587  *      %define _%$abc cde
3588  *
3589  * In this case user wants name to be expanded *before* %define starts
3590  * working, so we'll expand %$abc into something (if it has a value;
3591  * otherwise it will be left as-is) then concatenate all successive
3592  * PP_IDs into one.
3593  */
3594 static Token *
3595 expand_id(Token * tline)
3596 {
3597     Token *cur, *oldnext = NULL;
3598
3599     if (!tline || !tline->next)
3600         return tline;
3601
3602     cur = tline;
3603     while (cur->next &&
3604             (cur->next->type == TOK_ID ||
3605         cur->next->type == TOK_PREPROC_ID || cur->next->type == TOK_NUMBER))
3606         cur = cur->next;
3607
3608     /* If identifier consists of just one token, don't expand */
3609     if (cur == tline)
3610         return tline;
3611
3612     if (cur)
3613     {
3614         oldnext = cur->next;    /* Detach the tail past identifier */
3615         cur->next = NULL;       /* so that expand_smacro stops here */
3616     }
3617
3618     tline = expand_smacro(tline);
3619
3620     if (cur)
3621     {
3622         /* expand_smacro possibly changhed tline; re-scan for EOL */
3623         cur = tline;
3624         while (cur && cur->next)
3625             cur = cur->next;
3626         if (cur)
3627             cur->next = oldnext;
3628     }
3629
3630     return tline;
3631 }
3632
3633 /*
3634  * Determine whether the given line constitutes a multi-line macro
3635  * call, and return the MMacro structure called if so. Doesn't have
3636  * to check for an initial label - that's taken care of in
3637  * expand_mmacro - but must check numbers of parameters. Guaranteed
3638  * to be called with tline->type == TOK_ID, so the putative macro
3639  * name is easy to find.
3640  */
3641 static MMacro *
3642 is_mmacro(Token * tline, Token *** params_array)
3643 {
3644     MMacro *head, *m;
3645     Token **params;
3646     int nparam;
3647
3648     head = mmacros[hash(tline->text)];
3649
3650     /*
3651      * Efficiency: first we see if any macro exists with the given
3652      * name. If not, we can return NULL immediately. _Then_ we
3653      * count the parameters, and then we look further along the
3654      * list if necessary to find the proper MMacro.
3655      */
3656     for (m = head; m; m = m->next)
3657         if (!mstrcmp(m->name, tline->text, m->casesense))
3658             break;
3659     if (!m)
3660         return NULL;
3661
3662     /*
3663      * OK, we have a potential macro. Count and demarcate the
3664      * parameters.
3665      */
3666     count_mmac_params(tline->next, &nparam, &params);
3667
3668     /*
3669      * So we know how many parameters we've got. Find the MMacro
3670      * structure that handles this number.
3671      */
3672     while (m)
3673     {
3674         if (m->nparam_min <= nparam && (m->plus || nparam <= m->nparam_max))
3675         {
3676             /*
3677              * This one is right. Just check if cycle removal
3678              * prohibits us using it before we actually celebrate...
3679              */
3680             if (m->in_progress)
3681             {
3682 #if 0
3683                 error(ERR_NONFATAL,
3684                         "self-reference in multi-line macro `%s'", m->name);
3685 #endif
3686                 nasm_free(params);
3687                 return NULL;
3688             }
3689             /*
3690              * It's right, and we can use it. Add its default
3691              * parameters to the end of our list if necessary.
3692              */
3693             if (m->defaults && nparam < m->nparam_min + m->ndefs)
3694             {
3695                 params =
3696                         nasm_realloc(params,
3697                         ((m->nparam_min + m->ndefs + 1) * sizeof(*params)));
3698                 while (nparam < m->nparam_min + m->ndefs)
3699                 {
3700                     params[nparam] = m->defaults[nparam - m->nparam_min];
3701                     nparam++;
3702                 }
3703             }
3704             /*
3705              * If we've gone over the maximum parameter count (and
3706              * we're in Plus mode), ignore parameters beyond
3707              * nparam_max.
3708              */
3709             if (m->plus && nparam > m->nparam_max)
3710                 nparam = m->nparam_max;
3711             /*
3712              * Then terminate the parameter list, and leave.
3713              */
3714             if (!params)
3715             {                   /* need this special case */
3716                 params = nasm_malloc(sizeof(*params));
3717                 nparam = 0;
3718             }
3719             params[nparam] = NULL;
3720             *params_array = params;
3721             return m;
3722         }
3723         /*
3724          * This one wasn't right: look for the next one with the
3725          * same name.
3726          */
3727         for (m = m->next; m; m = m->next)
3728             if (!mstrcmp(m->name, tline->text, m->casesense))
3729                 break;
3730     }
3731
3732     /*
3733      * After all that, we didn't find one with the right number of
3734      * parameters. Issue a warning, and fail to expand the macro.
3735      */
3736     error(ERR_WARNING | ERR_WARN_MNP,
3737             "macro `%s' exists, but not taking %d parameters",
3738             tline->text, nparam);
3739     nasm_free(params);
3740     return NULL;
3741 }
3742
3743 /*
3744  * Expand the multi-line macro call made by the given line, if
3745  * there is one to be expanded. If there is, push the expansion on
3746  * istk->expansion and return 1. Otherwise return 0.
3747  */
3748 static int
3749 expand_mmacro(Token * tline)
3750 {
3751     Token *startline = tline;
3752     Token *label = NULL;
3753     int dont_prepend = 0;
3754     Token **params, *t, *tt;
3755     MMacro *m;
3756     Line *l, *ll;
3757     int i, nparam, *paramlen;
3758
3759     t = tline;
3760     skip_white_(t);
3761 /*    if (!tok_type_(t, TOK_ID))  Lino 02/25/02 */
3762     if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID))
3763         return 0;
3764     m = is_mmacro(t, &params);
3765     if (!m)
3766     {
3767         Token *last;
3768         /*
3769          * We have an id which isn't a macro call. We'll assume
3770          * it might be a label; we'll also check to see if a
3771          * colon follows it. Then, if there's another id after
3772          * that lot, we'll check it again for macro-hood.
3773          */
3774         label = last = t;
3775         t = t->next;
3776         if (tok_type_(t, TOK_WHITESPACE))
3777             last = t, t = t->next;
3778         if (tok_is_(t, ":"))
3779         {
3780             dont_prepend = 1;
3781             last = t, t = t->next;
3782             if (tok_type_(t, TOK_WHITESPACE))
3783                 last = t, t = t->next;
3784         }
3785         if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, &params)) == NULL)
3786             return 0;
3787         last->next = NULL;
3788         tline = t;
3789     }
3790
3791     /*
3792      * Fix up the parameters: this involves stripping leading and
3793      * trailing whitespace, then stripping braces if they are
3794      * present.
3795      */
3796     for (nparam = 0; params[nparam]; nparam++)
3797         ;
3798     paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
3799
3800     for (i = 0; params[i]; i++)
3801     {
3802         int brace = FALSE;
3803         int comma = (!m->plus || i < nparam - 1);
3804
3805         t = params[i];
3806         skip_white_(t);
3807         if (tok_is_(t, "{"))
3808             t = t->next, brace = TRUE, comma = FALSE;
3809         params[i] = t;
3810         paramlen[i] = 0;
3811         while (t)
3812         {
3813             if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
3814                 break;          /* ... because we have hit a comma */
3815             if (comma && t->type == TOK_WHITESPACE && tok_is_(t->next, ","))
3816                 break;          /* ... or a space then a comma */
3817             if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
3818                 break;          /* ... or a brace */
3819             t = t->next;
3820             paramlen[i]++;
3821         }
3822     }
3823
3824     /*
3825      * OK, we have a MMacro structure together with a set of
3826      * parameters. We must now go through the expansion and push
3827      * copies of each Line on to istk->expansion. Substitution of
3828      * parameter tokens and macro-local tokens doesn't get done
3829      * until the single-line macro substitution process; this is
3830      * because delaying them allows us to change the semantics
3831      * later through %rotate.
3832      *
3833      * First, push an end marker on to istk->expansion, mark this
3834      * macro as in progress, and set up its invocation-specific
3835      * variables.
3836      */
3837     ll = nasm_malloc(sizeof(Line));
3838     ll->next = istk->expansion;
3839     ll->finishes = m;
3840     ll->first = NULL;
3841     istk->expansion = ll;
3842
3843     m->in_progress = TRUE;
3844     m->params = params;
3845     m->iline = tline;
3846     m->nparam = nparam;
3847     m->rotate = 0;
3848     m->paramlen = paramlen;
3849     m->unique = unique++;
3850     m->lineno = 0;
3851
3852     m->next_active = istk->mstk;
3853     istk->mstk = m;
3854
3855     for (l = m->expansion; l; l = l->next)
3856     {
3857         Token **tail;
3858
3859         ll = nasm_malloc(sizeof(Line));
3860         ll->finishes = NULL;
3861         ll->next = istk->expansion;
3862         istk->expansion = ll;
3863         tail = &ll->first;
3864
3865         for (t = l->first; t; t = t->next)
3866         {
3867             Token *x = t;
3868             if (t->type == TOK_PREPROC_ID &&
3869                     t->text[1] == '0' && t->text[2] == '0')
3870             {
3871                 dont_prepend = -1;
3872                 x = label;
3873                 if (!x)
3874                     continue;
3875             }
3876             tt = *tail = new_Token(NULL, x->type, x->text, 0);
3877             tail = &tt->next;
3878         }
3879         *tail = NULL;
3880     }
3881
3882     /*
3883      * If we had a label, push it on as the first line of
3884      * the macro expansion.
3885      */
3886     if (label)
3887     {
3888         if (dont_prepend < 0)
3889             free_tlist(startline);
3890         else
3891         {
3892             ll = nasm_malloc(sizeof(Line));
3893             ll->finishes = NULL;
3894             ll->next = istk->expansion;
3895             istk->expansion = ll;
3896             ll->first = startline;
3897             if (!dont_prepend)
3898             {
3899                 while (label->next)
3900                     label = label->next;
3901                 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
3902             }
3903         }
3904     }
3905
3906     list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
3907
3908     return 1;
3909 }
3910
3911 /*
3912  * Since preprocessor always operate only on the line that didn't
3913  * arrived yet, we should always use ERR_OFFBY1. Also since user
3914  * won't want to see same error twice (preprocessing is done once
3915  * per pass) we will want to show errors only during pass one.
3916  */
3917 static void
3918 error(int severity, char *fmt, ...)
3919 {
3920     va_list arg;
3921     char buff[1024];
3922
3923     /* If we're in a dead branch of IF or something like it, ignore the error */
3924     if (istk->conds && !emitting(istk->conds->state))
3925         return;
3926
3927     va_start(arg, fmt);
3928     vsprintf(buff, fmt, arg);
3929     va_end(arg);
3930
3931     if (istk->mstk && istk->mstk->name)
3932         __error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
3933                 istk->mstk->lineno, buff);
3934     else
3935         __error(severity | ERR_PASS1, "%s", buff);
3936 }
3937
3938 static void
3939 pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
3940         ListGen * listgen)
3941 {
3942     int h;
3943
3944     __error = errfunc;
3945     cstk = NULL;
3946     istk = nasm_malloc(sizeof(Include));
3947     istk->next = NULL;
3948     istk->conds = NULL;
3949     istk->expansion = NULL;
3950     istk->mstk = NULL;
3951     istk->fp = fopen(file, "r");
3952     istk->fname = NULL;
3953     src_set_fname(nasm_strdup(file));
3954     src_set_linnum(0);
3955     istk->lineinc = 1;
3956     if (!istk->fp)
3957         error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'", file);
3958     defining = NULL;
3959     for (h = 0; h < NHASH; h++)
3960     {
3961         mmacros[h] = NULL;
3962         smacros[h] = NULL;
3963     }
3964     unique = 0;
3965         if (tasm_compatible_mode) {
3966             stdmacpos = stdmac;
3967         } else {
3968                 stdmacpos = &stdmac[TASM_MACRO_COUNT];
3969         }
3970     any_extrastdmac = (extrastdmac != NULL);
3971     list = listgen;
3972     evaluate = eval;
3973     pass = apass;
3974 }
3975
3976 static char *
3977 pp_getline(void)
3978 {
3979     char *line;
3980     Token *tline;
3981
3982     while (1)
3983     {
3984         /*
3985          * Fetch a tokenised line, either from the macro-expansion
3986          * buffer or from the input file.
3987          */
3988         tline = NULL;
3989         while (istk->expansion && istk->expansion->finishes)
3990         {
3991             Line *l = istk->expansion;
3992             if (!l->finishes->name && l->finishes->in_progress > 1)
3993             {
3994                 Line *ll;
3995
3996                 /*
3997                  * This is a macro-end marker for a macro with no
3998                  * name, which means it's not really a macro at all
3999                  * but a %rep block, and the `in_progress' field is
4000                  * more than 1, meaning that we still need to
4001                  * repeat. (1 means the natural last repetition; 0
4002                  * means termination by %exitrep.) We have
4003                  * therefore expanded up to the %endrep, and must
4004                  * push the whole block on to the expansion buffer
4005                  * again. We don't bother to remove the macro-end
4006                  * marker: we'd only have to generate another one
4007                  * if we did.
4008                  */
4009                 l->finishes->in_progress--;
4010                 for (l = l->finishes->expansion; l; l = l->next)
4011                 {
4012                     Token *t, *tt, **tail;
4013
4014                     ll = nasm_malloc(sizeof(Line));
4015                     ll->next = istk->expansion;
4016                     ll->finishes = NULL;
4017                     ll->first = NULL;
4018                     tail = &ll->first;
4019
4020                     for (t = l->first; t; t = t->next)
4021                     {
4022                         if (t->text || t->type == TOK_WHITESPACE)
4023                         {
4024                             tt = *tail = new_Token(NULL, t->type, t->text, 0);
4025                             tail = &tt->next;
4026                         }
4027                     }
4028
4029                     istk->expansion = ll;
4030                 }
4031             }
4032             else
4033             {
4034                 /*
4035                  * Check whether a `%rep' was started and not ended
4036                  * within this macro expansion. This can happen and
4037                  * should be detected. It's a fatal error because
4038                  * I'm too confused to work out how to recover
4039                  * sensibly from it.
4040                  */
4041                 if (defining)
4042                 {
4043                     if (defining->name)
4044                         error(ERR_PANIC, "defining with name in expansion");
4045                     else if (istk->mstk->name)
4046                         error(ERR_FATAL, "`%%rep' without `%%endrep' within"
4047                                 " expansion of macro `%s'", istk->mstk->name);
4048                 }
4049
4050                 /*
4051                  * FIXME:  investigate the relationship at this point between
4052                  * istk->mstk and l->finishes
4053                  */
4054                 {
4055                     MMacro *m = istk->mstk;
4056                     istk->mstk = m->next_active;
4057                     if (m->name)
4058                     {
4059                         /*
4060                          * This was a real macro call, not a %rep, and
4061                          * therefore the parameter information needs to
4062                          * be freed.
4063                          */
4064                         nasm_free(m->params);
4065                         free_tlist(m->iline);
4066                         nasm_free(m->paramlen);
4067                         l->finishes->in_progress = FALSE;
4068                     }
4069                     else
4070                         free_mmacro(m);
4071                 }
4072                 istk->expansion = l->next;
4073                 nasm_free(l);
4074                 list->downlevel(LIST_MACRO);
4075             }
4076         }
4077         while (1)
4078         {                       /* until we get a line we can use */
4079
4080             if (istk->expansion)
4081             {                   /* from a macro expansion */
4082                 char *p;
4083                 Line *l = istk->expansion;
4084                 if (istk->mstk)
4085                     istk->mstk->lineno++;
4086                 tline = l->first;
4087                 istk->expansion = l->next;
4088                 nasm_free(l);
4089                 p = detoken(tline, FALSE);
4090                 list->line(LIST_MACRO, p);
4091                 nasm_free(p);
4092                 break;
4093             }
4094             line = read_line();
4095             if (line)
4096             {                   /* from the current input file */
4097                 line = prepreproc(line);
4098                 tline = tokenise(line);
4099                 nasm_free(line);
4100                 break;
4101             }
4102             /*
4103              * The current file has ended; work down the istk
4104              */
4105             {
4106                 Include *i = istk;
4107                 fclose(i->fp);
4108                 if (i->conds)
4109                     error(ERR_FATAL, "expected `%%endif' before end of file");
4110                 istk = i->next;
4111                 list->downlevel(LIST_INCLUDE);
4112                 src_set_linnum(i->lineno);
4113                 nasm_free(src_set_fname(i->fname));
4114                 nasm_free(i);
4115                 if (!istk)
4116                     return NULL;
4117             }
4118         }
4119
4120         /*
4121          * We must expand MMacro parameters and MMacro-local labels
4122          * _before_ we plunge into directive processing, to cope
4123          * with things like `%define something %1' such as STRUC
4124          * uses. Unless we're _defining_ a MMacro, in which case
4125          * those tokens should be left alone to go into the
4126          * definition; and unless we're in a non-emitting
4127          * condition, in which case we don't want to meddle with
4128          * anything.
4129          */
4130         if (!defining && !(istk->conds && !emitting(istk->conds->state)))
4131             tline = expand_mmac_params(tline);
4132
4133         /*
4134          * Check the line to see if it's a preprocessor directive.
4135          */
4136         if (do_directive(tline) & 1)
4137         {
4138             continue;
4139         }
4140         else if (defining)
4141         {
4142             /*
4143              * We're defining a multi-line macro. We emit nothing
4144              * at all, and just
4145              * shove the tokenised line on to the macro definition.
4146              */
4147             Line *l = nasm_malloc(sizeof(Line));
4148             l->next = defining->expansion;
4149             l->first = tline;
4150             l->finishes = FALSE;
4151             defining->expansion = l;
4152             continue;
4153         }
4154         else if (istk->conds && !emitting(istk->conds->state))
4155         {
4156             /*
4157              * We're in a non-emitting branch of a condition block.
4158              * Emit nothing at all, not even a blank line: when we
4159              * emerge from the condition we'll give a line-number
4160              * directive so we keep our place correctly.
4161              */
4162             free_tlist(tline);
4163             continue;
4164         }
4165         else if (istk->mstk && !istk->mstk->in_progress)
4166         {
4167             /*
4168              * We're in a %rep block which has been terminated, so
4169              * we're walking through to the %endrep without
4170              * emitting anything. Emit nothing at all, not even a
4171              * blank line: when we emerge from the %rep block we'll
4172              * give a line-number directive so we keep our place
4173              * correctly.
4174              */
4175             free_tlist(tline);
4176             continue;
4177         }
4178         else
4179         {
4180             tline = expand_smacro(tline);
4181             if (!expand_mmacro(tline))
4182             {
4183                 /*
4184                  * De-tokenise the line again, and emit it.
4185                  */
4186                 line = detoken(tline, TRUE);
4187                 free_tlist(tline);
4188                 break;
4189             }
4190             else
4191             {
4192                 continue;       /* expand_mmacro calls free_tlist */
4193             }
4194         }
4195     }
4196
4197     return line;
4198 }
4199
4200 static void
4201 pp_cleanup(int pass)
4202 {
4203     int h;
4204
4205     if (defining)
4206     {
4207         error(ERR_NONFATAL, "end of file while still defining macro `%s'",
4208                 defining->name);
4209         free_mmacro(defining);
4210     }
4211     while (cstk)
4212         ctx_pop();
4213     for (h = 0; h < NHASH; h++)
4214     {
4215         while (mmacros[h])
4216         {
4217             MMacro *m = mmacros[h];
4218             mmacros[h] = mmacros[h]->next;
4219             free_mmacro(m);
4220         }
4221         while (smacros[h])
4222         {
4223             SMacro *s = smacros[h];
4224             smacros[h] = smacros[h]->next;
4225             nasm_free(s->name);
4226             free_tlist(s->expansion);
4227             nasm_free(s);
4228         }
4229     }
4230     while (istk)
4231     {
4232         Include *i = istk;
4233         istk = istk->next;
4234         fclose(i->fp);
4235         nasm_free(i->fname);
4236         nasm_free(i);
4237     }
4238     while (cstk)
4239         ctx_pop();
4240     if (pass == 0)
4241         {
4242                 free_llist(predef);
4243                 delete_Blocks();
4244         }
4245 }
4246
4247 void
4248 pp_include_path(char *path)
4249 {
4250     IncPath *i;
4251
4252     i = nasm_malloc(sizeof(IncPath));
4253     i->path = nasm_strdup(path);
4254     i->next = ipath;
4255     ipath = i;
4256 }
4257
4258 void
4259 pp_pre_include(char *fname)
4260 {
4261     Token *inc, *space, *name;
4262     Line *l;
4263
4264     name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
4265     space = new_Token(name, TOK_WHITESPACE, NULL, 0);
4266     inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
4267
4268     l = nasm_malloc(sizeof(Line));
4269     l->next = predef;
4270     l->first = inc;
4271     l->finishes = FALSE;
4272     predef = l;
4273 }
4274
4275 void
4276 pp_pre_define(char *definition)
4277 {
4278     Token *def, *space;
4279     Line *l;
4280     char *equals;
4281
4282     equals = strchr(definition, '=');
4283     space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4284     def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
4285     if (equals)
4286         *equals = ' ';
4287     space->next = tokenise(definition);
4288     if (equals)
4289         *equals = '=';
4290
4291     l = nasm_malloc(sizeof(Line));
4292     l->next = predef;
4293     l->first = def;
4294     l->finishes = FALSE;
4295     predef = l;
4296 }
4297
4298 void
4299 pp_pre_undefine(char *definition)
4300 {
4301     Token *def, *space;
4302     Line *l;
4303
4304     space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4305     def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
4306
4307     l = nasm_malloc(sizeof(Line));
4308     l->next = predef;
4309     l->first = def;
4310     l->finishes = FALSE;
4311     predef = l;
4312 }
4313
4314 void
4315 pp_extra_stdmac(char **macros)
4316 {
4317     extrastdmac = macros;
4318 }
4319
4320 static void
4321 make_tok_num(Token * tok, long val)
4322 {
4323     char numbuf[20];
4324     sprintf(numbuf, "%ld", val);
4325     tok->text = nasm_strdup(numbuf);
4326     tok->type = TOK_NUMBER;
4327 }
4328
4329 Preproc nasmpp = {
4330     pp_reset,
4331     pp_getline,
4332     pp_cleanup
4333 };