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
20 typedef struct SMacro SMacro
;
21 typedef struct MMacro MMacro
;
22 typedef struct Context Context
;
23 typedef struct Token Token
;
24 typedef struct Line Line
;
25 typedef struct Include Include
;
26 typedef struct Cond Cond
;
29 * Store the definition of a single-line macro.
41 * Store the definition of a multi-line macro.
47 int nparam_min
, nparam_max
;
48 int plus
; /* is the last parameter greedy? */
50 Token
**defaults
, *dlist
;
55 * The context stack is composed of a linked list of these.
65 * This is the internal form which we break input lines up into.
66 * Typically stored in linked lists.
68 * TOK_PS_OTHER is a token type used internally within
69 * expand_smacro(), to denote a token which has already been
70 * checked for being a potential macro, but may still be a context-
73 * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
74 * necessarily used as-is, but is intended to denote the number of
75 * the substituted parameter. So in the definition
77 * %define a(x,y) ( (x) & ~(y) )
79 * the token representing `x' will have its type changed to
80 * TOK_SMAC_PARAM, but the one representing `y' will be
86 SMacro
*mac
; /* associated macro for TOK_MAC_END */
90 TOK_WHITESPACE
= 1, TOK_COMMENT
, TOK_ID
, TOK_PREPROC_ID
, TOK_STRING
,
91 TOK_NUMBER
, TOK_SMAC_END
, TOK_OTHER
, TOK_PS_OTHER
, TOK_SMAC_PARAM
95 * Multi-line macro definitions are stored as a linked list of
96 * these, which is essentially a container to allow several linked
99 * Note that in this module, linked lists are treated as stacks
100 * wherever possible. For this reason, Lines are _pushed_ on to the
101 * `expansion' field in MMacro structures, so that the linked list,
102 * if walked, would give the macro lines in reverse order; this
103 * means that we can walk the list when expanding a macro, and thus
104 * push the lines on to the `expansion' field in _istk_ in reverse
105 * order (so that when popped back off they are in the right
106 * order). It may seem cockeyed, and it relies on my design having
107 * an even number of steps in, but it works...
109 * Some of these structures, rather than being actual lines, are
110 * markers delimiting the end of the expansion of a given macro.
111 * This is for use in the cycle-tracking code. Such structures have
112 * `finishes' non-NULL, and `first' NULL. All others have
113 * `finishes' NULL, but `first' may still be non-NULL if the line
123 * To handle an arbitrary level of file inclusion, we maintain a
124 * stack (ie linked list) of these things.
136 * Conditional assembly: we maintain a separate stack of these for
137 * each level of file inclusion. (The only reason we keep the
138 * stacks separate is to ensure that a stray `%endif' in a file
139 * included from within the true branch of a `%if' won't terminate
140 * it and cause confusion: instead, rightly, it'll cause an error.)
148 * These states are for use just after %if or %elif: IF_TRUE
149 * means the condition has evaluated to truth so we are
150 * currently emitting, whereas IF_FALSE means we are not
151 * currently emitting but will start doing so if a %else comes
152 * up. In these states, all directives are admissible: %elif,
153 * %else and %endif. (And of course %if.)
155 COND_IF_TRUE
, COND_IF_FALSE
,
157 * These states come up after a %else: ELSE_TRUE means we're
158 * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
159 * any %elif or %else will cause an error.
161 COND_ELSE_TRUE
, COND_ELSE_FALSE
,
163 * This state means that we're not emitting now, and also that
164 * nothing until %endif will be emitted at all. It's for use in
165 * two circumstances: (i) when we've had our moment of emission
166 * and have now started seeing %elifs, and (ii) when the
167 * condition construct in question is contained within a
168 * non-emitting branch of a larger condition construct.
172 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
175 * Condition codes. Note that we use c_ prefix not C_ because C_ is
176 * used in nasm.h for the "real" condition codes. At _this_ level,
177 * we treat CXZ and ECXZ as condition codes, albeit non-invertible
178 * ones, so we need a different enum...
180 static char *conditions
[] = {
181 "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
182 "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
183 "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
186 c_A
, c_AE
, c_B
, c_BE
, c_C
, c_CXZ
, c_E
, c_ECXZ
, c_G
, c_GE
, c_L
, c_LE
,
187 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, c_NE
, c_NG
, c_NGE
, c_NL
, c_NLE
, c_NO
,
188 c_NP
, c_NS
, c_NZ
, c_O
, c_P
, c_PE
, c_PO
, c_S
, c_Z
190 static int inverse_ccs
[] = {
191 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, -1, c_NE
, -1, c_NG
, c_NGE
, c_NL
, c_NLE
,
192 c_A
, c_AE
, c_B
, c_BE
, c_C
, c_E
, c_G
, c_GE
, c_L
, c_LE
, c_O
, c_P
, c_S
,
193 c_Z
, c_NO
, c_NP
, c_PO
, c_PE
, c_NS
, c_NZ
196 static Context
*cstk
;
197 static Include
*istk
;
201 static unsigned long unique
; /* unique identifier numbers */
203 static char *linesync
, *outline
;
206 * The number of hash values we use for the macro lookup tables.
211 * The current set of multi-line macros we have defined.
213 static MMacro
*mmacros
[NHASH
];
216 * The current set of single-line macros we have defined.
218 static SMacro
*smacros
[NHASH
];
221 * The multi-line macro we are currently defining, if any.
223 static MMacro
*defining
;
226 * The number of macro parameters to allocate space for at a time.
228 #define PARAM_DELTA 16
231 * The standard macro set: defined as `static char *stdmac[]'. Also
232 * gives our position in the macro set, when we're processing it.
235 static char **stdmacpos
;
238 * The pre-preprocessing stage... This function has two purposes:
239 * firstly, it translates line number indications as they emerge
240 * from GNU cpp (`# lineno "file" flags') into NASM preprocessor
241 * line number indications (`%line lineno file'), and secondly, it
242 * converts [INCLUDE] and [INC] old-style inclusion directives into
243 * the new-style `%include' form (though in the next version it
244 * won't do that any more).
246 static char *prepreproc(char *line
) {
248 char *fname
, *oldline
;
250 if (line
[0] == '#' && line
[1] == ' ') {
253 lineno
= atoi(fname
);
254 fname
+= strspn(fname
, "0123456789 ");
257 fnlen
= strcspn(fname
, "\"");
258 line
= nasm_malloc(20+fnlen
);
259 sprintf(line
, "%%line %d %.*s", lineno
, fnlen
, fname
);
262 } else if (!nasm_strnicmp(line
, "[include", 8)) {
265 fname
+= strspn(fname
, " \t");
266 fnlen
= strcspn(fname
, "]");
267 line
= nasm_malloc(20+fnlen
);
268 sprintf(line
, "%%include \"%.*s\"", fnlen
, fname
);
269 error (ERR_WARNING
|ERR_OFFBY1
, "use of [INCLUDE] is being phased out;"
270 " suggest `%%include'");
273 } else if (!nasm_strnicmp(line
, "[inc", 4)) {
276 fname
+= strspn(fname
, " \t");
277 fnlen
= strcspn(fname
, "]");
278 line
= nasm_malloc(20+fnlen
);
279 sprintf(line
, "%%include \"%.*s\"", fnlen
, fname
);
280 error (ERR_WARNING
|ERR_OFFBY1
, "use of [INC] is being phased out;"
281 " suggest `%%include'");
289 * The hash function for macro lookups. Note that due to some
290 * macros having case-insensitive names, the hash function must be
291 * invariant under case changes. We implement this by applying a
292 * perfectly normal hash function to the uppercase of the string.
294 static int hash(char *s
) {
296 * Powers of three, mod 31.
298 static const int multipliers
[] = {
299 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
300 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
306 h
+= multipliers
[i
] * (unsigned char) (toupper(*s
));
308 if (++i
>= sizeof(multipliers
)/sizeof(*multipliers
))
316 * Free a linked list of tokens.
318 static void free_tlist (Token
*list
) {
329 * Free a linked list of lines.
331 static void free_llist (Line
*list
) {
336 free_tlist (l
->first
);
342 * Pop the context stack.
344 static void ctx_pop (void) {
354 free_tlist (s
->expansion
);
362 * Generate a line synchronisation comment, to ensure the assembler
363 * knows which source file the current output has really come from.
365 static void line_sync (void) {
367 sprintf(text
, "%%line %d+%d %s",
368 (istk
->expansion
? istk
->lineno
- istk
->lineinc
: istk
->lineno
),
369 (istk
->expansion
? 0 : istk
->lineinc
), istk
->fname
);
372 linesync
= nasm_strdup(text
);
375 #define BUF_DELTA 512
377 * Read a line from the top file in istk, handling multiple CR/LFs
378 * at the end of the line read, and handling spurious ^Zs. Will
379 * return lines from the standard macro set if this has not already
382 static char *read_line (void) {
383 char *buffer
, *p
, *q
;
388 return nasm_strdup(*stdmacpos
++);
396 buffer
= nasm_malloc(BUF_DELTA
);
399 q
= fgets(p
, bufsize
-(p
-buffer
), istk
->fp
);
403 if (p
> buffer
&& p
[-1] == '\n') {
404 istk
->lineno
+= istk
->lineinc
;
407 if (p
-buffer
> bufsize
-10) {
408 bufsize
+= BUF_DELTA
;
409 buffer
= nasm_realloc(buffer
, bufsize
);
413 if (!q
&& p
== buffer
) {
419 * Play safe: remove CRs as well as LFs, if any of either are
420 * present at the end of the line.
422 while (p
> buffer
&& (p
[-1] == '\n' || p
[-1] == '\r'))
426 * Handle spurious ^Z, which may be inserted into source files
427 * by some file transfer utilities.
429 buffer
[strcspn(buffer
, "\032")] = '\0';
435 * Tokenise a line of text. This is a very simple process since we
436 * don't need to parse the value out of e.g. numeric tokens: we
437 * simply split one string into many.
439 static Token
*tokenise (char *line
) {
443 Token
*t
, **tail
= &list
;
448 (p
[1] == '{' || p
[1] == '!' || (p
[1] == '%' && isidchar(p
[2])) ||
449 p
[1] == '$' || p
[1] == '+' || p
[1] == '-' || isidchar(p
[1]))) {
450 type
= TOK_PREPROC_ID
;
454 while (*p
&& *p
!= '}') {
461 if (*p
== '!' || *p
== '%' || *p
== '$' ||
462 *p
== '+' || *p
== '-') p
++;
463 while (*p
&& isidchar(*p
))
466 } else if (isidstart(*p
)) {
469 while (*p
&& isidchar(*p
))
471 } else if (*p
== '\'' || *p
== '"') {
478 while (*p
&& *p
!= c
)
481 } else if (isnumstart(*p
)) {
487 while (*p
&& isnumchar(*p
))
489 } else if (isspace(*p
)) {
490 type
= TOK_WHITESPACE
;
492 while (*p
&& isspace(*p
))
495 * Whitespace just before end-of-line is discarded by
496 * pretending it's a comment; whitespace just before a
497 * comment gets lumped into the comment.
499 if (!*p
|| *p
== ';') {
503 } else if (*p
== ';') {
508 * Anything else is an operator of some kind; with the
509 * exceptions of >>, <<, // and %%, all operator tokens
510 * are single-character.
514 if ( (c
== '>' || c
== '<' || c
== '/' || c
== '%') && *p
== c
)
517 if (type
!= TOK_COMMENT
) {
518 *tail
= t
= nasm_malloc (sizeof(Token
));
522 t
->text
= nasm_malloc(1+p
-line
);
523 strncpy(t
->text
, line
, p
-line
);
524 t
->text
[p
-line
] = '\0';
533 * Convert a line of tokens back into text.
535 static char *detoken (Token
*tlist
) {
541 for (t
= tlist
; t
; t
= t
->next
) {
542 if (t
->type
== TOK_PREPROC_ID
&& t
->text
[1] == '!') {
543 char *p
= getenv(t
->text
+2);
546 t
->text
= nasm_strdup(p
);
551 len
+= strlen(t
->text
);
553 p
= line
= nasm_malloc(len
+1);
554 for (t
= tlist
; t
; t
= t
->next
) {
565 * Return the Context structure associated with a %$ token. Return
566 * NULL, having _already_ reported an error condition, if the
567 * context stack isn't deep enough for the supplied number of $
570 static Context
*get_ctx (char *name
) {
575 error (ERR_NONFATAL
|ERR_OFFBY1
, "`%s': context stack is empty", name
);
581 while (name
[i
+1] == '$') {
585 error (ERR_NONFATAL
|ERR_OFFBY1
, "`%s': context stack is only"
586 " %d level%s deep", name
, i
-1, (i
==2 ? "" : "s"));
594 * Compare a string to the name of an existing macro; this is a
595 * simple wrapper which calls either strcmp or nasm_stricmp
596 * depending on the value of the `casesense' parameter.
598 static int mstrcmp(char *p
, char *q
, int casesense
) {
599 return casesense
? strcmp(p
,q
) : nasm_stricmp(p
,q
);
603 * Determine if we should warn on defining a single-line macro of
604 * name `name', with `nparam' parameters. If nparam is 0, will
605 * return TRUE if _any_ single-line macro of that name is defined.
606 * Otherwise, will return TRUE if a single-line macro with either
607 * `nparam' or no parameters is defined.
609 * If a macro with precisely the right number of parameters is
610 * defined, the address of the definition structure will be
611 * returned in `defn'; otherwise NULL will be returned. If `defn'
612 * is NULL, no action will be taken regarding its contents, and no
615 * Note that this is also called with nparam zero to resolve
618 static int smacro_defined (char *name
, int nparam
, SMacro
**defn
) {
623 if (name
[0] == '%' && name
[1] == '$') {
624 ctx
= get_ctx (name
);
626 return FALSE
; /* got to return _something_ */
631 m
= smacros
[hash(name
)];
636 if (!mstrcmp(m
->name
, p
, m
->casesense
) &&
637 (nparam
== 0 || m
->nparam
== 0 || nparam
== m
->nparam
)) {
639 if (nparam
== m
->nparam
)
652 * Count and mark off the parameters in a multi-line macro call.
653 * This is called both from within the multi-line macro expansion
654 * code, and also to mark off the default parameters when provided
655 * in a %macro definition line.
657 static void count_mmac_params (Token
*t
, int *nparam
, Token
***params
) {
658 int paramsize
, brace
;
660 *nparam
= paramsize
= 0;
663 if (*nparam
>= paramsize
) {
664 paramsize
+= PARAM_DELTA
;
665 *params
= nasm_realloc(*params
, sizeof(**params
) * paramsize
);
667 if (t
&& t
->type
== TOK_WHITESPACE
)
670 if (t
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "{"))
672 (*params
)[(*nparam
)++] = t
;
673 while (t
&& (t
->type
!= TOK_OTHER
||
674 strcmp(t
->text
, brace
? "}" : ",")))
676 if (t
) { /* got a comma/brace */
680 * Now we've found the closing brace, look further
683 if (t
&& t
->type
== TOK_WHITESPACE
)
685 if (t
&& (t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ","))) {
686 error (ERR_NONFATAL
|ERR_OFFBY1
,
687 "braces do not enclose all of macro parameter");
688 while (t
&& (t
->type
!= TOK_OTHER
||
689 strcmp(t
->text
, ",")))
693 t
= t
->next
; /* eat the comma */
702 * Find out if a line contains a preprocessor directive, and deal
705 * If a directive _is_ found, the line will never be de-tokenised
706 * as is, so we have carte blanche to fiddle with it and adjust
709 * Return values go like this:
711 * bit 0 is set if a directive was found
712 * bit 1 is set if a blank line should be emitted
713 * bit 2 is set if a re-sync line number comment should be emitted
715 * (bits 1 and 2 are mutually exclusive in that the rest of the
716 * preprocessor doesn't guarantee to be able to handle the case in
717 * which both are set)
719 static int do_directive (Token
*tline
) {
720 static char *directives
[] = {
721 "%clear", "%define", "%elifctx", "%elifdef", "%elifnctx",
722 "%elifndef", "%else", "%endif", "%endm", "%endmacro", "%error",
723 "%idefine", "%ifctx", "%ifdef", "%ifnctx", "%ifndef", "%imacro",
724 "%include", "%line", "%macro", "%pop", "%push", "%repl"
727 PP_CLEAR
, PP_DEFINE
, PP_ELIFCTX
, PP_ELIFDEF
, PP_ELIFNCTX
,
728 PP_ELIFNDEF
, PP_ELSE
, PP_ENDIF
, PP_ENDM
, PP_ENDMACRO
, PP_ERROR
,
729 PP_IDEFINE
, PP_IFCTX
, PP_IFDEF
, PP_IFNCTX
, PP_IFNDEF
, PP_IMACRO
,
730 PP_INCLUDE
, PP_LINE
, PP_MACRO
, PP_POP
, PP_PUSH
, PP_REPL
732 int i
, j
, k
, m
, nparam
;
737 SMacro
*smac
, **smhead
;
739 Token
*t
, *tt
, *param_start
, *macro_start
, *last
;
741 if (tline
&& tline
->type
== TOK_WHITESPACE
)
743 if (!tline
|| tline
->type
!= TOK_PREPROC_ID
||
744 (tline
->text
[1] == '%' || tline
->text
[1] == '$'))
748 j
= sizeof(directives
)/sizeof(*directives
);
751 m
= nasm_stricmp(tline
->text
, directives
[k
]);
763 * If we're in a non-emitting branch of a condition construct,
764 * we should ignore all directives except for condition
767 if (istk
->conds
&& !emitting(istk
->conds
->state
) &&
768 i
!= PP_IFCTX
&& i
!= PP_IFDEF
&& i
!= PP_IFNCTX
&& i
!= PP_IFNDEF
&&
769 i
!=PP_ELIFCTX
&& i
!=PP_ELIFDEF
&& i
!=PP_ELIFNCTX
&& i
!=PP_ELIFNDEF
&&
770 i
!= PP_ELSE
&& i
!= PP_ENDIF
)
774 * If we're defining a macro, we should ignore all directives
775 * except for %macro/%imacro (which generate an error) and
778 if (defining
&& i
!= PP_MACRO
&& i
!= PP_IMACRO
&&
779 i
!= PP_ENDMACRO
&& i
!= PP_ENDM
)
783 error(ERR_NONFATAL
|ERR_OFFBY1
, "unknown preprocessor directive `%s'",
785 return 0; /* didn't get it */
792 error(ERR_WARNING
|ERR_OFFBY1
,
793 "trailing garbage after `%%pop' ignored");
794 for (j
=0; j
<NHASH
; j
++) {
796 MMacro
*m
= mmacros
[j
];
797 mmacros
[j
] = mmacros
[j
]->next
;
799 free_tlist (m
->dlist
);
800 free_llist (m
->expansion
);
804 SMacro
*s
= smacros
[j
];
805 smacros
[j
] = smacros
[j
]->next
;
807 free_tlist (s
->expansion
);
815 if (tline
&& tline
->type
== TOK_WHITESPACE
)
817 if (!tline
|| tline
->type
!= TOK_STRING
) {
818 error(ERR_NONFATAL
|ERR_OFFBY1
, "`%%include' expects a file name");
819 return 3; /* but we did _something_ */
822 error(ERR_WARNING
|ERR_OFFBY1
,
823 "trailing garbage after `%%include' ignored");
824 p
= tline
->text
+1; /* point past the quote to the name */
825 p
[strlen(p
)-1] = '\0'; /* remove the trailing quote */
826 inc
= nasm_malloc(sizeof(Include
));
829 inc
->fp
= fopen(p
, "r");
830 inc
->fname
= nasm_strdup(p
);
831 inc
->lineno
= inc
->lineinc
= 1;
832 inc
->expansion
= NULL
;
834 error (ERR_FATAL
|ERR_OFFBY1
,
835 "unable to open include file `%s'", p
);
841 if (tline
&& tline
->type
== TOK_WHITESPACE
)
843 if (!tline
|| tline
->type
!= TOK_ID
) {
844 error(ERR_NONFATAL
|ERR_OFFBY1
,
845 "`%%push' expects a context identifier");
846 return 3; /* but we did _something_ */
849 error(ERR_WARNING
|ERR_OFFBY1
,
850 "trailing garbage after `%%push' ignored");
851 ctx
= nasm_malloc(sizeof(Context
));
853 ctx
->localmac
= NULL
;
854 ctx
->name
= nasm_strdup(tline
->text
);
855 ctx
->number
= unique
++;
861 if (tline
&& tline
->type
== TOK_WHITESPACE
)
863 if (!tline
|| tline
->type
!= TOK_ID
) {
864 error(ERR_NONFATAL
|ERR_OFFBY1
,
865 "`%%repl' expects a context identifier");
866 return 3; /* but we did _something_ */
869 error(ERR_WARNING
|ERR_OFFBY1
,
870 "trailing garbage after `%%repl' ignored");
872 error(ERR_NONFATAL
|ERR_OFFBY1
,
873 "`%%repl': context stack is empty");
875 nasm_free (cstk
->name
);
876 cstk
->name
= nasm_strdup(tline
->text
);
882 error(ERR_WARNING
|ERR_OFFBY1
,
883 "trailing garbage after `%%pop' ignored");
885 error(ERR_NONFATAL
|ERR_OFFBY1
,
886 "`%%pop': context stack is already empty");
893 if (tline
&& tline
->type
== TOK_WHITESPACE
)
895 if (!tline
|| tline
->type
!= TOK_STRING
) {
896 error(ERR_NONFATAL
|ERR_OFFBY1
,
897 "`%%error' expects an error string");
898 return 3; /* but we did _something_ */
901 error(ERR_WARNING
|ERR_OFFBY1
,
902 "trailing garbage after `%%error' ignored");
903 p
= tline
->text
+1; /* point past the quote to the name */
904 p
[strlen(p
)-1] = '\0'; /* remove the trailing quote */
905 error(ERR_NONFATAL
|ERR_OFFBY1
, "user error: %s", p
);
911 if (istk
->conds
&& !emitting(istk
->conds
->state
))
914 j
= FALSE
; /* have we matched yet? */
916 error(ERR_FATAL
|ERR_OFFBY1
,
917 "`%%if%sctx': context stack is empty",
918 (i
==PP_IFNCTX
? "n" : ""));
920 if (tline
->type
== TOK_WHITESPACE
)
922 if (!tline
|| tline
->type
!= TOK_ID
) {
923 error(ERR_NONFATAL
|ERR_OFFBY1
,
924 "`%%ifctx' expects context identifiers");
925 return 3; /* but we did _something_ */
927 if (!nasm_stricmp(tline
->text
, cstk
->name
))
933 j
= (j
? COND_IF_TRUE
: COND_IF_FALSE
);
935 cond
= nasm_malloc(sizeof(Cond
));
936 cond
->next
= istk
->conds
;
945 error(ERR_FATAL
|ERR_OFFBY1
, "`%%elif%sctx': no matching `%%if'",
946 (i
==PP_ELIFNCTX
? "n" : ""));
947 if (emitting(istk
->conds
->state
) || istk
->conds
->state
== COND_NEVER
)
948 istk
->conds
->state
= COND_NEVER
;
950 j
= FALSE
; /* have we matched yet? */
952 error(ERR_FATAL
|ERR_OFFBY1
,
953 "`%%elif%sctx': context stack is empty",
954 (i
==PP_ELIFNCTX
? "n" : ""));
956 if (tline
->type
== TOK_WHITESPACE
)
958 if (!tline
|| tline
->type
!= TOK_ID
) {
959 error(ERR_NONFATAL
|ERR_OFFBY1
,
960 "`%%elif%sctx' expects context identifiers",
961 (i
==PP_ELIFNCTX
? "n" : ""));
962 return 3; /* but we did _something_ */
964 if (!nasm_stricmp(tline
->text
, cstk
->name
))
968 if (i
== PP_ELIFNCTX
)
970 istk
->conds
->state
= (j
? COND_IF_TRUE
: COND_IF_FALSE
);
977 if (istk
->conds
&& !emitting(istk
->conds
->state
))
980 j
= FALSE
; /* have we matched yet? */
982 if (tline
->type
== TOK_WHITESPACE
)
984 if (!tline
|| (tline
->type
!= TOK_ID
&&
985 (tline
->type
!= TOK_PREPROC_ID
||
986 tline
->text
[1] != '$'))) {
987 error(ERR_NONFATAL
|ERR_OFFBY1
,
988 "`%%if%sdef' expects macro identifiers",
989 (i
==PP_ELIFNDEF
? "n" : ""));
990 return 3; /* but we did _something_ */
992 if (smacro_defined(tline
->text
, 0, NULL
))
998 j
= (j
? COND_IF_TRUE
: COND_IF_FALSE
);
1000 cond
= nasm_malloc(sizeof(Cond
));
1001 cond
->next
= istk
->conds
;
1008 tline
= tline
->next
;
1010 error(ERR_FATAL
|ERR_OFFBY1
, "`%%elif%sctx': no matching `%%if'",
1011 (i
==PP_ELIFNCTX
? "n" : ""));
1012 if (emitting(istk
->conds
->state
) || istk
->conds
->state
== COND_NEVER
)
1013 istk
->conds
->state
= COND_NEVER
;
1015 j
= FALSE
; /* have we matched yet? */
1017 if (tline
->type
== TOK_WHITESPACE
)
1018 tline
= tline
->next
;
1019 if (!tline
|| (tline
->type
!= TOK_ID
&&
1020 (tline
->type
!= TOK_PREPROC_ID
||
1021 tline
->text
[1] != '$'))) {
1022 error(ERR_NONFATAL
|ERR_OFFBY1
,
1023 "`%%elif%sdef' expects macro identifiers",
1024 (i
==PP_ELIFNDEF
? "n" : ""));
1025 return 3; /* but we did _something_ */
1027 if (smacro_defined(tline
->text
, 0, NULL
))
1029 tline
= tline
->next
;
1031 if (i
== PP_ELIFNDEF
)
1033 istk
->conds
->state
= (j
? COND_IF_TRUE
: COND_IF_FALSE
);
1039 error(ERR_WARNING
|ERR_OFFBY1
,
1040 "trailing garbage after `%%else' ignored");
1042 error(ERR_FATAL
|ERR_OFFBY1
,
1043 "`%%else': no matching `%%if'");
1044 if (emitting(istk
->conds
->state
) || istk
->conds
->state
== COND_NEVER
)
1045 istk
->conds
->state
= COND_ELSE_FALSE
;
1047 istk
->conds
->state
= COND_ELSE_TRUE
;
1052 error(ERR_WARNING
|ERR_OFFBY1
,
1053 "trailing garbage after `%%endif' ignored");
1055 error(ERR_FATAL
|ERR_OFFBY1
,
1056 "`%%endif': no matching `%%if'");
1058 istk
->conds
= cond
->next
;
1065 error (ERR_FATAL
|ERR_OFFBY1
,
1066 "`%%%smacro': already defining a macro",
1067 (i
== PP_IMACRO
? "i" : ""));
1068 tline
= tline
->next
;
1069 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1070 tline
= tline
->next
;
1071 if (!tline
|| tline
->type
!= TOK_ID
) {
1072 error (ERR_NONFATAL
|ERR_OFFBY1
,
1073 "`%%%smacro' expects a macro name",
1074 (i
== PP_IMACRO
? "i" : ""));
1077 defining
= nasm_malloc(sizeof(MMacro
));
1078 defining
->name
= nasm_strdup(tline
->text
);
1079 defining
->casesense
= (i
== PP_MACRO
);
1080 defining
->plus
= FALSE
;
1081 defining
->in_progress
= FALSE
;
1082 tline
= tline
->next
;
1083 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1084 tline
= tline
->next
;
1085 if (!tline
|| tline
->type
!= TOK_NUMBER
) {
1086 error (ERR_NONFATAL
|ERR_OFFBY1
,
1087 "`%%%smacro' expects a parameter count",
1088 (i
== PP_IMACRO
? "i" : ""));
1089 defining
->nparam_min
= defining
->nparam_max
= 0;
1091 defining
->nparam_min
= defining
->nparam_max
=
1092 readnum(tline
->text
, &j
);
1094 error (ERR_NONFATAL
|ERR_OFFBY1
,
1095 "unable to parse parameter count `%s'", tline
->text
);
1097 if (tline
&& tline
->next
&& tline
->next
->type
== TOK_OTHER
&&
1098 !strcmp(tline
->next
->text
, "-")) {
1099 tline
= tline
->next
->next
;
1100 if (!tline
|| tline
->type
!= TOK_NUMBER
)
1101 error (ERR_NONFATAL
|ERR_OFFBY1
,
1102 "`%%%smacro' expects a parameter count after `-'",
1103 (i
== PP_IMACRO
? "i" : ""));
1105 defining
->nparam_max
= readnum(tline
->text
, &j
);
1107 error (ERR_NONFATAL
|ERR_OFFBY1
,
1108 "unable to parse parameter count `%s'",
1110 if (defining
->nparam_min
> defining
->nparam_max
)
1111 error (ERR_NONFATAL
|ERR_OFFBY1
,
1112 "minimum parameter count exceeds maximum");
1115 if (tline
&& tline
->next
&& tline
->next
->type
== TOK_OTHER
&&
1116 !strcmp(tline
->next
->text
, "+")) {
1117 tline
= tline
->next
;
1118 defining
->plus
= TRUE
;
1120 mmac
= mmacros
[hash(defining
->name
)];
1122 if (!strcmp(mmac
->name
, defining
->name
) &&
1123 (mmac
->nparam_min
<=defining
->nparam_max
|| defining
->plus
) &&
1124 (defining
->nparam_min
<=mmac
->nparam_max
|| mmac
->plus
)) {
1125 error (ERR_WARNING
|ERR_OFFBY1
,
1126 "redefining multi-line macro `%s'", defining
->name
);
1132 * Handle default parameters.
1134 if (tline
&& tline
->next
) {
1137 defining
->dlist
= tline
->next
;
1139 count_mmac_params (defining
->dlist
, &np
, &defining
->defaults
);
1140 want_np
= defining
->nparam_max
- defining
->nparam_min
;
1141 defining
->defaults
= nasm_realloc (defining
->defaults
,
1142 want_np
*sizeof(Token
*));
1143 while (np
< want_np
)
1144 defining
->defaults
[np
++] = NULL
;
1146 defining
->dlist
= NULL
;
1147 defining
->defaults
= NULL
;
1149 defining
->expansion
= NULL
;
1155 error (ERR_NONFATAL
|ERR_OFFBY1
, "`%s': not defining a macro",
1159 k
= hash(defining
->name
);
1160 defining
->next
= mmacros
[k
];
1161 mmacros
[k
] = defining
;
1167 tline
= tline
->next
;
1168 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1169 tline
= tline
->next
;
1170 if (!tline
|| (tline
->type
!= TOK_ID
&&
1171 (tline
->type
!= TOK_PREPROC_ID
||
1172 tline
->text
[1] != '$'))) {
1173 error (ERR_NONFATAL
|ERR_OFFBY1
,
1174 "`%%%sdefine' expects a macro identifier",
1175 (i
== PP_IDEFINE
? "i" : ""));
1178 mname
= tline
->text
;
1179 if (tline
->type
== TOK_ID
) {
1181 smhead
= &smacros
[hash(mname
)];
1183 ctx
= get_ctx (tline
->text
);
1188 p
+= strspn(p
, "$");
1189 smhead
= &ctx
->localmac
;
1193 param_start
= tline
= tline
->next
;
1195 if (tline
&& tline
->type
== TOK_OTHER
&& !strcmp(tline
->text
, "(")) {
1197 * This macro has parameters.
1200 tline
= tline
->next
;
1202 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1203 tline
= tline
->next
;
1205 error (ERR_NONFATAL
|ERR_OFFBY1
,
1206 "parameter identifier expected");
1209 if (tline
->type
!= TOK_ID
) {
1210 error (ERR_NONFATAL
|ERR_OFFBY1
,
1211 "`%s': parameter identifier expected",
1215 tline
->type
= TOK_SMAC_PARAM
+ nparam
++;
1216 tline
= tline
->next
;
1217 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1218 tline
= tline
->next
;
1219 if (tline
&& tline
->type
== TOK_OTHER
&&
1220 !strcmp(tline
->text
, ",")) {
1221 tline
= tline
->next
;
1224 if (!tline
|| tline
->type
!= TOK_OTHER
||
1225 strcmp(tline
->text
, ")")) {
1226 error (ERR_NONFATAL
|ERR_OFFBY1
,
1227 "`)' expected to terminate macro template");
1233 tline
= tline
->next
;
1235 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1236 last
= tline
, tline
= tline
->next
;
1241 if (t
->type
== TOK_ID
) {
1242 for (tt
= param_start
; tt
; tt
= tt
->next
)
1243 if (tt
->type
>= TOK_SMAC_PARAM
&&
1244 !strcmp(tt
->text
, t
->text
))
1248 t
->next
= macro_start
;
1253 * Good. We now have a macro name, a parameter count, and a
1254 * token list (in reverse order) for an expansion. We ought
1255 * to be OK just to create an SMacro, store it, and let
1256 * tlist_free have the rest of the line (which we have
1257 * carefully re-terminated after chopping off the expansion
1260 if (smacro_defined (mname
, nparam
, &smac
)) {
1262 error (ERR_WARNING
|ERR_OFFBY1
,
1263 "single-line macro `%s' defined both with and"
1264 " without parameters", mname
);
1267 * We're redefining, so we have to take over an
1268 * existing SMacro structure. This means freeing
1269 * what was already in it.
1271 nasm_free (smac
->name
);
1272 free_tlist (smac
->expansion
);
1275 smac
= nasm_malloc(sizeof(SMacro
));
1276 smac
->next
= *smhead
;
1279 smac
->name
= nasm_strdup(p
);
1280 smac
->casesense
= (i
== PP_DEFINE
);
1281 smac
->nparam
= nparam
;
1282 smac
->expansion
= macro_start
;
1283 smac
->in_progress
= FALSE
;
1288 * Syntax is `%line nnn[+mmm] [filename]'
1290 tline
= tline
->next
;
1291 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1292 tline
= tline
->next
;
1293 if (!tline
|| tline
->type
!= TOK_NUMBER
) {
1294 error (ERR_NONFATAL
|ERR_OFFBY1
, "`%%line' expects line number");
1297 k
= readnum(tline
->text
, &j
);
1299 tline
= tline
->next
;
1300 if (tline
&& tline
->type
== TOK_OTHER
&& !strcmp(tline
->text
, "+")) {
1301 tline
= tline
->next
;
1302 if (!tline
|| tline
->type
!= TOK_NUMBER
) {
1303 error (ERR_NONFATAL
|ERR_OFFBY1
,
1304 "`%%line' expects line increment");
1307 m
= readnum(tline
->text
, &j
);
1308 tline
= tline
->next
;
1310 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1311 tline
= tline
->next
;
1315 char *s
= detoken(tline
);
1316 nasm_free (istk
->fname
);
1322 error(ERR_FATAL
|ERR_OFFBY1
,
1323 "preprocessor directive `%s' not yet implemented",
1331 * Expand all single-line macro calls made in the given line.
1332 * Return the expanded version of the line. The original is deemed
1333 * to be destroyed in the process. (In reality we'll just move
1334 * Tokens from input to output a lot of the time, rather than
1335 * actually bothering to destroy and replicate.)
1337 static Token
*expand_smacro (Token
*tline
) {
1338 Token
*t
, *tt
, *mstart
, **tail
, *thead
;
1342 int nparam
, sparam
, brackets
;
1349 while (tline
&& tline
->type
!= TOK_ID
&&
1350 (tline
->type
!= TOK_PREPROC_ID
|| tline
->text
[1] != '$')) {
1351 if (tline
->type
== TOK_SMAC_END
) {
1352 tline
->mac
->in_progress
= FALSE
;
1354 tline
= tline
->next
;
1358 tline
= tline
->next
;
1362 if (t
->type
== TOK_PS_OTHER
) {
1364 * If we see a PS_OTHER, we must at the very
1365 * least restore its correct token type. We
1366 * should also check for a %$ token, since this
1367 * is the point at which we expand context-
1371 if (t
->text
[0] == '%' && t
->text
[1] == '$') {
1372 Context
*c
= get_ctx (t
->text
);
1373 char *p
, *q
, buffer
[40];
1377 q
+= strspn(q
, "$");
1378 sprintf(buffer
, "macro.%lu.", c
->number
);
1379 p
= nasm_malloc (strlen(buffer
)+strlen(q
)+1);
1382 nasm_free (t
->text
);
1392 * We've hit an identifier. As in is_mmacro below, we first
1393 * check whether the identifier is a single-line macro at
1394 * all, then think about checking for parameters if
1397 if (tline
->type
== TOK_ID
) {
1398 head
= smacros
[hash(tline
->text
)];
1401 Context
*ctx
= get_ctx (tline
->text
);
1404 p
+= strspn(p
, "$");
1405 head
= ctx
->localmac
;
1407 tline
->type
= TOK_OTHER
; /* so it will get copied above */
1411 for (m
= head
; m
; m
= m
->next
)
1412 if (!mstrcmp(m
->name
, p
, m
->casesense
))
1416 * Didn't find one: this can't be a macro call. Copy it
1417 * through and ignore it.
1419 tline
->type
= TOK_PS_OTHER
; /* so it will get copied above */
1423 if (m
->nparam
== 0) {
1425 * Simple case: the macro is parameterless. Discard the
1426 * one token that the macro call took, and push the
1427 * expansion back on the to-do stack.
1433 * Complicated case: at least one macro with this name
1434 * exists and takes parameters. We must find the
1435 * parameters in the call, count them, find the SMacro
1436 * that corresponds to that form of the macro call, and
1437 * substitute for the parameters when we expand. What a
1440 nparam
= sparam
= 0;
1443 tline
= tline
->next
;
1444 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1445 tline
= tline
->next
;
1446 if (!tline
|| tline
->type
!= TOK_OTHER
||
1447 strcmp(tline
->text
, "(")) {
1449 * This macro wasn't called with parameters: ignore
1450 * the call. (Behaviour borrowed from gnu cpp.)
1453 tline
->type
= TOK_PS_OTHER
;
1456 tline
= tline
->next
;
1458 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1459 tline
= tline
->next
;
1461 error(ERR_NONFATAL
|ERR_OFFBY1
,
1462 "macro call expects terminating `)'");
1465 if (nparam
>= sparam
) {
1466 sparam
+= PARAM_DELTA
;
1467 params
= nasm_realloc (params
, sparam
*sizeof(Token
*));
1468 paramsize
= nasm_realloc (paramsize
, sparam
*sizeof(int));
1470 params
[nparam
] = tline
;
1471 paramsize
[nparam
] = 0;
1473 if (tline
&& tline
->type
== TOK_OTHER
&&
1474 !strcmp(tline
->text
, "{")) {
1475 params
[nparam
] = tline
= tline
->next
;
1476 while (tline
&& (brackets
> 0 ||
1477 tline
->type
!= TOK_OTHER
||
1478 strcmp(tline
->text
, "}"))) {
1479 tline
= tline
->next
;
1480 paramsize
[nparam
]++;
1482 tline
= tline
->next
;
1483 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1484 tline
= tline
->next
;
1485 if (tline
&& (tline
->type
!= TOK_OTHER
||
1486 (strcmp(tline
->text
, ")") &&
1487 strcmp(tline
->text
, ",")))) {
1488 error (ERR_NONFATAL
|ERR_OFFBY1
, "braces do not "
1489 "enclose all of macro parameter");
1491 if (tline
&& tline
->type
== TOK_OTHER
&&
1492 !strcmp(tline
->text
, ","))
1493 tline
= tline
->next
;
1495 while (tline
&& (brackets
> 0 ||
1496 tline
->type
!= TOK_OTHER
||
1497 (strcmp(tline
->text
, ",") &&
1498 strcmp(tline
->text
, ")")))) {
1499 if (tline
->type
== TOK_OTHER
&& !tline
->text
[1])
1500 brackets
+= (tline
->text
[0] == '(' ? 1 :
1501 tline
->text
[0] == ')' ? -1 : 0);
1502 tline
= tline
->next
;
1503 paramsize
[nparam
]++;
1507 if (tline
&& !strcmp(tline
->text
, ")"))
1509 if (tline
&& !strcmp(tline
->text
, ","))
1510 tline
= tline
->next
;
1512 while (m
&& m
->nparam
!= nparam
) {
1513 while ( (m
= m
->next
) )
1514 if (!strcmp(m
->name
, mstart
->text
))
1518 error (ERR_WARNING
|ERR_OFFBY1
,
1519 "macro `%s' exists, but not taking %d parameters",
1520 mstart
->text
, nparam
);
1522 nasm_free (paramsize
);
1524 tline
->type
= TOK_PS_OTHER
;
1527 if (m
->in_progress
) {
1528 error (ERR_NONFATAL
, "self-reference in single-line macro"
1529 " `%s'", mstart
->text
);
1531 nasm_free (paramsize
);
1533 tline
->type
= TOK_PS_OTHER
;
1538 * Expand the macro: we are placed on the last token of the
1539 * call, so that we can easily split the call from the
1540 * following tokens. We also start by pushing an SMAC_END
1541 * token for the cycle removal.
1544 tline
= tline
->next
;
1546 tt
= nasm_malloc(sizeof(Token
));
1547 tt
->type
= TOK_SMAC_END
;
1550 m
->in_progress
= TRUE
;
1553 for (t
= m
->expansion
; t
; t
= t
->next
) {
1554 if (t
->type
>= TOK_SMAC_PARAM
) {
1555 Token
*pcopy
= tline
, **ptail
= &pcopy
;
1559 ttt
= params
[t
->type
- TOK_SMAC_PARAM
];
1560 for (i
=0; i
<paramsize
[t
->type
-TOK_SMAC_PARAM
]; i
++) {
1561 pt
= *ptail
= nasm_malloc(sizeof(Token
));
1564 pt
->text
= nasm_strdup(ttt
->text
);
1565 pt
->type
= ttt
->type
;
1571 tt
= nasm_malloc(sizeof(Token
));
1573 tt
->text
= nasm_strdup(t
->text
);
1581 * Having done that, get rid of the macro call, and clean
1582 * up the parameters.
1585 nasm_free (paramsize
);
1586 free_tlist (mstart
);
1593 * Ensure that a macro parameter contains a condition code and
1594 * nothing else. Return the condition code index if so, or -1
1597 static int find_cc (Token
*t
) {
1601 if (t
&& t
->type
== TOK_WHITESPACE
)
1603 if (t
->type
!= TOK_ID
)
1606 if (tt
&& tt
->type
== TOK_WHITESPACE
)
1608 if (tt
&& (tt
->type
!= TOK_OTHER
|| strcmp(tt
->text
, ",")))
1612 j
= sizeof(conditions
)/sizeof(*conditions
);
1615 m
= nasm_stricmp(t
->text
, conditions
[k
]);
1631 * Determine whether the given line constitutes a multi-line macro
1632 * call, and return the MMacro structure called if so. Doesn't have
1633 * to check for an initial label - that's taken care of in
1634 * expand_mmacro - but must check numbers of parameters. Guaranteed
1635 * to be called with tline->type == TOK_ID, so the putative macro
1636 * name is easy to find.
1638 static MMacro
*is_mmacro (Token
*tline
, Token
***params_array
) {
1643 head
= mmacros
[hash(tline
->text
)];
1646 * Efficiency: first we see if any macro exists with the given
1647 * name. If not, we can return NULL immediately. _Then_ we
1648 * count the parameters, and then we look further along the
1649 * list if necessary to find the proper MMacro.
1651 for (m
= head
; m
; m
= m
->next
)
1652 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
1658 * OK, we have a potential macro. Count and demarcate the
1661 count_mmac_params (tline
->next
, &nparam
, ¶ms
);
1664 * So we know how many parameters we've got. Find the MMacro
1665 * structure that handles this number.
1668 if (m
->nparam_min
<= nparam
&& (m
->plus
|| nparam
<= m
->nparam_max
)) {
1670 * This one is right. Just check if cycle removal
1671 * prohibits us using it before we actually celebrate...
1673 if (m
->in_progress
) {
1674 error (ERR_NONFATAL
|ERR_OFFBY1
,
1675 "self-reference in multi-line macro `%s'",
1681 * It's right, and we can use it. Add its default
1682 * parameters to the end of our list if necessary.
1684 params
= nasm_realloc (params
, (m
->nparam_max
+1)*sizeof(*params
));
1686 while (nparam
< m
->nparam_max
) {
1687 params
[nparam
] = m
->defaults
[nparam
- m
->nparam_min
];
1691 while (nparam
< m
->nparam_max
) {
1692 params
[nparam
] = NULL
;
1697 * Then terminate the parameter list, and leave.
1699 params
[m
->nparam_max
] = NULL
;
1700 *params_array
= params
;
1704 * This one wasn't right: look for the next one with the
1707 for (m
= m
->next
; m
; m
= m
->next
)
1708 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
1713 * After all that, we didn't find one with the right number of
1714 * parameters. Issue a warning, and fail to expand the macro.
1716 error (ERR_WARNING
|ERR_OFFBY1
,
1717 "macro `%s' exists, but not taking %d parameters",
1718 tline
->text
, nparam
);
1724 * Expand the multi-line macro call made by the given line, if
1725 * there is one to be expanded. If there is, push the expansion on
1726 * istk->expansion and return 1 or 2, as according to whether a
1727 * line sync is needed (2 if it is). Otherwise return 0.
1729 static int expand_mmacro (Token
*tline
) {
1730 Token
*label
= NULL
, **params
, *t
, *tt
, *ttt
, *last
= NULL
;
1733 int i
, n
, nparam
, *paramlen
;
1734 int need_sync
= FALSE
;
1737 if (t
&& t
->type
== TOK_WHITESPACE
)
1739 if (t
&& t
->type
== TOK_ID
) {
1740 m
= is_mmacro (t
, ¶ms
);
1743 * We have an id which isn't a macro call. We'll assume
1744 * it might be a label; we'll also check to see if a
1745 * colon follows it. Then, if there's another id after
1746 * that lot, we'll check it again for macro-hood.
1748 last
= t
, t
= t
->next
;
1749 if (t
&& t
->type
== TOK_WHITESPACE
)
1750 last
= t
, t
= t
->next
;
1751 if (t
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, ":"))
1752 last
= t
, t
= t
->next
;
1753 if (t
&& t
->type
== TOK_WHITESPACE
)
1754 last
= t
, t
= t
->next
;
1755 if (t
&& t
->type
== TOK_ID
) {
1756 m
= is_mmacro(t
, ¶ms
);
1769 * If we're not already inside another macro expansion, we'd
1770 * better push a line synchronisation to ensure we stay put on
1773 if (!istk
->expansion
)
1777 * Fix up the parameters: this involves stripping leading and
1778 * trailing whitespace, then stripping braces if they are
1781 for (nparam
= 0; params
[nparam
]; nparam
++);
1782 paramlen
= nparam
? nasm_malloc(nparam
*sizeof(*paramlen
)) : NULL
;
1784 for (i
= 0; params
[i
]; i
++) {
1786 int comma
= !m
->plus
;
1789 if (t
&& t
->type
== TOK_WHITESPACE
)
1791 if (t
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "{"))
1792 t
= t
->next
, brace
= TRUE
, comma
= FALSE
;
1796 if (!t
) /* end of param because EOL */
1798 if (comma
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, ","))
1799 break; /* ... because we have hit a comma */
1800 if (comma
&& t
->type
== TOK_WHITESPACE
&&
1801 t
->next
->type
== TOK_OTHER
&& !strcmp(t
->next
->text
, ","))
1802 break; /* ... or a space then a comma */
1803 if (brace
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "}"))
1804 break; /* ... or a brace */
1811 * OK, we have a MMacro structure together with a set of
1812 * parameters. We must now go through the expansion and push
1813 * _copies_ of each Line on to istk->expansion, having first
1814 * substituted for most % tokens (%1, %+1, %-1, %%foo). Note
1815 * that %$bar, %$$baz, %$$$quux, and so on, do not get
1816 * substituted here but rather have to wait until the
1817 * single-line macro substitution process. This is because they
1818 * don't just crop up in macro definitions, but can appear
1819 * anywhere they like.
1821 * First, push an end marker on to istk->expansion, and mark
1822 * this macro as in progress.
1824 ll
= nasm_malloc(sizeof(Line
));
1825 ll
->next
= istk
->expansion
;
1828 istk
->expansion
= ll
;
1829 m
->in_progress
= TRUE
;
1830 for (l
= m
->expansion
; l
; l
= l
->next
) {
1833 ll
= nasm_malloc(sizeof(Line
));
1834 ll
->next
= istk
->expansion
;
1835 ll
->finishes
= NULL
;
1838 for (t
= l
->first
; t
; t
= t
->next
) {
1840 int type
= 0, cc
; /* type = 0 to placate optimisers */
1843 if (t
->type
== TOK_PREPROC_ID
&&
1844 (t
->text
[1] == '+' || t
->text
[1] == '-' ||
1845 t
->text
[1] == '%' ||
1846 (t
->text
[1] >= '0' && t
->text
[1] <= '9'))) {
1848 * We have to make a substitution of one of the
1849 * forms %1, %-1, %+1, %%foo.
1851 switch (t
->text
[1]) {
1854 sprintf(tmpbuf
, "macro.%lu.", unique
);
1855 text
= nasm_malloc(strlen(tmpbuf
)+strlen(t
->text
+2)+1);
1856 strcpy(text
, tmpbuf
);
1857 strcat(text
, t
->text
+2);
1860 n
= atoi(t
->text
+2)-1;
1864 error (ERR_NONFATAL
|ERR_OFFBY1
,
1865 "macro parameter %d is not a condition code",
1870 if (inverse_ccs
[cc
] == -1) {
1871 error (ERR_NONFATAL
|ERR_OFFBY1
,
1872 "condition code `%s' is not invertible",
1876 text
= nasm_strdup(conditions
[inverse_ccs
[cc
]]);
1880 n
= atoi(t
->text
+2)-1;
1884 error (ERR_NONFATAL
|ERR_OFFBY1
,
1885 "macro parameter %d is not a condition code",
1890 text
= nasm_strdup(conditions
[cc
]);
1894 n
= atoi(t
->text
+1)-1;
1897 for (i
=0; i
<paramlen
[n
]; i
++) {
1898 tt
= *tail
= nasm_malloc(sizeof(Token
));
1901 tt
->type
= ttt
->type
;
1902 tt
->text
= nasm_strdup(ttt
->text
);
1907 text
= NULL
; /* we've done it here */
1912 text
= nasm_strdup(t
->text
);
1916 tt
= *tail
= nasm_malloc(sizeof(Token
));
1925 istk
->expansion
= ll
;
1929 * If we had a label, push it on the front of the first line of
1930 * the macro expansion.
1933 last
->next
= istk
->expansion
->first
;
1934 istk
->expansion
->first
= label
;
1941 nasm_free (paramlen
);
1945 return need_sync
? 2 : 1;
1948 static void pp_reset (char *file
, efunc errfunc
) {
1953 linesync
= outline
= NULL
;
1954 istk
= nasm_malloc(sizeof(Include
));
1957 istk
->expansion
= NULL
;
1958 istk
->fp
= fopen(file
, "r");
1959 istk
->fname
= nasm_strdup(file
);
1960 istk
->lineno
= istk
->lineinc
= 1;
1962 error (ERR_FATAL
|ERR_NOFILE
, "unable to open input file `%s'", file
);
1964 for (h
=0; h
<NHASH
; h
++) {
1972 static char *pp_getline (void) {
1985 * Fetch a tokenised line, either from the macro-expansion
1986 * buffer or from the input file.
1989 while (istk
->expansion
&& istk
->expansion
->finishes
) {
1990 Line
*l
= istk
->expansion
;
1992 l
->finishes
->in_progress
= FALSE
;
1993 istk
->expansion
= l
->next
;
1995 if (!istk
->expansion
)
1998 if (istk
->expansion
) {
1999 Line
*l
= istk
->expansion
;
2001 istk
->expansion
= l
->next
;
2003 if (!istk
->expansion
)
2009 * The current file has ended; work down the istk
2010 * until we find a file we can read from.
2015 error(ERR_FATAL
, "expected `%%endif' before end of file");
2018 nasm_free (i
->fname
);
2026 line
= prepreproc(line
);
2027 tline
= tokenise(line
);
2032 * Check the line to see if it's a preprocessor directive.
2034 ret
= do_directive(tline
);
2039 if ((ret
& 2) && !stdmacpos
) {/* give a blank line to the output */
2040 outline
= nasm_strdup("");
2045 } else if (defining
) {
2047 * We're defining a multi-line macro. We emit nothing
2048 * at all, not even a blank line (when we finish
2049 * defining the macro, we'll emit a line-number
2050 * directive so that we keep sync properly), and just
2051 * shove the tokenised line on to the macro definition.
2053 Line
*l
= nasm_malloc(sizeof(Line
));
2054 l
->next
= defining
->expansion
;
2056 l
->finishes
= FALSE
;
2057 defining
->expansion
= l
;
2059 } else if (istk
->conds
&& !emitting(istk
->conds
->state
)) {
2061 * We're in a non-emitting branch of a condition block.
2062 * Emit nothing at all, not even a blank line: when we
2063 * emerge from the condition we'll give a line-number
2064 * directive so we keep our place correctly.
2069 tline
= expand_smacro(tline
);
2070 ret
= expand_mmacro(tline
);
2073 * De-tokenise the line again, and emit it.
2075 line
= detoken(tline
);
2082 continue; /* expand_mmacro calls free_tlist */
2088 * Once we're out of this loop, outline _must_ be non-NULL. The
2089 * only question is whether linesync is NULL or not.
2101 static void pp_cleanup (void) {
2105 error (ERR_NONFATAL
, "end of file while still defining macro `%s'",
2107 nasm_free (defining
->name
);
2108 free_tlist (defining
->dlist
);
2109 free_llist (defining
->expansion
);
2110 nasm_free (defining
);
2112 nasm_free (linesync
); /* might just be necessary */
2113 nasm_free (outline
); /* really shouldn't be necessary */
2116 for (h
=0; h
<NHASH
; h
++) {
2117 while (mmacros
[h
]) {
2118 MMacro
*m
= mmacros
[h
];
2119 mmacros
[h
] = mmacros
[h
]->next
;
2120 nasm_free (m
->name
);
2121 free_tlist (m
->dlist
);
2122 free_llist (m
->expansion
);
2125 while (smacros
[h
]) {
2126 SMacro
*s
= smacros
[h
];
2127 smacros
[h
] = smacros
[h
]->next
;
2128 nasm_free (s
->name
);
2129 free_tlist (s
->expansion
);
2137 nasm_free (i
->fname
);