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