NASM 0.98.12
[nasm/avx512.git] / preproc.c
bloba62fe858e9f199eb3a81478eb286a54b3e986e33
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 t->next = freeTokens;
922 freeTokens = t;
923 return next;
927 * Convert a line of tokens back into text.
928 * If expand_locals is not zero, identifiers of the form "%$*xxx"
929 * will be transformed into ..@ctxnum.xxx
931 static char *
932 detoken(Token * tlist, int expand_locals)
934 Token *t;
935 int len;
936 char *line, *p;
938 len = 0;
939 for (t = tlist; t; t = t->next)
941 if (t->type == TOK_PREPROC_ID && t->text[1] == '!')
943 char *p = getenv(t->text + 2);
944 nasm_free(t->text);
945 if (p)
946 t->text = nasm_strdup(p);
947 else
948 t->text = NULL;
950 /* Expand local macros here and not during preprocessing */
951 if (expand_locals &&
952 t->type == TOK_PREPROC_ID && t->text &&
953 t->text[0] == '%' && t->text[1] == '$')
955 Context *ctx = get_ctx(t->text, FALSE);
956 if (ctx)
958 char buffer[40];
959 char *p, *q = t->text + 2;
961 q += strspn(q, "$");
962 sprintf(buffer, "..@%lu.", ctx->number);
963 p = nasm_strcat(buffer, q);
964 nasm_free(t->text);
965 t->text = p;
968 if (t->type == TOK_WHITESPACE)
970 len++;
972 else if (t->text)
974 len += strlen(t->text);
977 p = line = nasm_malloc(len + 1);
978 for (t = tlist; t; t = t->next)
980 if (t->type == TOK_WHITESPACE)
982 *p = ' ';
983 p++;
984 *p = '\0';
986 else if (t->text)
988 strcpy(p, t->text);
989 p += strlen(p);
992 *p = '\0';
993 return line;
997 * A scanner, suitable for use by the expression evaluator, which
998 * operates on a line of Tokens. Expects a pointer to a pointer to
999 * the first token in the line to be passed in as its private_data
1000 * field.
1002 static int
1003 ppscan(void *private_data, struct tokenval *tokval)
1005 Token **tlineptr = private_data;
1006 Token *tline;
1010 tline = *tlineptr;
1011 *tlineptr = tline ? tline->next : NULL;
1013 while (tline && (tline->type == TOK_WHITESPACE ||
1014 tline->type == TOK_COMMENT));
1016 if (!tline)
1017 return tokval->t_type = TOKEN_EOS;
1019 if (tline->text[0] == '$' && !tline->text[1])
1020 return tokval->t_type = TOKEN_HERE;
1021 if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[1])
1022 return tokval->t_type = TOKEN_BASE;
1024 if (tline->type == TOK_ID)
1026 tokval->t_charptr = tline->text;
1027 if (tline->text[0] == '$')
1029 tokval->t_charptr++;
1030 return tokval->t_type = TOKEN_ID;
1034 * This is the only special case we actually need to worry
1035 * about in this restricted context.
1037 if (!nasm_stricmp(tline->text, "seg"))
1038 return tokval->t_type = TOKEN_SEG;
1040 return tokval->t_type = TOKEN_ID;
1043 if (tline->type == TOK_NUMBER)
1045 int rn_error;
1047 tokval->t_integer = readnum(tline->text, &rn_error);
1048 if (rn_error)
1049 return tokval->t_type = TOKEN_ERRNUM;
1050 tokval->t_charptr = NULL;
1051 return tokval->t_type = TOKEN_NUM;
1054 if (tline->type == TOK_STRING)
1056 int rn_warn;
1057 char q, *r;
1058 int l;
1060 r = tline->text;
1061 q = *r++;
1062 l = strlen(r);
1064 if (l == 0 || r[l - 1] != q)
1065 return tokval->t_type = TOKEN_ERRNUM;
1066 tokval->t_integer = readstrnum(r, l - 1, &rn_warn);
1067 if (rn_warn)
1068 error(ERR_WARNING | ERR_PASS1, "character constant too long");
1069 tokval->t_charptr = NULL;
1070 return tokval->t_type = TOKEN_NUM;
1073 if (tline->type == TOK_OTHER)
1075 if (!strcmp(tline->text, "<<"))
1076 return tokval->t_type = TOKEN_SHL;
1077 if (!strcmp(tline->text, ">>"))
1078 return tokval->t_type = TOKEN_SHR;
1079 if (!strcmp(tline->text, "//"))
1080 return tokval->t_type = TOKEN_SDIV;
1081 if (!strcmp(tline->text, "%%"))
1082 return tokval->t_type = TOKEN_SMOD;
1083 if (!strcmp(tline->text, "=="))
1084 return tokval->t_type = TOKEN_EQ;
1085 if (!strcmp(tline->text, "<>"))
1086 return tokval->t_type = TOKEN_NE;
1087 if (!strcmp(tline->text, "!="))
1088 return tokval->t_type = TOKEN_NE;
1089 if (!strcmp(tline->text, "<="))
1090 return tokval->t_type = TOKEN_LE;
1091 if (!strcmp(tline->text, ">="))
1092 return tokval->t_type = TOKEN_GE;
1093 if (!strcmp(tline->text, "&&"))
1094 return tokval->t_type = TOKEN_DBL_AND;
1095 if (!strcmp(tline->text, "^^"))
1096 return tokval->t_type = TOKEN_DBL_XOR;
1097 if (!strcmp(tline->text, "||"))
1098 return tokval->t_type = TOKEN_DBL_OR;
1102 * We have no other options: just return the first character of
1103 * the token text.
1105 return tokval->t_type = tline->text[0];
1109 * Compare a string to the name of an existing macro; this is a
1110 * simple wrapper which calls either strcmp or nasm_stricmp
1111 * depending on the value of the `casesense' parameter.
1113 static int
1114 mstrcmp(char *p, char *q, int casesense)
1116 return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
1120 * Return the Context structure associated with a %$ token. Return
1121 * NULL, having _already_ reported an error condition, if the
1122 * context stack isn't deep enough for the supplied number of $
1123 * signs.
1124 * If all_contexts == TRUE, contexts that enclose current are
1125 * also scanned for such smacro, until it is found; if not -
1126 * only the context that directly results from the number of $'s
1127 * in variable's name.
1129 static Context *
1130 get_ctx(char *name, int all_contexts)
1132 Context *ctx;
1133 SMacro *m;
1134 int i;
1136 if (!name || name[0] != '%' || name[1] != '$')
1137 return NULL;
1139 if (!cstk)
1141 error(ERR_NONFATAL, "`%s': context stack is empty", name);
1142 return NULL;
1145 for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--)
1147 ctx = ctx->next;
1148 i--;
1150 if (!ctx)
1152 error(ERR_NONFATAL, "`%s': context stack is only"
1153 " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
1154 return NULL;
1156 if (!all_contexts)
1157 return ctx;
1161 /* Search for this smacro in found context */
1162 m = ctx->localmac;
1163 while (m)
1165 if (!mstrcmp(m->name, name, m->casesense))
1166 return ctx;
1167 m = m->next;
1169 ctx = ctx->next;
1171 while (ctx);
1172 return NULL;
1175 /* Add a slash to the end of a path if it is missing. We use the
1176 * forward slash to make it compatible with Unix systems.
1178 static void
1179 backslash(char *s)
1181 int pos = strlen(s);
1182 if (s[pos - 1] != '\\' && s[pos - 1] != '/')
1184 s[pos] = '/';
1185 s[pos + 1] = '\0';
1190 * Open an include file. This routine must always return a valid
1191 * file pointer if it returns - it's responsible for throwing an
1192 * ERR_FATAL and bombing out completely if not. It should also try
1193 * the include path one by one until it finds the file or reaches
1194 * the end of the path.
1196 static FILE *
1197 inc_fopen(char *file)
1199 FILE *fp;
1200 char *prefix = "", *combine;
1201 IncPath *ip = ipath;
1202 static int namelen = 0;
1203 int len = strlen(file);
1205 while (1)
1207 combine = nasm_malloc(strlen(prefix) + 1 + len + 1);
1208 strcpy(combine, prefix);
1209 if (prefix[0] != 0)
1210 backslash(combine);
1211 strcat(combine, file);
1212 fp = fopen(combine, "r");
1213 if (pass == 0 && fp)
1215 namelen += strlen(combine) + 1;
1216 if (namelen > 62)
1218 printf(" \\\n ");
1219 namelen = 2;
1221 printf(" %s", combine);
1223 nasm_free(combine);
1224 if (fp)
1225 return fp;
1226 if (!ip)
1227 break;
1228 prefix = ip->path;
1229 ip = ip->next;
1232 error(ERR_FATAL, "unable to open include file `%s'", file);
1233 return NULL; /* never reached - placate compilers */
1237 * Determine if we should warn on defining a single-line macro of
1238 * name `name', with `nparam' parameters. If nparam is 0 or -1, will
1239 * return TRUE if _any_ single-line macro of that name is defined.
1240 * Otherwise, will return TRUE if a single-line macro with either
1241 * `nparam' or no parameters is defined.
1243 * If a macro with precisely the right number of parameters is
1244 * defined, or nparam is -1, the address of the definition structure
1245 * will be returned in `defn'; otherwise NULL will be returned. If `defn'
1246 * is NULL, no action will be taken regarding its contents, and no
1247 * error will occur.
1249 * Note that this is also called with nparam zero to resolve
1250 * `ifdef'.
1252 * If you already know which context macro belongs to, you can pass
1253 * the context pointer as first parameter; if you won't but name begins
1254 * with %$ the context will be automatically computed. If all_contexts
1255 * is true, macro will be searched in outer contexts as well.
1257 static int
1258 smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
1259 int nocase)
1261 SMacro *m;
1263 if (ctx)
1264 m = ctx->localmac;
1265 else if (name[0] == '%' && name[1] == '$')
1267 if (cstk)
1268 ctx = get_ctx(name, FALSE);
1269 if (!ctx)
1270 return FALSE; /* got to return _something_ */
1271 m = ctx->localmac;
1273 else
1274 m = smacros[hash(name)];
1276 while (m)
1278 if (!mstrcmp(m->name, name, m->casesense && nocase) &&
1279 (nparam <= 0 || m->nparam == 0 || nparam == m->nparam))
1281 if (defn)
1283 if (nparam == m->nparam || nparam == -1)
1284 *defn = m;
1285 else
1286 *defn = NULL;
1288 return TRUE;
1290 m = m->next;
1293 return FALSE;
1297 * Count and mark off the parameters in a multi-line macro call.
1298 * This is called both from within the multi-line macro expansion
1299 * code, and also to mark off the default parameters when provided
1300 * in a %macro definition line.
1302 static void
1303 count_mmac_params(Token * t, int *nparam, Token *** params)
1305 int paramsize, brace;
1307 *nparam = paramsize = 0;
1308 *params = NULL;
1309 while (t)
1311 if (*nparam >= paramsize)
1313 paramsize += PARAM_DELTA;
1314 *params = nasm_realloc(*params, sizeof(**params) * paramsize);
1316 skip_white_(t);
1317 brace = FALSE;
1318 if (tok_is_(t, "{"))
1319 brace = TRUE;
1320 (*params)[(*nparam)++] = t;
1321 while (tok_isnt_(t, brace ? "}" : ","))
1322 t = t->next;
1323 if (t)
1324 { /* got a comma/brace */
1325 t = t->next;
1326 if (brace)
1329 * Now we've found the closing brace, look further
1330 * for the comma.
1332 skip_white_(t);
1333 if (tok_isnt_(t, ","))
1335 error(ERR_NONFATAL,
1336 "braces do not enclose all of macro parameter");
1337 while (tok_isnt_(t, ","))
1338 t = t->next;
1340 if (t)
1341 t = t->next; /* eat the comma */
1348 * Determine whether one of the various `if' conditions is true or
1349 * not.
1351 * We must free the tline we get passed.
1353 static int
1354 if_condition(Token * tline, int i)
1356 int j, casesense;
1357 Token *t, *tt, **tptr, *origline;
1358 struct tokenval tokval;
1359 expr *evalresult;
1361 origline = tline;
1363 switch (i)
1365 case PP_IFCTX:
1366 case PP_ELIFCTX:
1367 case PP_IFNCTX:
1368 case PP_ELIFNCTX:
1369 j = FALSE; /* have we matched yet? */
1370 while (cstk && tline)
1372 skip_white_(tline);
1373 if (!tline || tline->type != TOK_ID)
1375 error(ERR_NONFATAL,
1376 "`%s' expects context identifiers",
1377 directives[i]);
1378 free_tlist(origline);
1379 return -1;
1381 if (!nasm_stricmp(tline->text, cstk->name))
1382 j = TRUE;
1383 tline = tline->next;
1385 if (i == PP_IFNCTX || i == PP_ELIFNCTX)
1386 j = !j;
1387 free_tlist(origline);
1388 return j;
1390 case PP_IFDEF:
1391 case PP_ELIFDEF:
1392 case PP_IFNDEF:
1393 case PP_ELIFNDEF:
1394 j = FALSE; /* have we matched yet? */
1395 while (tline)
1397 skip_white_(tline);
1398 if (!tline || (tline->type != TOK_ID &&
1399 (tline->type != TOK_PREPROC_ID ||
1400 tline->text[1] != '$')))
1402 error(ERR_NONFATAL,
1403 "`%%if%sdef' expects macro identifiers",
1404 (i == PP_ELIFNDEF ? "n" : ""));
1405 free_tlist(origline);
1406 return -1;
1408 if (smacro_defined(NULL, tline->text, 0, NULL, 1))
1409 j = TRUE;
1410 tline = tline->next;
1412 if (i == PP_IFNDEF || i == PP_ELIFNDEF)
1413 j = !j;
1414 free_tlist(origline);
1415 return j;
1417 case PP_IFIDN:
1418 case PP_ELIFIDN:
1419 case PP_IFNIDN:
1420 case PP_ELIFNIDN:
1421 case PP_IFIDNI:
1422 case PP_ELIFIDNI:
1423 case PP_IFNIDNI:
1424 case PP_ELIFNIDNI:
1425 tline = expand_smacro(tline);
1426 t = tt = tline;
1427 while (tok_isnt_(tt, ","))
1428 tt = tt->next;
1429 if (!tt)
1431 error(ERR_NONFATAL,
1432 "`%s' expects two comma-separated arguments",
1433 directives[i]);
1434 free_tlist(tline);
1435 return -1;
1437 tt = tt->next;
1438 casesense = (i == PP_IFIDN || i == PP_ELIFIDN ||
1439 i == PP_IFNIDN || i == PP_ELIFNIDN);
1440 j = TRUE; /* assume equality unless proved not */
1441 while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt)
1443 if (tt->type == TOK_OTHER && !strcmp(tt->text, ","))
1445 error(ERR_NONFATAL, "`%s': more than one comma on line",
1446 directives[i]);
1447 free_tlist(tline);
1448 return -1;
1450 if (t->type == TOK_WHITESPACE)
1452 t = t->next;
1453 continue;
1455 else if (tt->type == TOK_WHITESPACE)
1457 tt = tt->next;
1458 continue;
1460 else if (tt->type != t->type ||
1461 mstrcmp(tt->text, t->text, casesense))
1463 j = FALSE; /* found mismatching tokens */
1464 break;
1466 else
1468 t = t->next;
1469 tt = tt->next;
1470 continue;
1473 if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
1474 j = FALSE; /* trailing gunk on one end or other */
1475 if (i == PP_IFNIDN || i == PP_ELIFNIDN ||
1476 i == PP_IFNIDNI || i == PP_ELIFNIDNI)
1477 j = !j;
1478 free_tlist(tline);
1479 return j;
1481 case PP_IFID:
1482 case PP_ELIFID:
1483 case PP_IFNID:
1484 case PP_ELIFNID:
1485 case PP_IFNUM:
1486 case PP_ELIFNUM:
1487 case PP_IFNNUM:
1488 case PP_ELIFNNUM:
1489 case PP_IFSTR:
1490 case PP_ELIFSTR:
1491 case PP_IFNSTR:
1492 case PP_ELIFNSTR:
1493 tline = expand_smacro(tline);
1494 t = tline;
1495 while (tok_type_(t, TOK_WHITESPACE))
1496 t = t->next;
1497 j = FALSE; /* placate optimiser */
1498 if (t)
1499 switch (i)
1501 case PP_IFID:
1502 case PP_ELIFID:
1503 case PP_IFNID:
1504 case PP_ELIFNID:
1505 j = (t->type == TOK_ID);
1506 break;
1507 case PP_IFNUM:
1508 case PP_ELIFNUM:
1509 case PP_IFNNUM:
1510 case PP_ELIFNNUM:
1511 j = (t->type == TOK_NUMBER);
1512 break;
1513 case PP_IFSTR:
1514 case PP_ELIFSTR:
1515 case PP_IFNSTR:
1516 case PP_ELIFNSTR:
1517 j = (t->type == TOK_STRING);
1518 break;
1520 if (i == PP_IFNID || i == PP_ELIFNID ||
1521 i == PP_IFNNUM || i == PP_ELIFNNUM ||
1522 i == PP_IFNSTR || i == PP_ELIFNSTR)
1523 j = !j;
1524 free_tlist(tline);
1525 return j;
1527 case PP_IF:
1528 case PP_ELIF:
1529 t = tline = expand_smacro(tline);
1530 tptr = &t;
1531 tokval.t_type = TOKEN_INVALID;
1532 evalresult = evaluate(ppscan, tptr, &tokval,
1533 NULL, pass | CRITICAL, error, NULL);
1534 free_tlist(tline);
1535 if (!evalresult)
1536 return -1;
1537 if (tokval.t_type)
1538 error(ERR_WARNING,
1539 "trailing garbage after expression ignored");
1540 if (!is_simple(evalresult))
1542 error(ERR_NONFATAL,
1543 "non-constant value given to `%s'", directives[i]);
1544 return -1;
1546 return reloc_value(evalresult) != 0;
1548 default:
1549 error(ERR_FATAL,
1550 "preprocessor directive `%s' not yet implemented",
1551 directives[i]);
1552 free_tlist(origline);
1553 return -1; /* yeah, right */
1558 * Expand macros in a string. Used in %error and %include directives.
1559 * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
1560 * The returned variable should ALWAYS be freed after usage.
1562 void
1563 expand_macros_in_string(char **p)
1565 Token *line = tokenise(*p);
1566 line = expand_smacro(line);
1567 *p = detoken(line, FALSE);
1571 * Find out if a line contains a preprocessor directive, and deal
1572 * with it if so.
1574 * If a directive _is_ found, we are expected to free_tlist() the
1575 * line.
1577 * Return values go like this:
1579 * bit 0 is set if a directive was found (so the line gets freed)
1581 static int
1582 do_directive(Token * tline)
1584 int i, j, k, m, nparam, nolist;
1585 int offset;
1586 char *p, *mname;
1587 Include *inc;
1588 Context *ctx;
1589 Cond *cond;
1590 SMacro *smac, **smhead;
1591 MMacro *mmac;
1592 Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
1593 Line *l;
1594 struct tokenval tokval;
1595 expr *evalresult;
1596 MMacro *tmp_defining; /* Used when manipulating rep_nest */
1598 origline = tline;
1600 skip_white_(tline);
1601 if (!tok_type_(tline, TOK_PREPROC_ID) ||
1602 (tline->text[1] == '%' || tline->text[1] == '$'
1603 || tline->text[1] == '!'))
1604 return 0;
1606 i = -1;
1607 j = sizeof(directives) / sizeof(*directives);
1608 while (j - i > 1)
1610 k = (j + i) / 2;
1611 m = nasm_stricmp(tline->text, directives[k]);
1612 if (m == 0) {
1613 if (tasm_compatible_mode) {
1614 i = k;
1615 j = -2;
1616 } else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) {
1617 i = k;
1618 j = -2;
1620 break;
1622 else if (m < 0) {
1623 j = k;
1625 else
1626 i = k;
1630 * If we're in a non-emitting branch of a condition construct,
1631 * or walking to the end of an already terminated %rep block,
1632 * we should ignore all directives except for condition
1633 * directives.
1635 if (((istk->conds && !emitting(istk->conds->state)) ||
1636 (istk->mstk && !istk->mstk->in_progress)) &&
1637 i != PP_IF && i != PP_ELIF &&
1638 i != PP_IFCTX && i != PP_ELIFCTX &&
1639 i != PP_IFDEF && i != PP_ELIFDEF &&
1640 i != PP_IFID && i != PP_ELIFID &&
1641 i != PP_IFIDN && i != PP_ELIFIDN &&
1642 i != PP_IFIDNI && i != PP_ELIFIDNI &&
1643 i != PP_IFNCTX && i != PP_ELIFNCTX &&
1644 i != PP_IFNDEF && i != PP_ELIFNDEF &&
1645 i != PP_IFNID && i != PP_ELIFNID &&
1646 i != PP_IFNIDN && i != PP_ELIFNIDN &&
1647 i != PP_IFNIDNI && i != PP_ELIFNIDNI &&
1648 i != PP_IFNNUM && i != PP_ELIFNNUM &&
1649 i != PP_IFNSTR && i != PP_ELIFNSTR &&
1650 i != PP_IFNUM && i != PP_ELIFNUM &&
1651 i != PP_IFSTR && i != PP_ELIFSTR && i != PP_ELSE && i != PP_ENDIF)
1653 return 0;
1657 * If we're defining a macro or reading a %rep block, we should
1658 * ignore all directives except for %macro/%imacro (which
1659 * generate an error), %endm/%endmacro, and (only if we're in a
1660 * %rep block) %endrep. If we're in a %rep block, another %rep
1661 * causes an error, so should be let through.
1663 if (defining && i != PP_MACRO && i != PP_IMACRO &&
1664 i != PP_ENDMACRO && i != PP_ENDM &&
1665 (defining->name || (i != PP_ENDREP && i != PP_REP)))
1667 return 0;
1670 if (j != -2)
1672 error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
1673 tline->text);
1674 return 0; /* didn't get it */
1677 switch (i)
1679 case PP_STACKSIZE:
1680 /* Directive to tell NASM what the default stack size is. The
1681 * default is for a 16-bit stack, and this can be overriden with
1682 * %stacksize large.
1683 * the following form:
1685 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1687 tline = tline->next;
1688 if (tline && tline->type == TOK_WHITESPACE)
1689 tline = tline->next;
1690 if (!tline || tline->type != TOK_ID)
1692 error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
1693 free_tlist(origline);
1694 return 3;
1696 if (nasm_stricmp(tline->text, "flat") == 0)
1698 /* All subsequent ARG directives are for a 32-bit stack */
1699 StackSize = 4;
1700 StackPointer = "ebp";
1701 ArgOffset = 8;
1702 LocalOffset = 4;
1704 else if (nasm_stricmp(tline->text, "large") == 0)
1706 /* All subsequent ARG directives are for a 16-bit stack,
1707 * far function call.
1709 StackSize = 2;
1710 StackPointer = "bp";
1711 ArgOffset = 4;
1712 LocalOffset = 2;
1714 else if (nasm_stricmp(tline->text, "small") == 0)
1716 /* All subsequent ARG directives are for a 16-bit stack,
1717 * far function call. We don't support near functions.
1719 StackSize = 2;
1720 StackPointer = "bp";
1721 ArgOffset = 6;
1722 LocalOffset = 2;
1724 else
1726 error(ERR_NONFATAL, "`%%stacksize' invalid size type");
1727 free_tlist(origline);
1728 return 3;
1730 free_tlist(origline);
1731 return 3;
1733 case PP_ARG:
1734 /* TASM like ARG directive to define arguments to functions, in
1735 * the following form:
1737 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1739 offset = ArgOffset;
1742 char *arg, directive[256];
1743 int size = StackSize;
1745 /* Find the argument name */
1746 tline = tline->next;
1747 if (tline && tline->type == TOK_WHITESPACE)
1748 tline = tline->next;
1749 if (!tline || tline->type != TOK_ID)
1751 error(ERR_NONFATAL, "`%%arg' missing argument parameter");
1752 free_tlist(origline);
1753 return 3;
1755 arg = tline->text;
1757 /* Find the argument size type */
1758 tline = tline->next;
1759 if (!tline || tline->type != TOK_OTHER
1760 || tline->text[0] != ':')
1762 error(ERR_NONFATAL,
1763 "Syntax error processing `%%arg' directive");
1764 free_tlist(origline);
1765 return 3;
1767 tline = tline->next;
1768 if (!tline || tline->type != TOK_ID)
1770 error(ERR_NONFATAL,
1771 "`%%arg' missing size type parameter");
1772 free_tlist(origline);
1773 return 3;
1776 /* Allow macro expansion of type parameter */
1777 tt = tokenise(tline->text);
1778 tt = expand_smacro(tt);
1779 if (nasm_stricmp(tt->text, "byte") == 0)
1781 size = MAX(StackSize, 1);
1783 else if (nasm_stricmp(tt->text, "word") == 0)
1785 size = MAX(StackSize, 2);
1787 else if (nasm_stricmp(tt->text, "dword") == 0)
1789 size = MAX(StackSize, 4);
1791 else if (nasm_stricmp(tt->text, "qword") == 0)
1793 size = MAX(StackSize, 8);
1795 else if (nasm_stricmp(tt->text, "tword") == 0)
1797 size = MAX(StackSize, 10);
1799 else
1801 error(ERR_NONFATAL,
1802 "Invalid size type for `%%arg' missing directive");
1803 free_tlist(tt);
1804 free_tlist(origline);
1805 return 3;
1807 free_tlist(tt);
1809 /* Now define the macro for the argument */
1810 sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer,
1811 offset);
1812 do_directive(tokenise(directive));
1813 offset += size;
1815 /* Move to the next argument in the list */
1816 tline = tline->next;
1817 if (tline && tline->type == TOK_WHITESPACE)
1818 tline = tline->next;
1820 while (tline && tline->type == TOK_OTHER
1821 && tline->text[0] == ',');
1822 free_tlist(origline);
1823 return 3;
1825 case PP_LOCAL:
1826 /* TASM like LOCAL directive to define local variables for a
1827 * function, in the following form:
1829 * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1831 * The '= LocalSize' at the end is ignored by NASM, but is
1832 * required by TASM to define the local parameter size (and used
1833 * by the TASM macro package).
1835 offset = LocalOffset;
1838 char *local, directive[256];
1839 int size = StackSize;
1841 /* Find the argument name */
1842 tline = tline->next;
1843 if (tline && tline->type == TOK_WHITESPACE)
1844 tline = tline->next;
1845 if (!tline || tline->type != TOK_ID)
1847 error(ERR_NONFATAL,
1848 "`%%local' missing argument parameter");
1849 free_tlist(origline);
1850 return 3;
1852 local = tline->text;
1854 /* Find the argument size type */
1855 tline = tline->next;
1856 if (!tline || tline->type != TOK_OTHER
1857 || tline->text[0] != ':')
1859 error(ERR_NONFATAL,
1860 "Syntax error processing `%%local' directive");
1861 free_tlist(origline);
1862 return 3;
1864 tline = tline->next;
1865 if (!tline || tline->type != TOK_ID)
1867 error(ERR_NONFATAL,
1868 "`%%local' missing size type parameter");
1869 free_tlist(origline);
1870 return 3;
1873 /* Allow macro expansion of type parameter */
1874 tt = tokenise(tline->text);
1875 tt = expand_smacro(tt);
1876 if (nasm_stricmp(tt->text, "byte") == 0)
1878 size = MAX(StackSize, 1);
1880 else if (nasm_stricmp(tt->text, "word") == 0)
1882 size = MAX(StackSize, 2);
1884 else if (nasm_stricmp(tt->text, "dword") == 0)
1886 size = MAX(StackSize, 4);
1888 else if (nasm_stricmp(tt->text, "qword") == 0)
1890 size = MAX(StackSize, 8);
1892 else if (nasm_stricmp(tt->text, "tword") == 0)
1894 size = MAX(StackSize, 10);
1896 else
1898 error(ERR_NONFATAL,
1899 "Invalid size type for `%%local' missing directive");
1900 free_tlist(tt);
1901 free_tlist(origline);
1902 return 3;
1904 free_tlist(tt);
1906 /* Now define the macro for the argument */
1907 sprintf(directive, "%%define %s (%s-%d)", local, StackPointer,
1908 offset);
1909 do_directive(tokenise(directive));
1910 offset += size;
1912 /* Now define the assign to setup the enter_c macro correctly */
1913 sprintf(directive, "%%assign %%$localsize %%$localsize+%d",
1914 size);
1915 do_directive(tokenise(directive));
1917 /* Move to the next argument in the list */
1918 tline = tline->next;
1919 if (tline && tline->type == TOK_WHITESPACE)
1920 tline = tline->next;
1922 while (tline && tline->type == TOK_OTHER
1923 && tline->text[0] == ',');
1924 free_tlist(origline);
1925 return 3;
1927 case PP_CLEAR:
1928 if (tline->next)
1929 error(ERR_WARNING,
1930 "trailing garbage after `%%clear' ignored");
1931 for (j = 0; j < NHASH; j++)
1933 while (mmacros[j])
1935 MMacro *m = mmacros[j];
1936 mmacros[j] = m->next;
1937 free_mmacro(m);
1939 while (smacros[j])
1941 SMacro *s = smacros[j];
1942 smacros[j] = smacros[j]->next;
1943 nasm_free(s->name);
1944 free_tlist(s->expansion);
1945 nasm_free(s);
1948 free_tlist(origline);
1949 return 3;
1951 case PP_INCLUDE:
1952 tline = tline->next;
1953 skip_white_(tline);
1954 if (!tline || (tline->type != TOK_STRING &&
1955 tline->type != TOK_INTERNAL_STRING))
1957 error(ERR_NONFATAL, "`%%include' expects a file name");
1958 free_tlist(origline);
1959 return 3; /* but we did _something_ */
1961 if (tline->next)
1962 error(ERR_WARNING,
1963 "trailing garbage after `%%include' ignored");
1964 if (tline->type != TOK_INTERNAL_STRING)
1966 p = tline->text + 1; /* point past the quote to the name */
1967 p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
1969 else
1970 p = tline->text; /* internal_string is easier */
1971 expand_macros_in_string(&p);
1972 inc = nasm_malloc(sizeof(Include));
1973 inc->next = istk;
1974 inc->conds = NULL;
1975 inc->fp = inc_fopen(p);
1976 inc->fname = src_set_fname(p);
1977 inc->lineno = src_set_linnum(0);
1978 inc->lineinc = 1;
1979 inc->expansion = NULL;
1980 inc->mstk = NULL;
1981 istk = inc;
1982 list->uplevel(LIST_INCLUDE);
1983 free_tlist(origline);
1984 return 5;
1986 case PP_PUSH:
1987 tline = tline->next;
1988 skip_white_(tline);
1989 tline = expand_id(tline);
1990 if (!tok_type_(tline, TOK_ID))
1992 error(ERR_NONFATAL, "`%%push' expects a context identifier");
1993 free_tlist(origline);
1994 return 3; /* but we did _something_ */
1996 if (tline->next)
1997 error(ERR_WARNING, "trailing garbage after `%%push' ignored");
1998 ctx = nasm_malloc(sizeof(Context));
1999 ctx->next = cstk;
2000 ctx->localmac = NULL;
2001 ctx->name = nasm_strdup(tline->text);
2002 ctx->number = unique++;
2003 cstk = ctx;
2004 free_tlist(origline);
2005 break;
2007 case PP_REPL:
2008 tline = tline->next;
2009 skip_white_(tline);
2010 tline = expand_id(tline);
2011 if (!tok_type_(tline, TOK_ID))
2013 error(ERR_NONFATAL, "`%%repl' expects a context identifier");
2014 free_tlist(origline);
2015 return 3; /* but we did _something_ */
2017 if (tline->next)
2018 error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
2019 if (!cstk)
2020 error(ERR_NONFATAL, "`%%repl': context stack is empty");
2021 else
2023 nasm_free(cstk->name);
2024 cstk->name = nasm_strdup(tline->text);
2026 free_tlist(origline);
2027 break;
2029 case PP_POP:
2030 if (tline->next)
2031 error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
2032 if (!cstk)
2033 error(ERR_NONFATAL,
2034 "`%%pop': context stack is already empty");
2035 else
2036 ctx_pop();
2037 free_tlist(origline);
2038 break;
2040 case PP_ERROR:
2041 tline->next = expand_smacro(tline->next);
2042 tline = tline->next;
2043 skip_white_(tline);
2044 if (tok_type_(tline, TOK_STRING))
2046 p = tline->text + 1; /* point past the quote to the name */
2047 p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
2048 expand_macros_in_string(&p);
2049 error(ERR_NONFATAL, "%s", p);
2050 nasm_free(p);
2052 else
2054 p = detoken(tline, FALSE);
2055 error(ERR_WARNING, "%s", p);
2056 nasm_free(p);
2058 free_tlist(origline);
2059 break;
2061 case PP_IF:
2062 case PP_IFCTX:
2063 case PP_IFDEF:
2064 case PP_IFID:
2065 case PP_IFIDN:
2066 case PP_IFIDNI:
2067 case PP_IFNCTX:
2068 case PP_IFNDEF:
2069 case PP_IFNID:
2070 case PP_IFNIDN:
2071 case PP_IFNIDNI:
2072 case PP_IFNNUM:
2073 case PP_IFNSTR:
2074 case PP_IFNUM:
2075 case PP_IFSTR:
2076 if (istk->conds && !emitting(istk->conds->state))
2077 j = COND_NEVER;
2078 else
2080 j = if_condition(tline->next, i);
2081 tline->next = NULL; /* it got freed */
2082 free_tlist(origline);
2083 j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2085 cond = nasm_malloc(sizeof(Cond));
2086 cond->next = istk->conds;
2087 cond->state = j;
2088 istk->conds = cond;
2089 return (j == COND_IF_TRUE ? 3 : 1);
2091 case PP_ELIF:
2092 case PP_ELIFCTX:
2093 case PP_ELIFDEF:
2094 case PP_ELIFID:
2095 case PP_ELIFIDN:
2096 case PP_ELIFIDNI:
2097 case PP_ELIFNCTX:
2098 case PP_ELIFNDEF:
2099 case PP_ELIFNID:
2100 case PP_ELIFNIDN:
2101 case PP_ELIFNIDNI:
2102 case PP_ELIFNNUM:
2103 case PP_ELIFNSTR:
2104 case PP_ELIFNUM:
2105 case PP_ELIFSTR:
2106 if (!istk->conds)
2107 error(ERR_FATAL, "`%s': no matching `%%if'", directives[i]);
2108 if (emitting(istk->conds->state)
2109 || istk->conds->state == COND_NEVER)
2110 istk->conds->state = COND_NEVER;
2111 else
2113 j = if_condition(expand_mmac_params(tline->next), i);
2114 tline->next = NULL; /* it got freed */
2115 free_tlist(origline);
2116 istk->conds->state =
2117 j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2119 return (istk->conds->state == COND_IF_TRUE ? 5 : 1);
2121 case PP_ELSE:
2122 if (tline->next)
2123 error(ERR_WARNING, "trailing garbage after `%%else' ignored");
2124 if (!istk->conds)
2125 error(ERR_FATAL, "`%%else': no matching `%%if'");
2126 if (emitting(istk->conds->state)
2127 || istk->conds->state == COND_NEVER)
2128 istk->conds->state = COND_ELSE_FALSE;
2129 else
2130 istk->conds->state = COND_ELSE_TRUE;
2131 free_tlist(origline);
2132 return 5;
2134 case PP_ENDIF:
2135 if (tline->next)
2136 error(ERR_WARNING,
2137 "trailing garbage after `%%endif' ignored");
2138 if (!istk->conds)
2139 error(ERR_FATAL, "`%%endif': no matching `%%if'");
2140 cond = istk->conds;
2141 istk->conds = cond->next;
2142 nasm_free(cond);
2143 free_tlist(origline);
2144 return 5;
2146 case PP_MACRO:
2147 case PP_IMACRO:
2148 if (defining)
2149 error(ERR_FATAL,
2150 "`%%%smacro': already defining a macro",
2151 (i == PP_IMACRO ? "i" : ""));
2152 tline = tline->next;
2153 skip_white_(tline);
2154 tline = expand_id(tline);
2155 if (!tok_type_(tline, TOK_ID))
2157 error(ERR_NONFATAL,
2158 "`%%%smacro' expects a macro name",
2159 (i == PP_IMACRO ? "i" : ""));
2160 return 3;
2162 defining = nasm_malloc(sizeof(MMacro));
2163 defining->name = nasm_strdup(tline->text);
2164 defining->casesense = (i == PP_MACRO);
2165 defining->plus = FALSE;
2166 defining->nolist = FALSE;
2167 defining->in_progress = FALSE;
2168 defining->rep_nest = NULL;
2169 tline = expand_smacro(tline->next);
2170 skip_white_(tline);
2171 if (!tok_type_(tline, TOK_NUMBER))
2173 error(ERR_NONFATAL,
2174 "`%%%smacro' expects a parameter count",
2175 (i == PP_IMACRO ? "i" : ""));
2176 defining->nparam_min = defining->nparam_max = 0;
2178 else
2180 defining->nparam_min = defining->nparam_max =
2181 readnum(tline->text, &j);
2182 if (j)
2183 error(ERR_NONFATAL,
2184 "unable to parse parameter count `%s'",
2185 tline->text);
2187 if (tline && tok_is_(tline->next, "-"))
2189 tline = tline->next->next;
2190 if (tok_is_(tline, "*"))
2191 defining->nparam_max = INT_MAX;
2192 else if (!tok_type_(tline, TOK_NUMBER))
2193 error(ERR_NONFATAL,
2194 "`%%%smacro' expects a parameter count after `-'",
2195 (i == PP_IMACRO ? "i" : ""));
2196 else
2198 defining->nparam_max = readnum(tline->text, &j);
2199 if (j)
2200 error(ERR_NONFATAL,
2201 "unable to parse parameter count `%s'",
2202 tline->text);
2203 if (defining->nparam_min > defining->nparam_max)
2204 error(ERR_NONFATAL,
2205 "minimum parameter count exceeds maximum");
2208 if (tline && tok_is_(tline->next, "+"))
2210 tline = tline->next;
2211 defining->plus = TRUE;
2213 if (tline && tok_type_(tline->next, TOK_ID) &&
2214 !nasm_stricmp(tline->next->text, ".nolist"))
2216 tline = tline->next;
2217 defining->nolist = TRUE;
2219 mmac = mmacros[hash(defining->name)];
2220 while (mmac)
2222 if (!strcmp(mmac->name, defining->name) &&
2223 (mmac->nparam_min <= defining->nparam_max
2224 || defining->plus)
2225 && (defining->nparam_min <= mmac->nparam_max
2226 || mmac->plus))
2228 error(ERR_WARNING,
2229 "redefining multi-line macro `%s'",
2230 defining->name);
2231 break;
2233 mmac = mmac->next;
2236 * Handle default parameters.
2238 if (tline && tline->next)
2240 defining->dlist = tline->next;
2241 tline->next = NULL;
2242 count_mmac_params(defining->dlist, &defining->ndefs,
2243 &defining->defaults);
2245 else
2247 defining->dlist = NULL;
2248 defining->defaults = NULL;
2250 defining->expansion = NULL;
2251 free_tlist(origline);
2252 return 1;
2254 case PP_ENDM:
2255 case PP_ENDMACRO:
2256 if (!defining)
2258 error(ERR_NONFATAL, "`%s': not defining a macro",
2259 tline->text);
2260 return 3;
2262 k = hash(defining->name);
2263 defining->next = mmacros[k];
2264 mmacros[k] = defining;
2265 defining = NULL;
2266 free_tlist(origline);
2267 return 5;
2269 case PP_ROTATE:
2270 if (tline->next && tline->next->type == TOK_WHITESPACE)
2271 tline = tline->next;
2272 t = expand_smacro(tline->next);
2273 tline->next = NULL;
2274 free_tlist(origline);
2275 tline = t;
2276 tptr = &t;
2277 tokval.t_type = TOKEN_INVALID;
2278 evalresult =
2279 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2280 free_tlist(tline);
2281 if (!evalresult)
2282 return 3;
2283 if (tokval.t_type)
2284 error(ERR_WARNING,
2285 "trailing garbage after expression ignored");
2286 if (!is_simple(evalresult))
2288 error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
2289 return 3;
2291 mmac = istk->mstk;
2292 while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
2293 mmac = mmac->next_active;
2294 if (!mmac)
2295 error(ERR_NONFATAL,
2296 "`%%rotate' invoked outside a macro call");
2297 mmac->rotate = mmac->rotate + reloc_value(evalresult);
2298 if (mmac->rotate < 0)
2299 mmac->rotate = mmac->nparam - (-mmac->rotate) % mmac->nparam;
2300 mmac->rotate %= mmac->nparam;
2301 return 1;
2303 case PP_REP:
2304 nolist = FALSE;
2305 tline = tline->next;
2306 if (tline->next && tline->next->type == TOK_WHITESPACE)
2307 tline = tline->next;
2308 if (tline->next && tline->next->type == TOK_ID &&
2309 !nasm_stricmp(tline->next->text, ".nolist"))
2311 tline = tline->next;
2312 nolist = TRUE;
2314 t = expand_smacro(tline->next);
2315 tline->next = NULL;
2316 free_tlist(origline);
2317 tline = t;
2318 tptr = &t;
2319 tokval.t_type = TOKEN_INVALID;
2320 evalresult =
2321 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2322 free_tlist(tline);
2323 if (!evalresult)
2324 return 3;
2325 if (tokval.t_type)
2326 error(ERR_WARNING,
2327 "trailing garbage after expression ignored");
2328 if (!is_simple(evalresult))
2330 error(ERR_NONFATAL, "non-constant value given to `%%rep'");
2331 return 3;
2333 tmp_defining = defining;
2334 defining = nasm_malloc(sizeof(MMacro));
2335 defining->name = NULL; /* flags this macro as a %rep block */
2336 defining->casesense = 0;
2337 defining->plus = FALSE;
2338 defining->nolist = nolist;
2339 defining->in_progress = reloc_value(evalresult) + 1;
2340 defining->nparam_min = defining->nparam_max = 0;
2341 defining->defaults = NULL;
2342 defining->dlist = NULL;
2343 defining->expansion = NULL;
2344 defining->next_active = istk->mstk;
2345 defining->rep_nest = tmp_defining;
2346 return 1;
2348 case PP_ENDREP:
2349 if (!defining || defining->name)
2351 error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
2352 return 3;
2356 * Now we have a "macro" defined - although it has no name
2357 * and we won't be entering it in the hash tables - we must
2358 * push a macro-end marker for it on to istk->expansion.
2359 * After that, it will take care of propagating itself (a
2360 * macro-end marker line for a macro which is really a %rep
2361 * block will cause the macro to be re-expanded, complete
2362 * with another macro-end marker to ensure the process
2363 * continues) until the whole expansion is forcibly removed
2364 * from istk->expansion by a %exitrep.
2366 l = nasm_malloc(sizeof(Line));
2367 l->next = istk->expansion;
2368 l->finishes = defining;
2369 l->first = NULL;
2370 istk->expansion = l;
2372 istk->mstk = defining;
2374 list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
2375 tmp_defining = defining;
2376 defining = defining->rep_nest;
2377 free_tlist(origline);
2378 return 1;
2380 case PP_EXITREP:
2382 * We must search along istk->expansion until we hit a
2383 * macro-end marker for a macro with no name. Then we set
2384 * its `in_progress' flag to 0.
2386 for (l = istk->expansion; l; l = l->next)
2387 if (l->finishes && !l->finishes->name)
2388 break;
2390 if (l)
2391 l->finishes->in_progress = 0;
2392 else
2393 error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
2394 free_tlist(origline);
2395 return 1;
2397 case PP_XDEFINE:
2398 case PP_IXDEFINE:
2399 case PP_DEFINE:
2400 case PP_IDEFINE:
2401 tline = tline->next;
2402 skip_white_(tline);
2403 tline = expand_id(tline);
2404 if (!tline || (tline->type != TOK_ID &&
2405 (tline->type != TOK_PREPROC_ID ||
2406 tline->text[1] != '$')))
2408 error(ERR_NONFATAL,
2409 "`%%%s%sdefine' expects a macro identifier",
2410 ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""),
2411 ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : ""));
2412 free_tlist(origline);
2413 return 3;
2416 ctx = get_ctx(tline->text, FALSE);
2417 if (!ctx)
2418 smhead = &smacros[hash(tline->text)];
2419 else
2420 smhead = &ctx->localmac;
2421 mname = tline->text;
2422 last = tline;
2423 param_start = tline = tline->next;
2424 nparam = 0;
2426 /* Expand the macro definition now for %xdefine and %ixdefine */
2427 if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
2428 tline = expand_smacro(tline);
2430 if (tok_is_(tline, "("))
2433 * This macro has parameters.
2436 tline = tline->next;
2437 while (1)
2439 skip_white_(tline);
2440 if (!tline)
2442 error(ERR_NONFATAL, "parameter identifier expected");
2443 free_tlist(origline);
2444 return 3;
2446 if (tline->type != TOK_ID)
2448 error(ERR_NONFATAL,
2449 "`%s': parameter identifier expected",
2450 tline->text);
2451 free_tlist(origline);
2452 return 3;
2454 tline->type = TOK_SMAC_PARAM + nparam++;
2455 tline = tline->next;
2456 skip_white_(tline);
2457 if (tok_is_(tline, ","))
2459 tline = tline->next;
2460 continue;
2462 if (!tok_is_(tline, ")"))
2464 error(ERR_NONFATAL,
2465 "`)' expected to terminate macro template");
2466 free_tlist(origline);
2467 return 3;
2469 break;
2471 last = tline;
2472 tline = tline->next;
2474 if (tok_type_(tline, TOK_WHITESPACE))
2475 last = tline, tline = tline->next;
2476 macro_start = NULL;
2477 last->next = NULL;
2478 t = tline;
2479 while (t)
2481 if (t->type == TOK_ID)
2483 for (tt = param_start; tt; tt = tt->next)
2484 if (tt->type >= TOK_SMAC_PARAM &&
2485 !strcmp(tt->text, t->text))
2486 t->type = tt->type;
2488 tt = t->next;
2489 t->next = macro_start;
2490 macro_start = t;
2491 t = tt;
2494 * Good. We now have a macro name, a parameter count, and a
2495 * token list (in reverse order) for an expansion. We ought
2496 * to be OK just to create an SMacro, store it, and let
2497 * free_tlist have the rest of the line (which we have
2498 * carefully re-terminated after chopping off the expansion
2499 * from the end).
2501 if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE))
2503 if (!smac)
2505 error(ERR_WARNING,
2506 "single-line macro `%s' defined both with and"
2507 " without parameters", mname);
2508 free_tlist(origline);
2509 free_tlist(macro_start);
2510 return 3;
2512 else
2515 * We're redefining, so we have to take over an
2516 * existing SMacro structure. This means freeing
2517 * what was already in it.
2519 nasm_free(smac->name);
2520 free_tlist(smac->expansion);
2523 else
2525 smac = nasm_malloc(sizeof(SMacro));
2526 smac->next = *smhead;
2527 *smhead = smac;
2529 smac->name = nasm_strdup(mname);
2530 smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE));
2531 smac->nparam = nparam;
2532 smac->expansion = macro_start;
2533 smac->in_progress = FALSE;
2534 free_tlist(origline);
2535 return 3;
2537 case PP_UNDEF:
2538 tline = tline->next;
2539 skip_white_(tline);
2540 tline = expand_id(tline);
2541 if (!tline || (tline->type != TOK_ID &&
2542 (tline->type != TOK_PREPROC_ID ||
2543 tline->text[1] != '$')))
2545 error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
2546 free_tlist(origline);
2547 return 3;
2549 if (tline->next)
2551 error(ERR_WARNING,
2552 "trailing garbage after macro name ignored");
2555 /* Find the context that symbol belongs to */
2556 ctx = get_ctx(tline->text, FALSE);
2557 if (!ctx)
2558 smhead = &smacros[hash(tline->text)];
2559 else
2560 smhead = &ctx->localmac;
2562 mname = tline->text;
2563 last = tline;
2564 last->next = NULL;
2567 * We now have a macro name... go hunt for it.
2569 while (smacro_defined(ctx, mname, -1, &smac, 1))
2571 /* Defined, so we need to find its predecessor and nuke it */
2572 SMacro **s;
2573 for (s = smhead; *s && *s != smac; s = &(*s)->next);
2574 if (*s)
2576 *s = smac->next;
2577 nasm_free(smac->name);
2578 free_tlist(smac->expansion);
2579 nasm_free(smac);
2582 free_tlist(origline);
2583 return 3;
2585 case PP_STRLEN:
2586 tline = tline->next;
2587 skip_white_(tline);
2588 tline = expand_id(tline);
2589 if (!tline || (tline->type != TOK_ID &&
2590 (tline->type != TOK_PREPROC_ID ||
2591 tline->text[1] != '$')))
2593 error(ERR_NONFATAL,
2594 "`%%strlen' expects a macro identifier as first parameter");
2595 free_tlist(origline);
2596 return 3;
2598 ctx = get_ctx(tline->text, FALSE);
2599 if (!ctx)
2600 smhead = &smacros[hash(tline->text)];
2601 else
2602 smhead = &ctx->localmac;
2603 mname = tline->text;
2604 last = tline;
2605 tline = expand_smacro(tline->next);
2606 last->next = NULL;
2608 t = tline;
2609 while (tok_type_(t, TOK_WHITESPACE))
2610 t = t->next;
2611 /* t should now point to the string */
2612 if (t->type != TOK_STRING)
2614 error(ERR_NONFATAL,
2615 "`%%strlen` requires string as second parameter");
2616 free_tlist(tline);
2617 free_tlist(origline);
2618 return 3;
2621 macro_start = nasm_malloc(sizeof(*macro_start));
2622 macro_start->next = NULL;
2623 make_tok_num(macro_start, strlen(t->text) - 2);
2624 macro_start->mac = NULL;
2627 * We now have a macro name, an implicit parameter count of
2628 * zero, and a numeric token to use as an expansion. Create
2629 * and store an SMacro.
2631 if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN))
2633 if (!smac)
2634 error(ERR_WARNING,
2635 "single-line macro `%s' defined both with and"
2636 " without parameters", mname);
2637 else
2640 * We're redefining, so we have to take over an
2641 * existing SMacro structure. This means freeing
2642 * what was already in it.
2644 nasm_free(smac->name);
2645 free_tlist(smac->expansion);
2648 else
2650 smac = nasm_malloc(sizeof(SMacro));
2651 smac->next = *smhead;
2652 *smhead = smac;
2654 smac->name = nasm_strdup(mname);
2655 smac->casesense = (i == PP_STRLEN);
2656 smac->nparam = 0;
2657 smac->expansion = macro_start;
2658 smac->in_progress = FALSE;
2659 free_tlist(tline);
2660 free_tlist(origline);
2661 return 3;
2663 case PP_SUBSTR:
2664 tline = tline->next;
2665 skip_white_(tline);
2666 tline = expand_id(tline);
2667 if (!tline || (tline->type != TOK_ID &&
2668 (tline->type != TOK_PREPROC_ID ||
2669 tline->text[1] != '$')))
2671 error(ERR_NONFATAL,
2672 "`%%substr' expects a macro identifier as first parameter");
2673 free_tlist(origline);
2674 return 3;
2676 ctx = get_ctx(tline->text, FALSE);
2677 if (!ctx)
2678 smhead = &smacros[hash(tline->text)];
2679 else
2680 smhead = &ctx->localmac;
2681 mname = tline->text;
2682 last = tline;
2683 tline = expand_smacro(tline->next);
2684 last->next = NULL;
2686 t = tline->next;
2687 while (tok_type_(t, TOK_WHITESPACE))
2688 t = t->next;
2690 /* t should now point to the string */
2691 if (t->type != TOK_STRING)
2693 error(ERR_NONFATAL,
2694 "`%%substr` requires string as second parameter");
2695 free_tlist(tline);
2696 free_tlist(origline);
2697 return 3;
2700 tt = t->next;
2701 tptr = &tt;
2702 tokval.t_type = TOKEN_INVALID;
2703 evalresult =
2704 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2705 if (!evalresult)
2707 free_tlist(tline);
2708 free_tlist(origline);
2709 return 3;
2711 if (!is_simple(evalresult))
2713 error(ERR_NONFATAL, "non-constant value given to `%%substr`");
2714 free_tlist(tline);
2715 free_tlist(origline);
2716 return 3;
2719 macro_start = nasm_malloc(sizeof(*macro_start));
2720 macro_start->next = NULL;
2721 macro_start->text = nasm_strdup("'''");
2722 if (evalresult->value > 0
2723 && evalresult->value < strlen(t->text) - 1)
2725 macro_start->text[1] = t->text[evalresult->value];
2727 else
2729 macro_start->text[2] = '\0';
2731 macro_start->type = TOK_STRING;
2732 macro_start->mac = NULL;
2735 * We now have a macro name, an implicit parameter count of
2736 * zero, and a numeric token to use as an expansion. Create
2737 * and store an SMacro.
2739 if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR))
2741 if (!smac)
2742 error(ERR_WARNING,
2743 "single-line macro `%s' defined both with and"
2744 " without parameters", mname);
2745 else
2748 * We're redefining, so we have to take over an
2749 * existing SMacro structure. This means freeing
2750 * what was already in it.
2752 nasm_free(smac->name);
2753 free_tlist(smac->expansion);
2756 else
2758 smac = nasm_malloc(sizeof(SMacro));
2759 smac->next = *smhead;
2760 *smhead = smac;
2762 smac->name = nasm_strdup(mname);
2763 smac->casesense = (i == PP_SUBSTR);
2764 smac->nparam = 0;
2765 smac->expansion = macro_start;
2766 smac->in_progress = FALSE;
2767 free_tlist(tline);
2768 free_tlist(origline);
2769 return 3;
2772 case PP_ASSIGN:
2773 case PP_IASSIGN:
2774 tline = tline->next;
2775 skip_white_(tline);
2776 tline = expand_id(tline);
2777 if (!tline || (tline->type != TOK_ID &&
2778 (tline->type != TOK_PREPROC_ID ||
2779 tline->text[1] != '$')))
2781 error(ERR_NONFATAL,
2782 "`%%%sassign' expects a macro identifier",
2783 (i == PP_IASSIGN ? "i" : ""));
2784 free_tlist(origline);
2785 return 3;
2787 ctx = get_ctx(tline->text, FALSE);
2788 if (!ctx)
2789 smhead = &smacros[hash(tline->text)];
2790 else
2791 smhead = &ctx->localmac;
2792 mname = tline->text;
2793 last = tline;
2794 tline = expand_smacro(tline->next);
2795 last->next = NULL;
2797 t = tline;
2798 tptr = &t;
2799 tokval.t_type = TOKEN_INVALID;
2800 evalresult =
2801 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2802 free_tlist(tline);
2803 if (!evalresult)
2805 free_tlist(origline);
2806 return 3;
2809 if (tokval.t_type)
2810 error(ERR_WARNING,
2811 "trailing garbage after expression ignored");
2813 if (!is_simple(evalresult))
2815 error(ERR_NONFATAL,
2816 "non-constant value given to `%%%sassign'",
2817 (i == PP_IASSIGN ? "i" : ""));
2818 free_tlist(origline);
2819 return 3;
2822 macro_start = nasm_malloc(sizeof(*macro_start));
2823 macro_start->next = NULL;
2824 make_tok_num(macro_start, reloc_value(evalresult));
2825 macro_start->mac = NULL;
2828 * We now have a macro name, an implicit parameter count of
2829 * zero, and a numeric token to use as an expansion. Create
2830 * and store an SMacro.
2832 if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN))
2834 if (!smac)
2835 error(ERR_WARNING,
2836 "single-line macro `%s' defined both with and"
2837 " without parameters", mname);
2838 else
2841 * We're redefining, so we have to take over an
2842 * existing SMacro structure. This means freeing
2843 * what was already in it.
2845 nasm_free(smac->name);
2846 free_tlist(smac->expansion);
2849 else
2851 smac = nasm_malloc(sizeof(SMacro));
2852 smac->next = *smhead;
2853 *smhead = smac;
2855 smac->name = nasm_strdup(mname);
2856 smac->casesense = (i == PP_ASSIGN);
2857 smac->nparam = 0;
2858 smac->expansion = macro_start;
2859 smac->in_progress = FALSE;
2860 free_tlist(origline);
2861 return 3;
2863 case PP_LINE:
2865 * Syntax is `%line nnn[+mmm] [filename]'
2867 tline = tline->next;
2868 skip_white_(tline);
2869 if (!tok_type_(tline, TOK_NUMBER))
2871 error(ERR_NONFATAL, "`%%line' expects line number");
2872 free_tlist(origline);
2873 return 3;
2875 k = readnum(tline->text, &j);
2876 m = 1;
2877 tline = tline->next;
2878 if (tok_is_(tline, "+"))
2880 tline = tline->next;
2881 if (!tok_type_(tline, TOK_NUMBER))
2883 error(ERR_NONFATAL, "`%%line' expects line increment");
2884 free_tlist(origline);
2885 return 3;
2887 m = readnum(tline->text, &j);
2888 tline = tline->next;
2890 skip_white_(tline);
2891 src_set_linnum(k);
2892 istk->lineinc = m;
2893 if (tline)
2895 nasm_free(src_set_fname(detoken(tline, FALSE)));
2897 free_tlist(origline);
2898 return 5;
2900 default:
2901 error(ERR_FATAL,
2902 "preprocessor directive `%s' not yet implemented",
2903 directives[i]);
2904 break;
2906 return 3;
2910 * Ensure that a macro parameter contains a condition code and
2911 * nothing else. Return the condition code index if so, or -1
2912 * otherwise.
2914 static int
2915 find_cc(Token * t)
2917 Token *tt;
2918 int i, j, k, m;
2920 skip_white_(t);
2921 if (t->type != TOK_ID)
2922 return -1;
2923 tt = t->next;
2924 skip_white_(tt);
2925 if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
2926 return -1;
2928 i = -1;
2929 j = sizeof(conditions) / sizeof(*conditions);
2930 while (j - i > 1)
2932 k = (j + i) / 2;
2933 m = nasm_stricmp(t->text, conditions[k]);
2934 if (m == 0)
2936 i = k;
2937 j = -2;
2938 break;
2940 else if (m < 0)
2942 j = k;
2944 else
2945 i = k;
2947 if (j != -2)
2948 return -1;
2949 return i;
2953 * Expand MMacro-local things: parameter references (%0, %n, %+n,
2954 * %-n) and MMacro-local identifiers (%%foo).
2956 static Token *
2957 expand_mmac_params(Token * tline)
2959 Token *t, *tt, **tail, *thead;
2961 tail = &thead;
2962 thead = NULL;
2964 while (tline)
2966 if (tline->type == TOK_PREPROC_ID &&
2967 (((tline->text[1] == '+' || tline->text[1] == '-')
2968 && tline->text[2]) || tline->text[1] == '%'
2969 || (tline->text[1] >= '0' && tline->text[1] <= '9')))
2971 char *text = NULL;
2972 int type = 0, cc; /* type = 0 to placate optimisers */
2973 char tmpbuf[30];
2974 int n, i;
2975 MMacro *mac;
2977 t = tline;
2978 tline = tline->next;
2980 mac = istk->mstk;
2981 while (mac && !mac->name) /* avoid mistaking %reps for macros */
2982 mac = mac->next_active;
2983 if (!mac)
2984 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
2985 else
2986 switch (t->text[1])
2989 * We have to make a substitution of one of the
2990 * forms %1, %-1, %+1, %%foo, %0.
2992 case '0':
2993 type = TOK_NUMBER;
2994 sprintf(tmpbuf, "%d", mac->nparam);
2995 text = nasm_strdup(tmpbuf);
2996 break;
2997 case '%':
2998 type = TOK_ID;
2999 sprintf(tmpbuf, "..@%lu.", mac->unique);
3000 text = nasm_strcat(tmpbuf, t->text + 2);
3001 break;
3002 case '-':
3003 n = atoi(t->text + 2) - 1;
3004 if (n >= mac->nparam)
3005 tt = NULL;
3006 else
3008 if (mac->nparam > 1)
3009 n = (n + mac->rotate) % mac->nparam;
3010 tt = mac->params[n];
3012 cc = find_cc(tt);
3013 if (cc == -1)
3015 error(ERR_NONFATAL,
3016 "macro parameter %d is not a condition code",
3017 n + 1);
3018 text = NULL;
3020 else
3022 type = TOK_ID;
3023 if (inverse_ccs[cc] == -1)
3025 error(ERR_NONFATAL,
3026 "condition code `%s' is not invertible",
3027 conditions[cc]);
3028 text = NULL;
3030 else
3031 text =
3032 nasm_strdup(conditions[inverse_ccs
3033 [cc]]);
3035 break;
3036 case '+':
3037 n = atoi(t->text + 2) - 1;
3038 if (n >= mac->nparam)
3039 tt = NULL;
3040 else
3042 if (mac->nparam > 1)
3043 n = (n + mac->rotate) % mac->nparam;
3044 tt = mac->params[n];
3046 cc = find_cc(tt);
3047 if (cc == -1)
3049 error(ERR_NONFATAL,
3050 "macro parameter %d is not a condition code",
3051 n + 1);
3052 text = NULL;
3054 else
3056 type = TOK_ID;
3057 text = nasm_strdup(conditions[cc]);
3059 break;
3060 default:
3061 n = atoi(t->text + 1) - 1;
3062 if (n >= mac->nparam)
3063 tt = NULL;
3064 else
3066 if (mac->nparam > 1)
3067 n = (n + mac->rotate) % mac->nparam;
3068 tt = mac->params[n];
3070 if (tt)
3072 for (i = 0; i < mac->paramlen[n]; i++)
3074 *tail =
3075 new_Token(NULL, tt->type, tt->text,
3077 tail = &(*tail)->next;
3078 tt = tt->next;
3081 text = NULL; /* we've done it here */
3082 break;
3084 if (!text)
3086 delete_Token(t);
3088 else
3090 *tail = t;
3091 tail = &t->next;
3092 t->type = type;
3093 nasm_free(t->text);
3094 t->text = text;
3095 t->mac = NULL;
3097 continue;
3099 else
3101 t = *tail = tline;
3102 tline = tline->next;
3103 t->mac = NULL;
3104 tail = &t->next;
3107 *tail = NULL;
3108 t = thead;
3109 for (; t && (tt = t->next) != NULL; t = t->next)
3110 switch (t->type)
3112 case TOK_WHITESPACE:
3113 if (tt->type == TOK_WHITESPACE)
3115 t->next = delete_Token(tt);
3117 break;
3118 case TOK_ID:
3119 if (tt->type == TOK_ID || tt->type == TOK_NUMBER)
3121 char *tmp = nasm_strcat(t->text, tt->text);
3122 nasm_free(t->text);
3123 t->text = tmp;
3124 t->next = delete_Token(tt);
3126 break;
3127 case TOK_NUMBER:
3128 if (tt->type == TOK_NUMBER)
3130 char *tmp = nasm_strcat(t->text, tt->text);
3131 nasm_free(t->text);
3132 t->text = tmp;
3133 t->next = delete_Token(tt);
3135 break;
3138 return thead;
3142 * Expand all single-line macro calls made in the given line.
3143 * Return the expanded version of the line. The original is deemed
3144 * to be destroyed in the process. (In reality we'll just move
3145 * Tokens from input to output a lot of the time, rather than
3146 * actually bothering to destroy and replicate.)
3148 static Token *
3149 expand_smacro(Token * tline)
3151 Token *t, *tt, *mstart, **tail, *thead;
3152 SMacro *head = NULL, *m;
3153 Token **params;
3154 int *paramsize;
3155 int nparam, sparam, brackets, rescan;
3156 Token *org_tline = tline;
3157 Context *ctx;
3158 char *mname;
3161 * Trick: we should avoid changing the start token pointer since it can
3162 * be contained in "next" field of other token. Because of this
3163 * we allocate a copy of first token and work with it; at the end of
3164 * routine we copy it back
3166 if (org_tline)
3168 tline =
3169 new_Token(org_tline->next, org_tline->type, org_tline->text,
3171 tline->mac = org_tline->mac;
3174 again:
3175 tail = &thead;
3176 thead = NULL;
3178 while (tline)
3179 { /* main token loop */
3180 if ((mname = tline->text))
3182 /* if this token is a local macro, look in local context */
3183 if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
3184 ctx = get_ctx(mname, TRUE);
3185 else
3186 ctx = NULL;
3187 if (!ctx)
3188 head = smacros[hash(mname)];
3189 else
3190 head = ctx->localmac;
3192 * We've hit an identifier. As in is_mmacro below, we first
3193 * check whether the identifier is a single-line macro at
3194 * all, then think about checking for parameters if
3195 * necessary.
3197 for (m = head; m; m = m->next)
3198 if (!mstrcmp(m->name, mname, m->casesense))
3199 break;
3200 if (m)
3202 mstart = tline;
3203 params = NULL;
3204 paramsize = NULL;
3205 if (m->nparam == 0)
3208 * Simple case: the macro is parameterless. Discard the
3209 * one token that the macro call took, and push the
3210 * expansion back on the to-do stack.
3212 if (!m->expansion)
3214 if (!strcmp("__FILE__", m->name))
3216 long num = 0;
3217 src_get(&num, &(tline->text));
3218 nasm_quote(&(tline->text));
3219 tline->type = TOK_STRING;
3220 continue;
3222 if (!strcmp("__LINE__", m->name))
3224 nasm_free(tline->text);
3225 make_tok_num(tline, src_get_linnum());
3226 continue;
3228 tline = delete_Token(tline);
3229 continue;
3232 else
3235 * Complicated case: at least one macro with this name
3236 * exists and takes parameters. We must find the
3237 * parameters in the call, count them, find the SMacro
3238 * that corresponds to that form of the macro call, and
3239 * substitute for the parameters when we expand. What a
3240 * pain.
3242 tline = tline->next;
3243 skip_white_(tline);
3244 if (!tok_is_(tline, "("))
3247 * This macro wasn't called with parameters: ignore
3248 * the call. (Behaviour borrowed from gnu cpp.)
3250 tline = mstart;
3251 m = NULL;
3253 else
3255 int paren = 0;
3256 int white = 0;
3257 brackets = 0;
3258 nparam = 0;
3259 tline = tline->next;
3260 sparam = PARAM_DELTA;
3261 params = nasm_malloc(sparam * sizeof(Token *));
3262 params[0] = tline;
3263 paramsize = nasm_malloc(sparam * sizeof(int));
3264 paramsize[0] = 0;
3265 for (;; tline = tline->next)
3266 { /* parameter loop */
3267 if (!tline)
3269 error(ERR_NONFATAL,
3270 "macro call expects terminating `)'");
3271 break;
3273 if (tline->type == TOK_WHITESPACE
3274 && brackets <= 0)
3276 if (paramsize[nparam])
3277 white++;
3278 else
3279 params[nparam] = tline->next;
3280 continue; /* parameter loop */
3282 if (tline->type == TOK_OTHER
3283 && tline->text[1] == 0)
3285 char ch = tline->text[0];
3286 if (ch == ',' && !paren && brackets <= 0)
3288 if (++nparam >= sparam)
3290 sparam += PARAM_DELTA;
3291 params = nasm_realloc(params,
3292 sparam * sizeof(Token *));
3293 paramsize = nasm_realloc(paramsize,
3294 sparam * sizeof(int));
3296 params[nparam] = tline->next;
3297 paramsize[nparam] = 0;
3298 white = 0;
3299 continue; /* parameter loop */
3301 if (ch == '{' &&
3302 (brackets > 0 || (brackets == 0 &&
3303 !paramsize[nparam])))
3305 if (!(brackets++))
3307 params[nparam] = tline->next;
3308 continue; /* parameter loop */
3311 if (ch == '}' && brackets > 0)
3312 if (--brackets == 0)
3314 brackets = -1;
3315 continue; /* parameter loop */
3317 if (ch == '(' && !brackets)
3318 paren++;
3319 if (ch == ')' && brackets <= 0)
3320 if (--paren < 0)
3321 break;
3323 if (brackets < 0)
3325 brackets = 0;
3326 error(ERR_NONFATAL, "braces do not "
3327 "enclose all of macro parameter");
3329 paramsize[nparam] += white + 1;
3330 white = 0;
3331 } /* parameter loop */
3332 nparam++;
3333 while (m && (m->nparam != nparam ||
3334 mstrcmp(m->name, mname,
3335 m->casesense)))
3336 m = m->next;
3337 if (!m)
3338 error(ERR_WARNING | ERR_WARN_MNP,
3339 "macro `%s' exists, "
3340 "but not taking %d parameters",
3341 mstart->text, nparam);
3344 if (m && m->in_progress)
3345 m = NULL;
3346 if (!m) /* in progess or didn't find '(' or wrong nparam */
3349 * Design question: should we handle !tline, which
3350 * indicates missing ')' here, or expand those
3351 * macros anyway, which requires the (t) test a few
3352 * lines down?
3354 nasm_free(params);
3355 nasm_free(paramsize);
3356 tline = mstart;
3358 else
3361 * Expand the macro: we are placed on the last token of the
3362 * call, so that we can easily split the call from the
3363 * following tokens. We also start by pushing an SMAC_END
3364 * token for the cycle removal.
3366 t = tline;
3367 if (t)
3369 tline = t->next;
3370 t->next = NULL;
3372 tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
3373 tt->mac = m;
3374 m->in_progress = TRUE;
3375 tline = tt;
3376 for (t = m->expansion; t; t = t->next)
3378 if (t->type >= TOK_SMAC_PARAM)
3380 Token *pcopy = tline, **ptail = &pcopy;
3381 Token *ttt, *pt;
3382 int i;
3384 ttt = params[t->type - TOK_SMAC_PARAM];
3385 for (i = paramsize[t->type - TOK_SMAC_PARAM];
3386 --i >= 0;)
3388 pt = *ptail =
3389 new_Token(tline, ttt->type, ttt->text,
3391 ptail = &pt->next;
3392 ttt = ttt->next;
3394 tline = pcopy;
3396 else
3398 tt = new_Token(tline, t->type, t->text, 0);
3399 tline = tt;
3404 * Having done that, get rid of the macro call, and clean
3405 * up the parameters.
3407 nasm_free(params);
3408 nasm_free(paramsize);
3409 free_tlist(mstart);
3410 continue; /* main token loop */
3415 if (tline->type == TOK_SMAC_END)
3417 tline->mac->in_progress = FALSE;
3418 tline = delete_Token(tline);
3420 else
3422 t = *tail = tline;
3423 tline = tline->next;
3424 t->mac = NULL;
3425 t->next = NULL;
3426 tail = &t->next;
3431 * Now scan the entire line and look for successive TOK_IDs that resulted
3432 * after expansion (they can't be produced by tokenise()). The successive
3433 * TOK_IDs should be concatenated.
3434 * Also we look for %+ tokens and concatenate the tokens before and after
3435 * them (without white spaces in between).
3437 t = thead;
3438 rescan = 0;
3439 while (t)
3441 while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
3442 t = t->next;
3443 if (!t || !t->next)
3444 break;
3445 if (t->next->type == TOK_ID ||
3446 t->next->type == TOK_PREPROC_ID ||
3447 t->next->type == TOK_NUMBER)
3449 char *p = nasm_strcat(t->text, t->next->text);
3450 nasm_free(t->text);
3451 t->next = delete_Token(t->next);
3452 t->text = p;
3453 rescan = 1;
3455 else if (t->next->type == TOK_WHITESPACE && t->next->next &&
3456 t->next->next->type == TOK_PREPROC_ID &&
3457 strcmp(t->next->next->text, "%+") == 0)
3459 /* free the next whitespace, the %+ token and next whitespace */
3460 int i;
3461 for (i = 1; i <= 3; i++)
3463 if (!t->next || (i != 2 && t->next->type != TOK_WHITESPACE))
3464 break;
3465 t->next = delete_Token(t->next);
3466 } /* endfor */
3468 else
3469 t = t->next;
3471 /* If we concatenaded something, re-scan the line for macros */
3472 if (rescan)
3474 tline = thead;
3475 goto again;
3478 if (org_tline)
3480 if (thead)
3482 *org_tline = *thead;
3483 /* since we just gave text to org_line, don't free it */
3484 thead->text = NULL;
3485 delete_Token(thead);
3487 else
3489 /* the expression expanded to empty line;
3490 we can't return NULL for some reasons
3491 we just set the line to a single WHITESPACE token. */
3492 memset(org_tline, 0, sizeof(*org_tline));
3493 org_tline->text = NULL;
3494 org_tline->type = TOK_WHITESPACE;
3496 thead = org_tline;
3499 return thead;
3503 * Similar to expand_smacro but used exclusively with macro identifiers
3504 * right before they are fetched in. The reason is that there can be
3505 * identifiers consisting of several subparts. We consider that if there
3506 * are more than one element forming the name, user wants a expansion,
3507 * otherwise it will be left as-is. Example:
3509 * %define %$abc cde
3511 * the identifier %$abc will be left as-is so that the handler for %define
3512 * will suck it and define the corresponding value. Other case:
3514 * %define _%$abc cde
3516 * In this case user wants name to be expanded *before* %define starts
3517 * working, so we'll expand %$abc into something (if it has a value;
3518 * otherwise it will be left as-is) then concatenate all successive
3519 * PP_IDs into one.
3521 static Token *
3522 expand_id(Token * tline)
3524 Token *cur, *oldnext = NULL;
3526 if (!tline || !tline->next)
3527 return tline;
3529 cur = tline;
3530 while (cur->next &&
3531 (cur->next->type == TOK_ID ||
3532 cur->next->type == TOK_PREPROC_ID || cur->next->type == TOK_NUMBER))
3533 cur = cur->next;
3535 /* If identifier consists of just one token, don't expand */
3536 if (cur == tline)
3537 return tline;
3539 if (cur)
3541 oldnext = cur->next; /* Detach the tail past identifier */
3542 cur->next = NULL; /* so that expand_smacro stops here */
3545 tline = expand_smacro(tline);
3547 if (cur)
3549 /* expand_smacro possibly changhed tline; re-scan for EOL */
3550 cur = tline;
3551 while (cur && cur->next)
3552 cur = cur->next;
3553 if (cur)
3554 cur->next = oldnext;
3557 return tline;
3561 * Determine whether the given line constitutes a multi-line macro
3562 * call, and return the MMacro structure called if so. Doesn't have
3563 * to check for an initial label - that's taken care of in
3564 * expand_mmacro - but must check numbers of parameters. Guaranteed
3565 * to be called with tline->type == TOK_ID, so the putative macro
3566 * name is easy to find.
3568 static MMacro *
3569 is_mmacro(Token * tline, Token *** params_array)
3571 MMacro *head, *m;
3572 Token **params;
3573 int nparam;
3575 head = mmacros[hash(tline->text)];
3578 * Efficiency: first we see if any macro exists with the given
3579 * name. If not, we can return NULL immediately. _Then_ we
3580 * count the parameters, and then we look further along the
3581 * list if necessary to find the proper MMacro.
3583 for (m = head; m; m = m->next)
3584 if (!mstrcmp(m->name, tline->text, m->casesense))
3585 break;
3586 if (!m)
3587 return NULL;
3590 * OK, we have a potential macro. Count and demarcate the
3591 * parameters.
3593 count_mmac_params(tline->next, &nparam, &params);
3596 * So we know how many parameters we've got. Find the MMacro
3597 * structure that handles this number.
3599 while (m)
3601 if (m->nparam_min <= nparam && (m->plus || nparam <= m->nparam_max))
3604 * This one is right. Just check if cycle removal
3605 * prohibits us using it before we actually celebrate...
3607 if (m->in_progress)
3609 #if 0
3610 error(ERR_NONFATAL,
3611 "self-reference in multi-line macro `%s'", m->name);
3612 #endif
3613 nasm_free(params);
3614 return NULL;
3617 * It's right, and we can use it. Add its default
3618 * parameters to the end of our list if necessary.
3620 if (m->defaults && nparam < m->nparam_min + m->ndefs)
3622 params =
3623 nasm_realloc(params,
3624 ((m->nparam_min + m->ndefs + 1) * sizeof(*params)));
3625 while (nparam < m->nparam_min + m->ndefs)
3627 params[nparam] = m->defaults[nparam - m->nparam_min];
3628 nparam++;
3632 * If we've gone over the maximum parameter count (and
3633 * we're in Plus mode), ignore parameters beyond
3634 * nparam_max.
3636 if (m->plus && nparam > m->nparam_max)
3637 nparam = m->nparam_max;
3639 * Then terminate the parameter list, and leave.
3641 if (!params)
3642 { /* need this special case */
3643 params = nasm_malloc(sizeof(*params));
3644 nparam = 0;
3646 params[nparam] = NULL;
3647 *params_array = params;
3648 return m;
3651 * This one wasn't right: look for the next one with the
3652 * same name.
3654 for (m = m->next; m; m = m->next)
3655 if (!mstrcmp(m->name, tline->text, m->casesense))
3656 break;
3660 * After all that, we didn't find one with the right number of
3661 * parameters. Issue a warning, and fail to expand the macro.
3663 error(ERR_WARNING | ERR_WARN_MNP,
3664 "macro `%s' exists, but not taking %d parameters",
3665 tline->text, nparam);
3666 nasm_free(params);
3667 return NULL;
3671 * Expand the multi-line macro call made by the given line, if
3672 * there is one to be expanded. If there is, push the expansion on
3673 * istk->expansion and return 1. Otherwise return 0.
3675 static int
3676 expand_mmacro(Token * tline)
3678 Token *startline = tline;
3679 Token *label = NULL;
3680 int dont_prepend = 0;
3681 Token **params, *t, *tt;
3682 MMacro *m;
3683 Line *l, *ll;
3684 int i, nparam, *paramlen;
3686 t = tline;
3687 skip_white_(t);
3688 if (!tok_type_(t, TOK_ID))
3689 return 0;
3690 m = is_mmacro(t, &params);
3691 if (!m)
3693 Token *last;
3695 * We have an id which isn't a macro call. We'll assume
3696 * it might be a label; we'll also check to see if a
3697 * colon follows it. Then, if there's another id after
3698 * that lot, we'll check it again for macro-hood.
3700 label = last = t;
3701 t = t->next;
3702 if (tok_type_(t, TOK_WHITESPACE))
3703 last = t, t = t->next;
3704 if (tok_is_(t, ":"))
3706 dont_prepend = 1;
3707 last = t, t = t->next;
3708 if (tok_type_(t, TOK_WHITESPACE))
3709 last = t, t = t->next;
3711 if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, &params)) == NULL)
3712 return 0;
3713 last->next = NULL;
3714 tline = t;
3718 * Fix up the parameters: this involves stripping leading and
3719 * trailing whitespace, then stripping braces if they are
3720 * present.
3722 for (nparam = 0; params[nparam]; nparam++)
3724 paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
3726 for (i = 0; params[i]; i++)
3728 int brace = FALSE;
3729 int comma = (!m->plus || i < nparam - 1);
3731 t = params[i];
3732 skip_white_(t);
3733 if (tok_is_(t, "{"))
3734 t = t->next, brace = TRUE, comma = FALSE;
3735 params[i] = t;
3736 paramlen[i] = 0;
3737 while (t)
3739 if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
3740 break; /* ... because we have hit a comma */
3741 if (comma && t->type == TOK_WHITESPACE && tok_is_(t->next, ","))
3742 break; /* ... or a space then a comma */
3743 if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
3744 break; /* ... or a brace */
3745 t = t->next;
3746 paramlen[i]++;
3751 * OK, we have a MMacro structure together with a set of
3752 * parameters. We must now go through the expansion and push
3753 * copies of each Line on to istk->expansion. Substitution of
3754 * parameter tokens and macro-local tokens doesn't get done
3755 * until the single-line macro substitution process; this is
3756 * because delaying them allows us to change the semantics
3757 * later through %rotate.
3759 * First, push an end marker on to istk->expansion, mark this
3760 * macro as in progress, and set up its invocation-specific
3761 * variables.
3763 ll = nasm_malloc(sizeof(Line));
3764 ll->next = istk->expansion;
3765 ll->finishes = m;
3766 ll->first = NULL;
3767 istk->expansion = ll;
3769 m->in_progress = TRUE;
3770 m->params = params;
3771 m->iline = tline;
3772 m->nparam = nparam;
3773 m->rotate = 0;
3774 m->paramlen = paramlen;
3775 m->unique = unique++;
3776 m->lineno = 0;
3778 m->next_active = istk->mstk;
3779 istk->mstk = m;
3781 for (l = m->expansion; l; l = l->next)
3783 Token **tail;
3785 ll = nasm_malloc(sizeof(Line));
3786 ll->finishes = NULL;
3787 ll->next = istk->expansion;
3788 istk->expansion = ll;
3789 tail = &ll->first;
3791 for (t = l->first; t; t = t->next)
3793 Token *x = t;
3794 if (t->type == TOK_PREPROC_ID &&
3795 t->text[1] == '0' && t->text[2] == '0')
3797 dont_prepend = -1;
3798 x = label;
3799 if (!x)
3800 continue;
3802 tt = *tail = new_Token(NULL, x->type, x->text, 0);
3803 tail = &tt->next;
3805 *tail = NULL;
3809 * If we had a label, push it on as the first line of
3810 * the macro expansion.
3812 if (label)
3814 if (dont_prepend < 0)
3815 free_tlist(startline);
3816 else
3818 ll = nasm_malloc(sizeof(Line));
3819 ll->finishes = NULL;
3820 ll->next = istk->expansion;
3821 istk->expansion = ll;
3822 ll->first = startline;
3823 if (!dont_prepend)
3825 while (label->next)
3826 label = label->next;
3827 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
3832 list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
3834 return 1;
3838 * Since preprocessor always operate only on the line that didn't
3839 * arrived yet, we should always use ERR_OFFBY1. Also since user
3840 * won't want to see same error twice (preprocessing is done once
3841 * per pass) we will want to show errors only during pass one.
3843 static void
3844 error(int severity, char *fmt, ...)
3846 va_list arg;
3847 char buff[1024];
3849 /* If we're in a dead branch of IF or something like it, ignore the error */
3850 if (istk->conds && !emitting(istk->conds->state))
3851 return;
3853 va_start(arg, fmt);
3854 vsprintf(buff, fmt, arg);
3855 va_end(arg);
3857 if (istk->mstk && istk->mstk->name)
3858 __error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
3859 istk->mstk->lineno, buff);
3860 else
3861 __error(severity | ERR_PASS1, "%s", buff);
3864 static void
3865 pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
3866 ListGen * listgen)
3868 int h;
3870 __error = errfunc;
3871 cstk = NULL;
3872 istk = nasm_malloc(sizeof(Include));
3873 istk->next = NULL;
3874 istk->conds = NULL;
3875 istk->expansion = NULL;
3876 istk->mstk = NULL;
3877 istk->fp = fopen(file, "r");
3878 istk->fname = NULL;
3879 src_set_fname(nasm_strdup(file));
3880 src_set_linnum(0);
3881 istk->lineinc = 1;
3882 if (!istk->fp)
3883 error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'", file);
3884 defining = NULL;
3885 for (h = 0; h < NHASH; h++)
3887 mmacros[h] = NULL;
3888 smacros[h] = NULL;
3890 unique = 0;
3891 if (tasm_compatible_mode) {
3892 stdmacpos = stdmac;
3893 } else {
3894 stdmacpos = &stdmac[TASM_MACRO_COUNT];
3896 any_extrastdmac = (extrastdmac != NULL);
3897 list = listgen;
3898 evaluate = eval;
3899 pass = apass;
3902 static char *
3903 pp_getline(void)
3905 char *line;
3906 Token *tline;
3908 while (1)
3911 * Fetch a tokenised line, either from the macro-expansion
3912 * buffer or from the input file.
3914 tline = NULL;
3915 while (istk->expansion && istk->expansion->finishes)
3917 Line *l = istk->expansion;
3918 if (!l->finishes->name && l->finishes->in_progress > 1)
3920 Line *ll;
3923 * This is a macro-end marker for a macro with no
3924 * name, which means it's not really a macro at all
3925 * but a %rep block, and the `in_progress' field is
3926 * more than 1, meaning that we still need to
3927 * repeat. (1 means the natural last repetition; 0
3928 * means termination by %exitrep.) We have
3929 * therefore expanded up to the %endrep, and must
3930 * push the whole block on to the expansion buffer
3931 * again. We don't bother to remove the macro-end
3932 * marker: we'd only have to generate another one
3933 * if we did.
3935 l->finishes->in_progress--;
3936 for (l = l->finishes->expansion; l; l = l->next)
3938 Token *t, *tt, **tail;
3940 ll = nasm_malloc(sizeof(Line));
3941 ll->next = istk->expansion;
3942 ll->finishes = NULL;
3943 ll->first = NULL;
3944 tail = &ll->first;
3946 for (t = l->first; t; t = t->next)
3948 if (t->text || t->type == TOK_WHITESPACE)
3950 tt = *tail = new_Token(NULL, t->type, t->text, 0);
3951 tail = &tt->next;
3955 istk->expansion = ll;
3958 else
3961 * Check whether a `%rep' was started and not ended
3962 * within this macro expansion. This can happen and
3963 * should be detected. It's a fatal error because
3964 * I'm too confused to work out how to recover
3965 * sensibly from it.
3967 if (defining)
3969 if (defining->name)
3970 error(ERR_PANIC, "defining with name in expansion");
3971 else if (istk->mstk->name)
3972 error(ERR_FATAL, "`%%rep' without `%%endrep' within"
3973 " expansion of macro `%s'", istk->mstk->name);
3977 * FIXME: investigate the relationship at this point between
3978 * istk->mstk and l->finishes
3981 MMacro *m = istk->mstk;
3982 istk->mstk = m->next_active;
3983 if (m->name)
3986 * This was a real macro call, not a %rep, and
3987 * therefore the parameter information needs to
3988 * be freed.
3990 nasm_free(m->params);
3991 free_tlist(m->iline);
3992 nasm_free(m->paramlen);
3993 l->finishes->in_progress = FALSE;
3995 else
3996 free_mmacro(m);
3998 istk->expansion = l->next;
3999 nasm_free(l);
4000 list->downlevel(LIST_MACRO);
4003 while (1)
4004 { /* until we get a line we can use */
4006 if (istk->expansion)
4007 { /* from a macro expansion */
4008 char *p;
4009 Line *l = istk->expansion;
4010 if (istk->mstk)
4011 istk->mstk->lineno++;
4012 tline = l->first;
4013 istk->expansion = l->next;
4014 nasm_free(l);
4015 p = detoken(tline, FALSE);
4016 list->line(LIST_MACRO, p);
4017 nasm_free(p);
4018 break;
4020 line = read_line();
4021 if (line)
4022 { /* from the current input file */
4023 line = prepreproc(line);
4024 tline = tokenise(line);
4025 nasm_free(line);
4026 break;
4029 * The current file has ended; work down the istk
4032 Include *i = istk;
4033 fclose(i->fp);
4034 if (i->conds)
4035 error(ERR_FATAL, "expected `%%endif' before end of file");
4036 istk = i->next;
4037 list->downlevel(LIST_INCLUDE);
4038 src_set_linnum(i->lineno);
4039 nasm_free(src_set_fname(i->fname));
4040 nasm_free(i);
4041 if (!istk)
4042 return NULL;
4047 * We must expand MMacro parameters and MMacro-local labels
4048 * _before_ we plunge into directive processing, to cope
4049 * with things like `%define something %1' such as STRUC
4050 * uses. Unless we're _defining_ a MMacro, in which case
4051 * those tokens should be left alone to go into the
4052 * definition; and unless we're in a non-emitting
4053 * condition, in which case we don't want to meddle with
4054 * anything.
4056 if (!defining && !(istk->conds && !emitting(istk->conds->state)))
4057 tline = expand_mmac_params(tline);
4060 * Check the line to see if it's a preprocessor directive.
4062 if (do_directive(tline) & 1)
4064 continue;
4066 else if (defining)
4069 * We're defining a multi-line macro. We emit nothing
4070 * at all, and just
4071 * shove the tokenised line on to the macro definition.
4073 Line *l = nasm_malloc(sizeof(Line));
4074 l->next = defining->expansion;
4075 l->first = tline;
4076 l->finishes = FALSE;
4077 defining->expansion = l;
4078 continue;
4080 else if (istk->conds && !emitting(istk->conds->state))
4083 * We're in a non-emitting branch of a condition block.
4084 * Emit nothing at all, not even a blank line: when we
4085 * emerge from the condition we'll give a line-number
4086 * directive so we keep our place correctly.
4088 free_tlist(tline);
4089 continue;
4091 else if (istk->mstk && !istk->mstk->in_progress)
4094 * We're in a %rep block which has been terminated, so
4095 * we're walking through to the %endrep without
4096 * emitting anything. Emit nothing at all, not even a
4097 * blank line: when we emerge from the %rep block we'll
4098 * give a line-number directive so we keep our place
4099 * correctly.
4101 free_tlist(tline);
4102 continue;
4104 else
4106 tline = expand_smacro(tline);
4107 if (!expand_mmacro(tline))
4110 * De-tokenise the line again, and emit it.
4112 line = detoken(tline, TRUE);
4113 free_tlist(tline);
4114 break;
4116 else
4118 continue; /* expand_mmacro calls free_tlist */
4123 return line;
4126 static void
4127 pp_cleanup(void)
4129 int h;
4131 if (defining)
4133 error(ERR_NONFATAL, "end of file while still defining macro `%s'",
4134 defining->name);
4135 free_mmacro(defining);
4137 while (cstk)
4138 ctx_pop();
4139 for (h = 0; h < NHASH; h++)
4141 while (mmacros[h])
4143 MMacro *m = mmacros[h];
4144 mmacros[h] = mmacros[h]->next;
4145 free_mmacro(m);
4147 while (smacros[h])
4149 SMacro *s = smacros[h];
4150 smacros[h] = smacros[h]->next;
4151 nasm_free(s->name);
4152 free_tlist(s->expansion);
4153 nasm_free(s);
4156 while (istk)
4158 Include *i = istk;
4159 istk = istk->next;
4160 fclose(i->fp);
4161 nasm_free(i->fname);
4162 nasm_free(i);
4164 while (cstk)
4165 ctx_pop();
4168 void
4169 pp_include_path(char *path)
4171 IncPath *i;
4173 i = nasm_malloc(sizeof(IncPath));
4174 i->path = nasm_strdup(path);
4175 i->next = ipath;
4176 ipath = i;
4179 void
4180 pp_pre_include(char *fname)
4182 Token *inc, *space, *name;
4183 Line *l;
4185 name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
4186 space = new_Token(name, TOK_WHITESPACE, NULL, 0);
4187 inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
4189 l = nasm_malloc(sizeof(Line));
4190 l->next = predef;
4191 l->first = inc;
4192 l->finishes = FALSE;
4193 predef = l;
4196 void
4197 pp_pre_define(char *definition)
4199 Token *def, *space;
4200 Line *l;
4201 char *equals;
4203 equals = strchr(definition, '=');
4204 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4205 def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
4206 if (equals)
4207 *equals = ' ';
4208 space->next = tokenise(definition);
4209 if (equals)
4210 *equals = '=';
4212 l = nasm_malloc(sizeof(Line));
4213 l->next = predef;
4214 l->first = def;
4215 l->finishes = FALSE;
4216 predef = l;
4219 void
4220 pp_pre_undefine(char *definition)
4222 Token *def, *space;
4223 Line *l;
4225 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4226 def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
4228 l = nasm_malloc(sizeof(Line));
4229 l->next = predef;
4230 l->first = def;
4231 l->finishes = FALSE;
4232 predef = l;
4235 void
4236 pp_extra_stdmac(char **macros)
4238 extrastdmac = macros;
4241 static void
4242 make_tok_num(Token * tok, long val)
4244 char numbuf[20];
4245 sprintf(numbuf, "%ld", val);
4246 tok->text = nasm_strdup(numbuf);
4247 tok->type = TOK_NUMBER;
4250 Preproc nasmpp = {
4251 pp_reset,
4252 pp_getline,
4253 pp_cleanup