cd8c6170115a63ae097bf699c3688faa2a4a2030
[platform/upstream/nasm.git] / preproc.c
1 /* preproc.c   macro preprocessor for the Netwide Assembler
2  *
3  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4  * Julian Hall. All rights reserved. The software is
5  * redistributable under the licence given in the file "Licence"
6  * distributed in the NASM archive.
7  *
8  * initial version 18/iii/97 by Simon Tatham
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stddef.h>
14 #include <string.h>
15 #include <ctype.h>
16
17 #include "nasm.h"
18 #include "nasmlib.h"
19
20 typedef struct SMacro SMacro;
21 typedef struct MMacro MMacro;
22 typedef struct Context Context;
23 typedef struct Token Token;
24 typedef struct Line Line;
25 typedef struct Include Include;
26 typedef struct Cond Cond;
27
28 /*
29  * Store the definition of a single-line macro.
30  */
31 struct SMacro {
32     SMacro *next;
33     char *name;
34     int casesense;
35     int nparam;
36     int in_progress;
37     Token *expansion;
38 };
39
40 /*
41  * Store the definition of a multi-line macro.
42  */
43 struct MMacro {
44     MMacro *next;
45     char *name;
46     int casesense;
47     int nparam_min, nparam_max;
48     int plus;                          /* is the last parameter greedy? */
49     int in_progress;
50     Token **defaults, *dlist;
51     Line *expansion;
52 };
53
54 /*
55  * The context stack is composed of a linked list of these.
56  */
57 struct Context {
58     Context *next;
59     SMacro *localmac;
60     char *name;
61     unsigned long number;
62 };
63
64 /*
65  * This is the internal form which we break input lines up into.
66  * Typically stored in linked lists.
67  *
68  * TOK_PS_OTHER is a token type used internally within
69  * expand_smacro(), to denote a token which has already been
70  * checked for being a potential macro, but may still be a context-
71  * local label.
72  *
73  * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
74  * necessarily used as-is, but is intended to denote the number of
75  * the substituted parameter. So in the definition
76  *
77  *     %define a(x,y) ( (x) & ~(y) )
78  * 
79  * the token representing `x' will have its type changed to
80  * TOK_SMAC_PARAM, but the one representing `y' will be
81  * TOK_SMAC_PARAM+1.
82  */
83 struct Token {
84     Token *next;
85     char *text;
86     SMacro *mac;                       /* associated macro for TOK_MAC_END */
87     int type;
88 };
89 enum {
90     TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING,
91     TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_PS_OTHER, TOK_SMAC_PARAM
92 };
93
94 /*
95  * Multi-line macro definitions are stored as a linked list of
96  * these, which is essentially a container to allow several linked
97  * lists of Tokens.
98  * 
99  * Note that in this module, linked lists are treated as stacks
100  * wherever possible. For this reason, Lines are _pushed_ on to the
101  * `expansion' field in MMacro structures, so that the linked list,
102  * if walked, would give the macro lines in reverse order; this
103  * means that we can walk the list when expanding a macro, and thus
104  * push the lines on to the `expansion' field in _istk_ in reverse
105  * order (so that when popped back off they are in the right
106  * order). It may seem cockeyed, and it relies on my design having
107  * an even number of steps in, but it works...
108  *
109  * Some of these structures, rather than being actual lines, are
110  * markers delimiting the end of the expansion of a given macro.
111  * This is for use in the cycle-tracking code. Such structures have
112  * `finishes' non-NULL, and `first' NULL. All others have
113  * `finishes' NULL, but `first' may still be non-NULL if the line
114  * is blank.
115  */
116 struct Line {
117     Line *next;
118     MMacro *finishes;
119     Token *first;
120 };
121
122 /*
123  * To handle an arbitrary level of file inclusion, we maintain a
124  * stack (ie linked list) of these things.
125  */
126 struct Include {
127     Include *next;
128     FILE *fp;
129     Cond *conds;
130     Line *expansion;
131     char *fname;
132     int lineno, lineinc;
133 };
134
135 /*
136  * Conditional assembly: we maintain a separate stack of these for
137  * each level of file inclusion. (The only reason we keep the
138  * stacks separate is to ensure that a stray `%endif' in a file
139  * included from within the true branch of a `%if' won't terminate
140  * it and cause confusion: instead, rightly, it'll cause an error.)
141  */
142 struct Cond {
143     Cond *next;
144     int state;
145 };
146 enum {
147     /*
148      * These states are for use just after %if or %elif: IF_TRUE
149      * means the condition has evaluated to truth so we are
150      * currently emitting, whereas IF_FALSE means we are not
151      * currently emitting but will start doing so if a %else comes
152      * up. In these states, all directives are admissible: %elif,
153      * %else and %endif. (And of course %if.)
154      */
155     COND_IF_TRUE, COND_IF_FALSE,
156     /*
157      * These states come up after a %else: ELSE_TRUE means we're
158      * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
159      * any %elif or %else will cause an error.
160      */
161     COND_ELSE_TRUE, COND_ELSE_FALSE,
162     /*
163      * This state means that we're not emitting now, and also that
164      * nothing until %endif will be emitted at all. It's for use in
165      * two circumstances: (i) when we've had our moment of emission
166      * and have now started seeing %elifs, and (ii) when the
167      * condition construct in question is contained within a
168      * non-emitting branch of a larger condition construct.
169      */
170     COND_NEVER
171 };
172 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
173
174 /*
175  * Condition codes. Note that we use c_ prefix not C_ because C_ is
176  * used in nasm.h for the "real" condition codes. At _this_ level,
177  * we treat CXZ and ECXZ as condition codes, albeit non-invertible
178  * ones, so we need a different enum...
179  */
180 static char *conditions[] = {
181     "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
182     "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
183     "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
184 };
185 enum {
186     c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE,
187     c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO,
188     c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_S, c_Z
189 };
190 static int inverse_ccs[] = {
191     c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE,
192     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,
193     c_Z, c_NO, c_NP, c_PO, c_PE, c_NS, c_NZ
194 };
195
196 static Context *cstk;
197 static Include *istk;
198
199 static efunc error;
200
201 static unsigned long unique;           /* unique identifier numbers */
202
203 static char *linesync, *outline;
204
205 /*
206  * The number of hash values we use for the macro lookup tables.
207  */
208 #define NHASH 31
209
210 /*
211  * The current set of multi-line macros we have defined.
212  */
213 static MMacro *mmacros[NHASH];
214
215 /*
216  * The current set of single-line macros we have defined.
217  */
218 static SMacro *smacros[NHASH];
219
220 /*
221  * The multi-line macro we are currently defining, if any.
222  */
223 static MMacro *defining;
224
225 /*
226  * The number of macro parameters to allocate space for at a time.
227  */
228 #define PARAM_DELTA 16
229
230 /*
231  * The standard macro set: defined as `static char *stdmac[]'. Also
232  * gives our position in the macro set, when we're processing it.
233  */
234 #include "macros.c"
235 static char **stdmacpos;
236
237 /*
238  * The pre-preprocessing stage... This function has two purposes:
239  * firstly, it translates line number indications as they emerge
240  * from GNU cpp (`# lineno "file" flags') into NASM preprocessor
241  * line number indications (`%line lineno file'), and secondly, it
242  * converts [INCLUDE] and [INC] old-style inclusion directives into
243  * the new-style `%include' form (though in the next version it
244  * won't do that any more).
245  */
246 static char *prepreproc(char *line) {
247     int lineno, fnlen;
248     char *fname, *oldline;
249
250     if (line[0] == '#' && line[1] == ' ') {
251         oldline = line;
252         fname = oldline+2;
253         lineno = atoi(fname);
254         fname += strspn(fname, "0123456789 ");
255         if (*fname == '"')
256             fname++;
257         fnlen = strcspn(fname, "\"");
258         line = nasm_malloc(20+fnlen);
259         sprintf(line, "%%line %d %.*s", lineno, fnlen, fname);
260         nasm_free (oldline);
261         return line;
262     } else if (!nasm_strnicmp(line, "[include", 8)) {
263         oldline = line;
264         fname = oldline+8;
265         fname += strspn(fname, " \t");
266         fnlen = strcspn(fname, "]");
267         line = nasm_malloc(20+fnlen);
268         sprintf(line, "%%include \"%.*s\"", fnlen, fname);
269         error (ERR_WARNING|ERR_OFFBY1, "use of [INCLUDE] is being phased out;"
270                " suggest `%%include'");
271         nasm_free (oldline);
272         return line;
273     } else if (!nasm_strnicmp(line, "[inc", 4)) {
274         oldline = line;
275         fname = oldline+4;
276         fname += strspn(fname, " \t");
277         fnlen = strcspn(fname, "]");
278         line = nasm_malloc(20+fnlen);
279         sprintf(line, "%%include \"%.*s\"", fnlen, fname);
280         error (ERR_WARNING|ERR_OFFBY1, "use of [INC] is being phased out;"
281                " suggest `%%include'");
282         nasm_free (oldline);
283         return line;
284     } else
285         return line;
286 }
287
288 /*
289  * The hash function for macro lookups. Note that due to some
290  * macros having case-insensitive names, the hash function must be
291  * invariant under case changes. We implement this by applying a
292  * perfectly normal hash function to the uppercase of the string.
293  */
294 static int hash(char *s) {
295     /*
296      * Powers of three, mod 31.
297      */
298     static const int multipliers[] = {
299         1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
300         30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
301     };
302     int h = 0;
303     int i = 0;
304
305     while (*s) {
306         h += multipliers[i] * (unsigned char) (toupper(*s));
307         s++;
308         if (++i >= sizeof(multipliers)/sizeof(*multipliers))
309             i = 0;
310     }
311     h %= NHASH;
312     return h;
313 }
314
315 /*
316  * Free a linked list of tokens.
317  */
318 static void free_tlist (Token *list) {
319     Token *t;
320     while (list) {
321         t = list;
322         list = list->next;
323         nasm_free (t->text);
324         nasm_free (t);
325     }
326 }
327
328 /*
329  * Free a linked list of lines.
330  */
331 static void free_llist (Line *list) {
332     Line *l;
333     while (list) {
334         l = list;
335         list = list->next;
336         free_tlist (l->first);
337         nasm_free (l);
338     }
339 }
340
341 /*
342  * Pop the context stack.
343  */
344 static void ctx_pop (void) {
345     Context *c = cstk;
346     SMacro *smac, *s;
347
348     cstk = cstk->next;
349     smac = c->localmac;
350     while (smac) {
351         s = smac;
352         smac = smac->next;
353         nasm_free (s->name);
354         free_tlist (s->expansion);
355         nasm_free (s);
356     }
357     nasm_free (c->name);
358     nasm_free (c);
359 }
360
361 /*
362  * Generate a line synchronisation comment, to ensure the assembler
363  * knows which source file the current output has really come from.
364  */
365 static void line_sync (void) {
366     char text[80];
367     sprintf(text, "%%line %d+%d %s",
368             (istk->expansion ? istk->lineno - istk->lineinc : istk->lineno),
369             (istk->expansion ? 0 : istk->lineinc), istk->fname);
370     if (linesync)
371         free (linesync);
372     linesync = nasm_strdup(text);
373 }
374
375 #define BUF_DELTA 512
376 /*
377  * Read a line from the top file in istk, handling multiple CR/LFs
378  * at the end of the line read, and handling spurious ^Zs. Will
379  * return lines from the standard macro set if this has not already
380  * been done.
381  */
382 static char *read_line (void) {
383     char *buffer, *p, *q;
384     int bufsize;
385
386     if (stdmacpos) {
387         if (*stdmacpos)
388             return nasm_strdup(*stdmacpos++);
389         else {
390             stdmacpos = NULL;
391             line_sync();
392         }
393     }
394
395     bufsize = BUF_DELTA;
396     buffer = nasm_malloc(BUF_DELTA);
397     p = buffer;
398     while (1) {
399         q = fgets(p, bufsize-(p-buffer), istk->fp);
400         if (!q)
401             break;
402         p += strlen(p);
403         if (p > buffer && p[-1] == '\n') {
404             istk->lineno += istk->lineinc;
405             break;
406         }
407         if (p-buffer > bufsize-10) {
408             bufsize += BUF_DELTA;
409             buffer = nasm_realloc(buffer, bufsize);
410         }
411     }
412
413     if (!q && p == buffer) {
414         nasm_free (buffer);
415         return NULL;
416     }
417
418     /*
419      * Play safe: remove CRs as well as LFs, if any of either are
420      * present at the end of the line.
421      */
422     while (p > buffer && (p[-1] == '\n' || p[-1] == '\r'))
423         *--p = '\0';
424
425     /*
426      * Handle spurious ^Z, which may be inserted into source files
427      * by some file transfer utilities.
428      */
429     buffer[strcspn(buffer, "\032")] = '\0';
430
431     return buffer;
432 }
433
434 /*
435  * Tokenise a line of text. This is a very simple process since we
436  * don't need to parse the value out of e.g. numeric tokens: we
437  * simply split one string into many.
438  */
439 static Token *tokenise (char *line) {
440     char *p = line;
441     int type;
442     Token *list = NULL;
443     Token *t, **tail = &list;
444
445     while (*line) {
446         p = line;
447         if (*p == '%' &&
448             (p[1] == '{' || p[1] == '!' || (p[1] == '%' && isidchar(p[2])) ||
449              p[1] == '$' || p[1] == '+' || p[1] == '-' || isidchar(p[1]))) {
450             type = TOK_PREPROC_ID;
451             p++;
452             if (*p == '{') {
453                 p++;
454                 while (*p && *p != '}') {
455                     p[-1] = *p;
456                     p++;
457                 }
458                 p[-1] = '\0';
459                 if (*p) p++;
460             } else {
461                 if (*p == '!' || *p == '%' || *p == '$' ||
462                     *p == '+' || *p == '-') p++;
463                 while (*p && isidchar(*p))
464                     p++;
465             }
466         } else if (isidstart(*p)) {
467             type = TOK_ID;
468             p++;
469             while (*p && isidchar(*p))
470                 p++;
471         } else if (*p == '\'' || *p == '"') {
472             /*
473              * A string token.
474              */
475             char c = *p;
476             p++;
477             type = TOK_STRING;
478             while (*p && *p != c)
479                 p++;
480             if (*p) p++;
481         } else if (isnumstart(*p)) {
482             /*
483              * A number token.
484              */
485             type = TOK_NUMBER;
486             p++;
487             while (*p && isnumchar(*p))
488                 p++;
489         } else if (isspace(*p)) {
490             type = TOK_WHITESPACE;
491             p++;
492             while (*p && isspace(*p))
493                 p++;
494             /*
495              * Whitespace just before end-of-line is discarded by
496              * pretending it's a comment; whitespace just before a
497              * comment gets lumped into the comment.
498              */
499             if (!*p || *p == ';') {
500                 type = TOK_COMMENT;
501                 while (*p) p++;
502             }
503         } else if (*p == ';') {
504             type = TOK_COMMENT;
505             while (*p) p++;
506         } else {
507             /*
508              * Anything else is an operator of some kind; with the
509              * exceptions of >>, <<, // and %%, all operator tokens
510              * are single-character.
511              */
512             char c = *p++;
513             type = TOK_OTHER;
514             if ( (c == '>' || c == '<' || c == '/' || c == '%') && *p == c)
515                 p++;
516         }
517         if (type != TOK_COMMENT) {
518             *tail = t = nasm_malloc (sizeof(Token));
519             tail = &t->next;
520             t->next = NULL;
521             t->type = type;
522             t->text = nasm_malloc(1+p-line);
523             strncpy(t->text, line, p-line);
524             t->text[p-line] = '\0';
525         }
526         line = p;
527     }
528
529     return list;
530 }
531
532 /*
533  * Convert a line of tokens back into text.
534  */
535 static char *detoken (Token *tlist) {
536     Token *t;
537     int len;
538     char *line, *p;
539
540     len = 0;
541     for (t = tlist; t; t = t->next) {
542         if (t->type == TOK_PREPROC_ID && t->text[1] == '!') {
543             char *p = getenv(t->text+2);
544             nasm_free (t->text);
545             if (p)
546                 t->text = nasm_strdup(p);
547             else
548                 t->text = NULL;
549         }
550         if (t->text)
551             len += strlen(t->text);
552     }
553     p = line = nasm_malloc(len+1);
554     for (t = tlist; t; t = t->next) {
555         if (t->text) {
556             strcpy (p, t->text);
557             p += strlen(p);
558         }
559     }
560     *p = '\0';
561     return line;
562 }
563
564 /*
565  * Return the Context structure associated with a %$ token. Return
566  * NULL, having _already_ reported an error condition, if the
567  * context stack isn't deep enough for the supplied number of $
568  * signs.
569  */
570 static Context *get_ctx (char *name) {
571     Context *ctx;
572     int i;
573
574     if (!cstk) {
575         error (ERR_NONFATAL|ERR_OFFBY1, "`%s': context stack is empty", name);
576         return NULL;
577     }
578
579     i = 1;
580     ctx = cstk;
581     while (name[i+1] == '$') {
582         i++;
583         ctx = ctx->next;
584         if (!ctx) {
585             error (ERR_NONFATAL|ERR_OFFBY1, "`%s': context stack is only"
586                    " %d level%s deep", name, i-1, (i==2 ? "" : "s"));
587             return NULL;
588         }
589     }
590     return ctx;
591 }
592
593 /*
594  * Compare a string to the name of an existing macro; this is a
595  * simple wrapper which calls either strcmp or nasm_stricmp
596  * depending on the value of the `casesense' parameter.
597  */
598 static int mstrcmp(char *p, char *q, int casesense) {
599     return casesense ? strcmp(p,q) : nasm_stricmp(p,q);
600 }
601
602 /*
603  * Determine if we should warn on defining a single-line macro of
604  * name `name', with `nparam' parameters. If nparam is 0, will
605  * return TRUE if _any_ single-line macro of that name is defined.
606  * Otherwise, will return TRUE if a single-line macro with either
607  * `nparam' or no parameters is defined.
608  *
609  * If a macro with precisely the right number of parameters is
610  * defined, the address of the definition structure will be
611  * returned in `defn'; otherwise NULL will be returned. If `defn'
612  * is NULL, no action will be taken regarding its contents, and no
613  * error will occur.
614  *
615  * Note that this is also called with nparam zero to resolve
616  * `ifdef'.
617  */
618 static int smacro_defined (char *name, int nparam, SMacro **defn) {
619     SMacro *m;
620     Context *ctx;
621     char *p;
622
623     if (name[0] == '%' && name[1] == '$') {
624         ctx = get_ctx (name);
625         if (!ctx)
626             return FALSE;              /* got to return _something_ */
627         m = ctx->localmac;
628         p = name+1;
629         p += strspn(p, "$");
630     } else {
631         m = smacros[hash(name)];
632         p = name;
633     }
634
635     while (m) {
636         if (!mstrcmp(m->name, p, m->casesense) &&
637             (nparam == 0 || m->nparam == 0 || nparam == m->nparam)) {
638             if (defn) {
639                 if (nparam == m->nparam)
640                     *defn = m;
641                 else
642                     *defn = NULL;
643             }
644             return TRUE;
645         }
646         m = m->next;
647     }
648     return FALSE;
649 }
650
651 /*
652  * Count and mark off the parameters in a multi-line macro call.
653  * This is called both from within the multi-line macro expansion
654  * code, and also to mark off the default parameters when provided
655  * in a %macro definition line.
656  */
657 static void count_mmac_params (Token *t, int *nparam, Token ***params) {
658     int paramsize, brace;
659
660     *nparam = paramsize = 0;
661     *params = NULL;
662     while (t) {
663         if (*nparam >= paramsize) {
664             paramsize += PARAM_DELTA;
665             *params = nasm_realloc(*params, sizeof(**params) * paramsize);
666         }
667         if (t && t->type == TOK_WHITESPACE)
668             t = t->next;
669         brace = FALSE;
670         if (t && t->type == TOK_OTHER && !strcmp(t->text, "{"))
671             brace = TRUE;
672         (*params)[(*nparam)++] = t;
673         while (t && (t->type != TOK_OTHER ||
674                      strcmp(t->text, brace ? "}" : ",")))
675             t = t->next;
676         if (t) {                       /* got a comma/brace */
677             t = t->next;
678             if (brace) {
679                 /*
680                  * Now we've found the closing brace, look further
681                  * for the comma.
682                  */
683                 if (t && t->type == TOK_WHITESPACE)
684                     t = t->next;
685                 if (t && (t->type != TOK_OTHER || strcmp(t->text, ","))) {
686                     error (ERR_NONFATAL|ERR_OFFBY1,
687                            "braces do not enclose all of macro parameter");
688                     while (t && (t->type != TOK_OTHER ||
689                                  strcmp(t->text, ",")))
690                         t = t->next;
691                 }
692                 if (t)
693                     t = t->next;               /* eat the comma */
694             }
695         }
696         else                           /* got EOL */
697             break;
698     }
699 }
700
701 /*
702  * Find out if a line contains a preprocessor directive, and deal
703  * with it if so.
704  * 
705  * If a directive _is_ found, the line will never be de-tokenised
706  * as is, so we have carte blanche to fiddle with it and adjust
707  * token values.
708  *
709  * Return values go like this:
710  * 
711  * bit 0 is set if a directive was found
712  * bit 1 is set if a blank line should be emitted
713  * bit 2 is set if a re-sync line number comment should be emitted
714  *
715  * (bits 1 and 2 are mutually exclusive in that the rest of the
716  * preprocessor doesn't guarantee to be able to handle the case in
717  * which both are set)
718  */
719 static int do_directive (Token *tline) {
720     static char *directives[] = {
721         "%clear", "%define", "%elifctx", "%elifdef", "%elifnctx",
722         "%elifndef", "%else", "%endif", "%endm", "%endmacro", "%error",
723         "%idefine", "%ifctx", "%ifdef", "%ifnctx", "%ifndef", "%imacro",
724         "%include", "%line", "%macro", "%pop", "%push", "%repl"
725     };
726     enum {
727         PP_CLEAR, PP_DEFINE, PP_ELIFCTX, PP_ELIFDEF, PP_ELIFNCTX,
728         PP_ELIFNDEF, PP_ELSE, PP_ENDIF, PP_ENDM, PP_ENDMACRO, PP_ERROR,
729         PP_IDEFINE, PP_IFCTX, PP_IFDEF, PP_IFNCTX, PP_IFNDEF, PP_IMACRO,
730         PP_INCLUDE, PP_LINE, PP_MACRO, PP_POP, PP_PUSH, PP_REPL
731     };
732     int i, j, k, m, nparam;
733     char *p, *mname;
734     Include *inc;
735     Context *ctx;
736     Cond *cond;
737     SMacro *smac, **smhead;
738     MMacro *mmac;
739     Token *t, *tt, *param_start, *macro_start, *last;
740
741     if (tline && tline->type == TOK_WHITESPACE)
742         tline = tline->next;
743     if (!tline || tline->type != TOK_PREPROC_ID ||
744         (tline->text[1] == '%' || tline->text[1] == '$'))
745         return 0;
746
747     i = -1;
748     j = sizeof(directives)/sizeof(*directives);
749     while (j-i > 1) {
750         k = (j+i) / 2;
751         m = nasm_stricmp(tline->text, directives[k]);
752         if (m == 0) {
753             i = k;
754             j = -2;
755             break;
756         } else if (m < 0) {
757             j = k;
758         } else
759             i = k;
760     }
761
762     /*
763      * If we're in a non-emitting branch of a condition construct,
764      * we should ignore all directives except for condition
765      * directives.
766      */
767     if (istk->conds && !emitting(istk->conds->state) &&
768         i != PP_IFCTX && i != PP_IFDEF && i != PP_IFNCTX && i != PP_IFNDEF &&
769         i!=PP_ELIFCTX && i!=PP_ELIFDEF && i!=PP_ELIFNCTX && i!=PP_ELIFNDEF &&
770         i != PP_ELSE && i != PP_ENDIF)
771         return 0;
772
773     /*
774      * If we're defining a macro, we should ignore all directives
775      * except for %macro/%imacro (which generate an error) and
776      * %endm/%endmacro.
777      */
778     if (defining && i != PP_MACRO && i != PP_IMACRO &&
779         i != PP_ENDMACRO && i != PP_ENDM)
780         return 0;
781
782     if (j != -2) {
783         error(ERR_NONFATAL|ERR_OFFBY1, "unknown preprocessor directive `%s'",
784               tline->text);
785         return 0;                      /* didn't get it */
786     }
787
788     switch (i) {
789
790       case PP_CLEAR:
791         if (tline->next)
792             error(ERR_WARNING|ERR_OFFBY1,
793                   "trailing garbage after `%%pop' ignored");
794         for (j=0; j<NHASH; j++) {
795             while (mmacros[j]) {
796                 MMacro *m = mmacros[j];
797                 mmacros[j] = mmacros[j]->next;
798                 nasm_free (m->name);
799                 free_tlist (m->dlist);
800                 free_llist (m->expansion);
801                 nasm_free (m);
802             }
803             while (smacros[j]) {
804                 SMacro *s = smacros[j];
805                 smacros[j] = smacros[j]->next;
806                 nasm_free (s->name);
807                 free_tlist (s->expansion);
808                 nasm_free (s);
809             }
810         }
811         return 3;
812
813       case PP_INCLUDE:
814         tline = tline->next;
815         if (tline && tline->type == TOK_WHITESPACE)
816             tline = tline->next;
817         if (!tline || tline->type != TOK_STRING) {
818             error(ERR_NONFATAL|ERR_OFFBY1, "`%%include' expects a file name");
819             return 3;                  /* but we did _something_ */
820         }
821         if (tline->next)
822             error(ERR_WARNING|ERR_OFFBY1,
823                   "trailing garbage after `%%include' ignored");
824         p = tline->text+1;             /* point past the quote to the name */
825         p[strlen(p)-1] = '\0';         /* remove the trailing quote */
826         inc = nasm_malloc(sizeof(Include));
827         inc->next = istk;
828         inc->conds = NULL;
829         inc->fp = fopen(p, "r");
830         inc->fname = nasm_strdup(p);
831         inc->lineno = inc->lineinc = 1;
832         inc->expansion = NULL;
833         if (!inc->fp)
834             error (ERR_FATAL|ERR_OFFBY1,
835                    "unable to open include file `%s'", p);
836         istk = inc;
837         return 5;
838
839       case PP_PUSH:
840         tline = tline->next;
841         if (tline && tline->type == TOK_WHITESPACE)
842             tline = tline->next;
843         if (!tline || tline->type != TOK_ID) {
844             error(ERR_NONFATAL|ERR_OFFBY1,
845                   "`%%push' expects a context identifier");
846             return 3;                  /* but we did _something_ */
847         }
848         if (tline->next)
849             error(ERR_WARNING|ERR_OFFBY1,
850                   "trailing garbage after `%%push' ignored");
851         ctx = nasm_malloc(sizeof(Context));
852         ctx->next = cstk;
853         ctx->localmac = NULL;
854         ctx->name = nasm_strdup(tline->text);
855         ctx->number = unique++;
856         cstk = ctx;
857         break;
858
859       case PP_REPL:
860         tline = tline->next;
861         if (tline && tline->type == TOK_WHITESPACE)
862             tline = tline->next;
863         if (!tline || tline->type != TOK_ID) {
864             error(ERR_NONFATAL|ERR_OFFBY1,
865                   "`%%repl' expects a context identifier");
866             return 3;                  /* but we did _something_ */
867         }
868         if (tline->next)
869             error(ERR_WARNING|ERR_OFFBY1,
870                   "trailing garbage after `%%repl' ignored");
871         if (!cstk)
872             error(ERR_NONFATAL|ERR_OFFBY1,
873                   "`%%repl': context stack is empty");
874         else {
875             nasm_free (cstk->name);
876             cstk->name = nasm_strdup(tline->text);
877         }
878         break;
879
880       case PP_POP:
881         if (tline->next)
882             error(ERR_WARNING|ERR_OFFBY1,
883                   "trailing garbage after `%%pop' ignored");
884         if (!cstk)
885             error(ERR_NONFATAL|ERR_OFFBY1,
886                   "`%%pop': context stack is already empty");
887         else
888             ctx_pop();
889         break;
890
891       case PP_ERROR:
892         tline = tline->next;
893         if (tline && tline->type == TOK_WHITESPACE)
894             tline = tline->next;
895         if (!tline || tline->type != TOK_STRING) {
896             error(ERR_NONFATAL|ERR_OFFBY1,
897                   "`%%error' expects an error string");
898             return 3;                  /* but we did _something_ */
899         }
900         if (tline->next)
901             error(ERR_WARNING|ERR_OFFBY1,
902                   "trailing garbage after `%%error' ignored");
903         p = tline->text+1;             /* point past the quote to the name */
904         p[strlen(p)-1] = '\0';         /* remove the trailing quote */
905         error(ERR_NONFATAL|ERR_OFFBY1, "user error: %s", p);
906         break;
907
908       case PP_IFCTX:
909       case PP_IFNCTX:
910         tline = tline->next;
911         if (istk->conds && !emitting(istk->conds->state))
912             j = COND_NEVER;
913         else {
914             j = FALSE;                 /* have we matched yet? */
915             if (!cstk)
916                 error(ERR_FATAL|ERR_OFFBY1,
917                       "`%%if%sctx': context stack is empty",
918                       (i==PP_IFNCTX ? "n" : ""));
919             else while (tline) {
920                 if (tline->type == TOK_WHITESPACE)
921                     tline = tline->next;
922                 if (!tline || tline->type != TOK_ID) {
923                     error(ERR_NONFATAL|ERR_OFFBY1,
924                           "`%%ifctx' expects context identifiers");
925                     return 3;          /* but we did _something_ */
926                 }
927                 if (!nasm_stricmp(tline->text, cstk->name))
928                     j = TRUE;
929                 tline = tline->next;
930             }
931             if (i == PP_IFNCTX)
932                 j = !j;
933             j = (j ? COND_IF_TRUE : COND_IF_FALSE);
934         }
935         cond = nasm_malloc(sizeof(Cond));
936         cond->next = istk->conds;
937         cond->state = j;
938         istk->conds = cond;
939         return 1;
940
941       case PP_ELIFCTX:
942       case PP_ELIFNCTX:
943         tline = tline->next;
944         if (!istk->conds)
945             error(ERR_FATAL|ERR_OFFBY1, "`%%elif%sctx': no matching `%%if'",
946                   (i==PP_ELIFNCTX ? "n" : ""));
947         if (emitting(istk->conds->state) || istk->conds->state == COND_NEVER)
948             istk->conds->state = COND_NEVER;
949         else {
950             j = FALSE;                 /* have we matched yet? */
951             if (!cstk)
952                 error(ERR_FATAL|ERR_OFFBY1,
953                       "`%%elif%sctx': context stack is empty",
954                       (i==PP_ELIFNCTX ? "n" : ""));
955             else while (tline) {
956                 if (tline->type == TOK_WHITESPACE)
957                     tline = tline->next;
958                 if (!tline || tline->type != TOK_ID) {
959                     error(ERR_NONFATAL|ERR_OFFBY1,
960                           "`%%elif%sctx' expects context identifiers",
961                           (i==PP_ELIFNCTX ? "n" : ""));
962                     return 3;          /* but we did _something_ */
963                 }
964                 if (!nasm_stricmp(tline->text, cstk->name))
965                     j = TRUE;
966                 tline = tline->next;
967             }
968             if (i == PP_ELIFNCTX)
969                 j = !j;
970             istk->conds->state = (j ? COND_IF_TRUE : COND_IF_FALSE);
971         }
972         return 1;
973
974       case PP_IFDEF:
975       case PP_IFNDEF:
976         tline = tline->next;
977         if (istk->conds && !emitting(istk->conds->state))
978             j = COND_NEVER;
979         else {
980             j = FALSE;                 /* have we matched yet? */
981             while (tline) {
982                 if (tline->type == TOK_WHITESPACE)
983                     tline = tline->next;
984                 if (!tline || (tline->type != TOK_ID &&
985                                (tline->type != TOK_PREPROC_ID ||
986                                 tline->text[1] != '$'))) {
987                     error(ERR_NONFATAL|ERR_OFFBY1,
988                           "`%%if%sdef' expects macro identifiers",
989                           (i==PP_ELIFNDEF ? "n" : ""));
990                     return 3;          /* but we did _something_ */
991                 }
992                 if (smacro_defined(tline->text, 0, NULL))
993                     j = TRUE;
994                 tline = tline->next;
995             }
996             if (i == PP_IFNDEF)
997                 j = !j;
998             j = (j ? COND_IF_TRUE : COND_IF_FALSE);
999         }
1000         cond = nasm_malloc(sizeof(Cond));
1001         cond->next = istk->conds;
1002         cond->state = j;
1003         istk->conds = cond;
1004         return 1;
1005
1006       case PP_ELIFDEF:
1007       case PP_ELIFNDEF:
1008         tline = tline->next;
1009         if (!istk->conds)
1010             error(ERR_FATAL|ERR_OFFBY1, "`%%elif%sctx': no matching `%%if'",
1011                   (i==PP_ELIFNCTX ? "n" : ""));
1012         if (emitting(istk->conds->state) || istk->conds->state == COND_NEVER)
1013             istk->conds->state = COND_NEVER;
1014         else {
1015             j = FALSE;                 /* have we matched yet? */
1016             while (tline) {
1017                 if (tline->type == TOK_WHITESPACE)
1018                     tline = tline->next;
1019                 if (!tline || (tline->type != TOK_ID &&
1020                                (tline->type != TOK_PREPROC_ID ||
1021                                 tline->text[1] != '$'))) {
1022                     error(ERR_NONFATAL|ERR_OFFBY1,
1023                           "`%%elif%sdef' expects macro identifiers",
1024                           (i==PP_ELIFNDEF ? "n" : ""));
1025                     return 3;          /* but we did _something_ */
1026                 }
1027                 if (smacro_defined(tline->text, 0, NULL))
1028                     j = TRUE;
1029                 tline = tline->next;
1030             }
1031             if (i == PP_ELIFNDEF)
1032                 j = !j;
1033             istk->conds->state = (j ? COND_IF_TRUE : COND_IF_FALSE);
1034         }
1035         return 1;
1036
1037       case PP_ELSE:
1038         if (tline->next)
1039             error(ERR_WARNING|ERR_OFFBY1,
1040                   "trailing garbage after `%%else' ignored");
1041         if (!istk->conds)
1042             error(ERR_FATAL|ERR_OFFBY1,
1043                   "`%%else': no matching `%%if'");
1044         if (emitting(istk->conds->state) || istk->conds->state == COND_NEVER)
1045             istk->conds->state = COND_ELSE_FALSE;
1046         else
1047             istk->conds->state = COND_ELSE_TRUE;
1048         return 1;
1049
1050       case PP_ENDIF:
1051         if (tline->next)
1052             error(ERR_WARNING|ERR_OFFBY1,
1053                   "trailing garbage after `%%endif' ignored");
1054         if (!istk->conds)
1055             error(ERR_FATAL|ERR_OFFBY1,
1056                   "`%%endif': no matching `%%if'");
1057         cond = istk->conds;
1058         istk->conds = cond->next;
1059         nasm_free (cond);
1060         return 5;
1061
1062       case PP_MACRO:
1063       case PP_IMACRO:
1064         if (defining)
1065             error (ERR_FATAL|ERR_OFFBY1,
1066                    "`%%%smacro': already defining a macro",
1067                    (i == PP_IMACRO ? "i" : ""));
1068         tline = tline->next;
1069         if (tline && tline->type == TOK_WHITESPACE)
1070             tline = tline->next;
1071         if (!tline || tline->type != TOK_ID) {
1072             error (ERR_NONFATAL|ERR_OFFBY1,
1073                    "`%%%smacro' expects a macro name",
1074                    (i == PP_IMACRO ? "i" : ""));
1075             return 3;
1076         }
1077         defining = nasm_malloc(sizeof(MMacro));
1078         defining->name = nasm_strdup(tline->text);
1079         defining->casesense = (i == PP_MACRO);
1080         defining->plus = FALSE;
1081         defining->in_progress = FALSE;
1082         tline = tline->next;
1083         if (tline && tline->type == TOK_WHITESPACE)
1084             tline = tline->next;
1085         if (!tline || tline->type != TOK_NUMBER) {
1086             error (ERR_NONFATAL|ERR_OFFBY1,
1087                    "`%%%smacro' expects a parameter count",
1088                    (i == PP_IMACRO ? "i" : ""));
1089             defining->nparam_min = defining->nparam_max = 0;
1090         } else {
1091             defining->nparam_min = defining->nparam_max =
1092                 readnum(tline->text, &j);
1093             if (j)
1094                 error (ERR_NONFATAL|ERR_OFFBY1,
1095                        "unable to parse parameter count `%s'", tline->text);
1096         }
1097         if (tline && tline->next && tline->next->type == TOK_OTHER &&
1098             !strcmp(tline->next->text, "-")) {
1099             tline = tline->next->next;
1100             if (!tline || tline->type != TOK_NUMBER)
1101                 error (ERR_NONFATAL|ERR_OFFBY1,
1102                        "`%%%smacro' expects a parameter count after `-'",
1103                        (i == PP_IMACRO ? "i" : ""));
1104             else {
1105                 defining->nparam_max = readnum(tline->text, &j);
1106                 if (j)
1107                     error (ERR_NONFATAL|ERR_OFFBY1,
1108                            "unable to parse parameter count `%s'",
1109                            tline->text);
1110                 if (defining->nparam_min > defining->nparam_max)
1111                     error (ERR_NONFATAL|ERR_OFFBY1,
1112                            "minimum parameter count exceeds maximum");
1113             }
1114         }
1115         if (tline && tline->next && tline->next->type == TOK_OTHER &&
1116             !strcmp(tline->next->text, "+")) {
1117             tline = tline->next;
1118             defining->plus = TRUE;
1119         }
1120         mmac = mmacros[hash(defining->name)];
1121         while (mmac) {
1122             if (!strcmp(mmac->name, defining->name) &&
1123                 (mmac->nparam_min<=defining->nparam_max || defining->plus) &&
1124                 (defining->nparam_min<=mmac->nparam_max || mmac->plus)) {
1125                 error (ERR_WARNING|ERR_OFFBY1,
1126                        "redefining multi-line macro `%s'", defining->name);
1127                 break;
1128             }
1129             mmac = mmac->next;
1130         }
1131         /*
1132          * Handle default parameters.
1133          */
1134         if (tline && tline->next) {
1135             int np, want_np;
1136
1137             defining->dlist = tline->next;
1138             tline->next = NULL;
1139             count_mmac_params (defining->dlist, &np, &defining->defaults);
1140             want_np = defining->nparam_max - defining->nparam_min;
1141             defining->defaults = nasm_realloc (defining->defaults,
1142                                                want_np*sizeof(Token *));
1143             while (np < want_np)
1144                 defining->defaults[np++] = NULL;
1145         } else {
1146             defining->dlist = NULL;
1147             defining->defaults = NULL;
1148         }
1149         defining->expansion = NULL;
1150         return 1;
1151
1152       case PP_ENDM:
1153       case PP_ENDMACRO:
1154         if (!defining) {
1155             error (ERR_NONFATAL|ERR_OFFBY1, "`%s': not defining a macro",
1156                    tline->text);
1157             return 3;
1158         }
1159         k = hash(defining->name);
1160         defining->next = mmacros[k];
1161         mmacros[k] = defining;
1162         defining = NULL;
1163         return 5;
1164
1165       case PP_DEFINE:
1166       case PP_IDEFINE:
1167         tline = tline->next;
1168         if (tline && tline->type == TOK_WHITESPACE)
1169             tline = tline->next;
1170         if (!tline || (tline->type != TOK_ID &&
1171                        (tline->type != TOK_PREPROC_ID ||
1172                         tline->text[1] != '$'))) {
1173             error (ERR_NONFATAL|ERR_OFFBY1,
1174                    "`%%%sdefine' expects a macro identifier",
1175                    (i == PP_IDEFINE ? "i" : ""));
1176             return 3;
1177         }
1178         mname = tline->text;
1179         if (tline->type == TOK_ID) {
1180             p = tline->text;
1181             smhead = &smacros[hash(mname)];
1182         } else {
1183             ctx = get_ctx (tline->text);
1184             if (ctx == NULL)
1185                 return 3;
1186             else {
1187                 p = tline->text+1;
1188                 p += strspn(p, "$");
1189                 smhead = &ctx->localmac;
1190             }
1191         }
1192         last = tline;
1193         param_start = tline = tline->next;
1194         nparam = 0;
1195         if (tline && tline->type == TOK_OTHER && !strcmp(tline->text, "(")) {
1196             /*
1197              * This macro has parameters.
1198              */
1199
1200             tline = tline->next;
1201             while (1) {
1202                 if (tline && tline->type == TOK_WHITESPACE)
1203                     tline = tline->next;
1204                 if (!tline) {
1205                     error (ERR_NONFATAL|ERR_OFFBY1,
1206                            "parameter identifier expected");
1207                     return 3;
1208                 }
1209                 if (tline->type != TOK_ID) {
1210                     error (ERR_NONFATAL|ERR_OFFBY1,
1211                            "`%s': parameter identifier expected",
1212                            tline->text);
1213                     return 3;
1214                 }
1215                 tline->type = TOK_SMAC_PARAM + nparam++;
1216                 tline = tline->next;
1217                 if (tline && tline->type == TOK_WHITESPACE)
1218                     tline = tline->next;
1219                 if (tline && tline->type == TOK_OTHER &&
1220                     !strcmp(tline->text, ",")) {
1221                     tline = tline->next;
1222                     continue;
1223                 }
1224                 if (!tline || tline->type != TOK_OTHER ||
1225                     strcmp(tline->text, ")")) {
1226                     error (ERR_NONFATAL|ERR_OFFBY1,
1227                            "`)' expected to terminate macro template");
1228                     return 3;
1229                 }
1230                 break;
1231             }
1232             last = tline;
1233             tline = tline->next;
1234         }
1235         if (tline && tline->type == TOK_WHITESPACE)
1236             last = tline, tline = tline->next;
1237         macro_start = NULL;
1238         last->next = NULL;
1239         t = tline;
1240         while (t) {
1241             if (t->type == TOK_ID) {
1242                 for (tt = param_start; tt; tt = tt->next)
1243                     if (tt->type >= TOK_SMAC_PARAM &&
1244                         !strcmp(tt->text, t->text))
1245                         t->type = tt->type;
1246             }
1247             tt = t->next;
1248             t->next = macro_start;
1249             macro_start = t;
1250             t = tt;
1251         }
1252         /*
1253          * Good. We now have a macro name, a parameter count, and a
1254          * token list (in reverse order) for an expansion. We ought
1255          * to be OK just to create an SMacro, store it, and let
1256          * tlist_free have the rest of the line (which we have
1257          * carefully re-terminated after chopping off the expansion
1258          * from the end).
1259          */
1260         if (smacro_defined (mname, nparam, &smac)) {
1261             if (!smac)
1262                 error (ERR_WARNING|ERR_OFFBY1,
1263                        "single-line macro `%s' defined both with and"
1264                        " without parameters", mname);
1265             else {
1266                 /*
1267                  * We're redefining, so we have to take over an
1268                  * existing SMacro structure. This means freeing
1269                  * what was already in it.
1270                  */
1271                 nasm_free (smac->name);
1272                 free_tlist (smac->expansion);
1273             }
1274         } else {
1275             smac = nasm_malloc(sizeof(SMacro));
1276             smac->next = *smhead;
1277             *smhead = smac;
1278         }
1279         smac->name = nasm_strdup(p);
1280         smac->casesense = (i == PP_DEFINE);
1281         smac->nparam = nparam;
1282         smac->expansion = macro_start;
1283         smac->in_progress = FALSE;
1284         return 3;
1285
1286       case PP_LINE:
1287         /*
1288          * Syntax is `%line nnn[+mmm] [filename]'
1289          */
1290         tline = tline->next;
1291         if (tline && tline->type == TOK_WHITESPACE)
1292             tline = tline->next;
1293         if (!tline || tline->type != TOK_NUMBER) {
1294             error (ERR_NONFATAL|ERR_OFFBY1, "`%%line' expects line number");
1295             return 3;
1296         }
1297         k = readnum(tline->text, &j);
1298         m = 1;
1299         tline = tline->next;
1300         if (tline && tline->type == TOK_OTHER && !strcmp(tline->text, "+")) {
1301             tline = tline->next;
1302             if (!tline || tline->type != TOK_NUMBER) {
1303                 error (ERR_NONFATAL|ERR_OFFBY1,
1304                        "`%%line' expects line increment");
1305                 return 3;
1306             }
1307             m = readnum(tline->text, &j);
1308             tline = tline->next;
1309         }
1310         if (tline && tline->type == TOK_WHITESPACE)
1311             tline = tline->next;
1312         istk->lineno = k;
1313         istk->lineinc = m;
1314         if (tline) {
1315             char *s = detoken(tline);
1316             nasm_free (istk->fname);
1317             istk->fname = s;
1318         }
1319         return 5;
1320
1321       default:
1322         error(ERR_FATAL|ERR_OFFBY1,
1323               "preprocessor directive `%s' not yet implemented",
1324               directives[k]);
1325         break;
1326     }
1327     return 3;
1328 }
1329
1330 /*
1331  * Expand all single-line macro calls made in the given line.
1332  * Return the expanded version of the line. The original is deemed
1333  * to be destroyed in the process. (In reality we'll just move
1334  * Tokens from input to output a lot of the time, rather than
1335  * actually bothering to destroy and replicate.)
1336  */
1337 static Token *expand_smacro (Token *tline) {
1338     Token *t, *tt, *mstart, **tail, *thead;
1339     SMacro *head, *m;
1340     Token **params;
1341     int *paramsize;
1342     int nparam, sparam, brackets;
1343     char *p;
1344
1345     tail = &thead;
1346     thead = NULL;
1347
1348     while (tline) {
1349         while (tline && tline->type != TOK_ID &&
1350                (tline->type != TOK_PREPROC_ID || tline->text[1] != '$')) {
1351             if (tline->type == TOK_SMAC_END) {
1352                 tline->mac->in_progress = FALSE;
1353                 t = tline;
1354                 tline = tline->next;
1355                 nasm_free (t);
1356             } else {
1357                 t = *tail = tline;
1358                 tline = tline->next;
1359                 t->mac = NULL;
1360                 t->next = NULL;
1361                 tail = &t->next;
1362                 if (t->type == TOK_PS_OTHER) {
1363                     /*
1364                      * If we see a PS_OTHER, we must at the very
1365                      * least restore its correct token type. We
1366                      * should also check for a %$ token, since this
1367                      * is the point at which we expand context-
1368                      * local labels.
1369                      */
1370                     t->type = TOK_ID;
1371                     if (t->text[0] == '%' && t->text[1] == '$') {
1372                         Context *c = get_ctx (t->text);
1373                         char *p, *q, buffer[40];
1374
1375                         if (c) {
1376                             q = t->text+1;
1377                             q += strspn(q, "$");
1378                             sprintf(buffer, "macro.%lu.", c->number);
1379                             p = nasm_malloc (strlen(buffer)+strlen(q)+1);
1380                             strcpy (p, buffer);
1381                             strcat (p, q);
1382                             nasm_free (t->text);
1383                             t->text = p;
1384                         }
1385                     }
1386                 }
1387             }
1388         }
1389         if (!tline)
1390             break;
1391         /*
1392          * We've hit an identifier. As in is_mmacro below, we first
1393          * check whether the identifier is a single-line macro at
1394          * all, then think about checking for parameters if
1395          * necessary.
1396          */
1397         if (tline->type == TOK_ID) {
1398             head = smacros[hash(tline->text)];
1399             p = tline->text;
1400         } else {
1401             Context *ctx = get_ctx (tline->text);
1402             if (ctx) {
1403                 p = tline->text+1;
1404                 p += strspn(p, "$");
1405                 head = ctx->localmac;
1406             } else {
1407                 tline->type = TOK_OTHER; /* so it will get copied above */
1408                 continue;               
1409             }
1410         }
1411         for (m = head; m; m = m->next)
1412             if (!mstrcmp(m->name, p, m->casesense))
1413                 break;
1414         if (!m) {
1415             /*
1416              * Didn't find one: this can't be a macro call. Copy it
1417              * through and ignore it.
1418              */
1419             tline->type = TOK_PS_OTHER;   /* so it will get copied above */
1420             continue;
1421         }
1422         mstart = tline;
1423         if (m->nparam == 0) {
1424             /*
1425              * Simple case: the macro is parameterless. Discard the
1426              * one token that the macro call took, and push the
1427              * expansion back on the to-do stack.
1428              */
1429             params = NULL;
1430             paramsize = NULL;
1431         } else {
1432             /*
1433              * Complicated case: at least one macro with this name
1434              * exists and takes parameters. We must find the
1435              * parameters in the call, count them, find the SMacro
1436              * that corresponds to that form of the macro call, and
1437              * substitute for the parameters when we expand. What a
1438              * pain.
1439              */
1440             nparam = sparam = 0;
1441             params = NULL;
1442             paramsize = NULL;
1443             tline = tline->next;
1444             if (tline && tline->type == TOK_WHITESPACE)
1445                 tline = tline->next;
1446             if (!tline || tline->type != TOK_OTHER ||
1447                 strcmp(tline->text, "(")) {
1448                 /*
1449                  * This macro wasn't called with parameters: ignore
1450                  * the call. (Behaviour borrowed from gnu cpp.)
1451                  */
1452                 tline = mstart;
1453                 tline->type = TOK_PS_OTHER;
1454                 continue;
1455             }
1456             tline = tline->next;
1457             while (1) {
1458                 if (tline && tline->type == TOK_WHITESPACE)
1459                     tline = tline->next;
1460                 if (!tline) {
1461                     error(ERR_NONFATAL|ERR_OFFBY1,
1462                           "macro call expects terminating `)'");
1463                     break;
1464                 }
1465                 if (nparam >= sparam) {
1466                     sparam += PARAM_DELTA;
1467                     params = nasm_realloc (params, sparam*sizeof(Token *));
1468                     paramsize = nasm_realloc (paramsize, sparam*sizeof(int));
1469                 }
1470                 params[nparam] = tline;
1471                 paramsize[nparam] = 0;
1472                 brackets = 0;
1473                 if (tline && tline->type == TOK_OTHER &&
1474                     !strcmp(tline->text, "{")) {
1475                     params[nparam] = tline = tline->next;
1476                     while (tline && (brackets > 0 ||
1477                                      tline->type != TOK_OTHER ||
1478                                      strcmp(tline->text, "}"))) {
1479                         tline = tline->next;
1480                         paramsize[nparam]++;
1481                     }
1482                     tline = tline->next;
1483                     if (tline && tline->type == TOK_WHITESPACE)
1484                         tline = tline->next;
1485                     if (tline && (tline->type != TOK_OTHER ||
1486                                   (strcmp(tline->text, ")") &&
1487                                    strcmp(tline->text, ",")))) {
1488                         error (ERR_NONFATAL|ERR_OFFBY1, "braces do not "
1489                                "enclose all of macro parameter");
1490                     }
1491                     if (tline && tline->type == TOK_OTHER &&
1492                         !strcmp(tline->text, ","))
1493                         tline = tline->next;
1494                 } else {
1495                     while (tline && (brackets > 0 ||
1496                                      tline->type != TOK_OTHER ||
1497                                      (strcmp(tline->text, ",") &&
1498                                       strcmp(tline->text, ")")))) {
1499                         if (tline->type == TOK_OTHER && !tline->text[1])
1500                             brackets += (tline->text[0] == '(' ? 1 :
1501                                          tline->text[0] == ')' ? -1 : 0);
1502                         tline = tline->next;
1503                         paramsize[nparam]++;
1504                     }
1505                 }
1506                 nparam++;
1507                 if (tline && !strcmp(tline->text, ")"))
1508                     break;
1509                 if (tline && !strcmp(tline->text, ","))
1510                     tline = tline->next;
1511             }
1512             while (m && m->nparam != nparam) {
1513                 while ( (m = m->next) )
1514                     if (!strcmp(m->name, mstart->text))
1515                         break;
1516             }
1517             if (!m) {
1518                 error (ERR_WARNING|ERR_OFFBY1,
1519                        "macro `%s' exists, but not taking %d parameters",
1520                        mstart->text, nparam);
1521                 nasm_free (params);
1522                 nasm_free (paramsize);
1523                 tline = mstart;
1524                 tline->type = TOK_PS_OTHER;
1525                 continue;
1526             }
1527             if (m->in_progress) {
1528                 error (ERR_NONFATAL, "self-reference in single-line macro"
1529                        " `%s'", mstart->text);
1530                 nasm_free (params);
1531                 nasm_free (paramsize);
1532                 tline = mstart;
1533                 tline->type = TOK_PS_OTHER;
1534                 continue;
1535             }
1536         }
1537         /*
1538          * Expand the macro: we are placed on the last token of the
1539          * call, so that we can easily split the call from the
1540          * following tokens. We also start by pushing an SMAC_END
1541          * token for the cycle removal.
1542          */
1543         t = tline;
1544         tline = tline->next;
1545         t->next = NULL;
1546         tt = nasm_malloc(sizeof(Token));
1547         tt->type = TOK_SMAC_END;
1548         tt->text = NULL;
1549         tt->mac = m;
1550         m->in_progress = TRUE;
1551         tt->next = tline;
1552         tline = tt;
1553         for (t = m->expansion; t; t = t->next) {
1554             if (t->type >= TOK_SMAC_PARAM) {
1555                 Token *pcopy = tline, **ptail = &pcopy;
1556                 Token *ttt, *pt;
1557                 int i;
1558                 
1559                 ttt = params[t->type - TOK_SMAC_PARAM];
1560                 for (i=0; i<paramsize[t->type-TOK_SMAC_PARAM]; i++) {
1561                     pt = *ptail = nasm_malloc(sizeof(Token));
1562                     pt->next = tline;
1563                     ptail = &pt->next;
1564                     pt->text = nasm_strdup(ttt->text);
1565                     pt->type = ttt->type;
1566                     pt->mac = NULL;
1567                     ttt = ttt->next;
1568                 }
1569                 tline = pcopy;
1570             } else {
1571                 tt = nasm_malloc(sizeof(Token));
1572                 tt->type = t->type;
1573                 tt->text = nasm_strdup(t->text);
1574                 tt->mac = NULL;
1575                 tt->next = tline;
1576                 tline = tt;
1577             }
1578         }
1579
1580         /*
1581          * Having done that, get rid of the macro call, and clean
1582          * up the parameters.
1583          */
1584         nasm_free (params);
1585         nasm_free (paramsize);
1586         free_tlist (mstart);
1587     }
1588
1589     return thead;
1590 }
1591
1592 /*
1593  * Ensure that a macro parameter contains a condition code and
1594  * nothing else. Return the condition code index if so, or -1
1595  * otherwise.
1596  */
1597 static int find_cc (Token *t) {
1598     Token *tt;
1599     int i, j, k, m;
1600
1601     if (t && t->type == TOK_WHITESPACE)
1602         t = t->next;
1603     if (t->type != TOK_ID)
1604         return -1;
1605     tt = t->next;
1606     if (tt && tt->type == TOK_WHITESPACE)
1607         tt = tt->next;
1608     if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
1609         return -1;
1610
1611     i = -1;
1612     j = sizeof(conditions)/sizeof(*conditions);
1613     while (j-i > 1) {
1614         k = (j+i) / 2;
1615         m = nasm_stricmp(t->text, conditions[k]);
1616         if (m == 0) {
1617             i = k;
1618             j = -2;
1619             break;
1620         } else if (m < 0) {
1621             j = k;
1622         } else
1623             i = k;
1624     }
1625     if (j != -2)
1626         return -1;
1627     return i;
1628 }
1629
1630 /*
1631  * Determine whether the given line constitutes a multi-line macro
1632  * call, and return the MMacro structure called if so. Doesn't have
1633  * to check for an initial label - that's taken care of in
1634  * expand_mmacro - but must check numbers of parameters. Guaranteed
1635  * to be called with tline->type == TOK_ID, so the putative macro
1636  * name is easy to find.
1637  */
1638 static MMacro *is_mmacro (Token *tline, Token ***params_array) {
1639     MMacro *head, *m;
1640     Token **params;
1641     int nparam;
1642
1643     head = mmacros[hash(tline->text)];
1644
1645     /*
1646      * Efficiency: first we see if any macro exists with the given
1647      * name. If not, we can return NULL immediately. _Then_ we
1648      * count the parameters, and then we look further along the
1649      * list if necessary to find the proper MMacro.
1650      */
1651     for (m = head; m; m = m->next)
1652         if (!mstrcmp(m->name, tline->text, m->casesense))
1653             break;
1654     if (!m)
1655         return NULL;
1656
1657     /*
1658      * OK, we have a potential macro. Count and demarcate the
1659      * parameters.
1660      */
1661     count_mmac_params (tline->next, &nparam, &params);
1662
1663     /*
1664      * So we know how many parameters we've got. Find the MMacro
1665      * structure that handles this number.
1666      */
1667     while (m) {
1668         if (m->nparam_min <= nparam && (m->plus || nparam <= m->nparam_max)) {
1669             /*
1670              * This one is right. Just check if cycle removal
1671              * prohibits us using it before we actually celebrate...
1672              */
1673             if (m->in_progress) {
1674                 error (ERR_NONFATAL|ERR_OFFBY1,
1675                        "self-reference in multi-line macro `%s'",
1676                        m->name);
1677                 nasm_free (params);
1678                 return NULL;
1679             }
1680             /*
1681              * It's right, and we can use it. Add its default
1682              * parameters to the end of our list if necessary.
1683              */
1684             params = nasm_realloc (params, (m->nparam_max+1)*sizeof(*params));
1685             if (m->defaults) {
1686                 while (nparam < m->nparam_max) {
1687                     params[nparam] = m->defaults[nparam - m->nparam_min];
1688                     nparam++;
1689                 }
1690             } else {
1691                 while (nparam < m->nparam_max) {
1692                     params[nparam] = NULL;
1693                     nparam++;
1694                 }
1695             }
1696             /*
1697              * Then terminate the parameter list, and leave.
1698              */
1699             params[m->nparam_max] = NULL;
1700             *params_array = params;
1701             return m;
1702         }
1703         /*
1704          * This one wasn't right: look for the next one with the
1705          * same name.
1706          */
1707         for (m = m->next; m; m = m->next)
1708             if (!mstrcmp(m->name, tline->text, m->casesense))
1709                 break;
1710     }
1711
1712     /*
1713      * After all that, we didn't find one with the right number of
1714      * parameters. Issue a warning, and fail to expand the macro.
1715      */
1716     error (ERR_WARNING|ERR_OFFBY1,
1717            "macro `%s' exists, but not taking %d parameters",
1718            tline->text, nparam);
1719     nasm_free (params);
1720     return NULL;
1721 }
1722
1723 /*
1724  * Expand the multi-line macro call made by the given line, if
1725  * there is one to be expanded. If there is, push the expansion on
1726  * istk->expansion and return 1 or 2, as according to whether a
1727  * line sync is needed (2 if it is). Otherwise return 0.
1728  */
1729 static int expand_mmacro (Token *tline) {
1730     Token *label = NULL, **params, *t, *tt, *ttt, *last = NULL;
1731     MMacro *m = NULL;
1732     Line *l, *ll;
1733     int i, n, nparam, *paramlen;
1734     int need_sync = FALSE;
1735
1736     t = tline;
1737     if (t && t->type == TOK_WHITESPACE)
1738         t = t->next;
1739     if (t && t->type == TOK_ID) {
1740         m = is_mmacro (t, &params);
1741         if (!m) {
1742             /*
1743              * We have an id which isn't a macro call. We'll assume
1744              * it might be a label; we'll also check to see if a
1745              * colon follows it. Then, if there's another id after
1746              * that lot, we'll check it again for macro-hood.
1747              */
1748             last = t, t = t->next;
1749             if (t && t->type == TOK_WHITESPACE)
1750                 last = t, t = t->next;
1751             if (t && t->type == TOK_OTHER && !strcmp(t->text, ":"))
1752                 last = t, t = t->next;
1753             if (t && t->type == TOK_WHITESPACE)
1754                 last = t, t = t->next;
1755             if (t && t->type == TOK_ID) {
1756                 m = is_mmacro(t, &params);
1757                 if (m) {
1758                     last->next = NULL;
1759                     label = tline;
1760                     tline = t;
1761                 }
1762             }
1763         }       
1764     }
1765     if (!m)
1766         return 0;
1767
1768     /*
1769      * If we're not already inside another macro expansion, we'd
1770      * better push a line synchronisation to ensure we stay put on
1771      * line numbering.
1772      */
1773     if (!istk->expansion)
1774         need_sync = TRUE;
1775
1776     /*
1777      * Fix up the parameters: this involves stripping leading and
1778      * trailing whitespace, then stripping braces if they are
1779      * present.
1780      */
1781     for (nparam = 0; params[nparam]; nparam++);
1782     paramlen = nparam ? nasm_malloc(nparam*sizeof(*paramlen)) : NULL;
1783
1784     for (i = 0; params[i]; i++) {
1785         int brace = FALSE;
1786         int comma = !m->plus;
1787
1788         t = params[i];
1789         if (t && t->type == TOK_WHITESPACE)
1790             t = t->next;
1791         if (t && t->type == TOK_OTHER && !strcmp(t->text, "{"))
1792             t = t->next, brace = TRUE, comma = FALSE;
1793         params[i] = t;
1794         paramlen[i] = 0;
1795         while (t) {
1796             if (!t)                    /* end of param because EOL */
1797                 break;
1798             if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
1799                     break;             /* ... because we have hit a comma */
1800             if (comma && t->type == TOK_WHITESPACE &&
1801                 t->next->type == TOK_OTHER && !strcmp(t->next->text, ","))
1802                 break;                 /* ... or a space then a comma */
1803             if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
1804                     break;             /* ... or a brace */
1805             t = t->next;
1806             paramlen[i]++;
1807         }
1808     }
1809
1810     /*
1811      * OK, we have a MMacro structure together with a set of
1812      * parameters. We must now go through the expansion and push
1813      * _copies_ of each Line on to istk->expansion, having first
1814      * substituted for most % tokens (%1, %+1, %-1, %%foo). Note
1815      * that %$bar, %$$baz, %$$$quux, and so on, do not get
1816      * substituted here but rather have to wait until the
1817      * single-line macro substitution process. This is because they
1818      * don't just crop up in macro definitions, but can appear
1819      * anywhere they like.
1820      *
1821      * First, push an end marker on to istk->expansion, and mark
1822      * this macro as in progress.
1823      */
1824     ll = nasm_malloc(sizeof(Line));
1825     ll->next = istk->expansion;
1826     ll->finishes = m;
1827     ll->first = NULL;
1828     istk->expansion = ll;
1829     m->in_progress = TRUE;
1830     for (l = m->expansion; l; l = l->next) {
1831         Token **tail;
1832
1833         ll = nasm_malloc(sizeof(Line));
1834         ll->next = istk->expansion;
1835         ll->finishes = NULL;
1836         tail = &ll->first;
1837
1838         for (t = l->first; t; t = t->next) {
1839             char *text;
1840             int type = 0, cc;          /* type = 0 to placate optimisers */
1841             char tmpbuf[30];
1842
1843             if (t->type == TOK_PREPROC_ID &&
1844                 (t->text[1] == '+' || t->text[1] == '-' ||
1845                  t->text[1] == '%' ||
1846                  (t->text[1] >= '0' && t->text[1] <= '9'))) {
1847                 /*
1848                  * We have to make a substitution of one of the
1849                  * forms %1, %-1, %+1, %%foo.
1850                  */
1851                 switch (t->text[1]) {
1852                   case '%':
1853                     type = TOK_ID;
1854                     sprintf(tmpbuf, "macro.%lu.", unique);
1855                     text = nasm_malloc(strlen(tmpbuf)+strlen(t->text+2)+1);
1856                     strcpy(text, tmpbuf);
1857                     strcat(text, t->text+2);
1858                     break;
1859                   case '-':
1860                     n = atoi(t->text+2)-1;
1861                     tt = params[n];
1862                     cc = find_cc (tt);
1863                     if (cc == -1) {
1864                         error (ERR_NONFATAL|ERR_OFFBY1,
1865                                "macro parameter %d is not a condition code",
1866                                n+1);
1867                         text = NULL;
1868                     } else {
1869                         type = TOK_ID;
1870                         if (inverse_ccs[cc] == -1) {
1871                             error (ERR_NONFATAL|ERR_OFFBY1,
1872                                    "condition code `%s' is not invertible",
1873                                    conditions[cc]);
1874                             text = NULL;
1875                         } else
1876                             text = nasm_strdup(conditions[inverse_ccs[cc]]);
1877                     }
1878                     break;
1879                   case '+':
1880                     n = atoi(t->text+2)-1;
1881                     tt = params[n];
1882                     cc = find_cc (tt);
1883                     if (cc == -1) {
1884                         error (ERR_NONFATAL|ERR_OFFBY1,
1885                                "macro parameter %d is not a condition code",
1886                                n+1);
1887                         text = NULL;
1888                     } else {
1889                         type = TOK_ID;
1890                         text = nasm_strdup(conditions[cc]);
1891                     }
1892                     break;
1893                   default:
1894                     n = atoi(t->text+1)-1;
1895                     if (n < nparam) {
1896                         ttt = params[n];
1897                         for (i=0; i<paramlen[n]; i++) {
1898                             tt = *tail = nasm_malloc(sizeof(Token));
1899                             tt->next = NULL;
1900                             tail = &tt->next;
1901                             tt->type = ttt->type;
1902                             tt->text = nasm_strdup(ttt->text);
1903                             tt->mac = NULL;
1904                             ttt = ttt->next;
1905                         }
1906                     }
1907                     text = NULL;       /* we've done it here */
1908                     break;
1909                 }
1910             } else {
1911                 type = t->type;
1912                 text = nasm_strdup(t->text);
1913             }
1914
1915             if (text) {
1916                 tt = *tail = nasm_malloc(sizeof(Token));
1917                 tt->next = NULL;
1918                 tail = &tt->next;
1919                 tt->type = type;
1920                 tt->text = text;
1921                 tt->mac = NULL;
1922             }
1923         }
1924
1925         istk->expansion = ll;
1926     }
1927
1928     /*
1929      * If we had a label, push it on the front of the first line of
1930      * the macro expansion.
1931      */
1932     if (label) {
1933         last->next = istk->expansion->first;
1934         istk->expansion->first = label;
1935     }
1936
1937     /*
1938      * Clean up.
1939      */
1940     unique++;
1941     nasm_free (paramlen);
1942     nasm_free (params);
1943     free_tlist (tline);
1944
1945     return need_sync ? 2 : 1;
1946 }
1947
1948 static void pp_reset (char *file, efunc errfunc) {
1949     int h;
1950
1951     error = errfunc;
1952     cstk = NULL;
1953     linesync = outline = NULL;
1954     istk = nasm_malloc(sizeof(Include));
1955     istk->next = NULL;
1956     istk->conds = NULL;
1957     istk->expansion = NULL;
1958     istk->fp = fopen(file, "r");
1959     istk->fname = nasm_strdup(file);
1960     istk->lineno = istk->lineinc = 1;
1961     if (!istk->fp)
1962         error (ERR_FATAL|ERR_NOFILE, "unable to open input file `%s'", file);
1963     defining = NULL;
1964     for (h=0; h<NHASH; h++) {
1965         mmacros[h] = NULL;
1966         smacros[h] = NULL;
1967     }
1968     unique = 0;
1969     stdmacpos = stdmac;
1970 }
1971
1972 static char *pp_getline (void) {
1973     char *line;
1974     Token *tline;
1975     int ret;
1976
1977     if (outline) {
1978         line = outline;
1979         outline = NULL;
1980         return line;
1981     }
1982
1983     while (1) {
1984         /*
1985          * Fetch a tokenised line, either from the macro-expansion
1986          * buffer or from the input file.
1987          */
1988         tline = NULL;
1989         while (istk->expansion && istk->expansion->finishes) {
1990             Line *l = istk->expansion;
1991             tline = l->first;
1992             l->finishes->in_progress = FALSE;
1993             istk->expansion = l->next;
1994             nasm_free (l);
1995             if (!istk->expansion)
1996                 line_sync();
1997         }
1998         if (istk->expansion) {
1999             Line *l = istk->expansion;
2000             tline = l->first;
2001             istk->expansion = l->next;
2002             nasm_free (l);
2003             if (!istk->expansion)
2004                 line_sync();
2005         } else {
2006             line = read_line();
2007             while (!line) {
2008                 /*
2009                  * The current file has ended; work down the istk
2010                  * until we find a file we can read from.
2011                  */
2012                 Include *i;
2013                 fclose(istk->fp);
2014                 if (istk->conds)
2015                     error(ERR_FATAL, "expected `%%endif' before end of file");
2016                 i = istk;
2017                 istk = istk->next;
2018                 nasm_free (i->fname);
2019                 nasm_free (i);
2020                 if (!istk)
2021                     return NULL;
2022                 else
2023                     line_sync();
2024                 line = read_line();
2025             }
2026             line = prepreproc(line);
2027             tline = tokenise(line);
2028             nasm_free (line);
2029         }
2030
2031         /*
2032          * Check the line to see if it's a preprocessor directive.
2033          */
2034         ret = do_directive(tline);
2035         if (ret & 1) {
2036             free_tlist (tline);
2037             if (ret & 4)
2038                 line_sync();
2039             if ((ret & 2) && !stdmacpos) {/* give a blank line to the output */
2040                 outline = nasm_strdup("");
2041                 break;
2042             }
2043             else
2044                 continue;
2045         } else if (defining) {
2046             /*
2047              * We're defining a multi-line macro. We emit nothing
2048              * at all, not even a blank line (when we finish
2049              * defining the macro, we'll emit a line-number
2050              * directive so that we keep sync properly), and just
2051              * shove the tokenised line on to the macro definition.
2052              */
2053             Line *l = nasm_malloc(sizeof(Line));
2054             l->next = defining->expansion;
2055             l->first = tline;
2056             l->finishes = FALSE;
2057             defining->expansion = l;
2058             continue;
2059         } else if (istk->conds && !emitting(istk->conds->state)) {
2060             /*
2061              * We're in a non-emitting branch of a condition block.
2062              * Emit nothing at all, not even a blank line: when we
2063              * emerge from the condition we'll give a line-number
2064              * directive so we keep our place correctly.
2065              */
2066             free_tlist(tline);
2067             continue;
2068         } else {
2069             tline = expand_smacro(tline);
2070             ret = expand_mmacro(tline);
2071             if (!ret) {
2072                 /*
2073                  * De-tokenise the line again, and emit it.
2074                  */
2075                 line = detoken(tline);
2076                 free_tlist (tline);
2077                 outline = line;
2078                 break;
2079             } else {
2080                 if (ret == 2)
2081                     line_sync();
2082                 continue;              /* expand_mmacro calls free_tlist */
2083             }
2084         }
2085     }
2086
2087     /*
2088      * Once we're out of this loop, outline _must_ be non-NULL. The
2089      * only question is whether linesync is NULL or not.
2090      */
2091     if (linesync) {
2092         line = linesync;
2093         linesync = NULL;
2094     } else {
2095         line = outline;
2096         outline = NULL;
2097     }
2098     return line;
2099 }
2100
2101 static void pp_cleanup (void) {
2102     int h;
2103
2104     if (defining) {
2105         error (ERR_NONFATAL, "end of file while still defining macro `%s'",
2106                defining->name);
2107         nasm_free (defining->name);
2108         free_tlist (defining->dlist);
2109         free_llist (defining->expansion);
2110         nasm_free (defining);
2111     }
2112     nasm_free (linesync);              /* might just be necessary */
2113     nasm_free (outline);               /* really shouldn't be necessary */
2114     while (cstk)
2115         ctx_pop();
2116     for (h=0; h<NHASH; h++) {
2117         while (mmacros[h]) {
2118             MMacro *m = mmacros[h];
2119             mmacros[h] = mmacros[h]->next;
2120             nasm_free (m->name);
2121             free_tlist (m->dlist);
2122             free_llist (m->expansion);
2123             nasm_free (m);
2124         }
2125         while (smacros[h]) {
2126             SMacro *s = smacros[h];
2127             smacros[h] = smacros[h]->next;
2128             nasm_free (s->name);
2129             free_tlist (s->expansion);
2130             nasm_free (s);
2131         }
2132     }
2133     while (istk) {
2134         Include *i = istk;
2135         istk = istk->next;
2136         fclose(i->fp);
2137         nasm_free (i->fname);
2138         nasm_free (i);
2139     }
2140     while (cstk)
2141         ctx_pop();
2142 }
2143
2144 Preproc nasmpp = {
2145     pp_reset,
2146     pp_getline,
2147     pp_cleanup
2148 };