NASM 0.98.09
[nasm.git] / preproc.c
blob488517b640c53f39a36d5ef30faa54d84417a2d7
1 /* preproc.c macro preprocessor for the Netwide Assembler
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.
8 * initial version 18/iii/97 by Simon Tatham
9 */
11 /* Typical flow of text through preproc
13 * pp_getline gets tokenised lines, either
15 * from a macro expansion
17 * or
18 * {
19 * read_line gets raw text from stdmacpos, or predef, or current input file
20 * tokenise converts to tokens
21 * }
23 * expand_mmac_params is used to expand %1 etc., unless a macro is being
24 * defined or a false conditional is being processed
25 * (%0, %1, %+1, %-1, %%foo
27 * do_directive checks for directives
29 * expand_smacro is used to expand single line macros
31 * expand_mmacro is used to expand multi-line macros
33 * detoken is used to convert the line back to text
36 #include <stdio.h>
37 #include <stdarg.h>
38 #include <stdlib.h>
39 #include <stddef.h>
40 #include <string.h>
41 #include <ctype.h>
42 #include <limits.h>
44 #include "nasm.h"
45 #include "nasmlib.h"
47 typedef struct SMacro SMacro;
48 typedef struct MMacro MMacro;
49 typedef struct Context Context;
50 typedef struct Token Token;
51 typedef struct Line Line;
52 typedef struct Include Include;
53 typedef struct Cond Cond;
54 typedef struct IncPath IncPath;
57 * Store the definition of a single-line macro.
59 struct SMacro
61 SMacro *next;
62 char *name;
63 int casesense;
64 int nparam;
65 int in_progress;
66 Token *expansion;
70 * Store the definition of a multi-line macro. This is also used to
71 * store the interiors of `%rep...%endrep' blocks, which are
72 * effectively self-re-invoking multi-line macros which simply
73 * don't have a name or bother to appear in the hash tables. %rep
74 * blocks are signified by having a NULL `name' field.
76 * In a MMacro describing a `%rep' block, the `in_progress' field
77 * isn't merely boolean, but gives the number of repeats left to
78 * run.
80 * The `next' field is used for storing MMacros in hash tables; the
81 * `next_active' field is for stacking them on istk entries.
83 * When a MMacro is being expanded, `params', `iline', `nparam',
84 * `paramlen', `rotate' and `unique' are local to the invocation.
86 struct MMacro
88 MMacro *next;
89 char *name;
90 int casesense;
91 int nparam_min, nparam_max;
92 int plus; /* is the last parameter greedy? */
93 int nolist; /* is this macro listing-inhibited? */
94 int in_progress;
95 Token *dlist; /* All defaults as one list */
96 Token **defaults; /* Parameter default pointers */
97 int ndefs; /* number of default parameters */
98 Line *expansion;
100 MMacro *next_active;
101 MMacro *rep_nest; /* used for nesting %rep */
102 Token **params; /* actual parameters */
103 Token *iline; /* invocation line */
104 int nparam, rotate, *paramlen;
105 unsigned long unique;
106 int lineno; /* Current line number on expansion */
110 * The context stack is composed of a linked list of these.
112 struct Context
114 Context *next;
115 SMacro *localmac;
116 char *name;
117 unsigned long number;
121 * This is the internal form which we break input lines up into.
122 * Typically stored in linked lists.
124 * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
125 * necessarily used as-is, but is intended to denote the number of
126 * the substituted parameter. So in the definition
128 * %define a(x,y) ( (x) & ~(y) )
130 * the token representing `x' will have its type changed to
131 * TOK_SMAC_PARAM, but the one representing `y' will be
132 * TOK_SMAC_PARAM+1.
134 * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
135 * which doesn't need quotes around it. Used in the pre-include
136 * mechanism as an alternative to trying to find a sensible type of
137 * quote to use on the filename we were passed.
139 struct Token
141 Token *next;
142 char *text;
143 SMacro *mac; /* associated macro for TOK_SMAC_END */
144 int type;
146 enum
148 TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING,
149 TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM,
150 TOK_INTERNAL_STRING
154 * Multi-line macro definitions are stored as a linked list of
155 * these, which is essentially a container to allow several linked
156 * lists of Tokens.
158 * Note that in this module, linked lists are treated as stacks
159 * wherever possible. For this reason, Lines are _pushed_ on to the
160 * `expansion' field in MMacro structures, so that the linked list,
161 * if walked, would give the macro lines in reverse order; this
162 * means that we can walk the list when expanding a macro, and thus
163 * push the lines on to the `expansion' field in _istk_ in reverse
164 * order (so that when popped back off they are in the right
165 * order). It may seem cockeyed, and it relies on my design having
166 * an even number of steps in, but it works...
168 * Some of these structures, rather than being actual lines, are
169 * markers delimiting the end of the expansion of a given macro.
170 * This is for use in the cycle-tracking and %rep-handling code.
171 * Such structures have `finishes' non-NULL, and `first' NULL. All
172 * others have `finishes' NULL, but `first' may still be NULL if
173 * the line is blank.
175 struct Line
177 Line *next;
178 MMacro *finishes;
179 Token *first;
183 * To handle an arbitrary level of file inclusion, we maintain a
184 * stack (ie linked list) of these things.
186 struct Include
188 Include *next;
189 FILE *fp;
190 Cond *conds;
191 Line *expansion;
192 char *fname;
193 int lineno, lineinc;
194 MMacro *mstk; /* stack of active macros/reps */
198 * Include search path. This is simply a list of strings which get
199 * prepended, in turn, to the name of an include file, in an
200 * attempt to find the file if it's not in the current directory.
202 struct IncPath
204 IncPath *next;
205 char *path;
209 * Conditional assembly: we maintain a separate stack of these for
210 * each level of file inclusion. (The only reason we keep the
211 * stacks separate is to ensure that a stray `%endif' in a file
212 * included from within the true branch of a `%if' won't terminate
213 * it and cause confusion: instead, rightly, it'll cause an error.)
215 struct Cond
217 Cond *next;
218 int state;
220 enum
223 * These states are for use just after %if or %elif: IF_TRUE
224 * means the condition has evaluated to truth so we are
225 * currently emitting, whereas IF_FALSE means we are not
226 * currently emitting but will start doing so if a %else comes
227 * up. In these states, all directives are admissible: %elif,
228 * %else and %endif. (And of course %if.)
230 COND_IF_TRUE, COND_IF_FALSE,
232 * These states come up after a %else: ELSE_TRUE means we're
233 * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
234 * any %elif or %else will cause an error.
236 COND_ELSE_TRUE, COND_ELSE_FALSE,
238 * This state means that we're not emitting now, and also that
239 * nothing until %endif will be emitted at all. It's for use in
240 * two circumstances: (i) when we've had our moment of emission
241 * and have now started seeing %elifs, and (ii) when the
242 * condition construct in question is contained within a
243 * non-emitting branch of a larger condition construct.
245 COND_NEVER
247 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
250 * Condition codes. Note that we use c_ prefix not C_ because C_ is
251 * used in nasm.h for the "real" condition codes. At _this_ level,
252 * we treat CXZ and ECXZ as condition codes, albeit non-invertible
253 * ones, so we need a different enum...
255 static char *conditions[] = {
256 "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
257 "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
258 "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
260 enum
262 c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE,
263 c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO,
264 c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_S, c_Z
266 static int inverse_ccs[] = {
267 c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE,
268 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,
269 c_Z, c_NO, c_NP, c_PO, c_PE, c_NS, c_NZ
273 * Directive names.
275 static char *directives[] = {
276 "%arg",
277 "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
278 "%elifid", "%elifidn", "%elifidni", "%elifnctx", "%elifndef",
279 "%elifnid", "%elifnidn", "%elifnidni", "%elifnnum", "%elifnstr",
280 "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
281 "%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
282 "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifnctx",
283 "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnnum",
284 "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
285 "%ixdefine", "%line",
286 "%local",
287 "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
288 "%stacksize",
289 "%strlen", "%substr", "%undef", "%xdefine"
291 enum
293 PP_ARG,
294 PP_ASSIGN, PP_CLEAR, PP_DEFINE, PP_ELIF, PP_ELIFCTX, PP_ELIFDEF,
295 PP_ELIFID, PP_ELIFIDN, PP_ELIFIDNI, PP_ELIFNCTX, PP_ELIFNDEF,
296 PP_ELIFNID, PP_ELIFNIDN, PP_ELIFNIDNI, PP_ELIFNNUM, PP_ELIFNSTR,
297 PP_ELIFNUM, PP_ELIFSTR, PP_ELSE, PP_ENDIF, PP_ENDM, PP_ENDMACRO,
298 PP_ENDREP, PP_ERROR, PP_EXITREP, PP_IASSIGN, PP_IDEFINE, PP_IF,
299 PP_IFCTX, PP_IFDEF, PP_IFID, PP_IFIDN, PP_IFIDNI, PP_IFNCTX,
300 PP_IFNDEF, PP_IFNID, PP_IFNIDN, PP_IFNIDNI, PP_IFNNUM,
301 PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE,
302 PP_IXDEFINE, PP_LINE,
303 PP_LOCAL,
304 PP_MACRO, PP_POP, PP_PUSH, PP_REP, PP_REPL, PP_ROTATE,
305 PP_STACKSIZE,
306 PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
310 /* For TASM compatibility we need to be able to recognise TASM compatible
311 * conditional compilation directives. Using the NASM pre-processor does
312 * not work, so we look for them specifically from the following list and
313 * then jam in the equivalent NASM directive into the input stream.
316 #ifndef MAX
317 # define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
318 #endif
320 enum
322 TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
323 TM_IFNDEF, TM_INCLUDE, TM_LOCAL
326 static char *tasm_directives[] = {
327 "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
328 "ifndef", "include", "local"
331 static int StackSize = 4;
332 static char *StackPointer = "ebp";
333 static int ArgOffset = 8;
334 static int LocalOffset = 4;
337 static Context *cstk;
338 static Include *istk;
339 static IncPath *ipath = NULL;
341 static efunc __error; /* Pointer to client-provided error reporting function */
342 static evalfunc evaluate;
344 static int pass; /* HACK: pass 0 = generate dependencies only */
346 static unsigned long unique; /* unique identifier numbers */
348 static Line *predef = NULL;
350 static ListGen *list;
353 * The number of hash values we use for the macro lookup tables.
354 * FIXME: We should *really* be able to configure this at run time,
355 * or even have the hash table automatically expanding when necessary.
357 #define NHASH 31
360 * The current set of multi-line macros we have defined.
362 static MMacro *mmacros[NHASH];
365 * The current set of single-line macros we have defined.
367 static SMacro *smacros[NHASH];
370 * The multi-line macro we are currently defining, or the %rep
371 * block we are currently reading, if any.
373 static MMacro *defining;
376 * The number of macro parameters to allocate space for at a time.
378 #define PARAM_DELTA 16
381 * The standard macro set: defined as `static char *stdmac[]'. Also
382 * gives our position in the macro set, when we're processing it.
384 #include "macros.c"
385 static char **stdmacpos;
388 * The extra standard macros that come from the object format, if
389 * any.
391 static char **extrastdmac = NULL;
392 int any_extrastdmac;
395 * Tokens are allocated in blocks to improve speed
397 #define TOKEN_BLOCKSIZE 4096
398 static Token *freeTokens = NULL;
401 * Forward declarations.
403 static Token *expand_mmac_params(Token * tline);
404 static Token *expand_smacro(Token * tline);
405 static Token *expand_id(Token * tline);
406 static Context *get_ctx(char *name, int all_contexts);
407 static void make_tok_num(Token * tok, long val);
408 static void error(int severity, char *fmt, ...);
409 static Token *new_Token(Token * next, int type, char *text, int txtlen);
410 static Token *delete_Token(Token * t);
413 * Macros for safe checking of token pointers, avoid *(NULL)
415 #define tok_type_(x,t) ((x) && (x)->type == (t))
416 #define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
417 #define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
418 #define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
420 /* Handle TASM specific directives, which do not contain a % in
421 * front of them. We do it here because I could not find any other
422 * place to do it for the moment, and it is a hack (ideally it would
423 * be nice to be able to use the NASM pre-processor to do it).
425 static char *
426 check_tasm_directive(char *line)
428 int i, j, k, m, len;
429 char *p = line, *oldline, oldchar;
431 /* Skip whitespace */
432 while (isspace(*p) && *p != 0)
433 p++;
435 /* Binary search for the directive name */
436 i = -1;
437 j = sizeof(tasm_directives) / sizeof(*tasm_directives);
438 len = 0;
439 while (!isspace(p[len]) && p[len] != 0)
440 len++;
441 if (len)
443 oldchar = p[len];
444 p[len] = 0;
445 while (j - i > 1)
447 k = (j + i) / 2;
448 m = nasm_stricmp(p, tasm_directives[k]);
449 if (m == 0)
451 /* We have found a directive, so jam a % in front of it
452 * so that NASM will then recognise it as one if it's own.
454 p[len] = oldchar;
455 len = strlen(p);
456 oldline = line;
457 line = nasm_malloc(len + 2);
458 line[0] = '%';
459 if (k == TM_IFDIFI)
461 /* NASM does not recognise IFDIFI, so we convert it to
462 * %ifdef BOGUS. This is not used in NASM comaptible
463 * code, but does need to parse for the TASM macro
464 * package.
466 strcpy(line + 1, "ifdef BOGUS");
468 else
470 memcpy(line + 1, p, len + 1);
472 nasm_free(oldline);
473 return line;
475 else if (m < 0)
477 j = k;
479 else
480 i = k;
482 p[len] = oldchar;
484 return line;
488 * The pre-preprocessing stage... This function translates line
489 * number indications as they emerge from GNU cpp (`# lineno "file"
490 * flags') into NASM preprocessor line number indications (`%line
491 * lineno file').
493 static char *
494 prepreproc(char *line)
496 int lineno, fnlen;
497 char *fname, *oldline;
499 if (line[0] == '#' && line[1] == ' ')
501 oldline = line;
502 fname = oldline + 2;
503 lineno = atoi(fname);
504 fname += strspn(fname, "0123456789 ");
505 if (*fname == '"')
506 fname++;
507 fnlen = strcspn(fname, "\"");
508 line = nasm_malloc(20 + fnlen);
509 sprintf(line, "%%line %d %.*s", lineno, fnlen, fname);
510 nasm_free(oldline);
512 if (tasm_compatible_mode)
513 return check_tasm_directive(line);
514 return line;
518 * The hash function for macro lookups. Note that due to some
519 * macros having case-insensitive names, the hash function must be
520 * invariant under case changes. We implement this by applying a
521 * perfectly normal hash function to the uppercase of the string.
523 static int
524 hash(char *s)
526 unsigned int h = 0;
527 int i = 0;
529 * Powers of three, mod 31.
531 static const int multipliers[] = {
532 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
533 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
537 while (*s)
539 h += multipliers[i] * (unsigned char) (toupper(*s));
540 s++;
541 if (++i >= sizeof(multipliers) / sizeof(*multipliers))
542 i = 0;
544 h %= NHASH;
545 return h;
549 * Free a linked list of tokens.
551 static void
552 free_tlist(Token * list)
554 while (list)
556 list = delete_Token(list);
561 * Free a linked list of lines.
563 static void
564 free_llist(Line * list)
566 Line *l;
567 while (list)
569 l = list;
570 list = list->next;
571 free_tlist(l->first);
572 nasm_free(l);
577 * Free an MMacro
579 static void
580 free_mmacro(MMacro * m)
582 nasm_free(m->name);
583 free_tlist(m->dlist);
584 nasm_free(m->defaults);
585 free_llist(m->expansion);
586 nasm_free(m);
590 * Pop the context stack.
592 static void
593 ctx_pop(void)
595 Context *c = cstk;
596 SMacro *smac, *s;
598 cstk = cstk->next;
599 smac = c->localmac;
600 while (smac)
602 s = smac;
603 smac = smac->next;
604 nasm_free(s->name);
605 free_tlist(s->expansion);
606 nasm_free(s);
608 nasm_free(c->name);
609 nasm_free(c);
612 #define BUF_DELTA 512
614 * Read a line from the top file in istk, handling multiple CR/LFs
615 * at the end of the line read, and handling spurious ^Zs. Will
616 * return lines from the standard macro set if this has not already
617 * been done.
619 static char *
620 read_line(void)
622 char *buffer, *p, *q;
623 int bufsize;
625 if (stdmacpos)
627 if (*stdmacpos)
629 char *ret = nasm_strdup(*stdmacpos++);
630 if (!*stdmacpos && any_extrastdmac)
632 stdmacpos = extrastdmac;
633 any_extrastdmac = FALSE;
634 return ret;
637 * Nasty hack: here we push the contents of `predef' on
638 * to the top-level expansion stack, since this is the
639 * most convenient way to implement the pre-include and
640 * pre-define features.
642 if (!*stdmacpos)
644 Line *pd, *l;
645 Token *head, **tail, *t;
647 for (pd = predef; pd; pd = pd->next)
649 head = NULL;
650 tail = &head;
651 for (t = pd->first; t; t = t->next)
653 *tail = new_Token(NULL, t->type, t->text, 0);
654 tail = &(*tail)->next;
656 l = nasm_malloc(sizeof(Line));
657 l->next = istk->expansion;
658 l->first = head;
659 l->finishes = FALSE;
660 istk->expansion = l;
663 return ret;
665 else
667 stdmacpos = NULL;
671 bufsize = BUF_DELTA;
672 buffer = nasm_malloc(BUF_DELTA);
673 p = buffer;
674 while (1)
676 q = fgets(p, bufsize - (p - buffer), istk->fp);
677 if (!q)
678 break;
679 p += strlen(p);
680 if (p > buffer && p[-1] == '\n')
682 break;
684 if (p - buffer > bufsize - 10)
686 long offset = p - buffer;
687 bufsize += BUF_DELTA;
688 buffer = nasm_realloc(buffer, bufsize);
689 p = buffer + offset; /* prevent stale-pointer problems */
693 if (!q && p == buffer)
695 nasm_free(buffer);
696 return NULL;
699 src_set_linnum(src_get_linnum() + istk->lineinc);
702 * Play safe: remove CRs as well as LFs, if any of either are
703 * present at the end of the line.
705 while (--p >= buffer && (*p == '\n' || *p == '\r'))
706 *p = '\0';
709 * Handle spurious ^Z, which may be inserted into source files
710 * by some file transfer utilities.
712 buffer[strcspn(buffer, "\032")] = '\0';
714 list->line(LIST_READ, buffer);
716 return buffer;
720 * Tokenise a line of text. This is a very simple process since we
721 * don't need to parse the value out of e.g. numeric tokens: we
722 * simply split one string into many.
724 static Token *
725 tokenise(char *line)
727 char *p = line;
728 int type;
729 Token *list = NULL;
730 Token *t, **tail = &list;
732 while (*line)
734 p = line;
735 if (*p == '%')
737 p++;
738 if ( isdigit(*p) ||
739 ((*p == '-' || *p == '+') && isdigit(p[1])) ||
740 ((*p == '+') && (isspace(p[1]) || !p[1])))
744 p++;
746 while (isdigit(*p));
747 type = TOK_PREPROC_ID;
749 else if (*p == '{')
751 p++;
752 while (*p && *p != '}')
754 p[-1] = *p;
755 p++;
757 p[-1] = '\0';
758 if (*p)
759 p++;
760 type = TOK_PREPROC_ID;
762 else if (isidchar(*p) ||
763 ((*p == '!' || *p == '%' || *p == '$') &&
764 isidchar(p[1])))
768 p++;
770 while (isidchar(*p));
771 type = TOK_PREPROC_ID;
773 else
775 type = TOK_OTHER;
776 if (*p == '%')
777 p++;
780 else if (isidstart(*p) || (*p == '$' && isidstart(p[1])))
782 type = TOK_ID;
783 p++;
784 while (*p && isidchar(*p))
785 p++;
787 else if (*p == '\'' || *p == '"')
790 * A string token.
792 char c = *p;
793 p++;
794 type = TOK_STRING;
795 while (*p && *p != c)
796 p++;
797 if (*p)
799 p++;
801 else
803 error(ERR_WARNING, "unterminated string");
806 else if (isnumstart(*p))
809 * A number token.
811 type = TOK_NUMBER;
812 p++;
813 while (*p && isnumchar(*p))
814 p++;
816 else if (isspace(*p))
818 type = TOK_WHITESPACE;
819 p++;
820 while (*p && isspace(*p))
821 p++;
823 * Whitespace just before end-of-line is discarded by
824 * pretending it's a comment; whitespace just before a
825 * comment gets lumped into the comment.
827 if (!*p || *p == ';')
829 type = TOK_COMMENT;
830 while (*p)
831 p++;
834 else if (*p == ';')
836 type = TOK_COMMENT;
837 while (*p)
838 p++;
840 else
843 * Anything else is an operator of some kind. We check
844 * for all the double-character operators (>>, <<, //,
845 * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
846 * else is a single-character operator.
848 type = TOK_OTHER;
849 if ((p[0] == '>' && p[1] == '>') ||
850 (p[0] == '<' && p[1] == '<') ||
851 (p[0] == '/' && p[1] == '/') ||
852 (p[0] == '<' && p[1] == '=') ||
853 (p[0] == '>' && p[1] == '=') ||
854 (p[0] == '=' && p[1] == '=') ||
855 (p[0] == '!' && p[1] == '=') ||
856 (p[0] == '<' && p[1] == '>') ||
857 (p[0] == '&' && p[1] == '&') ||
858 (p[0] == '|' && p[1] == '|') ||
859 (p[0] == '^' && p[1] == '^'))
861 p++;
863 p++;
865 if (type != TOK_COMMENT)
867 *tail = t = new_Token(NULL, type, line, p - line);
868 tail = &t->next;
870 line = p;
873 return list;
878 * this function creates a new Token and passes a pointer to it
879 * back to the caller. It sets the type and text elements, and
880 * also the mac and next elements to NULL.
882 static Token *
883 new_Token(Token * next, int type, char *text, int txtlen)
885 Token *t;
886 int i;
888 if (freeTokens == NULL)
890 freeTokens = nasm_malloc(TOKEN_BLOCKSIZE * sizeof(Token));
891 for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
892 freeTokens[i].next = &freeTokens[i + 1];
893 freeTokens[i].next = NULL;
895 t = freeTokens;
896 freeTokens = t->next;
897 t->next = next;
898 t->mac = NULL;
899 t->type = type;
900 if (type == TOK_WHITESPACE || text == NULL)
902 t->text = NULL;
904 else
906 if (txtlen == 0)
907 txtlen = strlen(text);
908 t->text = nasm_malloc(1 + txtlen);
909 strncpy(t->text, text, txtlen);
910 t->text[txtlen] = '\0';
912 return t;
915 static Token *
916 delete_Token(Token * t)
918 Token *next = t->next;
919 nasm_free(t->text);
920 t->next = freeTokens ? freeTokens->next : NULL;
921 freeTokens = t;
922 return next;
926 * Convert a line of tokens back into text.
927 * If expand_locals is not zero, identifiers of the form "%$*xxx"
928 * will be transformed into ..@ctxnum.xxx
930 static char *
931 detoken(Token * tlist, int expand_locals)
933 Token *t;
934 int len;
935 char *line, *p;
937 len = 0;
938 for (t = tlist; t; t = t->next)
940 if (t->type == TOK_PREPROC_ID && t->text[1] == '!')
942 char *p = getenv(t->text + 2);
943 nasm_free(t->text);
944 if (p)
945 t->text = nasm_strdup(p);
946 else
947 t->text = NULL;
949 /* Expand local macros here and not during preprocessing */
950 if (expand_locals &&
951 t->type == TOK_PREPROC_ID && t->text &&
952 t->text[0] == '%' && t->text[1] == '$')
954 Context *ctx = get_ctx(t->text, FALSE);
955 if (ctx)
957 char buffer[40];
958 char *p, *q = t->text + 2;
960 q += strspn(q, "$");
961 sprintf(buffer, "..@%lu.", ctx->number);
962 p = nasm_strcat(buffer, q);
963 nasm_free(t->text);
964 t->text = p;
967 if (t->type == TOK_WHITESPACE)
969 len++;
971 else if (t->text)
973 len += strlen(t->text);
976 p = line = nasm_malloc(len + 1);
977 for (t = tlist; t; t = t->next)
979 if (t->type == TOK_WHITESPACE)
981 *p = ' ';
982 p++;
983 *p = '\0';
985 else if (t->text)
987 strcpy(p, t->text);
988 p += strlen(p);
991 *p = '\0';
992 return line;
996 * A scanner, suitable for use by the expression evaluator, which
997 * operates on a line of Tokens. Expects a pointer to a pointer to
998 * the first token in the line to be passed in as its private_data
999 * field.
1001 static int
1002 ppscan(void *private_data, struct tokenval *tokval)
1004 Token **tlineptr = private_data;
1005 Token *tline;
1009 tline = *tlineptr;
1010 *tlineptr = tline ? tline->next : NULL;
1012 while (tline && (tline->type == TOK_WHITESPACE ||
1013 tline->type == TOK_COMMENT));
1015 if (!tline)
1016 return tokval->t_type = TOKEN_EOS;
1018 if (tline->text[0] == '$' && !tline->text[1])
1019 return tokval->t_type = TOKEN_HERE;
1020 if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[1])
1021 return tokval->t_type = TOKEN_BASE;
1023 if (tline->type == TOK_ID)
1025 tokval->t_charptr = tline->text;
1026 if (tline->text[0] == '$')
1028 tokval->t_charptr++;
1029 return tokval->t_type = TOKEN_ID;
1033 * This is the only special case we actually need to worry
1034 * about in this restricted context.
1036 if (!nasm_stricmp(tline->text, "seg"))
1037 return tokval->t_type = TOKEN_SEG;
1039 return tokval->t_type = TOKEN_ID;
1042 if (tline->type == TOK_NUMBER)
1044 int rn_error;
1046 tokval->t_integer = readnum(tline->text, &rn_error);
1047 if (rn_error)
1048 return tokval->t_type = TOKEN_ERRNUM;
1049 tokval->t_charptr = NULL;
1050 return tokval->t_type = TOKEN_NUM;
1053 if (tline->type == TOK_STRING)
1055 int rn_warn;
1056 char q, *r;
1057 int l;
1059 r = tline->text;
1060 q = *r++;
1061 l = strlen(r);
1063 if (l == 0 || r[l - 1] != q)
1064 return tokval->t_type = TOKEN_ERRNUM;
1065 tokval->t_integer = readstrnum(r, l - 1, &rn_warn);
1066 if (rn_warn)
1067 error(ERR_WARNING | ERR_PASS1, "character constant too long");
1068 tokval->t_charptr = NULL;
1069 return tokval->t_type = TOKEN_NUM;
1072 if (tline->type == TOK_OTHER)
1074 if (!strcmp(tline->text, "<<"))
1075 return tokval->t_type = TOKEN_SHL;
1076 if (!strcmp(tline->text, ">>"))
1077 return tokval->t_type = TOKEN_SHR;
1078 if (!strcmp(tline->text, "//"))
1079 return tokval->t_type = TOKEN_SDIV;
1080 if (!strcmp(tline->text, "%%"))
1081 return tokval->t_type = TOKEN_SMOD;
1082 if (!strcmp(tline->text, "=="))
1083 return tokval->t_type = TOKEN_EQ;
1084 if (!strcmp(tline->text, "<>"))
1085 return tokval->t_type = TOKEN_NE;
1086 if (!strcmp(tline->text, "!="))
1087 return tokval->t_type = TOKEN_NE;
1088 if (!strcmp(tline->text, "<="))
1089 return tokval->t_type = TOKEN_LE;
1090 if (!strcmp(tline->text, ">="))
1091 return tokval->t_type = TOKEN_GE;
1092 if (!strcmp(tline->text, "&&"))
1093 return tokval->t_type = TOKEN_DBL_AND;
1094 if (!strcmp(tline->text, "^^"))
1095 return tokval->t_type = TOKEN_DBL_XOR;
1096 if (!strcmp(tline->text, "||"))
1097 return tokval->t_type = TOKEN_DBL_OR;
1101 * We have no other options: just return the first character of
1102 * the token text.
1104 return tokval->t_type = tline->text[0];
1108 * Compare a string to the name of an existing macro; this is a
1109 * simple wrapper which calls either strcmp or nasm_stricmp
1110 * depending on the value of the `casesense' parameter.
1112 static int
1113 mstrcmp(char *p, char *q, int casesense)
1115 return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
1119 * Return the Context structure associated with a %$ token. Return
1120 * NULL, having _already_ reported an error condition, if the
1121 * context stack isn't deep enough for the supplied number of $
1122 * signs.
1123 * If all_contexts == TRUE, contexts that enclose current are
1124 * also scanned for such smacro, until it is found; if not -
1125 * only the context that directly results from the number of $'s
1126 * in variable's name.
1128 static Context *
1129 get_ctx(char *name, int all_contexts)
1131 Context *ctx;
1132 SMacro *m;
1133 int i;
1135 if (!name || name[0] != '%' || name[1] != '$')
1136 return NULL;
1138 if (!cstk)
1140 error(ERR_NONFATAL, "`%s': context stack is empty", name);
1141 return NULL;
1144 for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--)
1146 ctx = ctx->next;
1147 i--;
1149 if (!ctx)
1151 error(ERR_NONFATAL, "`%s': context stack is only"
1152 " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
1153 return NULL;
1155 if (!all_contexts)
1156 return ctx;
1160 /* Search for this smacro in found context */
1161 m = ctx->localmac;
1162 while (m)
1164 if (!mstrcmp(m->name, name, m->casesense))
1165 return ctx;
1166 m = m->next;
1168 ctx = ctx->next;
1170 while (ctx);
1171 return NULL;
1174 /* Add a slash to the end of a path if it is missing. We use the
1175 * forward slash to make it compatible with Unix systems.
1177 static void
1178 backslash(char *s)
1180 int pos = strlen(s);
1181 if (s[pos - 1] != '\\' && s[pos - 1] != '/')
1183 s[pos] = '/';
1184 s[pos + 1] = '\0';
1189 * Open an include file. This routine must always return a valid
1190 * file pointer if it returns - it's responsible for throwing an
1191 * ERR_FATAL and bombing out completely if not. It should also try
1192 * the include path one by one until it finds the file or reaches
1193 * the end of the path.
1195 static FILE *
1196 inc_fopen(char *file)
1198 FILE *fp;
1199 char *prefix = "", *combine;
1200 IncPath *ip = ipath;
1201 static int namelen = 0;
1202 int len = strlen(file);
1204 while (1)
1206 combine = nasm_malloc(strlen(prefix) + 1 + len + 1);
1207 strcpy(combine, prefix);
1208 if (prefix[0] != 0)
1209 backslash(combine);
1210 strcat(combine, file);
1211 fp = fopen(combine, "r");
1212 if (pass == 0 && fp)
1214 namelen += strlen(combine) + 1;
1215 if (namelen > 62)
1217 printf(" \\\n ");
1218 namelen = 2;
1220 printf(" %s", combine);
1222 nasm_free(combine);
1223 if (fp)
1224 return fp;
1225 if (!ip)
1226 break;
1227 prefix = ip->path;
1228 ip = ip->next;
1231 error(ERR_FATAL, "unable to open include file `%s'", file);
1232 return NULL; /* never reached - placate compilers */
1236 * Determine if we should warn on defining a single-line macro of
1237 * name `name', with `nparam' parameters. If nparam is 0 or -1, will
1238 * return TRUE if _any_ single-line macro of that name is defined.
1239 * Otherwise, will return TRUE if a single-line macro with either
1240 * `nparam' or no parameters is defined.
1242 * If a macro with precisely the right number of parameters is
1243 * defined, or nparam is -1, the address of the definition structure
1244 * will be returned in `defn'; otherwise NULL will be returned. If `defn'
1245 * is NULL, no action will be taken regarding its contents, and no
1246 * error will occur.
1248 * Note that this is also called with nparam zero to resolve
1249 * `ifdef'.
1251 * If you already know which context macro belongs to, you can pass
1252 * the context pointer as first parameter; if you won't but name begins
1253 * with %$ the context will be automatically computed. If all_contexts
1254 * is true, macro will be searched in outer contexts as well.
1256 static int
1257 smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
1258 int nocase)
1260 SMacro *m;
1262 if (ctx)
1263 m = ctx->localmac;
1264 else if (name[0] == '%' && name[1] == '$')
1266 if (cstk)
1267 ctx = get_ctx(name, FALSE);
1268 if (!ctx)
1269 return FALSE; /* got to return _something_ */
1270 m = ctx->localmac;
1272 else
1273 m = smacros[hash(name)];
1275 while (m)
1277 if (!mstrcmp(m->name, name, m->casesense && nocase) &&
1278 (nparam <= 0 || m->nparam == 0 || nparam == m->nparam))
1280 if (defn)
1282 if (nparam == m->nparam || nparam == -1)
1283 *defn = m;
1284 else
1285 *defn = NULL;
1287 return TRUE;
1289 m = m->next;
1292 return FALSE;
1296 * Count and mark off the parameters in a multi-line macro call.
1297 * This is called both from within the multi-line macro expansion
1298 * code, and also to mark off the default parameters when provided
1299 * in a %macro definition line.
1301 static void
1302 count_mmac_params(Token * t, int *nparam, Token *** params)
1304 int paramsize, brace;
1306 *nparam = paramsize = 0;
1307 *params = NULL;
1308 while (t)
1310 if (*nparam >= paramsize)
1312 paramsize += PARAM_DELTA;
1313 *params = nasm_realloc(*params, sizeof(**params) * paramsize);
1315 skip_white_(t);
1316 brace = FALSE;
1317 if (tok_is_(t, "{"))
1318 brace = TRUE;
1319 (*params)[(*nparam)++] = t;
1320 while (tok_isnt_(t, brace ? "}" : ","))
1321 t = t->next;
1322 if (t)
1323 { /* got a comma/brace */
1324 t = t->next;
1325 if (brace)
1328 * Now we've found the closing brace, look further
1329 * for the comma.
1331 skip_white_(t);
1332 if (tok_isnt_(t, ","))
1334 error(ERR_NONFATAL,
1335 "braces do not enclose all of macro parameter");
1336 while (tok_isnt_(t, ","))
1337 t = t->next;
1339 if (t)
1340 t = t->next; /* eat the comma */
1347 * Determine whether one of the various `if' conditions is true or
1348 * not.
1350 * We must free the tline we get passed.
1352 static int
1353 if_condition(Token * tline, int i)
1355 int j, casesense;
1356 Token *t, *tt, **tptr, *origline;
1357 struct tokenval tokval;
1358 expr *evalresult;
1360 origline = tline;
1362 switch (i)
1364 case PP_IFCTX:
1365 case PP_ELIFCTX:
1366 case PP_IFNCTX:
1367 case PP_ELIFNCTX:
1368 j = FALSE; /* have we matched yet? */
1369 while (cstk && tline)
1371 skip_white_(tline);
1372 if (!tline || tline->type != TOK_ID)
1374 error(ERR_NONFATAL,
1375 "`%s' expects context identifiers",
1376 directives[i]);
1377 free_tlist(origline);
1378 return -1;
1380 if (!nasm_stricmp(tline->text, cstk->name))
1381 j = TRUE;
1382 tline = tline->next;
1384 if (i == PP_IFNCTX || i == PP_ELIFNCTX)
1385 j = !j;
1386 free_tlist(origline);
1387 return j;
1389 case PP_IFDEF:
1390 case PP_ELIFDEF:
1391 case PP_IFNDEF:
1392 case PP_ELIFNDEF:
1393 j = FALSE; /* have we matched yet? */
1394 while (tline)
1396 skip_white_(tline);
1397 if (!tline || (tline->type != TOK_ID &&
1398 (tline->type != TOK_PREPROC_ID ||
1399 tline->text[1] != '$')))
1401 error(ERR_NONFATAL,
1402 "`%%if%sdef' expects macro identifiers",
1403 (i == PP_ELIFNDEF ? "n" : ""));
1404 free_tlist(origline);
1405 return -1;
1407 if (smacro_defined(NULL, tline->text, 0, NULL, 1))
1408 j = TRUE;
1409 tline = tline->next;
1411 if (i == PP_IFNDEF || i == PP_ELIFNDEF)
1412 j = !j;
1413 free_tlist(origline);
1414 return j;
1416 case PP_IFIDN:
1417 case PP_ELIFIDN:
1418 case PP_IFNIDN:
1419 case PP_ELIFNIDN:
1420 case PP_IFIDNI:
1421 case PP_ELIFIDNI:
1422 case PP_IFNIDNI:
1423 case PP_ELIFNIDNI:
1424 tline = expand_smacro(tline);
1425 t = tt = tline;
1426 while (tok_isnt_(tt, ","))
1427 tt = tt->next;
1428 if (!tt)
1430 error(ERR_NONFATAL,
1431 "`%s' expects two comma-separated arguments",
1432 directives[i]);
1433 free_tlist(tline);
1434 return -1;
1436 tt = tt->next;
1437 casesense = (i == PP_IFIDN || i == PP_ELIFIDN ||
1438 i == PP_IFNIDN || i == PP_ELIFNIDN);
1439 j = TRUE; /* assume equality unless proved not */
1440 while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt)
1442 if (tt->type == TOK_OTHER && !strcmp(tt->text, ","))
1444 error(ERR_NONFATAL, "`%s': more than one comma on line",
1445 directives[i]);
1446 free_tlist(tline);
1447 return -1;
1449 if (t->type == TOK_WHITESPACE)
1451 t = t->next;
1452 continue;
1454 else if (tt->type == TOK_WHITESPACE)
1456 tt = tt->next;
1457 continue;
1459 else if (tt->type != t->type ||
1460 mstrcmp(tt->text, t->text, casesense))
1462 j = FALSE; /* found mismatching tokens */
1463 break;
1465 else
1467 t = t->next;
1468 tt = tt->next;
1469 continue;
1472 if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
1473 j = FALSE; /* trailing gunk on one end or other */
1474 if (i == PP_IFNIDN || i == PP_ELIFNIDN ||
1475 i == PP_IFNIDNI || i == PP_ELIFNIDNI)
1476 j = !j;
1477 free_tlist(tline);
1478 return j;
1480 case PP_IFID:
1481 case PP_ELIFID:
1482 case PP_IFNID:
1483 case PP_ELIFNID:
1484 case PP_IFNUM:
1485 case PP_ELIFNUM:
1486 case PP_IFNNUM:
1487 case PP_ELIFNNUM:
1488 case PP_IFSTR:
1489 case PP_ELIFSTR:
1490 case PP_IFNSTR:
1491 case PP_ELIFNSTR:
1492 tline = expand_smacro(tline);
1493 t = tline;
1494 while (tok_type_(t, TOK_WHITESPACE))
1495 t = t->next;
1496 j = FALSE; /* placate optimiser */
1497 if (t)
1498 switch (i)
1500 case PP_IFID:
1501 case PP_ELIFID:
1502 case PP_IFNID:
1503 case PP_ELIFNID:
1504 j = (t->type == TOK_ID);
1505 break;
1506 case PP_IFNUM:
1507 case PP_ELIFNUM:
1508 case PP_IFNNUM:
1509 case PP_ELIFNNUM:
1510 j = (t->type == TOK_NUMBER);
1511 break;
1512 case PP_IFSTR:
1513 case PP_ELIFSTR:
1514 case PP_IFNSTR:
1515 case PP_ELIFNSTR:
1516 j = (t->type == TOK_STRING);
1517 break;
1519 if (i == PP_IFNID || i == PP_ELIFNID ||
1520 i == PP_IFNNUM || i == PP_ELIFNNUM ||
1521 i == PP_IFNSTR || i == PP_ELIFNSTR)
1522 j = !j;
1523 free_tlist(tline);
1524 return j;
1526 case PP_IF:
1527 case PP_ELIF:
1528 t = tline = expand_smacro(tline);
1529 tptr = &t;
1530 tokval.t_type = TOKEN_INVALID;
1531 evalresult = evaluate(ppscan, tptr, &tokval,
1532 NULL, pass | CRITICAL, error, NULL);
1533 free_tlist(tline);
1534 if (!evalresult)
1535 return -1;
1536 if (tokval.t_type)
1537 error(ERR_WARNING,
1538 "trailing garbage after expression ignored");
1539 if (!is_simple(evalresult))
1541 error(ERR_NONFATAL,
1542 "non-constant value given to `%s'", directives[i]);
1543 return -1;
1545 return reloc_value(evalresult) != 0;
1547 default:
1548 error(ERR_FATAL,
1549 "preprocessor directive `%s' not yet implemented",
1550 directives[i]);
1551 free_tlist(origline);
1552 return -1; /* yeah, right */
1557 * Expand macros in a string. Used in %error and %include directives.
1558 * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
1559 * The returned variable should ALWAYS be freed after usage.
1561 void
1562 expand_macros_in_string(char **p)
1564 Token *line = tokenise(*p);
1565 line = expand_smacro(line);
1566 *p = detoken(line, FALSE);
1570 * Find out if a line contains a preprocessor directive, and deal
1571 * with it if so.
1573 * If a directive _is_ found, we are expected to free_tlist() the
1574 * line.
1576 * Return values go like this:
1578 * bit 0 is set if a directive was found (so the line gets freed)
1580 static int
1581 do_directive(Token * tline)
1583 int i, j, k, m, nparam, nolist;
1584 int offset;
1585 char *p, *mname;
1586 Include *inc;
1587 Context *ctx;
1588 Cond *cond;
1589 SMacro *smac, **smhead;
1590 MMacro *mmac;
1591 Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
1592 Line *l;
1593 struct tokenval tokval;
1594 expr *evalresult;
1595 MMacro *tmp_defining; /* Used when manipulating rep_nest */
1597 origline = tline;
1599 skip_white_(tline);
1600 if (!tok_type_(tline, TOK_PREPROC_ID) ||
1601 (tline->text[1] == '%' || tline->text[1] == '$'
1602 || tline->text[1] == '!'))
1603 return 0;
1605 i = -1;
1606 j = sizeof(directives) / sizeof(*directives);
1607 while (j - i > 1)
1609 k = (j + i) / 2;
1610 m = nasm_stricmp(tline->text, directives[k]);
1611 if (m == 0) {
1612 if (tasm_compatible_mode) {
1613 i = k;
1614 j = -2;
1615 } else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) {
1616 i = k;
1617 j = -2;
1619 break;
1621 else if (m < 0) {
1622 j = k;
1624 else
1625 i = k;
1629 * If we're in a non-emitting branch of a condition construct,
1630 * or walking to the end of an already terminated %rep block,
1631 * we should ignore all directives except for condition
1632 * directives.
1634 if (((istk->conds && !emitting(istk->conds->state)) ||
1635 (istk->mstk && !istk->mstk->in_progress)) &&
1636 i != PP_IF && i != PP_ELIF &&
1637 i != PP_IFCTX && i != PP_ELIFCTX &&
1638 i != PP_IFDEF && i != PP_ELIFDEF &&
1639 i != PP_IFID && i != PP_ELIFID &&
1640 i != PP_IFIDN && i != PP_ELIFIDN &&
1641 i != PP_IFIDNI && i != PP_ELIFIDNI &&
1642 i != PP_IFNCTX && i != PP_ELIFNCTX &&
1643 i != PP_IFNDEF && i != PP_ELIFNDEF &&
1644 i != PP_IFNID && i != PP_ELIFNID &&
1645 i != PP_IFNIDN && i != PP_ELIFNIDN &&
1646 i != PP_IFNIDNI && i != PP_ELIFNIDNI &&
1647 i != PP_IFNNUM && i != PP_ELIFNNUM &&
1648 i != PP_IFNSTR && i != PP_ELIFNSTR &&
1649 i != PP_IFNUM && i != PP_ELIFNUM &&
1650 i != PP_IFSTR && i != PP_ELIFSTR && i != PP_ELSE && i != PP_ENDIF)
1652 return 0;
1656 * If we're defining a macro or reading a %rep block, we should
1657 * ignore all directives except for %macro/%imacro (which
1658 * generate an error), %endm/%endmacro, and (only if we're in a
1659 * %rep block) %endrep. If we're in a %rep block, another %rep
1660 * causes an error, so should be let through.
1662 if (defining && i != PP_MACRO && i != PP_IMACRO &&
1663 i != PP_ENDMACRO && i != PP_ENDM &&
1664 (defining->name || (i != PP_ENDREP && i != PP_REP)))
1666 return 0;
1669 if (j != -2)
1671 error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
1672 tline->text);
1673 return 0; /* didn't get it */
1676 switch (i)
1678 case PP_STACKSIZE:
1679 /* Directive to tell NASM what the default stack size is. The
1680 * default is for a 16-bit stack, and this can be overriden with
1681 * %stacksize large.
1682 * the following form:
1684 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1686 tline = tline->next;
1687 if (tline && tline->type == TOK_WHITESPACE)
1688 tline = tline->next;
1689 if (!tline || tline->type != TOK_ID)
1691 error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
1692 free_tlist(origline);
1693 return 3;
1695 if (nasm_stricmp(tline->text, "flat") == 0)
1697 /* All subsequent ARG directives are for a 32-bit stack */
1698 StackSize = 4;
1699 StackPointer = "ebp";
1700 ArgOffset = 8;
1701 LocalOffset = 4;
1703 else if (nasm_stricmp(tline->text, "large") == 0)
1705 /* All subsequent ARG directives are for a 16-bit stack,
1706 * far function call.
1708 StackSize = 2;
1709 StackPointer = "bp";
1710 ArgOffset = 4;
1711 LocalOffset = 2;
1713 else if (nasm_stricmp(tline->text, "small") == 0)
1715 /* All subsequent ARG directives are for a 16-bit stack,
1716 * far function call. We don't support near functions.
1718 StackSize = 2;
1719 StackPointer = "bp";
1720 ArgOffset = 6;
1721 LocalOffset = 2;
1723 else
1725 error(ERR_NONFATAL, "`%%stacksize' invalid size type");
1726 free_tlist(origline);
1727 return 3;
1729 free_tlist(origline);
1730 return 3;
1732 case PP_ARG:
1733 /* TASM like ARG directive to define arguments to functions, in
1734 * the following form:
1736 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1738 offset = ArgOffset;
1741 char *arg, directive[256];
1742 int size = StackSize;
1744 /* Find the argument name */
1745 tline = tline->next;
1746 if (tline && tline->type == TOK_WHITESPACE)
1747 tline = tline->next;
1748 if (!tline || tline->type != TOK_ID)
1750 error(ERR_NONFATAL, "`%%arg' missing argument parameter");
1751 free_tlist(origline);
1752 return 3;
1754 arg = tline->text;
1756 /* Find the argument size type */
1757 tline = tline->next;
1758 if (!tline || tline->type != TOK_OTHER
1759 || tline->text[0] != ':')
1761 error(ERR_NONFATAL,
1762 "Syntax error processing `%%arg' directive");
1763 free_tlist(origline);
1764 return 3;
1766 tline = tline->next;
1767 if (!tline || tline->type != TOK_ID)
1769 error(ERR_NONFATAL,
1770 "`%%arg' missing size type parameter");
1771 free_tlist(origline);
1772 return 3;
1775 /* Allow macro expansion of type parameter */
1776 tt = tokenise(tline->text);
1777 tt = expand_smacro(tt);
1778 if (nasm_stricmp(tt->text, "byte") == 0)
1780 size = MAX(StackSize, 1);
1782 else if (nasm_stricmp(tt->text, "word") == 0)
1784 size = MAX(StackSize, 2);
1786 else if (nasm_stricmp(tt->text, "dword") == 0)
1788 size = MAX(StackSize, 4);
1790 else if (nasm_stricmp(tt->text, "qword") == 0)
1792 size = MAX(StackSize, 8);
1794 else if (nasm_stricmp(tt->text, "tword") == 0)
1796 size = MAX(StackSize, 10);
1798 else
1800 error(ERR_NONFATAL,
1801 "Invalid size type for `%%arg' missing directive");
1802 free_tlist(tt);
1803 free_tlist(origline);
1804 return 3;
1806 free_tlist(tt);
1808 /* Now define the macro for the argument */
1809 sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer,
1810 offset);
1811 do_directive(tokenise(directive));
1812 offset += size;
1814 /* Move to the next argument in the list */
1815 tline = tline->next;
1816 if (tline && tline->type == TOK_WHITESPACE)
1817 tline = tline->next;
1819 while (tline && tline->type == TOK_OTHER
1820 && tline->text[0] == ',');
1821 free_tlist(origline);
1822 return 3;
1824 case PP_LOCAL:
1825 /* TASM like LOCAL directive to define local variables for a
1826 * function, in the following form:
1828 * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1830 * The '= LocalSize' at the end is ignored by NASM, but is
1831 * required by TASM to define the local parameter size (and used
1832 * by the TASM macro package).
1834 offset = LocalOffset;
1837 char *local, directive[256];
1838 int size = StackSize;
1840 /* Find the argument name */
1841 tline = tline->next;
1842 if (tline && tline->type == TOK_WHITESPACE)
1843 tline = tline->next;
1844 if (!tline || tline->type != TOK_ID)
1846 error(ERR_NONFATAL,
1847 "`%%local' missing argument parameter");
1848 free_tlist(origline);
1849 return 3;
1851 local = tline->text;
1853 /* Find the argument size type */
1854 tline = tline->next;
1855 if (!tline || tline->type != TOK_OTHER
1856 || tline->text[0] != ':')
1858 error(ERR_NONFATAL,
1859 "Syntax error processing `%%local' directive");
1860 free_tlist(origline);
1861 return 3;
1863 tline = tline->next;
1864 if (!tline || tline->type != TOK_ID)
1866 error(ERR_NONFATAL,
1867 "`%%local' missing size type parameter");
1868 free_tlist(origline);
1869 return 3;
1872 /* Allow macro expansion of type parameter */
1873 tt = tokenise(tline->text);
1874 tt = expand_smacro(tt);
1875 if (nasm_stricmp(tt->text, "byte") == 0)
1877 size = MAX(StackSize, 1);
1879 else if (nasm_stricmp(tt->text, "word") == 0)
1881 size = MAX(StackSize, 2);
1883 else if (nasm_stricmp(tt->text, "dword") == 0)
1885 size = MAX(StackSize, 4);
1887 else if (nasm_stricmp(tt->text, "qword") == 0)
1889 size = MAX(StackSize, 8);
1891 else if (nasm_stricmp(tt->text, "tword") == 0)
1893 size = MAX(StackSize, 10);
1895 else
1897 error(ERR_NONFATAL,
1898 "Invalid size type for `%%local' missing directive");
1899 free_tlist(tt);
1900 free_tlist(origline);
1901 return 3;
1903 free_tlist(tt);
1905 /* Now define the macro for the argument */
1906 sprintf(directive, "%%define %s (%s-%d)", local, StackPointer,
1907 offset);
1908 do_directive(tokenise(directive));
1909 offset += size;
1911 /* Now define the assign to setup the enter_c macro correctly */
1912 sprintf(directive, "%%assign %%$localsize %%$localsize+%d",
1913 size);
1914 do_directive(tokenise(directive));
1916 /* Move to the next argument in the list */
1917 tline = tline->next;
1918 if (tline && tline->type == TOK_WHITESPACE)
1919 tline = tline->next;
1921 while (tline && tline->type == TOK_OTHER
1922 && tline->text[0] == ',');
1923 free_tlist(origline);
1924 return 3;
1926 case PP_CLEAR:
1927 if (tline->next)
1928 error(ERR_WARNING,
1929 "trailing garbage after `%%clear' ignored");
1930 for (j = 0; j < NHASH; j++)
1932 while (mmacros[j])
1934 MMacro *m = mmacros[j];
1935 mmacros[j] = m->next;
1936 free_mmacro(m);
1938 while (smacros[j])
1940 SMacro *s = smacros[j];
1941 smacros[j] = smacros[j]->next;
1942 nasm_free(s->name);
1943 free_tlist(s->expansion);
1944 nasm_free(s);
1947 free_tlist(origline);
1948 return 3;
1950 case PP_INCLUDE:
1951 tline = tline->next;
1952 skip_white_(tline);
1953 if (!tline || (tline->type != TOK_STRING &&
1954 tline->type != TOK_INTERNAL_STRING))
1956 error(ERR_NONFATAL, "`%%include' expects a file name");
1957 free_tlist(origline);
1958 return 3; /* but we did _something_ */
1960 if (tline->next)
1961 error(ERR_WARNING,
1962 "trailing garbage after `%%include' ignored");
1963 if (tline->type != TOK_INTERNAL_STRING)
1965 p = tline->text + 1; /* point past the quote to the name */
1966 p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
1968 else
1969 p = tline->text; /* internal_string is easier */
1970 expand_macros_in_string(&p);
1971 inc = nasm_malloc(sizeof(Include));
1972 inc->next = istk;
1973 inc->conds = NULL;
1974 inc->fp = inc_fopen(p);
1975 inc->fname = src_set_fname(p);
1976 inc->lineno = src_set_linnum(0);
1977 inc->lineinc = 1;
1978 inc->expansion = NULL;
1979 inc->mstk = NULL;
1980 istk = inc;
1981 list->uplevel(LIST_INCLUDE);
1982 free_tlist(origline);
1983 return 5;
1985 case PP_PUSH:
1986 tline = tline->next;
1987 skip_white_(tline);
1988 tline = expand_id(tline);
1989 if (!tok_type_(tline, TOK_ID))
1991 error(ERR_NONFATAL, "`%%push' expects a context identifier");
1992 free_tlist(origline);
1993 return 3; /* but we did _something_ */
1995 if (tline->next)
1996 error(ERR_WARNING, "trailing garbage after `%%push' ignored");
1997 ctx = nasm_malloc(sizeof(Context));
1998 ctx->next = cstk;
1999 ctx->localmac = NULL;
2000 ctx->name = nasm_strdup(tline->text);
2001 ctx->number = unique++;
2002 cstk = ctx;
2003 free_tlist(origline);
2004 break;
2006 case PP_REPL:
2007 tline = tline->next;
2008 skip_white_(tline);
2009 tline = expand_id(tline);
2010 if (!tok_type_(tline, TOK_ID))
2012 error(ERR_NONFATAL, "`%%repl' expects a context identifier");
2013 free_tlist(origline);
2014 return 3; /* but we did _something_ */
2016 if (tline->next)
2017 error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
2018 if (!cstk)
2019 error(ERR_NONFATAL, "`%%repl': context stack is empty");
2020 else
2022 nasm_free(cstk->name);
2023 cstk->name = nasm_strdup(tline->text);
2025 free_tlist(origline);
2026 break;
2028 case PP_POP:
2029 if (tline->next)
2030 error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
2031 if (!cstk)
2032 error(ERR_NONFATAL,
2033 "`%%pop': context stack is already empty");
2034 else
2035 ctx_pop();
2036 free_tlist(origline);
2037 break;
2039 case PP_ERROR:
2040 tline->next = expand_smacro(tline->next);
2041 tline = tline->next;
2042 skip_white_(tline);
2043 if (tok_type_(tline, TOK_STRING))
2045 p = tline->text + 1; /* point past the quote to the name */
2046 p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
2047 expand_macros_in_string(&p);
2048 error(ERR_NONFATAL, "%s", p);
2049 nasm_free(p);
2051 else
2053 p = detoken(tline, FALSE);
2054 error(ERR_WARNING, "%s", p);
2055 nasm_free(p);
2057 free_tlist(origline);
2058 break;
2060 case PP_IF:
2061 case PP_IFCTX:
2062 case PP_IFDEF:
2063 case PP_IFID:
2064 case PP_IFIDN:
2065 case PP_IFIDNI:
2066 case PP_IFNCTX:
2067 case PP_IFNDEF:
2068 case PP_IFNID:
2069 case PP_IFNIDN:
2070 case PP_IFNIDNI:
2071 case PP_IFNNUM:
2072 case PP_IFNSTR:
2073 case PP_IFNUM:
2074 case PP_IFSTR:
2075 if (istk->conds && !emitting(istk->conds->state))
2076 j = COND_NEVER;
2077 else
2079 j = if_condition(tline->next, i);
2080 tline->next = NULL; /* it got freed */
2081 free_tlist(origline);
2082 j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2084 cond = nasm_malloc(sizeof(Cond));
2085 cond->next = istk->conds;
2086 cond->state = j;
2087 istk->conds = cond;
2088 return (j == COND_IF_TRUE ? 3 : 1);
2090 case PP_ELIF:
2091 case PP_ELIFCTX:
2092 case PP_ELIFDEF:
2093 case PP_ELIFID:
2094 case PP_ELIFIDN:
2095 case PP_ELIFIDNI:
2096 case PP_ELIFNCTX:
2097 case PP_ELIFNDEF:
2098 case PP_ELIFNID:
2099 case PP_ELIFNIDN:
2100 case PP_ELIFNIDNI:
2101 case PP_ELIFNNUM:
2102 case PP_ELIFNSTR:
2103 case PP_ELIFNUM:
2104 case PP_ELIFSTR:
2105 if (!istk->conds)
2106 error(ERR_FATAL, "`%s': no matching `%%if'", directives[i]);
2107 if (emitting(istk->conds->state)
2108 || istk->conds->state == COND_NEVER)
2109 istk->conds->state = COND_NEVER;
2110 else
2112 j = if_condition(expand_mmac_params(tline->next), i);
2113 tline->next = NULL; /* it got freed */
2114 free_tlist(origline);
2115 istk->conds->state =
2116 j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2118 return (istk->conds->state == COND_IF_TRUE ? 5 : 1);
2120 case PP_ELSE:
2121 if (tline->next)
2122 error(ERR_WARNING, "trailing garbage after `%%else' ignored");
2123 if (!istk->conds)
2124 error(ERR_FATAL, "`%%else': no matching `%%if'");
2125 if (emitting(istk->conds->state)
2126 || istk->conds->state == COND_NEVER)
2127 istk->conds->state = COND_ELSE_FALSE;
2128 else
2129 istk->conds->state = COND_ELSE_TRUE;
2130 free_tlist(origline);
2131 return 5;
2133 case PP_ENDIF:
2134 if (tline->next)
2135 error(ERR_WARNING,
2136 "trailing garbage after `%%endif' ignored");
2137 if (!istk->conds)
2138 error(ERR_FATAL, "`%%endif': no matching `%%if'");
2139 cond = istk->conds;
2140 istk->conds = cond->next;
2141 nasm_free(cond);
2142 free_tlist(origline);
2143 return 5;
2145 case PP_MACRO:
2146 case PP_IMACRO:
2147 if (defining)
2148 error(ERR_FATAL,
2149 "`%%%smacro': already defining a macro",
2150 (i == PP_IMACRO ? "i" : ""));
2151 tline = tline->next;
2152 skip_white_(tline);
2153 tline = expand_id(tline);
2154 if (!tok_type_(tline, TOK_ID))
2156 error(ERR_NONFATAL,
2157 "`%%%smacro' expects a macro name",
2158 (i == PP_IMACRO ? "i" : ""));
2159 return 3;
2161 defining = nasm_malloc(sizeof(MMacro));
2162 defining->name = nasm_strdup(tline->text);
2163 defining->casesense = (i == PP_MACRO);
2164 defining->plus = FALSE;
2165 defining->nolist = FALSE;
2166 defining->in_progress = FALSE;
2167 defining->rep_nest = NULL;
2168 tline = expand_smacro(tline->next);
2169 skip_white_(tline);
2170 if (!tok_type_(tline, TOK_NUMBER))
2172 error(ERR_NONFATAL,
2173 "`%%%smacro' expects a parameter count",
2174 (i == PP_IMACRO ? "i" : ""));
2175 defining->nparam_min = defining->nparam_max = 0;
2177 else
2179 defining->nparam_min = defining->nparam_max =
2180 readnum(tline->text, &j);
2181 if (j)
2182 error(ERR_NONFATAL,
2183 "unable to parse parameter count `%s'",
2184 tline->text);
2186 if (tline && tok_is_(tline->next, "-"))
2188 tline = tline->next->next;
2189 if (tok_is_(tline, "*"))
2190 defining->nparam_max = INT_MAX;
2191 else if (!tok_type_(tline, TOK_NUMBER))
2192 error(ERR_NONFATAL,
2193 "`%%%smacro' expects a parameter count after `-'",
2194 (i == PP_IMACRO ? "i" : ""));
2195 else
2197 defining->nparam_max = readnum(tline->text, &j);
2198 if (j)
2199 error(ERR_NONFATAL,
2200 "unable to parse parameter count `%s'",
2201 tline->text);
2202 if (defining->nparam_min > defining->nparam_max)
2203 error(ERR_NONFATAL,
2204 "minimum parameter count exceeds maximum");
2207 if (tline && tok_is_(tline->next, "+"))
2209 tline = tline->next;
2210 defining->plus = TRUE;
2212 if (tline && tok_type_(tline->next, TOK_ID) &&
2213 !nasm_stricmp(tline->next->text, ".nolist"))
2215 tline = tline->next;
2216 defining->nolist = TRUE;
2218 mmac = mmacros[hash(defining->name)];
2219 while (mmac)
2221 if (!strcmp(mmac->name, defining->name) &&
2222 (mmac->nparam_min <= defining->nparam_max
2223 || defining->plus)
2224 && (defining->nparam_min <= mmac->nparam_max
2225 || mmac->plus))
2227 error(ERR_WARNING,
2228 "redefining multi-line macro `%s'",
2229 defining->name);
2230 break;
2232 mmac = mmac->next;
2235 * Handle default parameters.
2237 if (tline && tline->next)
2239 defining->dlist = tline->next;
2240 tline->next = NULL;
2241 count_mmac_params(defining->dlist, &defining->ndefs,
2242 &defining->defaults);
2244 else
2246 defining->dlist = NULL;
2247 defining->defaults = NULL;
2249 defining->expansion = NULL;
2250 free_tlist(origline);
2251 return 1;
2253 case PP_ENDM:
2254 case PP_ENDMACRO:
2255 if (!defining)
2257 error(ERR_NONFATAL, "`%s': not defining a macro",
2258 tline->text);
2259 return 3;
2261 k = hash(defining->name);
2262 defining->next = mmacros[k];
2263 mmacros[k] = defining;
2264 defining = NULL;
2265 free_tlist(origline);
2266 return 5;
2268 case PP_ROTATE:
2269 if (tline->next && tline->next->type == TOK_WHITESPACE)
2270 tline = tline->next;
2271 t = expand_smacro(tline->next);
2272 tline->next = NULL;
2273 free_tlist(origline);
2274 tline = t;
2275 tptr = &t;
2276 tokval.t_type = TOKEN_INVALID;
2277 evalresult =
2278 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2279 free_tlist(tline);
2280 if (!evalresult)
2281 return 3;
2282 if (tokval.t_type)
2283 error(ERR_WARNING,
2284 "trailing garbage after expression ignored");
2285 if (!is_simple(evalresult))
2287 error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
2288 return 3;
2290 mmac = istk->mstk;
2291 while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
2292 mmac = mmac->next_active;
2293 if (!mmac)
2294 error(ERR_NONFATAL,
2295 "`%%rotate' invoked outside a macro call");
2296 mmac->rotate = mmac->rotate + reloc_value(evalresult);
2297 if (mmac->rotate < 0)
2298 mmac->rotate = mmac->nparam - (-mmac->rotate) % mmac->nparam;
2299 mmac->rotate %= mmac->nparam;
2300 return 1;
2302 case PP_REP:
2303 nolist = FALSE;
2304 tline = tline->next;
2305 if (tline->next && tline->next->type == TOK_WHITESPACE)
2306 tline = tline->next;
2307 if (tline->next && tline->next->type == TOK_ID &&
2308 !nasm_stricmp(tline->next->text, ".nolist"))
2310 tline = tline->next;
2311 nolist = TRUE;
2313 t = expand_smacro(tline->next);
2314 tline->next = NULL;
2315 free_tlist(origline);
2316 tline = t;
2317 tptr = &t;
2318 tokval.t_type = TOKEN_INVALID;
2319 evalresult =
2320 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2321 free_tlist(tline);
2322 if (!evalresult)
2323 return 3;
2324 if (tokval.t_type)
2325 error(ERR_WARNING,
2326 "trailing garbage after expression ignored");
2327 if (!is_simple(evalresult))
2329 error(ERR_NONFATAL, "non-constant value given to `%%rep'");
2330 return 3;
2332 tmp_defining = defining;
2333 defining = nasm_malloc(sizeof(MMacro));
2334 defining->name = NULL; /* flags this macro as a %rep block */
2335 defining->casesense = 0;
2336 defining->plus = FALSE;
2337 defining->nolist = nolist;
2338 defining->in_progress = reloc_value(evalresult) + 1;
2339 defining->nparam_min = defining->nparam_max = 0;
2340 defining->defaults = NULL;
2341 defining->dlist = NULL;
2342 defining->expansion = NULL;
2343 defining->next_active = istk->mstk;
2344 defining->rep_nest = tmp_defining;
2345 return 1;
2347 case PP_ENDREP:
2348 if (!defining || defining->name)
2350 error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
2351 return 3;
2355 * Now we have a "macro" defined - although it has no name
2356 * and we won't be entering it in the hash tables - we must
2357 * push a macro-end marker for it on to istk->expansion.
2358 * After that, it will take care of propagating itself (a
2359 * macro-end marker line for a macro which is really a %rep
2360 * block will cause the macro to be re-expanded, complete
2361 * with another macro-end marker to ensure the process
2362 * continues) until the whole expansion is forcibly removed
2363 * from istk->expansion by a %exitrep.
2365 l = nasm_malloc(sizeof(Line));
2366 l->next = istk->expansion;
2367 l->finishes = defining;
2368 l->first = NULL;
2369 istk->expansion = l;
2371 istk->mstk = defining;
2373 list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
2374 tmp_defining = defining;
2375 defining = defining->rep_nest;
2376 free_tlist(origline);
2377 return 1;
2379 case PP_EXITREP:
2381 * We must search along istk->expansion until we hit a
2382 * macro-end marker for a macro with no name. Then we set
2383 * its `in_progress' flag to 0.
2385 for (l = istk->expansion; l; l = l->next)
2386 if (l->finishes && !l->finishes->name)
2387 break;
2389 if (l)
2390 l->finishes->in_progress = 0;
2391 else
2392 error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
2393 free_tlist(origline);
2394 return 1;
2396 case PP_XDEFINE:
2397 case PP_IXDEFINE:
2398 case PP_DEFINE:
2399 case PP_IDEFINE:
2400 tline = tline->next;
2401 skip_white_(tline);
2402 tline = expand_id(tline);
2403 if (!tline || (tline->type != TOK_ID &&
2404 (tline->type != TOK_PREPROC_ID ||
2405 tline->text[1] != '$')))
2407 error(ERR_NONFATAL,
2408 "`%%%s%sdefine' expects a macro identifier",
2409 ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""),
2410 ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : ""));
2411 free_tlist(origline);
2412 return 3;
2415 ctx = get_ctx(tline->text, FALSE);
2416 if (!ctx)
2417 smhead = &smacros[hash(tline->text)];
2418 else
2419 smhead = &ctx->localmac;
2420 mname = tline->text;
2421 last = tline;
2422 param_start = tline = tline->next;
2423 nparam = 0;
2425 /* Expand the macro definition now for %xdefine and %ixdefine */
2426 if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
2427 tline = expand_smacro(tline);
2429 if (tok_is_(tline, "("))
2432 * This macro has parameters.
2435 tline = tline->next;
2436 while (1)
2438 skip_white_(tline);
2439 if (!tline)
2441 error(ERR_NONFATAL, "parameter identifier expected");
2442 free_tlist(origline);
2443 return 3;
2445 if (tline->type != TOK_ID)
2447 error(ERR_NONFATAL,
2448 "`%s': parameter identifier expected",
2449 tline->text);
2450 free_tlist(origline);
2451 return 3;
2453 tline->type = TOK_SMAC_PARAM + nparam++;
2454 tline = tline->next;
2455 skip_white_(tline);
2456 if (tok_is_(tline, ","))
2458 tline = tline->next;
2459 continue;
2461 if (!tok_is_(tline, ")"))
2463 error(ERR_NONFATAL,
2464 "`)' expected to terminate macro template");
2465 free_tlist(origline);
2466 return 3;
2468 break;
2470 last = tline;
2471 tline = tline->next;
2473 if (tok_type_(tline, TOK_WHITESPACE))
2474 last = tline, tline = tline->next;
2475 macro_start = NULL;
2476 last->next = NULL;
2477 t = tline;
2478 while (t)
2480 if (t->type == TOK_ID)
2482 for (tt = param_start; tt; tt = tt->next)
2483 if (tt->type >= TOK_SMAC_PARAM &&
2484 !strcmp(tt->text, t->text))
2485 t->type = tt->type;
2487 tt = t->next;
2488 t->next = macro_start;
2489 macro_start = t;
2490 t = tt;
2493 * Good. We now have a macro name, a parameter count, and a
2494 * token list (in reverse order) for an expansion. We ought
2495 * to be OK just to create an SMacro, store it, and let
2496 * free_tlist have the rest of the line (which we have
2497 * carefully re-terminated after chopping off the expansion
2498 * from the end).
2500 if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE))
2502 if (!smac)
2504 error(ERR_WARNING,
2505 "single-line macro `%s' defined both with and"
2506 " without parameters", mname);
2507 free_tlist(origline);
2508 free_tlist(macro_start);
2509 return 3;
2511 else
2514 * We're redefining, so we have to take over an
2515 * existing SMacro structure. This means freeing
2516 * what was already in it.
2518 nasm_free(smac->name);
2519 free_tlist(smac->expansion);
2522 else
2524 smac = nasm_malloc(sizeof(SMacro));
2525 smac->next = *smhead;
2526 *smhead = smac;
2528 smac->name = nasm_strdup(mname);
2529 smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE));
2530 smac->nparam = nparam;
2531 smac->expansion = macro_start;
2532 smac->in_progress = FALSE;
2533 free_tlist(origline);
2534 return 3;
2536 case PP_UNDEF:
2537 tline = tline->next;
2538 skip_white_(tline);
2539 tline = expand_id(tline);
2540 if (!tline || (tline->type != TOK_ID &&
2541 (tline->type != TOK_PREPROC_ID ||
2542 tline->text[1] != '$')))
2544 error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
2545 free_tlist(origline);
2546 return 3;
2548 if (tline->next)
2550 error(ERR_WARNING,
2551 "trailing garbage after macro name ignored");
2554 /* Find the context that symbol belongs to */
2555 ctx = get_ctx(tline->text, FALSE);
2556 if (!ctx)
2557 smhead = &smacros[hash(tline->text)];
2558 else
2559 smhead = &ctx->localmac;
2561 mname = tline->text;
2562 last = tline;
2563 last->next = NULL;
2566 * We now have a macro name... go hunt for it.
2568 while (smacro_defined(ctx, mname, -1, &smac, 1))
2570 /* Defined, so we need to find its predecessor and nuke it */
2571 SMacro **s;
2572 for (s = smhead; *s && *s != smac; s = &(*s)->next);
2573 if (*s)
2575 *s = smac->next;
2576 nasm_free(smac->name);
2577 free_tlist(smac->expansion);
2578 nasm_free(smac);
2581 free_tlist(origline);
2582 return 3;
2584 case PP_STRLEN:
2585 tline = tline->next;
2586 skip_white_(tline);
2587 tline = expand_id(tline);
2588 if (!tline || (tline->type != TOK_ID &&
2589 (tline->type != TOK_PREPROC_ID ||
2590 tline->text[1] != '$')))
2592 error(ERR_NONFATAL,
2593 "`%%strlen' expects a macro identifier as first parameter");
2594 free_tlist(origline);
2595 return 3;
2597 ctx = get_ctx(tline->text, FALSE);
2598 if (!ctx)
2599 smhead = &smacros[hash(tline->text)];
2600 else
2601 smhead = &ctx->localmac;
2602 mname = tline->text;
2603 last = tline;
2604 tline = expand_smacro(tline->next);
2605 last->next = NULL;
2607 t = tline;
2608 while (tok_type_(t, TOK_WHITESPACE))
2609 t = t->next;
2610 /* t should now point to the string */
2611 if (t->type != TOK_STRING)
2613 error(ERR_NONFATAL,
2614 "`%%strlen` requires string as second parameter");
2615 free_tlist(tline);
2616 free_tlist(origline);
2617 return 3;
2620 macro_start = nasm_malloc(sizeof(*macro_start));
2621 macro_start->next = NULL;
2622 make_tok_num(macro_start, strlen(t->text) - 2);
2623 macro_start->mac = NULL;
2626 * We now have a macro name, an implicit parameter count of
2627 * zero, and a numeric token to use as an expansion. Create
2628 * and store an SMacro.
2630 if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN))
2632 if (!smac)
2633 error(ERR_WARNING,
2634 "single-line macro `%s' defined both with and"
2635 " without parameters", mname);
2636 else
2639 * We're redefining, so we have to take over an
2640 * existing SMacro structure. This means freeing
2641 * what was already in it.
2643 nasm_free(smac->name);
2644 free_tlist(smac->expansion);
2647 else
2649 smac = nasm_malloc(sizeof(SMacro));
2650 smac->next = *smhead;
2651 *smhead = smac;
2653 smac->name = nasm_strdup(mname);
2654 smac->casesense = (i == PP_STRLEN);
2655 smac->nparam = 0;
2656 smac->expansion = macro_start;
2657 smac->in_progress = FALSE;
2658 free_tlist(tline);
2659 free_tlist(origline);
2660 return 3;
2662 case PP_SUBSTR:
2663 tline = tline->next;
2664 skip_white_(tline);
2665 tline = expand_id(tline);
2666 if (!tline || (tline->type != TOK_ID &&
2667 (tline->type != TOK_PREPROC_ID ||
2668 tline->text[1] != '$')))
2670 error(ERR_NONFATAL,
2671 "`%%substr' expects a macro identifier as first parameter");
2672 free_tlist(origline);
2673 return 3;
2675 ctx = get_ctx(tline->text, FALSE);
2676 if (!ctx)
2677 smhead = &smacros[hash(tline->text)];
2678 else
2679 smhead = &ctx->localmac;
2680 mname = tline->text;
2681 last = tline;
2682 tline = expand_smacro(tline->next);
2683 last->next = NULL;
2685 t = tline->next;
2686 while (tok_type_(t, TOK_WHITESPACE))
2687 t = t->next;
2689 /* t should now point to the string */
2690 if (t->type != TOK_STRING)
2692 error(ERR_NONFATAL,
2693 "`%%substr` requires string as second parameter");
2694 free_tlist(tline);
2695 free_tlist(origline);
2696 return 3;
2699 tt = t->next;
2700 tptr = &tt;
2701 tokval.t_type = TOKEN_INVALID;
2702 evalresult =
2703 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2704 if (!evalresult)
2706 free_tlist(tline);
2707 free_tlist(origline);
2708 return 3;
2710 if (!is_simple(evalresult))
2712 error(ERR_NONFATAL, "non-constant value given to `%%substr`");
2713 free_tlist(tline);
2714 free_tlist(origline);
2715 return 3;
2718 macro_start = nasm_malloc(sizeof(*macro_start));
2719 macro_start->next = NULL;
2720 macro_start->text = nasm_strdup("'''");
2721 if (evalresult->value > 0
2722 && evalresult->value < strlen(t->text) - 1)
2724 macro_start->text[1] = t->text[evalresult->value];
2726 else
2728 macro_start->text[2] = '\0';
2730 macro_start->type = TOK_STRING;
2731 macro_start->mac = NULL;
2734 * We now have a macro name, an implicit parameter count of
2735 * zero, and a numeric token to use as an expansion. Create
2736 * and store an SMacro.
2738 if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR))
2740 if (!smac)
2741 error(ERR_WARNING,
2742 "single-line macro `%s' defined both with and"
2743 " without parameters", mname);
2744 else
2747 * We're redefining, so we have to take over an
2748 * existing SMacro structure. This means freeing
2749 * what was already in it.
2751 nasm_free(smac->name);
2752 free_tlist(smac->expansion);
2755 else
2757 smac = nasm_malloc(sizeof(SMacro));
2758 smac->next = *smhead;
2759 *smhead = smac;
2761 smac->name = nasm_strdup(mname);
2762 smac->casesense = (i == PP_SUBSTR);
2763 smac->nparam = 0;
2764 smac->expansion = macro_start;
2765 smac->in_progress = FALSE;
2766 free_tlist(tline);
2767 free_tlist(origline);
2768 return 3;
2771 case PP_ASSIGN:
2772 case PP_IASSIGN:
2773 tline = tline->next;
2774 skip_white_(tline);
2775 tline = expand_id(tline);
2776 if (!tline || (tline->type != TOK_ID &&
2777 (tline->type != TOK_PREPROC_ID ||
2778 tline->text[1] != '$')))
2780 error(ERR_NONFATAL,
2781 "`%%%sassign' expects a macro identifier",
2782 (i == PP_IASSIGN ? "i" : ""));
2783 free_tlist(origline);
2784 return 3;
2786 ctx = get_ctx(tline->text, FALSE);
2787 if (!ctx)
2788 smhead = &smacros[hash(tline->text)];
2789 else
2790 smhead = &ctx->localmac;
2791 mname = tline->text;
2792 last = tline;
2793 tline = expand_smacro(tline->next);
2794 last->next = NULL;
2796 t = tline;
2797 tptr = &t;
2798 tokval.t_type = TOKEN_INVALID;
2799 evalresult =
2800 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2801 free_tlist(tline);
2802 if (!evalresult)
2804 free_tlist(origline);
2805 return 3;
2808 if (tokval.t_type)
2809 error(ERR_WARNING,
2810 "trailing garbage after expression ignored");
2812 if (!is_simple(evalresult))
2814 error(ERR_NONFATAL,
2815 "non-constant value given to `%%%sassign'",
2816 (i == PP_IASSIGN ? "i" : ""));
2817 free_tlist(origline);
2818 return 3;
2821 macro_start = nasm_malloc(sizeof(*macro_start));
2822 macro_start->next = NULL;
2823 make_tok_num(macro_start, reloc_value(evalresult));
2824 macro_start->mac = NULL;
2827 * We now have a macro name, an implicit parameter count of
2828 * zero, and a numeric token to use as an expansion. Create
2829 * and store an SMacro.
2831 if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN))
2833 if (!smac)
2834 error(ERR_WARNING,
2835 "single-line macro `%s' defined both with and"
2836 " without parameters", mname);
2837 else
2840 * We're redefining, so we have to take over an
2841 * existing SMacro structure. This means freeing
2842 * what was already in it.
2844 nasm_free(smac->name);
2845 free_tlist(smac->expansion);
2848 else
2850 smac = nasm_malloc(sizeof(SMacro));
2851 smac->next = *smhead;
2852 *smhead = smac;
2854 smac->name = nasm_strdup(mname);
2855 smac->casesense = (i == PP_ASSIGN);
2856 smac->nparam = 0;
2857 smac->expansion = macro_start;
2858 smac->in_progress = FALSE;
2859 free_tlist(origline);
2860 return 3;
2862 case PP_LINE:
2864 * Syntax is `%line nnn[+mmm] [filename]'
2866 tline = tline->next;
2867 skip_white_(tline);
2868 if (!tok_type_(tline, TOK_NUMBER))
2870 error(ERR_NONFATAL, "`%%line' expects line number");
2871 free_tlist(origline);
2872 return 3;
2874 k = readnum(tline->text, &j);
2875 m = 1;
2876 tline = tline->next;
2877 if (tok_is_(tline, "+"))
2879 tline = tline->next;
2880 if (!tok_type_(tline, TOK_NUMBER))
2882 error(ERR_NONFATAL, "`%%line' expects line increment");
2883 free_tlist(origline);
2884 return 3;
2886 m = readnum(tline->text, &j);
2887 tline = tline->next;
2889 skip_white_(tline);
2890 src_set_linnum(k);
2891 istk->lineinc = m;
2892 if (tline)
2894 nasm_free(src_set_fname(detoken(tline, FALSE)));
2896 free_tlist(origline);
2897 return 5;
2899 default:
2900 error(ERR_FATAL,
2901 "preprocessor directive `%s' not yet implemented",
2902 directives[i]);
2903 break;
2905 return 3;
2909 * Ensure that a macro parameter contains a condition code and
2910 * nothing else. Return the condition code index if so, or -1
2911 * otherwise.
2913 static int
2914 find_cc(Token * t)
2916 Token *tt;
2917 int i, j, k, m;
2919 skip_white_(t);
2920 if (t->type != TOK_ID)
2921 return -1;
2922 tt = t->next;
2923 skip_white_(tt);
2924 if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
2925 return -1;
2927 i = -1;
2928 j = sizeof(conditions) / sizeof(*conditions);
2929 while (j - i > 1)
2931 k = (j + i) / 2;
2932 m = nasm_stricmp(t->text, conditions[k]);
2933 if (m == 0)
2935 i = k;
2936 j = -2;
2937 break;
2939 else if (m < 0)
2941 j = k;
2943 else
2944 i = k;
2946 if (j != -2)
2947 return -1;
2948 return i;
2952 * Expand MMacro-local things: parameter references (%0, %n, %+n,
2953 * %-n) and MMacro-local identifiers (%%foo).
2955 static Token *
2956 expand_mmac_params(Token * tline)
2958 Token *t, *tt, **tail, *thead;
2960 tail = &thead;
2961 thead = NULL;
2963 while (tline)
2965 if (tline->type == TOK_PREPROC_ID &&
2966 (((tline->text[1] == '+' || tline->text[1] == '-')
2967 && tline->text[2]) || tline->text[1] == '%'
2968 || (tline->text[1] >= '0' && tline->text[1] <= '9')))
2970 char *text = NULL;
2971 int type = 0, cc; /* type = 0 to placate optimisers */
2972 char tmpbuf[30];
2973 int n, i;
2974 MMacro *mac;
2976 t = tline;
2977 tline = tline->next;
2979 mac = istk->mstk;
2980 while (mac && !mac->name) /* avoid mistaking %reps for macros */
2981 mac = mac->next_active;
2982 if (!mac)
2983 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
2984 else
2985 switch (t->text[1])
2988 * We have to make a substitution of one of the
2989 * forms %1, %-1, %+1, %%foo, %0.
2991 case '0':
2992 type = TOK_NUMBER;
2993 sprintf(tmpbuf, "%d", mac->nparam);
2994 text = nasm_strdup(tmpbuf);
2995 break;
2996 case '%':
2997 type = TOK_ID;
2998 sprintf(tmpbuf, "..@%lu.", mac->unique);
2999 text = nasm_strcat(tmpbuf, t->text + 2);
3000 break;
3001 case '-':
3002 n = atoi(t->text + 2) - 1;
3003 if (n >= mac->nparam)
3004 tt = NULL;
3005 else
3007 if (mac->nparam > 1)
3008 n = (n + mac->rotate) % mac->nparam;
3009 tt = mac->params[n];
3011 cc = find_cc(tt);
3012 if (cc == -1)
3014 error(ERR_NONFATAL,
3015 "macro parameter %d is not a condition code",
3016 n + 1);
3017 text = NULL;
3019 else
3021 type = TOK_ID;
3022 if (inverse_ccs[cc] == -1)
3024 error(ERR_NONFATAL,
3025 "condition code `%s' is not invertible",
3026 conditions[cc]);
3027 text = NULL;
3029 else
3030 text =
3031 nasm_strdup(conditions[inverse_ccs
3032 [cc]]);
3034 break;
3035 case '+':
3036 n = atoi(t->text + 2) - 1;
3037 if (n >= mac->nparam)
3038 tt = NULL;
3039 else
3041 if (mac->nparam > 1)
3042 n = (n + mac->rotate) % mac->nparam;
3043 tt = mac->params[n];
3045 cc = find_cc(tt);
3046 if (cc == -1)
3048 error(ERR_NONFATAL,
3049 "macro parameter %d is not a condition code",
3050 n + 1);
3051 text = NULL;
3053 else
3055 type = TOK_ID;
3056 text = nasm_strdup(conditions[cc]);
3058 break;
3059 default:
3060 n = atoi(t->text + 1) - 1;
3061 if (n >= mac->nparam)
3062 tt = NULL;
3063 else
3065 if (mac->nparam > 1)
3066 n = (n + mac->rotate) % mac->nparam;
3067 tt = mac->params[n];
3069 if (tt)
3071 for (i = 0; i < mac->paramlen[n]; i++)
3073 *tail =
3074 new_Token(NULL, tt->type, tt->text,
3076 tail = &(*tail)->next;
3077 tt = tt->next;
3080 text = NULL; /* we've done it here */
3081 break;
3083 if (!text)
3085 delete_Token(t);
3087 else
3089 *tail = t;
3090 tail = &t->next;
3091 t->type = type;
3092 nasm_free(t->text);
3093 t->text = text;
3094 t->mac = NULL;
3096 continue;
3098 else
3100 t = *tail = tline;
3101 tline = tline->next;
3102 t->mac = NULL;
3103 tail = &t->next;
3106 *tail = NULL;
3107 t = thead;
3108 for (; t && (tt = t->next) != NULL; t = t->next)
3109 switch (t->type)
3111 case TOK_WHITESPACE:
3112 if (tt->type == TOK_WHITESPACE)
3114 t->next = delete_Token(tt);
3116 break;
3117 case TOK_ID:
3118 if (tt->type == TOK_ID || tt->type == TOK_NUMBER)
3120 char *tmp = nasm_strcat(t->text, tt->text);
3121 nasm_free(t->text);
3122 t->text = tmp;
3123 t->next = delete_Token(tt);
3125 break;
3126 case TOK_NUMBER:
3127 if (tt->type == TOK_NUMBER)
3129 char *tmp = nasm_strcat(t->text, tt->text);
3130 nasm_free(t->text);
3131 t->text = tmp;
3132 t->next = delete_Token(tt);
3134 break;
3137 return thead;
3141 * Expand all single-line macro calls made in the given line.
3142 * Return the expanded version of the line. The original is deemed
3143 * to be destroyed in the process. (In reality we'll just move
3144 * Tokens from input to output a lot of the time, rather than
3145 * actually bothering to destroy and replicate.)
3147 static Token *
3148 expand_smacro(Token * tline)
3150 Token *t, *tt, *mstart, **tail, *thead;
3151 SMacro *head = NULL, *m;
3152 Token **params;
3153 int *paramsize;
3154 int nparam, sparam, brackets, rescan;
3155 Token *org_tline = tline;
3156 Context *ctx;
3157 char *mname;
3160 * Trick: we should avoid changing the start token pointer since it can
3161 * be contained in "next" field of other token. Because of this
3162 * we allocate a copy of first token and work with it; at the end of
3163 * routine we copy it back
3165 if (org_tline)
3167 tline =
3168 new_Token(org_tline->next, org_tline->type, org_tline->text,
3170 tline->mac = org_tline->mac;
3173 again:
3174 tail = &thead;
3175 thead = NULL;
3177 while (tline)
3178 { /* main token loop */
3179 if ((mname = tline->text))
3181 /* if this token is a local macro, look in local context */
3182 if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
3183 ctx = get_ctx(mname, TRUE);
3184 else
3185 ctx = NULL;
3186 if (!ctx)
3187 head = smacros[hash(mname)];
3188 else
3189 head = ctx->localmac;
3191 * We've hit an identifier. As in is_mmacro below, we first
3192 * check whether the identifier is a single-line macro at
3193 * all, then think about checking for parameters if
3194 * necessary.
3196 for (m = head; m; m = m->next)
3197 if (!mstrcmp(m->name, mname, m->casesense))
3198 break;
3199 if (m)
3201 mstart = tline;
3202 params = NULL;
3203 paramsize = NULL;
3204 if (m->nparam == 0)
3207 * Simple case: the macro is parameterless. Discard the
3208 * one token that the macro call took, and push the
3209 * expansion back on the to-do stack.
3211 if (!m->expansion)
3213 if (!strcmp("__FILE__", m->name))
3215 long num = 0;
3216 src_get(&num, &(tline->text));
3217 nasm_quote(&(tline->text));
3218 tline->type = TOK_STRING;
3219 continue;
3221 if (!strcmp("__LINE__", m->name))
3223 nasm_free(tline->text);
3224 make_tok_num(tline, src_get_linnum());
3225 continue;
3227 tline = delete_Token(tline);
3228 continue;
3231 else
3234 * Complicated case: at least one macro with this name
3235 * exists and takes parameters. We must find the
3236 * parameters in the call, count them, find the SMacro
3237 * that corresponds to that form of the macro call, and
3238 * substitute for the parameters when we expand. What a
3239 * pain.
3241 tline = tline->next;
3242 skip_white_(tline);
3243 if (!tok_is_(tline, "("))
3246 * This macro wasn't called with parameters: ignore
3247 * the call. (Behaviour borrowed from gnu cpp.)
3249 tline = mstart;
3250 m = NULL;
3252 else
3254 int paren = 0;
3255 int white = 0;
3256 brackets = 0;
3257 nparam = 0;
3258 tline = tline->next;
3259 sparam = PARAM_DELTA;
3260 params = nasm_malloc(sparam * sizeof(Token *));
3261 params[0] = tline;
3262 paramsize = nasm_malloc(sparam * sizeof(int));
3263 paramsize[0] = 0;
3264 for (;; tline = tline->next)
3265 { /* parameter loop */
3266 if (!tline)
3268 error(ERR_NONFATAL,
3269 "macro call expects terminating `)'");
3270 break;
3272 if (tline->type == TOK_WHITESPACE
3273 && brackets <= 0)
3275 if (paramsize[nparam])
3276 white++;
3277 else
3278 params[nparam] = tline->next;
3279 continue; /* parameter loop */
3281 if (tline->type == TOK_OTHER
3282 && tline->text[1] == 0)
3284 char ch = tline->text[0];
3285 if (ch == ',' && !paren && brackets <= 0)
3287 if (++nparam >= sparam)
3289 sparam += PARAM_DELTA;
3290 params = nasm_realloc(params,
3291 sparam * sizeof(Token *));
3292 paramsize = nasm_realloc(paramsize,
3293 sparam * sizeof(int));
3295 params[nparam] = tline->next;
3296 paramsize[nparam] = 0;
3297 white = 0;
3298 continue; /* parameter loop */
3300 if (ch == '{' &&
3301 (brackets > 0 || (brackets == 0 &&
3302 !paramsize[nparam])))
3304 if (!(brackets++))
3306 params[nparam] = tline->next;
3307 continue; /* parameter loop */
3310 if (ch == '}' && brackets > 0)
3311 if (--brackets == 0)
3313 brackets = -1;
3314 continue; /* parameter loop */
3316 if (ch == '(' && !brackets)
3317 paren++;
3318 if (ch == ')' && brackets <= 0)
3319 if (--paren < 0)
3320 break;
3322 if (brackets < 0)
3324 brackets = 0;
3325 error(ERR_NONFATAL, "braces do not "
3326 "enclose all of macro parameter");
3328 paramsize[nparam] += white + 1;
3329 white = 0;
3330 } /* parameter loop */
3331 nparam++;
3332 while (m && (m->nparam != nparam ||
3333 mstrcmp(m->name, mname,
3334 m->casesense)))
3335 m = m->next;
3336 if (!m)
3337 error(ERR_WARNING | ERR_WARN_MNP,
3338 "macro `%s' exists, "
3339 "but not taking %d parameters",
3340 mstart->text, nparam);
3343 if (m && m->in_progress)
3344 m = NULL;
3345 if (!m) /* in progess or didn't find '(' or wrong nparam */
3348 * Design question: should we handle !tline, which
3349 * indicates missing ')' here, or expand those
3350 * macros anyway, which requires the (t) test a few
3351 * lines down?
3353 nasm_free(params);
3354 nasm_free(paramsize);
3355 tline = mstart;
3357 else
3360 * Expand the macro: we are placed on the last token of the
3361 * call, so that we can easily split the call from the
3362 * following tokens. We also start by pushing an SMAC_END
3363 * token for the cycle removal.
3365 t = tline;
3366 if (t)
3368 tline = t->next;
3369 t->next = NULL;
3371 tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
3372 tt->mac = m;
3373 m->in_progress = TRUE;
3374 tline = tt;
3375 for (t = m->expansion; t; t = t->next)
3377 if (t->type >= TOK_SMAC_PARAM)
3379 Token *pcopy = tline, **ptail = &pcopy;
3380 Token *ttt, *pt;
3381 int i;
3383 ttt = params[t->type - TOK_SMAC_PARAM];
3384 for (i = paramsize[t->type - TOK_SMAC_PARAM];
3385 --i >= 0;)
3387 pt = *ptail =
3388 new_Token(tline, ttt->type, ttt->text,
3390 ptail = &pt->next;
3391 ttt = ttt->next;
3393 tline = pcopy;
3395 else
3397 tt = new_Token(tline, t->type, t->text, 0);
3398 tline = tt;
3403 * Having done that, get rid of the macro call, and clean
3404 * up the parameters.
3406 nasm_free(params);
3407 nasm_free(paramsize);
3408 free_tlist(mstart);
3409 continue; /* main token loop */
3414 if (tline->type == TOK_SMAC_END)
3416 tline->mac->in_progress = FALSE;
3417 tline = delete_Token(tline);
3419 else
3421 t = *tail = tline;
3422 tline = tline->next;
3423 t->mac = NULL;
3424 t->next = NULL;
3425 tail = &t->next;
3430 * Now scan the entire line and look for successive TOK_IDs that resulted
3431 * after expansion (they can't be produced by tokenise()). The successive
3432 * TOK_IDs should be concatenated.
3433 * Also we look for %+ tokens and concatenate the tokens before and after
3434 * them (without white spaces in between).
3436 t = thead;
3437 rescan = 0;
3438 while (t)
3440 while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
3441 t = t->next;
3442 if (!t || !t->next)
3443 break;
3444 if (t->next->type == TOK_ID ||
3445 t->next->type == TOK_PREPROC_ID ||
3446 t->next->type == TOK_NUMBER)
3448 char *p = nasm_strcat(t->text, t->next->text);
3449 nasm_free(t->text);
3450 t->next = delete_Token(t->next);
3451 t->text = p;
3452 rescan = 1;
3454 else if (t->next->type == TOK_WHITESPACE && t->next->next &&
3455 t->next->next->type == TOK_PREPROC_ID &&
3456 strcmp(t->next->next->text, "%+") == 0)
3458 /* free the next whitespace, the %+ token and next whitespace */
3459 int i;
3460 for (i = 1; i <= 3; i++)
3462 if (!t->next || (i != 2 && t->next->type != TOK_WHITESPACE))
3463 break;
3464 t->next = delete_Token(t->next);
3465 } /* endfor */
3467 else
3468 t = t->next;
3470 /* If we concatenaded something, re-scan the line for macros */
3471 if (rescan)
3473 tline = thead;
3474 goto again;
3477 if (org_tline)
3479 if (thead)
3481 *org_tline = *thead;
3482 /* since we just gave text to org_line, don't free it */
3483 thead->text = NULL;
3484 delete_Token(thead);
3486 else
3488 /* the expression expanded to empty line;
3489 we can't return NULL for some reasons
3490 we just set the line to a single WHITESPACE token. */
3491 memset(org_tline, 0, sizeof(*org_tline));
3492 org_tline->text = NULL;
3493 org_tline->type = TOK_WHITESPACE;
3495 thead = org_tline;
3498 return thead;
3502 * Similar to expand_smacro but used exclusively with macro identifiers
3503 * right before they are fetched in. The reason is that there can be
3504 * identifiers consisting of several subparts. We consider that if there
3505 * are more than one element forming the name, user wants a expansion,
3506 * otherwise it will be left as-is. Example:
3508 * %define %$abc cde
3510 * the identifier %$abc will be left as-is so that the handler for %define
3511 * will suck it and define the corresponding value. Other case:
3513 * %define _%$abc cde
3515 * In this case user wants name to be expanded *before* %define starts
3516 * working, so we'll expand %$abc into something (if it has a value;
3517 * otherwise it will be left as-is) then concatenate all successive
3518 * PP_IDs into one.
3520 static Token *
3521 expand_id(Token * tline)
3523 Token *cur, *oldnext = NULL;
3525 if (!tline || !tline->next)
3526 return tline;
3528 cur = tline;
3529 while (cur->next &&
3530 (cur->next->type == TOK_ID ||
3531 cur->next->type == TOK_PREPROC_ID || cur->next->type == TOK_NUMBER))
3532 cur = cur->next;
3534 /* If identifier consists of just one token, don't expand */
3535 if (cur == tline)
3536 return tline;
3538 if (cur)
3540 oldnext = cur->next; /* Detach the tail past identifier */
3541 cur->next = NULL; /* so that expand_smacro stops here */
3544 tline = expand_smacro(tline);
3546 if (cur)
3548 /* expand_smacro possibly changhed tline; re-scan for EOL */
3549 cur = tline;
3550 while (cur && cur->next)
3551 cur = cur->next;
3552 if (cur)
3553 cur->next = oldnext;
3556 return tline;
3560 * Determine whether the given line constitutes a multi-line macro
3561 * call, and return the MMacro structure called if so. Doesn't have
3562 * to check for an initial label - that's taken care of in
3563 * expand_mmacro - but must check numbers of parameters. Guaranteed
3564 * to be called with tline->type == TOK_ID, so the putative macro
3565 * name is easy to find.
3567 static MMacro *
3568 is_mmacro(Token * tline, Token *** params_array)
3570 MMacro *head, *m;
3571 Token **params;
3572 int nparam;
3574 head = mmacros[hash(tline->text)];
3577 * Efficiency: first we see if any macro exists with the given
3578 * name. If not, we can return NULL immediately. _Then_ we
3579 * count the parameters, and then we look further along the
3580 * list if necessary to find the proper MMacro.
3582 for (m = head; m; m = m->next)
3583 if (!mstrcmp(m->name, tline->text, m->casesense))
3584 break;
3585 if (!m)
3586 return NULL;
3589 * OK, we have a potential macro. Count and demarcate the
3590 * parameters.
3592 count_mmac_params(tline->next, &nparam, &params);
3595 * So we know how many parameters we've got. Find the MMacro
3596 * structure that handles this number.
3598 while (m)
3600 if (m->nparam_min <= nparam && (m->plus || nparam <= m->nparam_max))
3603 * This one is right. Just check if cycle removal
3604 * prohibits us using it before we actually celebrate...
3606 if (m->in_progress)
3608 #if 0
3609 error(ERR_NONFATAL,
3610 "self-reference in multi-line macro `%s'", m->name);
3611 #endif
3612 nasm_free(params);
3613 return NULL;
3616 * It's right, and we can use it. Add its default
3617 * parameters to the end of our list if necessary.
3619 if (m->defaults && nparam < m->nparam_min + m->ndefs)
3621 params =
3622 nasm_realloc(params,
3623 ((m->nparam_min + m->ndefs + 1) * sizeof(*params)));
3624 while (nparam < m->nparam_min + m->ndefs)
3626 params[nparam] = m->defaults[nparam - m->nparam_min];
3627 nparam++;
3631 * If we've gone over the maximum parameter count (and
3632 * we're in Plus mode), ignore parameters beyond
3633 * nparam_max.
3635 if (m->plus && nparam > m->nparam_max)
3636 nparam = m->nparam_max;
3638 * Then terminate the parameter list, and leave.
3640 if (!params)
3641 { /* need this special case */
3642 params = nasm_malloc(sizeof(*params));
3643 nparam = 0;
3645 params[nparam] = NULL;
3646 *params_array = params;
3647 return m;
3650 * This one wasn't right: look for the next one with the
3651 * same name.
3653 for (m = m->next; m; m = m->next)
3654 if (!mstrcmp(m->name, tline->text, m->casesense))
3655 break;
3659 * After all that, we didn't find one with the right number of
3660 * parameters. Issue a warning, and fail to expand the macro.
3662 error(ERR_WARNING | ERR_WARN_MNP,
3663 "macro `%s' exists, but not taking %d parameters",
3664 tline->text, nparam);
3665 nasm_free(params);
3666 return NULL;
3670 * Expand the multi-line macro call made by the given line, if
3671 * there is one to be expanded. If there is, push the expansion on
3672 * istk->expansion and return 1. Otherwise return 0.
3674 static int
3675 expand_mmacro(Token * tline)
3677 Token *startline = tline;
3678 Token *label = NULL;
3679 int dont_prepend = 0;
3680 Token **params, *t, *tt;
3681 MMacro *m;
3682 Line *l, *ll;
3683 int i, nparam, *paramlen;
3685 t = tline;
3686 skip_white_(t);
3687 if (!tok_type_(t, TOK_ID))
3688 return 0;
3689 m = is_mmacro(t, &params);
3690 if (!m)
3692 Token *last;
3694 * We have an id which isn't a macro call. We'll assume
3695 * it might be a label; we'll also check to see if a
3696 * colon follows it. Then, if there's another id after
3697 * that lot, we'll check it again for macro-hood.
3699 label = last = t;
3700 t = t->next;
3701 if (tok_type_(t, TOK_WHITESPACE))
3702 last = t, t = t->next;
3703 if (tok_is_(t, ":"))
3705 dont_prepend = 1;
3706 last = t, t = t->next;
3707 if (tok_type_(t, TOK_WHITESPACE))
3708 last = t, t = t->next;
3710 if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, &params)) == NULL)
3711 return 0;
3712 last->next = NULL;
3713 tline = t;
3717 * Fix up the parameters: this involves stripping leading and
3718 * trailing whitespace, then stripping braces if they are
3719 * present.
3721 for (nparam = 0; params[nparam]; nparam++)
3723 paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
3725 for (i = 0; params[i]; i++)
3727 int brace = FALSE;
3728 int comma = (!m->plus || i < nparam - 1);
3730 t = params[i];
3731 skip_white_(t);
3732 if (tok_is_(t, "{"))
3733 t = t->next, brace = TRUE, comma = FALSE;
3734 params[i] = t;
3735 paramlen[i] = 0;
3736 while (t)
3738 if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
3739 break; /* ... because we have hit a comma */
3740 if (comma && t->type == TOK_WHITESPACE && tok_is_(t->next, ","))
3741 break; /* ... or a space then a comma */
3742 if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
3743 break; /* ... or a brace */
3744 t = t->next;
3745 paramlen[i]++;
3750 * OK, we have a MMacro structure together with a set of
3751 * parameters. We must now go through the expansion and push
3752 * copies of each Line on to istk->expansion. Substitution of
3753 * parameter tokens and macro-local tokens doesn't get done
3754 * until the single-line macro substitution process; this is
3755 * because delaying them allows us to change the semantics
3756 * later through %rotate.
3758 * First, push an end marker on to istk->expansion, mark this
3759 * macro as in progress, and set up its invocation-specific
3760 * variables.
3762 ll = nasm_malloc(sizeof(Line));
3763 ll->next = istk->expansion;
3764 ll->finishes = m;
3765 ll->first = NULL;
3766 istk->expansion = ll;
3768 m->in_progress = TRUE;
3769 m->params = params;
3770 m->iline = tline;
3771 m->nparam = nparam;
3772 m->rotate = 0;
3773 m->paramlen = paramlen;
3774 m->unique = unique++;
3775 m->lineno = 0;
3777 m->next_active = istk->mstk;
3778 istk->mstk = m;
3780 for (l = m->expansion; l; l = l->next)
3782 Token **tail;
3784 ll = nasm_malloc(sizeof(Line));
3785 ll->finishes = NULL;
3786 ll->next = istk->expansion;
3787 istk->expansion = ll;
3788 tail = &ll->first;
3790 for (t = l->first; t; t = t->next)
3792 Token *x = t;
3793 if (t->type == TOK_PREPROC_ID &&
3794 t->text[1] == '0' && t->text[2] == '0')
3796 dont_prepend = -1;
3797 x = label;
3798 if (!x)
3799 continue;
3801 tt = *tail = new_Token(NULL, x->type, x->text, 0);
3802 tail = &tt->next;
3804 *tail = NULL;
3808 * If we had a label, push it on as the first line of
3809 * the macro expansion.
3811 if (label)
3813 if (dont_prepend < 0)
3814 free_tlist(startline);
3815 else
3817 ll = nasm_malloc(sizeof(Line));
3818 ll->finishes = NULL;
3819 ll->next = istk->expansion;
3820 istk->expansion = ll;
3821 ll->first = startline;
3822 if (!dont_prepend)
3824 while (label->next)
3825 label = label->next;
3826 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
3831 list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
3833 return 1;
3837 * Since preprocessor always operate only on the line that didn't
3838 * arrived yet, we should always use ERR_OFFBY1. Also since user
3839 * won't want to see same error twice (preprocessing is done once
3840 * per pass) we will want to show errors only during pass one.
3842 static void
3843 error(int severity, char *fmt, ...)
3845 va_list arg;
3846 char buff[1024];
3848 /* If we're in a dead branch of IF or something like it, ignore the error */
3849 if (istk->conds && !emitting(istk->conds->state))
3850 return;
3852 va_start(arg, fmt);
3853 vsprintf(buff, fmt, arg);
3854 va_end(arg);
3856 if (istk->mstk && istk->mstk->name)
3857 __error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
3858 istk->mstk->lineno, buff);
3859 else
3860 __error(severity | ERR_PASS1, "%s", buff);
3863 static void
3864 pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
3865 ListGen * listgen)
3867 int h;
3869 __error = errfunc;
3870 cstk = NULL;
3871 istk = nasm_malloc(sizeof(Include));
3872 istk->next = NULL;
3873 istk->conds = NULL;
3874 istk->expansion = NULL;
3875 istk->mstk = NULL;
3876 istk->fp = fopen(file, "r");
3877 istk->fname = NULL;
3878 src_set_fname(nasm_strdup(file));
3879 src_set_linnum(0);
3880 istk->lineinc = 1;
3881 if (!istk->fp)
3882 error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'", file);
3883 defining = NULL;
3884 for (h = 0; h < NHASH; h++)
3886 mmacros[h] = NULL;
3887 smacros[h] = NULL;
3889 unique = 0;
3890 if (tasm_compatible_mode) {
3891 stdmacpos = stdmac;
3892 } else {
3893 stdmacpos = &stdmac[TASM_MACRO_COUNT];
3895 any_extrastdmac = (extrastdmac != NULL);
3896 list = listgen;
3897 evaluate = eval;
3898 pass = apass;
3901 static char *
3902 pp_getline(void)
3904 char *line;
3905 Token *tline;
3907 while (1)
3910 * Fetch a tokenised line, either from the macro-expansion
3911 * buffer or from the input file.
3913 tline = NULL;
3914 while (istk->expansion && istk->expansion->finishes)
3916 Line *l = istk->expansion;
3917 if (!l->finishes->name && l->finishes->in_progress > 1)
3919 Line *ll;
3922 * This is a macro-end marker for a macro with no
3923 * name, which means it's not really a macro at all
3924 * but a %rep block, and the `in_progress' field is
3925 * more than 1, meaning that we still need to
3926 * repeat. (1 means the natural last repetition; 0
3927 * means termination by %exitrep.) We have
3928 * therefore expanded up to the %endrep, and must
3929 * push the whole block on to the expansion buffer
3930 * again. We don't bother to remove the macro-end
3931 * marker: we'd only have to generate another one
3932 * if we did.
3934 l->finishes->in_progress--;
3935 for (l = l->finishes->expansion; l; l = l->next)
3937 Token *t, *tt, **tail;
3939 ll = nasm_malloc(sizeof(Line));
3940 ll->next = istk->expansion;
3941 ll->finishes = NULL;
3942 ll->first = NULL;
3943 tail = &ll->first;
3945 for (t = l->first; t; t = t->next)
3947 if (t->text || t->type == TOK_WHITESPACE)
3949 tt = *tail = new_Token(NULL, t->type, t->text, 0);
3950 tail = &tt->next;
3954 istk->expansion = ll;
3957 else
3960 * Check whether a `%rep' was started and not ended
3961 * within this macro expansion. This can happen and
3962 * should be detected. It's a fatal error because
3963 * I'm too confused to work out how to recover
3964 * sensibly from it.
3966 if (defining)
3968 if (defining->name)
3969 error(ERR_PANIC, "defining with name in expansion");
3970 else if (istk->mstk->name)
3971 error(ERR_FATAL, "`%%rep' without `%%endrep' within"
3972 " expansion of macro `%s'", istk->mstk->name);
3976 * FIXME: investigate the relationship at this point between
3977 * istk->mstk and l->finishes
3980 MMacro *m = istk->mstk;
3981 istk->mstk = m->next_active;
3982 if (m->name)
3985 * This was a real macro call, not a %rep, and
3986 * therefore the parameter information needs to
3987 * be freed.
3989 nasm_free(m->params);
3990 free_tlist(m->iline);
3991 nasm_free(m->paramlen);
3992 l->finishes->in_progress = FALSE;
3994 else
3995 free_mmacro(m);
3997 istk->expansion = l->next;
3998 nasm_free(l);
3999 list->downlevel(LIST_MACRO);
4002 while (1)
4003 { /* until we get a line we can use */
4005 if (istk->expansion)
4006 { /* from a macro expansion */
4007 char *p;
4008 Line *l = istk->expansion;
4009 if (istk->mstk)
4010 istk->mstk->lineno++;
4011 tline = l->first;
4012 istk->expansion = l->next;
4013 nasm_free(l);
4014 p = detoken(tline, FALSE);
4015 list->line(LIST_MACRO, p);
4016 nasm_free(p);
4017 break;
4019 line = read_line();
4020 if (line)
4021 { /* from the current input file */
4022 line = prepreproc(line);
4023 tline = tokenise(line);
4024 nasm_free(line);
4025 break;
4028 * The current file has ended; work down the istk
4031 Include *i = istk;
4032 fclose(i->fp);
4033 if (i->conds)
4034 error(ERR_FATAL, "expected `%%endif' before end of file");
4035 istk = i->next;
4036 list->downlevel(LIST_INCLUDE);
4037 src_set_linnum(i->lineno);
4038 nasm_free(src_set_fname(i->fname));
4039 nasm_free(i);
4040 if (!istk)
4041 return NULL;
4046 * We must expand MMacro parameters and MMacro-local labels
4047 * _before_ we plunge into directive processing, to cope
4048 * with things like `%define something %1' such as STRUC
4049 * uses. Unless we're _defining_ a MMacro, in which case
4050 * those tokens should be left alone to go into the
4051 * definition; and unless we're in a non-emitting
4052 * condition, in which case we don't want to meddle with
4053 * anything.
4055 if (!defining && !(istk->conds && !emitting(istk->conds->state)))
4056 tline = expand_mmac_params(tline);
4059 * Check the line to see if it's a preprocessor directive.
4061 if (do_directive(tline) & 1)
4063 continue;
4065 else if (defining)
4068 * We're defining a multi-line macro. We emit nothing
4069 * at all, and just
4070 * shove the tokenised line on to the macro definition.
4072 Line *l = nasm_malloc(sizeof(Line));
4073 l->next = defining->expansion;
4074 l->first = tline;
4075 l->finishes = FALSE;
4076 defining->expansion = l;
4077 continue;
4079 else if (istk->conds && !emitting(istk->conds->state))
4082 * We're in a non-emitting branch of a condition block.
4083 * Emit nothing at all, not even a blank line: when we
4084 * emerge from the condition we'll give a line-number
4085 * directive so we keep our place correctly.
4087 free_tlist(tline);
4088 continue;
4090 else if (istk->mstk && !istk->mstk->in_progress)
4093 * We're in a %rep block which has been terminated, so
4094 * we're walking through to the %endrep without
4095 * emitting anything. Emit nothing at all, not even a
4096 * blank line: when we emerge from the %rep block we'll
4097 * give a line-number directive so we keep our place
4098 * correctly.
4100 free_tlist(tline);
4101 continue;
4103 else
4105 tline = expand_smacro(tline);
4106 if (!expand_mmacro(tline))
4109 * De-tokenise the line again, and emit it.
4111 line = detoken(tline, TRUE);
4112 free_tlist(tline);
4113 break;
4115 else
4117 continue; /* expand_mmacro calls free_tlist */
4122 return line;
4125 static void
4126 pp_cleanup(void)
4128 int h;
4130 if (defining)
4132 error(ERR_NONFATAL, "end of file while still defining macro `%s'",
4133 defining->name);
4134 free_mmacro(defining);
4136 while (cstk)
4137 ctx_pop();
4138 for (h = 0; h < NHASH; h++)
4140 while (mmacros[h])
4142 MMacro *m = mmacros[h];
4143 mmacros[h] = mmacros[h]->next;
4144 free_mmacro(m);
4146 while (smacros[h])
4148 SMacro *s = smacros[h];
4149 smacros[h] = smacros[h]->next;
4150 nasm_free(s->name);
4151 free_tlist(s->expansion);
4152 nasm_free(s);
4155 while (istk)
4157 Include *i = istk;
4158 istk = istk->next;
4159 fclose(i->fp);
4160 nasm_free(i->fname);
4161 nasm_free(i);
4163 while (cstk)
4164 ctx_pop();
4167 void
4168 pp_include_path(char *path)
4170 IncPath *i;
4172 i = nasm_malloc(sizeof(IncPath));
4173 i->path = nasm_strdup(path);
4174 i->next = ipath;
4175 ipath = i;
4178 void
4179 pp_pre_include(char *fname)
4181 Token *inc, *space, *name;
4182 Line *l;
4184 name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
4185 space = new_Token(name, TOK_WHITESPACE, NULL, 0);
4186 inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
4188 l = nasm_malloc(sizeof(Line));
4189 l->next = predef;
4190 l->first = inc;
4191 l->finishes = FALSE;
4192 predef = l;
4195 void
4196 pp_pre_define(char *definition)
4198 Token *def, *space;
4199 Line *l;
4200 char *equals;
4202 equals = strchr(definition, '=');
4203 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4204 def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
4205 if (equals)
4206 *equals = ' ';
4207 space->next = tokenise(definition);
4208 if (equals)
4209 *equals = '=';
4211 l = nasm_malloc(sizeof(Line));
4212 l->next = predef;
4213 l->first = def;
4214 l->finishes = FALSE;
4215 predef = l;
4218 void
4219 pp_pre_undefine(char *definition)
4221 Token *def, *space;
4222 Line *l;
4224 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4225 def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
4227 l = nasm_malloc(sizeof(Line));
4228 l->next = predef;
4229 l->first = def;
4230 l->finishes = FALSE;
4231 predef = l;
4234 void
4235 pp_extra_stdmac(char **macros)
4237 extrastdmac = macros;
4240 static void
4241 make_tok_num(Token * tok, long val)
4243 char numbuf[20];
4244 sprintf(numbuf, "%ld", val);
4245 tok->text = nasm_strdup(numbuf);
4246 tok->type = TOK_NUMBER;
4249 Preproc nasmpp = {
4250 pp_reset,
4251 pp_getline,
4252 pp_cleanup