]>
git.saurik.com Git - apple/boot.git/blob - i386/nasm/preproc.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
24 /* preproc.c macro preprocessor for the Netwide Assembler
26 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
27 * Julian Hall. All rights reserved. The software is
28 * redistributable under the licence given in the file "Licence"
29 * distributed in the NASM archive.
31 * initial version 18/iii/97 by Simon Tatham
44 typedef struct SMacro SMacro
;
45 typedef struct MMacro MMacro
;
46 typedef struct Context Context
;
47 typedef struct Token Token
;
48 typedef struct Line Line
;
49 typedef struct Include Include
;
50 typedef struct Cond Cond
;
51 typedef struct IncPath IncPath
;
54 * Store the definition of a single-line macro.
66 * Store the definition of a multi-line macro. This is also used to
67 * store the interiors of `%rep...%endrep' blocks, which are
68 * effectively self-re-invoking multi-line macros which simply
69 * don't have a name or bother to appear in the hash tables. %rep
70 * blocks are signified by having a NULL `name' field.
72 * In a MMacro describing a `%rep' block, the `in_progress' field
73 * isn't merely boolean, but gives the number of repeats left to
76 * The `next' field is used for storing MMacros in hash tables; the
77 * `next_active' field is for stacking them on istk entries.
79 * When a MMacro is being expanded, `params', `iline', `nparam',
80 * `paramlen', `rotate' and `unique' are local to the invocation.
86 int nparam_min
, nparam_max
;
87 int plus
; /* is the last parameter greedy? */
88 int nolist
; /* is this macro listing-inhibited? */
90 Token
**defaults
, *dlist
;
91 int ndefs
; /* number of default parameters */
95 Token
**params
, *iline
;
96 int nparam
, rotate
, *paramlen
;
101 * The context stack is composed of a linked list of these.
107 unsigned long number
;
111 * This is the internal form which we break input lines up into.
112 * Typically stored in linked lists.
114 * TOK_PS_OTHER is a token type used internally within
115 * expand_smacro(), to denote a token which has already been
116 * checked for being a potential macro, but may still be a context-
119 * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
120 * necessarily used as-is, but is intended to denote the number of
121 * the substituted parameter. So in the definition
123 * %define a(x,y) ( (x) & ~(y) )
125 * the token representing `x' will have its type changed to
126 * TOK_SMAC_PARAM, but the one representing `y' will be
129 * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
130 * which doesn't need quotes around it. Used in the pre-include
131 * mechanism as an alternative to trying to find a sensible type of
132 * quote to use on the filename we were passed.
137 SMacro
*mac
; /* associated macro for TOK_SMAC_END */
141 TOK_WHITESPACE
= 1, TOK_COMMENT
, TOK_ID
, TOK_PREPROC_ID
, TOK_STRING
,
142 TOK_NUMBER
, TOK_SMAC_END
, TOK_OTHER
, TOK_PS_OTHER
, TOK_SMAC_PARAM
,
147 * Multi-line macro definitions are stored as a linked list of
148 * these, which is essentially a container to allow several linked
151 * Note that in this module, linked lists are treated as stacks
152 * wherever possible. For this reason, Lines are _pushed_ on to the
153 * `expansion' field in MMacro structures, so that the linked list,
154 * if walked, would give the macro lines in reverse order; this
155 * means that we can walk the list when expanding a macro, and thus
156 * push the lines on to the `expansion' field in _istk_ in reverse
157 * order (so that when popped back off they are in the right
158 * order). It may seem cockeyed, and it relies on my design having
159 * an even number of steps in, but it works...
161 * Some of these structures, rather than being actual lines, are
162 * markers delimiting the end of the expansion of a given macro.
163 * This is for use in the cycle-tracking and %rep-handling code.
164 * Such structures have `finishes' non-NULL, and `first' NULL. All
165 * others have `finishes' NULL, but `first' may still be NULL if
175 * To handle an arbitrary level of file inclusion, we maintain a
176 * stack (ie linked list) of these things.
185 MMacro
*mstk
; /* stack of active macros/reps */
189 * Include search path. This is simply a list of strings which get
190 * prepended, in turn, to the name of an include file, in an
191 * attempt to find the file if it's not in the current directory.
199 * Conditional assembly: we maintain a separate stack of these for
200 * each level of file inclusion. (The only reason we keep the
201 * stacks separate is to ensure that a stray `%endif' in a file
202 * included from within the true branch of a `%if' won't terminate
203 * it and cause confusion: instead, rightly, it'll cause an error.)
211 * These states are for use just after %if or %elif: IF_TRUE
212 * means the condition has evaluated to truth so we are
213 * currently emitting, whereas IF_FALSE means we are not
214 * currently emitting but will start doing so if a %else comes
215 * up. In these states, all directives are admissible: %elif,
216 * %else and %endif. (And of course %if.)
218 COND_IF_TRUE
, COND_IF_FALSE
,
220 * These states come up after a %else: ELSE_TRUE means we're
221 * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
222 * any %elif or %else will cause an error.
224 COND_ELSE_TRUE
, COND_ELSE_FALSE
,
226 * This state means that we're not emitting now, and also that
227 * nothing until %endif will be emitted at all. It's for use in
228 * two circumstances: (i) when we've had our moment of emission
229 * and have now started seeing %elifs, and (ii) when the
230 * condition construct in question is contained within a
231 * non-emitting branch of a larger condition construct.
235 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
238 * Condition codes. Note that we use c_ prefix not C_ because C_ is
239 * used in nasm.h for the "real" condition codes. At _this_ level,
240 * we treat CXZ and ECXZ as condition codes, albeit non-invertible
241 * ones, so we need a different enum...
243 static char *conditions
[] = {
244 "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
245 "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
246 "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
249 c_A
, c_AE
, c_B
, c_BE
, c_C
, c_CXZ
, c_E
, c_ECXZ
, c_G
, c_GE
, c_L
, c_LE
,
250 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, c_NE
, c_NG
, c_NGE
, c_NL
, c_NLE
, c_NO
,
251 c_NP
, c_NS
, c_NZ
, c_O
, c_P
, c_PE
, c_PO
, c_S
, c_Z
253 static int inverse_ccs
[] = {
254 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, -1, c_NE
, -1, c_NG
, c_NGE
, c_NL
, c_NLE
,
255 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
,
256 c_Z
, c_NO
, c_NP
, c_PO
, c_PE
, c_NS
, c_NZ
262 static char *directives
[] = {
263 "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
264 "%elifid", "%elifidn", "%elifidni", "%elifnctx", "%elifndef",
265 "%elifnid", "%elifnidn", "%elifnidni", "%elifnnum", "%elifnstr",
266 "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
267 "%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
268 "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifnctx",
269 "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnnum",
270 "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include", "%line",
271 "%macro", "%pop", "%push", "%rep", "%repl", "%rotate"
274 PP_ASSIGN
, PP_CLEAR
, PP_DEFINE
, PP_ELIF
, PP_ELIFCTX
, PP_ELIFDEF
,
275 PP_ELIFID
, PP_ELIFIDN
, PP_ELIFIDNI
, PP_ELIFNCTX
, PP_ELIFNDEF
,
276 PP_ELIFNID
, PP_ELIFNIDN
, PP_ELIFNIDNI
, PP_ELIFNNUM
, PP_ELIFNSTR
,
277 PP_ELIFNUM
, PP_ELIFSTR
, PP_ELSE
, PP_ENDIF
, PP_ENDM
, PP_ENDMACRO
,
278 PP_ENDREP
, PP_ERROR
, PP_EXITREP
, PP_IASSIGN
, PP_IDEFINE
, PP_IF
,
279 PP_IFCTX
, PP_IFDEF
, PP_IFID
, PP_IFIDN
, PP_IFIDNI
, PP_IFNCTX
,
280 PP_IFNDEF
, PP_IFNID
, PP_IFNIDN
, PP_IFNIDNI
, PP_IFNNUM
,
281 PP_IFNSTR
, PP_IFNUM
, PP_IFSTR
, PP_IMACRO
, PP_INCLUDE
, PP_LINE
,
282 PP_MACRO
, PP_POP
, PP_PUSH
, PP_REP
, PP_REPL
, PP_ROTATE
286 static Context
*cstk
;
287 static Include
*istk
;
288 static IncPath
*ipath
= NULL
;
291 static evalfunc evaluate
;
295 static unsigned long unique
; /* unique identifier numbers */
297 static char *linesync
, *outline
;
299 static Line
*predef
= NULL
;
301 static ListGen
*list
;
304 * The number of hash values we use for the macro lookup tables.
309 * The current set of multi-line macros we have defined.
311 static MMacro
*mmacros
[NHASH
];
314 * The current set of single-line macros we have defined.
316 static SMacro
*smacros
[NHASH
];
319 * The multi-line macro we are currently defining, or the %rep
320 * block we are currently reading, if any.
322 static MMacro
*defining
;
325 * The number of macro parameters to allocate space for at a time.
327 #define PARAM_DELTA 16
330 * The standard macro set: defined as `static char *stdmac[]'. Also
331 * gives our position in the macro set, when we're processing it.
334 static char **stdmacpos
;
337 * The extra standard macros that come from the object format, if
340 static char **extrastdmac
= NULL
;
344 * Forward declarations.
346 static Token
*expand_smacro (Token
*tline
);
347 static void update_fileline (int which
);
350 * The pre-preprocessing stage... This function translates line
351 * number indications as they emerge from GNU cpp (`# lineno "file"
352 * flags') into NASM preprocessor line number indications (`%line
355 static char *prepreproc(char *line
) {
357 char *fname
, *oldline
;
359 if (line
[0] == '#' && line
[1] == ' ') {
362 lineno
= atoi(fname
);
363 fname
+= strspn(fname
, "0123456789 ");
366 fnlen
= strcspn(fname
, "\"");
367 line
= nasm_malloc(20+fnlen
);
368 sprintf(line
, "%%line %d %.*s", lineno
, fnlen
, fname
);
375 * The hash function for macro lookups. Note that due to some
376 * macros having case-insensitive names, the hash function must be
377 * invariant under case changes. We implement this by applying a
378 * perfectly normal hash function to the uppercase of the string.
380 static int hash(char *s
) {
382 * Powers of three, mod 31.
384 static const int multipliers
[] = {
385 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
386 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
392 h
+= multipliers
[i
] * (unsigned char) (toupper(*s
));
394 if (++i
>= (int)sizeof(multipliers
)/(int)sizeof(*multipliers
))
402 * Free a linked list of tokens.
404 static void free_tlist (Token
*list
) {
415 * Free a linked list of lines.
417 static void free_llist (Line
*list
) {
422 free_tlist (l
->first
);
428 * Pop the context stack.
430 static void ctx_pop (void) {
440 free_tlist (s
->expansion
);
448 * Generate a line synchronisation comment, to ensure the assembler
449 * knows which source file the current output has really come from.
451 static void line_sync (void) {
452 char text
[30+FILENAME_MAX
];
453 sprintf(text
, "%%line %d+%d %s",
454 (istk
->expansion
? istk
->lineno
- istk
->lineinc
: istk
->lineno
),
455 (istk
->expansion
? 0 : istk
->lineinc
), istk
->fname
);
456 nasm_free (linesync
);
457 linesync
= nasm_strdup(text
);
460 #define BUF_DELTA 512
462 * Read a line from the top file in istk, handling multiple CR/LFs
463 * at the end of the line read, and handling spurious ^Zs. Will
464 * return lines from the standard macro set if this has not already
467 static char *read_line (void) {
468 char *buffer
, *p
, *q
;
473 char *ret
= nasm_strdup(*stdmacpos
++);
474 if (!*stdmacpos
&& any_extrastdmac
) {
475 stdmacpos
= extrastdmac
;
476 any_extrastdmac
= FALSE
;
480 * Nasty hack: here we push the contents of `predef' on
481 * to the top-level expansion stack, since this is the
482 * most convenient way to implement the pre-include and
483 * pre-define features.
487 Token
*head
, **tail
, *t
, *tt
;
489 for (pd
= predef
; pd
; pd
= pd
->next
) {
492 for (t
= pd
->first
; t
; t
= t
->next
) {
493 tt
= *tail
= nasm_malloc(sizeof(Token
));
497 tt
->text
= nasm_strdup(t
->text
);
498 tt
->mac
= t
->mac
; /* always NULL here, in fact */
500 l
= nasm_malloc(sizeof(Line
));
501 l
->next
= istk
->expansion
;
511 update_fileline(3); /* update __FILE__ and __LINE__ */
516 buffer
= nasm_malloc(BUF_DELTA
);
519 q
= fgets(p
, bufsize
-(p
-buffer
), istk
->fp
);
523 if (p
> buffer
&& p
[-1] == '\n') {
524 istk
->lineno
+= istk
->lineinc
;
525 update_fileline(1); /* update __LINE__ only */
528 if (p
-buffer
> bufsize
-10) {
529 bufsize
+= BUF_DELTA
;
530 buffer
= nasm_realloc(buffer
, bufsize
);
534 if (!q
&& p
== buffer
) {
540 * Play safe: remove CRs as well as LFs, if any of either are
541 * present at the end of the line.
543 while (p
> buffer
&& (p
[-1] == '\n' || p
[-1] == '\r'))
547 * Handle spurious ^Z, which may be inserted into source files
548 * by some file transfer utilities.
550 buffer
[strcspn(buffer
, "\032")] = '\0';
552 list
->line (LIST_READ
, buffer
);
558 * Tokenise a line of text. This is a very simple process since we
559 * don't need to parse the value out of e.g. numeric tokens: we
560 * simply split one string into many.
562 static Token
*tokenise (char *line
) {
566 Token
*t
, **tail
= &list
;
571 (p
[1] == '{' || p
[1] == '!' || (p
[1] == '%' && isidchar(p
[2])) ||
572 p
[1] == '$' || p
[1] == '+' || p
[1] == '-' || isidchar(p
[1]))) {
573 type
= TOK_PREPROC_ID
;
577 while (*p
&& *p
!= '}') {
584 if (*p
== '!' || *p
== '%' || *p
== '$' ||
585 *p
== '+' || *p
== '-') p
++;
586 while (*p
&& isidchar(*p
))
589 } else if (isidstart(*p
) || (*p
== '$' && isidstart(p
[1]))) {
592 while (*p
&& isidchar(*p
))
594 } else if (*p
== '\'' || *p
== '"') {
601 while (*p
&& *p
!= c
)
604 } else if (isnumstart(*p
)) {
610 while (*p
&& isnumchar(*p
))
612 } else if (isspace(*p
)) {
613 type
= TOK_WHITESPACE
;
615 while (*p
&& isspace(*p
))
618 * Whitespace just before end-of-line is discarded by
619 * pretending it's a comment; whitespace just before a
620 * comment gets lumped into the comment.
622 if (!*p
|| *p
== ';') {
626 } else if (*p
== ';') {
631 * Anything else is an operator of some kind. We check
632 * for all the double-character operators (>>, <<, //,
633 * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
634 * else is a single-character operator.
637 if ((p
[0] == '>' && p
[1] == '>') ||
638 (p
[0] == '<' && p
[1] == '<') ||
639 (p
[0] == '/' && p
[1] == '/') ||
640 (p
[0] == '%' && p
[1] == '%') ||
641 (p
[0] == '<' && p
[1] == '=') ||
642 (p
[0] == '>' && p
[1] == '=') ||
643 (p
[0] == '=' && p
[1] == '=') ||
644 (p
[0] == '!' && p
[1] == '=') ||
645 (p
[0] == '<' && p
[1] == '>') ||
646 (p
[0] == '&' && p
[1] == '&') ||
647 (p
[0] == '|' && p
[1] == '|') ||
648 (p
[0] == '^' && p
[1] == '^'))
652 if (type
!= TOK_COMMENT
) {
653 *tail
= t
= nasm_malloc (sizeof(Token
));
657 t
->text
= nasm_malloc(1+p
-line
);
658 strncpy(t
->text
, line
, p
-line
);
659 t
->text
[p
-line
] = '\0';
668 * Convert a line of tokens back into text.
670 static char *detoken (Token
*tlist
) {
676 for (t
= tlist
; t
; t
= t
->next
) {
677 if (t
->type
== TOK_PREPROC_ID
&& t
->text
[1] == '!') {
678 char *p
= getenv(t
->text
+2);
681 t
->text
= nasm_strdup(p
);
686 len
+= strlen(t
->text
);
688 p
= line
= nasm_malloc(len
+1);
689 for (t
= tlist
; t
; t
= t
->next
) {
700 * A scanner, suitable for use by the expression evaluator, which
701 * operates on a line of Tokens. Expects a pointer to a pointer to
702 * the first token in the line to be passed in as its private_data
705 static int ppscan(void *private_data
, struct tokenval
*tokval
) {
706 Token
**tlineptr
= private_data
;
711 *tlineptr
= tline
? tline
->next
: NULL
;
712 } while (tline
&& (tline
->type
== TOK_WHITESPACE
||
713 tline
->type
== TOK_COMMENT
));
716 return tokval
->t_type
= TOKEN_EOS
;
718 if (tline
->text
[0] == '$' && !tline
->text
[1])
719 return tokval
->t_type
= TOKEN_HERE
;
720 if (tline
->text
[0] == '$' && tline
->text
[1] == '$' && !tline
->text
[1])
721 return tokval
->t_type
= TOKEN_BASE
;
723 if (tline
->type
== TOK_ID
) {
724 tokval
->t_charptr
= tline
->text
;
725 if (tline
->text
[0] == '$') {
727 return tokval
->t_type
= TOKEN_ID
;
731 * This is the only special case we actually need to worry
732 * about in this restricted context.
734 if (!nasm_stricmp(tline
->text
, "seg"))
735 return tokval
->t_type
= TOKEN_SEG
;
737 return tokval
->t_type
= TOKEN_ID
;
740 if (tline
->type
== TOK_NUMBER
) {
743 tokval
->t_integer
= readnum(tline
->text
, &rn_error
);
745 return tokval
->t_type
= TOKEN_ERRNUM
;
746 tokval
->t_charptr
= NULL
;
747 return tokval
->t_type
= TOKEN_NUM
;
750 if (tline
->type
== TOK_OTHER
) {
751 if (!strcmp(tline
->text
, "<<")) return tokval
->t_type
= TOKEN_SHL
;
752 if (!strcmp(tline
->text
, ">>")) return tokval
->t_type
= TOKEN_SHR
;
753 if (!strcmp(tline
->text
, "//")) return tokval
->t_type
= TOKEN_SDIV
;
754 if (!strcmp(tline
->text
, "%%")) return tokval
->t_type
= TOKEN_SMOD
;
755 if (!strcmp(tline
->text
, "==")) return tokval
->t_type
= TOKEN_EQ
;
756 if (!strcmp(tline
->text
, "<>")) return tokval
->t_type
= TOKEN_NE
;
757 if (!strcmp(tline
->text
, "!=")) return tokval
->t_type
= TOKEN_NE
;
758 if (!strcmp(tline
->text
, "<=")) return tokval
->t_type
= TOKEN_LE
;
759 if (!strcmp(tline
->text
, ">=")) return tokval
->t_type
= TOKEN_GE
;
760 if (!strcmp(tline
->text
, "&&")) return tokval
->t_type
= TOKEN_DBL_AND
;
761 if (!strcmp(tline
->text
, "^^")) return tokval
->t_type
= TOKEN_DBL_XOR
;
762 if (!strcmp(tline
->text
, "||")) return tokval
->t_type
= TOKEN_DBL_OR
;
766 * We have no other options: just return the first character of
769 return tokval
->t_type
= tline
->text
[0];
773 * Return the Context structure associated with a %$ token. Return
774 * NULL, having _already_ reported an error condition, if the
775 * context stack isn't deep enough for the supplied number of $
778 static Context
*get_ctx (char *name
) {
783 error (ERR_NONFATAL
|ERR_OFFBY1
, "`%s': context stack is empty", name
);
789 while (name
[i
+1] == '$') {
793 error (ERR_NONFATAL
|ERR_OFFBY1
, "`%s': context stack is only"
794 " %d level%s deep", name
, i
-1, (i
==2 ? "" : "s"));
802 * Compare a string to the name of an existing macro; this is a
803 * simple wrapper which calls either strcmp or nasm_stricmp
804 * depending on the value of the `casesense' parameter.
806 static int mstrcmp(char *p
, char *q
, int casesense
) {
807 return casesense
? strcmp(p
,q
) : nasm_stricmp(p
,q
);
811 * Open an include file. This routine must always return a valid
812 * file pointer if it returns - it's responsible for throwing an
813 * ERR_FATAL and bombing out completely if not. It should also try
814 * the include path one by one until it finds the file or reaches
815 * the end of the path.
817 static FILE *inc_fopen(char *file
) {
819 char *prefix
= "", *combine
;
821 int len
= strlen(file
);
824 combine
= nasm_malloc(strlen(prefix
)+len
+1);
825 strcpy(combine
, prefix
);
826 strcat(combine
, file
);
827 fp
= fopen(combine
, "r");
831 prefix
= ip
? ip
->path
: NULL
;
836 error (ERR_FATAL
|ERR_OFFBY1
,
837 "unable to open include file `%s'", file
);
838 return NULL
; /* never reached - placate compilers */
842 * Determine if we should warn on defining a single-line macro of
843 * name `name', with `nparam' parameters. If nparam is 0, will
844 * return TRUE if _any_ single-line macro of that name is defined.
845 * Otherwise, will return TRUE if a single-line macro with either
846 * `nparam' or no parameters is defined.
848 * If a macro with precisely the right number of parameters is
849 * defined, the address of the definition structure will be
850 * returned in `defn'; otherwise NULL will be returned. If `defn'
851 * is NULL, no action will be taken regarding its contents, and no
854 * Note that this is also called with nparam zero to resolve
857 static int smacro_defined (char *name
, int nparam
, SMacro
**defn
) {
862 if (name
[0] == '%' && name
[1] == '$') {
863 ctx
= get_ctx (name
);
865 return FALSE
; /* got to return _something_ */
870 m
= smacros
[hash(name
)];
875 if (!mstrcmp(m
->name
, p
, m
->casesense
) &&
876 (nparam
== 0 || m
->nparam
== 0 || nparam
== m
->nparam
)) {
878 if (nparam
== m
->nparam
)
891 * Update the __FILE__ and __LINE__ macros. Specifically, update
892 * __FILE__ if bit 1 of our argument is set, and update __LINE__ if
895 * If the macros don't exist, a `%clear' must have happened, in
896 * which case we should exit quite happily and carry on going. It's
897 * not an error condition.
899 static void update_fileline(int which
) {
903 if ((which
& 3) && smacro_defined ("__FILE__", 0, &sm
) && sm
) {
904 free_tlist(sm
->expansion
);
905 sm
->expansion
= nasm_malloc(sizeof(Token
));
906 sm
->expansion
->next
= NULL
;
907 sm
->expansion
->mac
= NULL
;
908 sm
->expansion
->type
= TOK_STRING
;
909 sm
->expansion
->text
= nasm_malloc(3+strlen(istk
->fname
));
910 /* FIXME: throw an error if both sorts of quote are present */
911 /* Better still, invent a way for us to cope with that case */
912 sprintf(sm
->expansion
->text
, "\"%s\"", istk
->fname
);
915 if ((which
& 1) && smacro_defined ("__LINE__", 0, &sm
) && sm
) {
916 free_tlist(sm
->expansion
);
917 sm
->expansion
= nasm_malloc(sizeof(Token
));
918 sm
->expansion
->next
= NULL
;
919 sm
->expansion
->mac
= NULL
;
920 sm
->expansion
->type
= TOK_NUMBER
;
921 sprintf(num
, "%d", istk
->lineno
- istk
->lineinc
);
922 sm
->expansion
->text
= nasm_strdup(num
);
927 * Count and mark off the parameters in a multi-line macro call.
928 * This is called both from within the multi-line macro expansion
929 * code, and also to mark off the default parameters when provided
930 * in a %macro definition line.
932 static void count_mmac_params (Token
*t
, int *nparam
, Token
***params
) {
933 int paramsize
, brace
;
935 *nparam
= paramsize
= 0;
938 if (*nparam
>= paramsize
) {
939 paramsize
+= PARAM_DELTA
;
940 *params
= nasm_realloc(*params
, sizeof(**params
) * paramsize
);
942 if (t
&& t
->type
== TOK_WHITESPACE
)
945 if (t
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "{"))
947 (*params
)[(*nparam
)++] = t
;
948 while (t
&& (t
->type
!= TOK_OTHER
||
949 strcmp(t
->text
, brace
? "}" : ",")))
951 if (t
) { /* got a comma/brace */
955 * Now we've found the closing brace, look further
958 if (t
&& t
->type
== TOK_WHITESPACE
)
960 if (t
&& (t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ","))) {
961 error (ERR_NONFATAL
|ERR_OFFBY1
,
962 "braces do not enclose all of macro parameter");
963 while (t
&& (t
->type
!= TOK_OTHER
||
964 strcmp(t
->text
, ",")))
968 t
= t
->next
; /* eat the comma */
977 * Determine whether one of the various `if' conditions is true or
980 * We must free the tline we get passed.
982 static int if_condition (Token
*tline
, int i
) {
984 Token
*t
, *tt
, **tptr
, *origline
;
985 struct tokenval tokval
;
991 case PP_IFCTX
: case PP_ELIFCTX
:
992 case PP_IFNCTX
: case PP_ELIFNCTX
:
993 j
= FALSE
; /* have we matched yet? */
995 error(ERR_FATAL
|ERR_OFFBY1
,
996 "`%s': context stack is empty", directives
[i
]);
998 if (tline
->type
== TOK_WHITESPACE
)
1000 if (!tline
|| tline
->type
!= TOK_ID
) {
1001 error(ERR_NONFATAL
|ERR_OFFBY1
,
1002 "`%s' expects context identifiers", directives
[i
]);
1003 free_tlist (origline
);
1006 if (!nasm_stricmp(tline
->text
, cstk
->name
))
1008 tline
= tline
->next
;
1010 if (i
== PP_IFNCTX
|| i
== PP_ELIFNCTX
)
1012 free_tlist (origline
);
1015 case PP_IFDEF
: case PP_ELIFDEF
:
1016 case PP_IFNDEF
: case PP_ELIFNDEF
:
1017 j
= FALSE
; /* have we matched yet? */
1019 if (tline
->type
== TOK_WHITESPACE
)
1020 tline
= tline
->next
;
1021 if (!tline
|| (tline
->type
!= TOK_ID
&&
1022 (tline
->type
!= TOK_PREPROC_ID
||
1023 tline
->text
[1] != '$'))) {
1024 error(ERR_NONFATAL
|ERR_OFFBY1
,
1025 "`%%if%sdef' expects macro identifiers",
1026 (i
==PP_ELIFNDEF
? "n" : ""));
1027 free_tlist (origline
);
1030 if (smacro_defined(tline
->text
, 0, NULL
))
1032 tline
= tline
->next
;
1034 if (i
== PP_IFNDEF
|| i
== PP_ELIFNDEF
)
1036 free_tlist (origline
);
1039 case PP_IFIDN
: case PP_ELIFIDN
: case PP_IFNIDN
: case PP_ELIFNIDN
:
1040 case PP_IFIDNI
: case PP_ELIFIDNI
: case PP_IFNIDNI
: case PP_ELIFNIDNI
:
1041 tline
= expand_smacro(tline
);
1043 while (tt
&& (tt
->type
!= TOK_OTHER
|| strcmp(tt
->text
, ",")))
1046 error(ERR_NONFATAL
, "`%s' expects two comma-separated arguments");
1051 casesense
= (i
== PP_IFIDN
|| i
== PP_ELIFIDN
||
1052 i
== PP_IFNIDN
|| i
== PP_ELIFNIDN
);
1053 j
= TRUE
; /* assume equality unless proved not */
1054 while ((t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ",")) && tt
) {
1055 if (tt
->type
== TOK_OTHER
&& !strcmp(tt
->text
, ",")) {
1056 error(ERR_NONFATAL
, "`%s': more than one comma on line",
1061 if (t
->type
== TOK_WHITESPACE
) {
1064 } else if (tt
->type
== TOK_WHITESPACE
) {
1067 } else if (tt
->type
!= t
->type
||
1068 (casesense
? strcmp(tt
->text
, t
->text
) :
1069 nasm_stricmp(tt
->text
, t
->text
))) {
1070 j
= FALSE
; /* found mismatching tokens */
1078 if ((t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ",")) || tt
)
1079 j
= FALSE
; /* trailing gunk on one end or other */
1080 if (i
== PP_IFNIDN
|| i
== PP_ELIFNIDN
)
1085 case PP_IFID
: case PP_ELIFID
: case PP_IFNID
: case PP_ELIFNID
:
1086 case PP_IFNUM
: case PP_ELIFNUM
: case PP_IFNNUM
: case PP_ELIFNNUM
:
1087 case PP_IFSTR
: case PP_ELIFSTR
: case PP_IFNSTR
: case PP_ELIFNSTR
:
1088 tline
= expand_smacro(tline
);
1090 while (t
&& t
->type
== TOK_WHITESPACE
)
1092 j
= FALSE
; /* placate optimiser */
1094 case PP_IFID
: case PP_ELIFID
: case PP_IFNID
: case PP_ELIFNID
:
1095 j
= (t
->type
== TOK_ID
);
1097 case PP_IFNUM
: case PP_ELIFNUM
: case PP_IFNNUM
: case PP_ELIFNNUM
:
1098 j
= (t
->type
== TOK_NUMBER
);
1100 case PP_IFSTR
: case PP_ELIFSTR
: case PP_IFNSTR
: case PP_ELIFNSTR
:
1101 j
= (t
->type
== TOK_STRING
);
1104 if (i
== PP_IFNID
|| i
== PP_ELIFNID
||
1105 i
== PP_IFNNUM
|| i
== PP_ELIFNNUM
||
1106 i
== PP_IFNSTR
|| i
== PP_ELIFNSTR
)
1111 case PP_IF
: case PP_ELIF
:
1112 t
= tline
= expand_smacro(tline
);
1114 tokval
.t_type
= TOKEN_INVALID
;
1115 evalresult
= evaluate (ppscan
, tptr
, &tokval
,
1116 NULL
, pass
| 0x10, error
, NULL
);
1121 error(ERR_WARNING
|ERR_OFFBY1
,
1122 "trailing garbage after expression ignored");
1123 if (!is_simple(evalresult
)) {
1124 error(ERR_NONFATAL
|ERR_OFFBY1
,
1125 "non-constant value given to `%s'", directives
[i
]);
1128 return reloc_value(evalresult
) != 0;
1131 error(ERR_FATAL
|ERR_OFFBY1
,
1132 "preprocessor directive `%s' not yet implemented",
1134 free_tlist (origline
);
1135 return -1; /* yeah, right */
1140 * Find out if a line contains a preprocessor directive, and deal
1143 * If a directive _is_ found, we are expected to free_tlist() the
1146 * Return values go like this:
1148 * bit 0 is set if a directive was found (so the line gets freed)
1149 * bit 1 is set if a blank line should be emitted
1150 * bit 2 is set if a re-sync line number comment should be emitted
1152 * (bits 1 and 2 are mutually exclusive in that the rest of the
1153 * preprocessor doesn't guarantee to be able to handle the case in
1154 * which both are set)
1156 static int do_directive (Token
*tline
) {
1157 int i
, j
, k
, m
, nparam
, nolist
;
1162 SMacro
*smac
, **smhead
;
1164 Token
*t
, *tt
, *param_start
, *macro_start
, *last
, **tptr
, *origline
;
1166 struct tokenval tokval
;
1171 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1172 tline
= tline
->next
;
1173 if (!tline
|| tline
->type
!= TOK_PREPROC_ID
||
1174 (tline
->text
[1]=='%' || tline
->text
[1]=='$' || tline
->text
[1]=='!'))
1178 j
= sizeof(directives
)/sizeof(*directives
);
1181 m
= nasm_stricmp(tline
->text
, directives
[k
]);
1193 * If we're in a non-emitting branch of a condition construct,
1194 * or walking to the end of an already terminated %rep block,
1195 * we should ignore all directives except for condition
1198 if (((istk
->conds
&& !emitting(istk
->conds
->state
)) ||
1199 (istk
->mstk
&& !istk
->mstk
->in_progress
)) &&
1200 i
!= PP_IF
&& i
!= PP_ELIF
&&
1201 i
!= PP_IFCTX
&& i
!= PP_ELIFCTX
&&
1202 i
!= PP_IFDEF
&& i
!= PP_ELIFDEF
&&
1203 i
!= PP_IFID
&& i
!= PP_ELIFID
&&
1204 i
!= PP_IFIDN
&& i
!= PP_ELIFIDN
&&
1205 i
!= PP_IFIDNI
&& i
!= PP_ELIFIDNI
&&
1206 i
!= PP_IFNCTX
&& i
!= PP_ELIFNCTX
&&
1207 i
!= PP_IFNDEF
&& i
!= PP_ELIFNDEF
&&
1208 i
!= PP_IFNID
&& i
!= PP_ELIFNID
&&
1209 i
!= PP_IFNIDN
&& i
!= PP_ELIFNIDN
&&
1210 i
!= PP_IFNIDNI
&& i
!= PP_ELIFNIDNI
&&
1211 i
!= PP_IFNNUM
&& i
!= PP_ELIFNNUM
&&
1212 i
!= PP_IFNSTR
&& i
!= PP_ELIFNSTR
&&
1213 i
!= PP_IFNUM
&& i
!= PP_ELIFNUM
&&
1214 i
!= PP_IFSTR
&& i
!= PP_ELIFSTR
&&
1215 i
!= PP_ELSE
&& i
!= PP_ENDIF
)
1219 * If we're defining a macro or reading a %rep block, we should
1220 * ignore all directives except for %macro/%imacro (which
1221 * generate an error), %endm/%endmacro, and (only if we're in a
1222 * %rep block) %endrep.
1224 if (defining
&& i
!= PP_MACRO
&& i
!= PP_IMACRO
&&
1225 i
!= PP_ENDMACRO
&& i
!= PP_ENDM
&&
1226 (defining
->name
|| i
!= PP_ENDREP
))
1230 error(ERR_NONFATAL
|ERR_OFFBY1
, "unknown preprocessor directive `%s'",
1232 return 0; /* didn't get it */
1239 error(ERR_WARNING
|ERR_OFFBY1
,
1240 "trailing garbage after `%%clear' ignored");
1241 for (j
=0; j
<NHASH
; j
++) {
1242 while (mmacros
[j
]) {
1243 MMacro
*m
= mmacros
[j
];
1244 mmacros
[j
] = mmacros
[j
]->next
;
1245 nasm_free (m
->name
);
1246 free_tlist (m
->dlist
);
1247 free_llist (m
->expansion
);
1250 while (smacros
[j
]) {
1251 SMacro
*s
= smacros
[j
];
1252 smacros
[j
] = smacros
[j
]->next
;
1253 nasm_free (s
->name
);
1254 free_tlist (s
->expansion
);
1258 free_tlist (origline
);
1262 tline
= tline
->next
;
1263 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1264 tline
= tline
->next
;
1265 if (!tline
|| (tline
->type
!= TOK_STRING
&&
1266 tline
->type
!= TOK_INTERNAL_STRING
)) {
1267 error(ERR_NONFATAL
|ERR_OFFBY1
, "`%%include' expects a file name");
1268 free_tlist (origline
);
1269 return 3; /* but we did _something_ */
1272 error(ERR_WARNING
|ERR_OFFBY1
,
1273 "trailing garbage after `%%include' ignored");
1274 if (tline
->type
!= TOK_INTERNAL_STRING
) {
1275 p
= tline
->text
+1; /* point past the quote to the name */
1276 p
[strlen(p
)-1] = '\0'; /* remove the trailing quote */
1278 p
= tline
->text
; /* internal_string is easier */
1279 inc
= nasm_malloc(sizeof(Include
));
1282 inc
->fp
= inc_fopen(p
);
1283 inc
->fname
= nasm_strdup(p
);
1284 inc
->lineno
= inc
->lineinc
= 1;
1285 inc
->expansion
= NULL
;
1288 list
->uplevel (LIST_INCLUDE
);
1289 update_fileline(3); /* update __FILE__ and __LINE__ */
1290 free_tlist (origline
);
1294 tline
= tline
->next
;
1295 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1296 tline
= tline
->next
;
1297 if (!tline
|| tline
->type
!= TOK_ID
) {
1298 error(ERR_NONFATAL
|ERR_OFFBY1
,
1299 "`%%push' expects a context identifier");
1300 free_tlist (origline
);
1301 return 3; /* but we did _something_ */
1304 error(ERR_WARNING
|ERR_OFFBY1
,
1305 "trailing garbage after `%%push' ignored");
1306 ctx
= nasm_malloc(sizeof(Context
));
1308 ctx
->localmac
= NULL
;
1309 ctx
->name
= nasm_strdup(tline
->text
);
1310 ctx
->number
= unique
++;
1312 free_tlist (origline
);
1316 tline
= tline
->next
;
1317 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1318 tline
= tline
->next
;
1319 if (!tline
|| tline
->type
!= TOK_ID
) {
1320 error(ERR_NONFATAL
|ERR_OFFBY1
,
1321 "`%%repl' expects a context identifier");
1322 free_tlist (origline
);
1323 return 3; /* but we did _something_ */
1326 error(ERR_WARNING
|ERR_OFFBY1
,
1327 "trailing garbage after `%%repl' ignored");
1329 error(ERR_NONFATAL
|ERR_OFFBY1
,
1330 "`%%repl': context stack is empty");
1332 nasm_free (cstk
->name
);
1333 cstk
->name
= nasm_strdup(tline
->text
);
1335 free_tlist (origline
);
1340 error(ERR_WARNING
|ERR_OFFBY1
,
1341 "trailing garbage after `%%pop' ignored");
1343 error(ERR_NONFATAL
|ERR_OFFBY1
,
1344 "`%%pop': context stack is already empty");
1347 free_tlist (origline
);
1351 tline
= tline
->next
;
1352 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1353 tline
= tline
->next
;
1354 if (!tline
|| tline
->type
!= TOK_STRING
) {
1355 error(ERR_NONFATAL
|ERR_OFFBY1
,
1356 "`%%error' expects an error string");
1357 free_tlist (origline
);
1358 return 3; /* but we did _something_ */
1361 error(ERR_WARNING
|ERR_OFFBY1
,
1362 "trailing garbage after `%%error' ignored");
1363 p
= tline
->text
+1; /* point past the quote to the name */
1364 p
[strlen(p
)-1] = '\0'; /* remove the trailing quote */
1365 error(ERR_NONFATAL
|ERR_OFFBY1
, "user error: %s", p
);
1366 free_tlist (origline
);
1384 if (istk
->conds
&& !emitting(istk
->conds
->state
))
1387 j
= if_condition(tline
->next
, i
);
1388 tline
->next
= NULL
; /* it got freed */
1389 free_tlist (origline
);
1393 j
= j
? COND_IF_TRUE
: COND_IF_FALSE
;
1395 cond
= nasm_malloc(sizeof(Cond
));
1396 cond
->next
= istk
->conds
;
1399 return (j
== COND_IF_TRUE
? 3 : 1);
1417 error(ERR_FATAL
|ERR_OFFBY1
, "`%s': no matching `%%if'",
1419 if (emitting(istk
->conds
->state
) || istk
->conds
->state
== COND_NEVER
)
1420 istk
->conds
->state
= COND_NEVER
;
1422 j
= if_condition(tline
->next
, i
);
1423 tline
->next
= NULL
; /* it got freed */
1424 free_tlist (origline
);
1428 istk
->conds
->state
= j
? COND_IF_TRUE
: COND_IF_FALSE
;
1430 return (istk
->conds
->state
== COND_IF_TRUE
? 5 : 1);
1434 error(ERR_WARNING
|ERR_OFFBY1
,
1435 "trailing garbage after `%%else' ignored");
1437 error(ERR_FATAL
|ERR_OFFBY1
,
1438 "`%%else': no matching `%%if'");
1439 if (emitting(istk
->conds
->state
) || istk
->conds
->state
== COND_NEVER
)
1440 istk
->conds
->state
= COND_ELSE_FALSE
;
1442 istk
->conds
->state
= COND_ELSE_TRUE
;
1443 free_tlist (origline
);
1448 error(ERR_WARNING
|ERR_OFFBY1
,
1449 "trailing garbage after `%%endif' ignored");
1451 error(ERR_FATAL
|ERR_OFFBY1
,
1452 "`%%endif': no matching `%%if'");
1454 istk
->conds
= cond
->next
;
1456 free_tlist (origline
);
1462 error (ERR_FATAL
|ERR_OFFBY1
,
1463 "`%%%smacro': already defining a macro",
1464 (i
== PP_IMACRO
? "i" : ""));
1465 tline
= tline
->next
;
1466 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1467 tline
= tline
->next
;
1468 if (!tline
|| tline
->type
!= TOK_ID
) {
1469 error (ERR_NONFATAL
|ERR_OFFBY1
,
1470 "`%%%smacro' expects a macro name",
1471 (i
== PP_IMACRO
? "i" : ""));
1474 defining
= nasm_malloc(sizeof(MMacro
));
1475 defining
->name
= nasm_strdup(tline
->text
);
1476 defining
->casesense
= (i
== PP_MACRO
);
1477 defining
->plus
= FALSE
;
1478 defining
->nolist
= FALSE
;
1479 defining
->in_progress
= FALSE
;
1480 tline
= tline
->next
;
1481 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1482 tline
= tline
->next
;
1483 if (!tline
|| tline
->type
!= TOK_NUMBER
) {
1484 error (ERR_NONFATAL
|ERR_OFFBY1
,
1485 "`%%%smacro' expects a parameter count",
1486 (i
== PP_IMACRO
? "i" : ""));
1487 defining
->nparam_min
= defining
->nparam_max
= 0;
1489 defining
->nparam_min
= defining
->nparam_max
=
1490 readnum(tline
->text
, &j
);
1492 error (ERR_NONFATAL
|ERR_OFFBY1
,
1493 "unable to parse parameter count `%s'", tline
->text
);
1495 if (tline
&& tline
->next
&& tline
->next
->type
== TOK_OTHER
&&
1496 !strcmp(tline
->next
->text
, "-")) {
1497 tline
= tline
->next
->next
;
1498 if (tline
&& tline
->type
== TOK_OTHER
&&
1499 !strcmp(tline
->text
, "*"))
1500 defining
->nparam_max
= INT_MAX
;
1501 else if (!tline
|| tline
->type
!= TOK_NUMBER
)
1502 error (ERR_NONFATAL
|ERR_OFFBY1
,
1503 "`%%%smacro' expects a parameter count after `-'",
1504 (i
== PP_IMACRO
? "i" : ""));
1506 defining
->nparam_max
= readnum(tline
->text
, &j
);
1508 error (ERR_NONFATAL
|ERR_OFFBY1
,
1509 "unable to parse parameter count `%s'",
1511 if (defining
->nparam_min
> defining
->nparam_max
)
1512 error (ERR_NONFATAL
|ERR_OFFBY1
,
1513 "minimum parameter count exceeds maximum");
1516 if (tline
&& tline
->next
&& tline
->next
->type
== TOK_OTHER
&&
1517 !strcmp(tline
->next
->text
, "+")) {
1518 tline
= tline
->next
;
1519 defining
->plus
= TRUE
;
1521 if (tline
&& tline
->next
&& tline
->next
->type
== TOK_ID
&&
1522 !nasm_stricmp(tline
->next
->text
, ".nolist")) {
1523 tline
= tline
->next
;
1524 defining
->nolist
= TRUE
;
1526 mmac
= mmacros
[hash(defining
->name
)];
1528 if (!strcmp(mmac
->name
, defining
->name
) &&
1529 (mmac
->nparam_min
<=defining
->nparam_max
|| defining
->plus
) &&
1530 (defining
->nparam_min
<=mmac
->nparam_max
|| mmac
->plus
)) {
1531 error (ERR_WARNING
|ERR_OFFBY1
,
1532 "redefining multi-line macro `%s'", defining
->name
);
1538 * Handle default parameters.
1540 if (tline
&& tline
->next
) {
1541 defining
->dlist
= tline
->next
;
1543 count_mmac_params (defining
->dlist
, &defining
->ndefs
,
1544 &defining
->defaults
);
1546 defining
->dlist
= NULL
;
1547 defining
->defaults
= NULL
;
1549 defining
->expansion
= NULL
;
1550 free_tlist (origline
);
1556 error (ERR_NONFATAL
|ERR_OFFBY1
, "`%s': not defining a macro",
1560 k
= hash(defining
->name
);
1561 defining
->next
= mmacros
[k
];
1562 mmacros
[k
] = defining
;
1564 free_tlist (origline
);
1568 if (tline
->next
&& tline
->next
->type
== TOK_WHITESPACE
)
1569 tline
= tline
->next
;
1570 t
= expand_smacro(tline
->next
);
1572 free_tlist (origline
);
1575 tokval
.t_type
= TOKEN_INVALID
;
1576 evalresult
= evaluate (ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
1581 error(ERR_WARNING
|ERR_OFFBY1
,
1582 "trailing garbage after expression ignored");
1583 if (!is_simple(evalresult
)) {
1584 error(ERR_NONFATAL
|ERR_OFFBY1
,
1585 "non-constant value given to `%%rotate'");
1589 while (mmac
&& !mmac
->name
) /* avoid mistaking %reps for macros */
1590 mmac
= mmac
->next_active
;
1592 error(ERR_NONFATAL
, "`%rotate' invoked outside a macro call");
1593 mmac
->rotate
= mmac
->rotate
+ reloc_value(evalresult
);
1594 if (mmac
->rotate
< 0)
1595 mmac
->rotate
= mmac
->nparam
- (-mmac
->rotate
) % mmac
->nparam
;
1596 mmac
->rotate
%= mmac
->nparam
;
1601 tline
= tline
->next
;
1602 if (tline
->next
&& tline
->next
->type
== TOK_WHITESPACE
)
1603 tline
= tline
->next
;
1604 if (tline
->next
&& tline
->next
->type
== TOK_ID
&&
1605 !nasm_stricmp(tline
->next
->text
, ".nolist")) {
1606 tline
= tline
->next
;
1609 t
= expand_smacro(tline
->next
);
1611 free_tlist (origline
);
1614 tokval
.t_type
= TOKEN_INVALID
;
1615 evalresult
= evaluate (ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
1620 error(ERR_WARNING
|ERR_OFFBY1
,
1621 "trailing garbage after expression ignored");
1622 if (!is_simple(evalresult
)) {
1623 error(ERR_NONFATAL
|ERR_OFFBY1
,
1624 "non-constant value given to `%%rep'");
1627 defining
= nasm_malloc(sizeof(MMacro
));
1628 defining
->name
= NULL
; /* flags this macro as a %rep block */
1629 defining
->casesense
= 0;
1630 defining
->plus
= FALSE
;
1631 defining
->nolist
= nolist
;
1632 defining
->in_progress
= reloc_value(evalresult
) + 1;
1633 defining
->nparam_min
= defining
->nparam_max
= 0;
1634 defining
->expansion
= NULL
;
1635 defining
->next_active
= istk
->mstk
;
1640 error (ERR_NONFATAL
|ERR_OFFBY1
,
1641 "`%%endrep': no matching `%%rep'");
1646 * Now we have a "macro" defined - although it has no name
1647 * and we won't be entering it in the hash tables - we must
1648 * push a macro-end marker for it on to istk->expansion.
1649 * After that, it will take care of propagating itself (a
1650 * macro-end marker line for a macro which is really a %rep
1651 * block will cause the macro to be re-expanded, complete
1652 * with another macro-end marker to ensure the process
1653 * continues) until the whole expansion is forcibly removed
1654 * from istk->expansion by a %exitrep.
1656 l
= nasm_malloc(sizeof(Line
));
1657 l
->next
= istk
->expansion
;
1658 l
->finishes
= defining
;
1660 istk
->expansion
= l
;
1662 istk
->mstk
= defining
;
1664 list
->uplevel (defining
->nolist
? LIST_MACRO_NOLIST
: LIST_MACRO
);
1666 free_tlist (origline
);
1667 return 1; /* the expansion will line-sync */
1671 * We must search along istk->expansion until we hit a
1672 * macro-end marker for a macro with no name. Then we set
1673 * its `in_progress' flag to 0.
1675 for (l
= istk
->expansion
; l
; l
= l
->next
)
1676 if (l
->finishes
&& !l
->finishes
->name
)
1679 if (l
->finishes
&& !l
->finishes
->name
)
1680 l
->finishes
->in_progress
= 0;
1682 error (ERR_NONFATAL
, "`%%exitrep' not within `%%rep' block");
1683 free_tlist (origline
);
1684 return 1; /* the end marker will line-sync */
1688 tline
= tline
->next
;
1689 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1690 tline
= tline
->next
;
1691 if (!tline
|| (tline
->type
!= TOK_ID
&&
1692 (tline
->type
!= TOK_PREPROC_ID
||
1693 tline
->text
[1] != '$'))) {
1694 error (ERR_NONFATAL
|ERR_OFFBY1
,
1695 "`%%%sdefine' expects a macro identifier",
1696 (i
== PP_IDEFINE
? "i" : ""));
1697 free_tlist (origline
);
1700 mname
= tline
->text
;
1701 if (tline
->type
== TOK_ID
) {
1703 smhead
= &smacros
[hash(mname
)];
1705 ctx
= get_ctx (tline
->text
);
1710 p
+= strspn(p
, "$");
1711 smhead
= &ctx
->localmac
;
1715 param_start
= tline
= tline
->next
;
1717 if (tline
&& tline
->type
== TOK_OTHER
&& !strcmp(tline
->text
, "(")) {
1719 * This macro has parameters.
1722 tline
= tline
->next
;
1724 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1725 tline
= tline
->next
;
1727 error (ERR_NONFATAL
|ERR_OFFBY1
,
1728 "parameter identifier expected");
1729 free_tlist (origline
);
1732 if (tline
->type
!= TOK_ID
) {
1733 error (ERR_NONFATAL
|ERR_OFFBY1
,
1734 "`%s': parameter identifier expected",
1736 free_tlist (origline
);
1739 tline
->type
= TOK_SMAC_PARAM
+ nparam
++;
1740 tline
= tline
->next
;
1741 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1742 tline
= tline
->next
;
1743 if (tline
&& tline
->type
== TOK_OTHER
&&
1744 !strcmp(tline
->text
, ",")) {
1745 tline
= tline
->next
;
1748 if (!tline
|| tline
->type
!= TOK_OTHER
||
1749 strcmp(tline
->text
, ")")) {
1750 error (ERR_NONFATAL
|ERR_OFFBY1
,
1751 "`)' expected to terminate macro template");
1752 free_tlist (origline
);
1758 tline
= tline
->next
;
1760 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1761 last
= tline
, tline
= tline
->next
;
1766 if (t
->type
== TOK_ID
) {
1767 for (tt
= param_start
; tt
; tt
= tt
->next
)
1768 if (tt
->type
>= TOK_SMAC_PARAM
&&
1769 !strcmp(tt
->text
, t
->text
))
1773 t
->next
= macro_start
;
1778 * Good. We now have a macro name, a parameter count, and a
1779 * token list (in reverse order) for an expansion. We ought
1780 * to be OK just to create an SMacro, store it, and let
1781 * free_tlist have the rest of the line (which we have
1782 * carefully re-terminated after chopping off the expansion
1785 if (smacro_defined (mname
, nparam
, &smac
)) {
1787 error (ERR_WARNING
|ERR_OFFBY1
,
1788 "single-line macro `%s' defined both with and"
1789 " without parameters", mname
);
1792 * We're redefining, so we have to take over an
1793 * existing SMacro structure. This means freeing
1794 * what was already in it.
1796 nasm_free (smac
->name
);
1797 free_tlist (smac
->expansion
);
1800 smac
= nasm_malloc(sizeof(SMacro
));
1801 smac
->next
= *smhead
;
1804 smac
->name
= nasm_strdup(p
);
1805 smac
->casesense
= (i
== PP_DEFINE
);
1806 smac
->nparam
= nparam
;
1807 smac
->expansion
= macro_start
;
1808 smac
->in_progress
= FALSE
;
1809 free_tlist (origline
);
1814 tline
= tline
->next
;
1815 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1816 tline
= tline
->next
;
1817 if (!tline
|| (tline
->type
!= TOK_ID
&&
1818 (tline
->type
!= TOK_PREPROC_ID
||
1819 tline
->text
[1] != '$'))) {
1820 error (ERR_NONFATAL
|ERR_OFFBY1
,
1821 "`%%%sassign' expects a macro identifier",
1822 (i
== PP_IASSIGN
? "i" : ""));
1823 free_tlist (origline
);
1826 mname
= tline
->text
;
1827 if (tline
->type
== TOK_ID
) {
1829 smhead
= &smacros
[hash(mname
)];
1831 ctx
= get_ctx (tline
->text
);
1833 free_tlist (origline
);
1837 p
+= strspn(p
, "$");
1838 smhead
= &ctx
->localmac
;
1842 tline
= tline
->next
;
1845 tline
= expand_smacro (tline
);
1848 tokval
.t_type
= TOKEN_INVALID
;
1849 evalresult
= evaluate (ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
1852 free_tlist (origline
);
1857 error(ERR_WARNING
|ERR_OFFBY1
,
1858 "trailing garbage after expression ignored");
1860 if (!is_simple(evalresult
)) {
1861 error(ERR_NONFATAL
|ERR_OFFBY1
,
1862 "non-constant value given to `%%%sassign'",
1863 (i
== PP_IASSIGN
? "i" : ""));
1864 free_tlist (origline
);
1868 macro_start
= nasm_malloc(sizeof(*macro_start
));
1869 macro_start
->next
= NULL
;
1872 sprintf(numbuf
, "%ld", reloc_value(evalresult
));
1873 macro_start
->text
= nasm_strdup(numbuf
);
1875 macro_start
->mac
= NULL
;
1876 macro_start
->type
= TOK_NUMBER
;
1879 * We now have a macro name, an implicit parameter count of
1880 * zero, and a numeric token to use as an expansion. Create
1881 * and store an SMacro.
1883 if (smacro_defined (mname
, 0, &smac
)) {
1885 error (ERR_WARNING
|ERR_OFFBY1
,
1886 "single-line macro `%s' defined both with and"
1887 " without parameters", mname
);
1890 * We're redefining, so we have to take over an
1891 * existing SMacro structure. This means freeing
1892 * what was already in it.
1894 nasm_free (smac
->name
);
1895 free_tlist (smac
->expansion
);
1898 smac
= nasm_malloc(sizeof(SMacro
));
1899 smac
->next
= *smhead
;
1902 smac
->name
= nasm_strdup(p
);
1903 smac
->casesense
= (i
== PP_ASSIGN
);
1905 smac
->expansion
= macro_start
;
1906 smac
->in_progress
= FALSE
;
1907 free_tlist (origline
);
1912 * Syntax is `%line nnn[+mmm] [filename]'
1914 tline
= tline
->next
;
1915 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1916 tline
= tline
->next
;
1917 if (!tline
|| tline
->type
!= TOK_NUMBER
) {
1918 error (ERR_NONFATAL
|ERR_OFFBY1
, "`%%line' expects line number");
1919 free_tlist (origline
);
1922 k
= readnum(tline
->text
, &j
);
1924 tline
= tline
->next
;
1925 if (tline
&& tline
->type
== TOK_OTHER
&& !strcmp(tline
->text
, "+")) {
1926 tline
= tline
->next
;
1927 if (!tline
|| tline
->type
!= TOK_NUMBER
) {
1928 error (ERR_NONFATAL
|ERR_OFFBY1
,
1929 "`%%line' expects line increment");
1930 free_tlist (origline
);
1933 m
= readnum(tline
->text
, &j
);
1934 tline
= tline
->next
;
1936 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1937 tline
= tline
->next
;
1940 update_fileline(3); /* update __FILE__ and __LINE__ */
1942 char *s
= detoken(tline
);
1943 nasm_free (istk
->fname
);
1946 free_tlist (origline
);
1950 error(ERR_FATAL
|ERR_OFFBY1
,
1951 "preprocessor directive `%s' not yet implemented",
1959 * Ensure that a macro parameter contains a condition code and
1960 * nothing else. Return the condition code index if so, or -1
1963 static int find_cc (Token
*t
) {
1967 if (t
&& t
->type
== TOK_WHITESPACE
)
1969 if (t
->type
!= TOK_ID
)
1972 if (tt
&& tt
->type
== TOK_WHITESPACE
)
1974 if (tt
&& (tt
->type
!= TOK_OTHER
|| strcmp(tt
->text
, ",")))
1978 j
= sizeof(conditions
)/sizeof(*conditions
);
1981 m
= nasm_stricmp(t
->text
, conditions
[k
]);
1997 * Expand MMacro-local things: parameter references (%0, %n, %+n,
1998 * %-n) and MMacro-local identifiers (%%foo).
2000 static Token
*expand_mmac_params (Token
*tline
) {
2001 Token
*t
, *tt
, *ttt
, **tail
, *thead
;
2007 if (tline
->type
== TOK_PREPROC_ID
&&
2008 (tline
->text
[1] == '+' || tline
->text
[1] == '-' ||
2009 tline
->text
[1] == '%' ||
2010 (tline
->text
[1] >= '0' && tline
->text
[1] <= '9'))) {
2012 int type
= 0, cc
; /* type = 0 to placate optimisers */
2018 tline
= tline
->next
;
2021 while (mac
&& !mac
->name
) /* avoid mistaking %reps for macros */
2022 mac
= mac
->next_active
;
2024 error(ERR_NONFATAL
, "`%s': not in a macro call", t
->text
);
2025 else switch (t
->text
[1]) {
2027 * We have to make a substitution of one of the
2028 * forms %1, %-1, %+1, %%foo, %0.
2032 sprintf(tmpbuf
, "%d", mac
->nparam
);
2033 text
= nasm_strdup(tmpbuf
);
2037 sprintf(tmpbuf
, "..@%lu.", mac
->unique
);
2038 text
= nasm_malloc(strlen(tmpbuf
)+strlen(t
->text
+2)+1);
2039 strcpy(text
, tmpbuf
);
2040 strcat(text
, t
->text
+2);
2043 n
= atoi(t
->text
+2)-1;
2044 if (n
>= mac
->nparam
)
2047 if (mac
->nparam
> 1)
2048 n
= (n
+ mac
->rotate
) % mac
->nparam
;
2049 tt
= mac
->params
[n
];
2053 error (ERR_NONFATAL
|ERR_OFFBY1
,
2054 "macro parameter %d is not a condition code",
2059 if (inverse_ccs
[cc
] == -1) {
2060 error (ERR_NONFATAL
|ERR_OFFBY1
,
2061 "condition code `%s' is not invertible",
2065 text
= nasm_strdup(conditions
[inverse_ccs
[cc
]]);
2069 n
= atoi(t
->text
+2)-1;
2070 if (n
>= mac
->nparam
)
2073 if (mac
->nparam
> 1)
2074 n
= (n
+ mac
->rotate
) % mac
->nparam
;
2075 tt
= mac
->params
[n
];
2079 error (ERR_NONFATAL
|ERR_OFFBY1
,
2080 "macro parameter %d is not a condition code",
2085 text
= nasm_strdup(conditions
[cc
]);
2089 n
= atoi(t
->text
+1)-1;
2090 if (n
>= mac
->nparam
)
2093 if (mac
->nparam
> 1)
2094 n
= (n
+ mac
->rotate
) % mac
->nparam
;
2095 tt
= mac
->params
[n
];
2098 for (i
=0; i
<mac
->paramlen
[n
]; i
++) {
2099 ttt
= *tail
= nasm_malloc(sizeof(Token
));
2102 ttt
->type
= tt
->type
;
2103 ttt
->text
= nasm_strdup(tt
->text
);
2108 text
= NULL
; /* we've done it here */
2111 nasm_free (t
->text
);
2114 t
= *tail
= nasm_malloc(sizeof(Token
));
2124 tline
= tline
->next
;
2134 * Expand all single-line macro calls made in the given line.
2135 * Return the expanded version of the line. The original is deemed
2136 * to be destroyed in the process. (In reality we'll just move
2137 * Tokens from input to output a lot of the time, rather than
2138 * actually bothering to destroy and replicate.)
2140 static Token
*expand_smacro (Token
*tline
) {
2141 Token
*t
, *tt
, *mstart
, **tail
, *thead
;
2145 int nparam
, sparam
, brackets
;
2152 while (tline
&& tline
->type
!= TOK_ID
&&
2153 (tline
->type
!= TOK_PREPROC_ID
|| tline
->text
[1] != '$')) {
2154 if (tline
->type
== TOK_SMAC_END
) {
2155 tline
->mac
->in_progress
= FALSE
;
2157 tline
= tline
->next
;
2161 tline
= tline
->next
;
2165 if (t
->type
== TOK_PS_OTHER
) {
2167 * If we see a PS_OTHER, we must at the very
2168 * least restore its correct token type. We
2169 * should also check for a %$ token, since this
2170 * is the point at which we expand context-
2174 if (t
->text
[0] == '%' && t
->text
[1] == '$') {
2175 Context
*c
= get_ctx (t
->text
);
2176 char *p
, *q
, buffer
[40];
2180 q
+= strspn(q
, "$");
2181 sprintf(buffer
, "..@%lu.", c
->number
);
2182 p
= nasm_malloc (strlen(buffer
)+strlen(q
)+1);
2185 nasm_free (t
->text
);
2196 * We've hit an identifier. As in is_mmacro below, we first
2197 * check whether the identifier is a single-line macro at
2198 * all, then think about checking for parameters if
2201 if (tline
->type
== TOK_ID
) {
2202 head
= smacros
[hash(tline
->text
)];
2205 Context
*ctx
= get_ctx (tline
->text
);
2208 p
+= strspn(p
, "$");
2209 head
= ctx
->localmac
;
2211 tline
->type
= TOK_OTHER
; /* so it will get copied above */
2215 for (m
= head
; m
; m
= m
->next
)
2216 if (!mstrcmp(m
->name
, p
, m
->casesense
))
2218 if (!m
|| m
->in_progress
) {
2220 * Either we didn't find a macro, so this can't be a
2221 * macro call, or we found a macro which was already in
2222 * progress, in which case we don't _treat_ this as a
2223 * macro call. Copy it through and ignore it.
2225 tline
->type
= TOK_PS_OTHER
; /* so it will get copied above */
2229 if (m
->nparam
== 0) {
2231 * Simple case: the macro is parameterless. Discard the
2232 * one token that the macro call took, and push the
2233 * expansion back on the to-do stack.
2239 * Complicated case: at least one macro with this name
2240 * exists and takes parameters. We must find the
2241 * parameters in the call, count them, find the SMacro
2242 * that corresponds to that form of the macro call, and
2243 * substitute for the parameters when we expand. What a
2246 nparam
= sparam
= 0;
2249 tline
= tline
->next
;
2250 if (tline
&& tline
->type
== TOK_WHITESPACE
)
2251 tline
= tline
->next
;
2252 if (!tline
|| tline
->type
!= TOK_OTHER
||
2253 strcmp(tline
->text
, "(")) {
2255 * This macro wasn't called with parameters: ignore
2256 * the call. (Behaviour borrowed from gnu cpp.)
2259 tline
->type
= TOK_PS_OTHER
;
2262 tline
= tline
->next
;
2264 if (tline
&& tline
->type
== TOK_WHITESPACE
)
2265 tline
= tline
->next
;
2267 error(ERR_NONFATAL
|ERR_OFFBY1
,
2268 "macro call expects terminating `)'");
2271 if (nparam
>= sparam
) {
2272 sparam
+= PARAM_DELTA
;
2273 params
= nasm_realloc (params
, sparam
*sizeof(Token
*));
2274 paramsize
= nasm_realloc (paramsize
, sparam
*sizeof(int));
2276 params
[nparam
] = tline
;
2277 paramsize
[nparam
] = 0;
2279 if (tline
&& tline
->type
== TOK_OTHER
&&
2280 !strcmp(tline
->text
, "{")) {
2281 params
[nparam
] = tline
= tline
->next
;
2282 while (tline
&& (brackets
> 0 ||
2283 tline
->type
!= TOK_OTHER
||
2284 strcmp(tline
->text
, "}"))) {
2285 tline
= tline
->next
;
2286 paramsize
[nparam
]++;
2288 tline
= tline
->next
;
2289 if (tline
&& tline
->type
== TOK_WHITESPACE
)
2290 tline
= tline
->next
;
2291 if (tline
&& (tline
->type
!= TOK_OTHER
||
2292 (strcmp(tline
->text
, ")") &&
2293 strcmp(tline
->text
, ",")))) {
2294 error (ERR_NONFATAL
|ERR_OFFBY1
, "braces do not "
2295 "enclose all of macro parameter");
2297 if (tline
&& tline
->type
== TOK_OTHER
&&
2298 !strcmp(tline
->text
, ","))
2299 tline
= tline
->next
;
2301 while (tline
&& (brackets
> 0 ||
2302 tline
->type
!= TOK_OTHER
||
2303 (strcmp(tline
->text
, ",") &&
2304 strcmp(tline
->text
, ")")))) {
2305 if (tline
->type
== TOK_OTHER
&& !tline
->text
[1])
2306 brackets
+= (tline
->text
[0] == '(' ? 1 :
2307 tline
->text
[0] == ')' ? -1 : 0);
2308 tline
= tline
->next
;
2309 paramsize
[nparam
]++;
2313 if (tline
&& !strcmp(tline
->text
, ")"))
2315 if (tline
&& !strcmp(tline
->text
, ","))
2316 tline
= tline
->next
;
2318 while (m
&& m
->nparam
!= nparam
) {
2319 while ( (m
= m
->next
) )
2320 if (!strcmp(m
->name
, mstart
->text
))
2324 error (ERR_WARNING
|ERR_OFFBY1
|ERR_WARN_MNP
,
2325 "macro `%s' exists, but not taking %d parameters",
2326 mstart
->text
, nparam
);
2328 nasm_free (paramsize
);
2330 tline
->type
= TOK_PS_OTHER
;
2335 * Expand the macro: we are placed on the last token of the
2336 * call, so that we can easily split the call from the
2337 * following tokens. We also start by pushing an SMAC_END
2338 * token for the cycle removal.
2341 tline
= tline
->next
;
2343 tt
= nasm_malloc(sizeof(Token
));
2344 tt
->type
= TOK_SMAC_END
;
2347 m
->in_progress
= TRUE
;
2350 for (t
= m
->expansion
; t
; t
= t
->next
) {
2351 if (t
->type
>= TOK_SMAC_PARAM
) {
2352 Token
*pcopy
= tline
, **ptail
= &pcopy
;
2356 ttt
= params
[t
->type
- TOK_SMAC_PARAM
];
2357 for (i
=0; i
<paramsize
[t
->type
-TOK_SMAC_PARAM
]; i
++) {
2358 pt
= *ptail
= nasm_malloc(sizeof(Token
));
2361 pt
->text
= nasm_strdup(ttt
->text
);
2362 pt
->type
= ttt
->type
;
2368 tt
= nasm_malloc(sizeof(Token
));
2370 tt
->text
= nasm_strdup(t
->text
);
2378 * Having done that, get rid of the macro call, and clean
2379 * up the parameters.
2382 nasm_free (paramsize
);
2383 free_tlist (mstart
);
2390 * Determine whether the given line constitutes a multi-line macro
2391 * call, and return the MMacro structure called if so. Doesn't have
2392 * to check for an initial label - that's taken care of in
2393 * expand_mmacro - but must check numbers of parameters. Guaranteed
2394 * to be called with tline->type == TOK_ID, so the putative macro
2395 * name is easy to find.
2397 static MMacro
*is_mmacro (Token
*tline
, Token
***params_array
) {
2402 head
= mmacros
[hash(tline
->text
)];
2405 * Efficiency: first we see if any macro exists with the given
2406 * name. If not, we can return NULL immediately. _Then_ we
2407 * count the parameters, and then we look further along the
2408 * list if necessary to find the proper MMacro.
2410 for (m
= head
; m
; m
= m
->next
)
2411 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
2417 * OK, we have a potential macro. Count and demarcate the
2420 count_mmac_params (tline
->next
, &nparam
, ¶ms
);
2423 * So we know how many parameters we've got. Find the MMacro
2424 * structure that handles this number.
2427 if (m
->nparam_min
<= nparam
&& (m
->plus
|| nparam
<= m
->nparam_max
)) {
2429 * This one is right. Just check if cycle removal
2430 * prohibits us using it before we actually celebrate...
2432 if (m
->in_progress
) {
2433 error (ERR_NONFATAL
|ERR_OFFBY1
,
2434 "self-reference in multi-line macro `%s'",
2440 * It's right, and we can use it. Add its default
2441 * parameters to the end of our list if necessary.
2443 if (m
->defaults
&& nparam
< m
->nparam_min
+ m
->ndefs
) {
2444 params
= nasm_realloc (params
, ((m
->nparam_min
+m
->ndefs
+1) *
2446 while (nparam
< m
->nparam_min
+ m
->ndefs
) {
2447 params
[nparam
] = m
->defaults
[nparam
- m
->nparam_min
];
2452 * If we've gone over the maximum parameter count (and
2453 * we're in Plus mode), ignore parameters beyond
2456 if (m
->plus
&& nparam
> m
->nparam_max
)
2457 nparam
= m
->nparam_max
;
2459 * Then terminate the parameter list, and leave.
2461 if (!params
) { /* need this special case */
2462 params
= nasm_malloc(sizeof(*params
));
2465 params
[nparam
] = NULL
;
2466 *params_array
= params
;
2470 * This one wasn't right: look for the next one with the
2473 for (m
= m
->next
; m
; m
= m
->next
)
2474 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
2479 * After all that, we didn't find one with the right number of
2480 * parameters. Issue a warning, and fail to expand the macro.
2482 error (ERR_WARNING
|ERR_OFFBY1
|ERR_WARN_MNP
,
2483 "macro `%s' exists, but not taking %d parameters",
2484 tline
->text
, nparam
);
2490 * Expand the multi-line macro call made by the given line, if
2491 * there is one to be expanded. If there is, push the expansion on
2492 * istk->expansion and return 1 or 2, as according to whether a
2493 * line sync is needed (2 if it is). Otherwise return 0.
2495 static int expand_mmacro (Token
*tline
) {
2496 Token
*label
= NULL
, **params
, *t
, *tt
, *last
= NULL
;
2499 int i
, nparam
, *paramlen
;
2500 int need_sync
= FALSE
;
2503 if (t
&& t
->type
== TOK_WHITESPACE
)
2505 if (t
&& t
->type
== TOK_ID
) {
2506 m
= is_mmacro (t
, ¶ms
);
2509 * We have an id which isn't a macro call. We'll assume
2510 * it might be a label; we'll also check to see if a
2511 * colon follows it. Then, if there's another id after
2512 * that lot, we'll check it again for macro-hood.
2514 last
= t
, t
= t
->next
;
2515 if (t
&& t
->type
== TOK_WHITESPACE
)
2516 last
= t
, t
= t
->next
;
2517 if (t
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, ":"))
2518 last
= t
, t
= t
->next
;
2519 if (t
&& t
->type
== TOK_WHITESPACE
)
2520 last
= t
, t
= t
->next
;
2521 if (t
&& t
->type
== TOK_ID
) {
2522 m
= is_mmacro(t
, ¶ms
);
2535 * If we're not already inside another macro expansion, we'd
2536 * better push a line synchronisation to ensure we stay put on
2539 if (!istk
->expansion
)
2543 * Fix up the parameters: this involves stripping leading and
2544 * trailing whitespace, then stripping braces if they are
2547 for (nparam
= 0; params
[nparam
]; nparam
++);
2548 paramlen
= nparam
? nasm_malloc(nparam
*sizeof(*paramlen
)) : NULL
;
2550 for (i
= 0; params
[i
]; i
++) {
2552 int comma
= (!m
->plus
|| i
< nparam
-1);
2555 if (t
&& t
->type
== TOK_WHITESPACE
)
2557 if (t
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "{"))
2558 t
= t
->next
, brace
= TRUE
, comma
= FALSE
;
2562 if (!t
) /* end of param because EOL */
2564 if (comma
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, ","))
2565 break; /* ... because we have hit a comma */
2566 if (comma
&& t
->type
== TOK_WHITESPACE
&&
2567 t
->next
->type
== TOK_OTHER
&& !strcmp(t
->next
->text
, ","))
2568 break; /* ... or a space then a comma */
2569 if (brace
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "}"))
2570 break; /* ... or a brace */
2577 * OK, we have a MMacro structure together with a set of
2578 * parameters. We must now go through the expansion and push
2579 * copies of each Line on to istk->expansion. Substitution of
2580 * parameter tokens and macro-local tokens doesn't get done
2581 * until the single-line macro substitution process; this is
2582 * because delaying them allows us to change the semantics
2583 * later through %rotate.
2585 * First, push an end marker on to istk->expansion, mark this
2586 * macro as in progress, and set up its invocation-specific
2589 ll
= nasm_malloc(sizeof(Line
));
2590 ll
->next
= istk
->expansion
;
2593 istk
->expansion
= ll
;
2595 m
->in_progress
= TRUE
;
2600 m
->paramlen
= paramlen
;
2601 m
->unique
= unique
++;
2603 m
->next_active
= istk
->mstk
;
2606 for (l
= m
->expansion
; l
; l
= l
->next
) {
2609 ll
= nasm_malloc(sizeof(Line
));
2610 ll
->next
= istk
->expansion
;
2611 ll
->finishes
= NULL
;
2615 for (t
= l
->first
; t
; t
= t
->next
) {
2616 tt
= *tail
= nasm_malloc(sizeof(Token
));
2620 tt
->text
= nasm_strdup(t
->text
);
2624 istk
->expansion
= ll
;
2629 * If we had a label, push it on the front of the first line of
2630 * the macro expansion. We must check that this doesn't give
2631 * two consecutive TOK_WHITESPACE.
2634 if (last
->type
== TOK_WHITESPACE
&&
2635 istk
->expansion
->first
->type
== TOK_WHITESPACE
) {
2636 Token
*victim
= istk
->expansion
->first
; /* kill this whitespace */
2637 istk
->expansion
->first
= victim
->next
;
2638 nasm_free (victim
->text
);
2641 last
->next
= istk
->expansion
->first
;
2642 istk
->expansion
->first
= label
;
2645 list
->uplevel (m
->nolist
? LIST_MACRO_NOLIST
: LIST_MACRO
);
2647 return need_sync
? 2 : 1;
2650 static void pp_reset (char *file
, int apass
, efunc errfunc
, evalfunc eval
,
2656 linesync
= outline
= NULL
;
2657 istk
= nasm_malloc(sizeof(Include
));
2660 istk
->expansion
= NULL
;
2662 istk
->fp
= fopen(file
, "r");
2663 istk
->fname
= nasm_strdup(file
);
2664 istk
->lineno
= istk
->lineinc
= 1;
2666 error (ERR_FATAL
|ERR_NOFILE
, "unable to open input file `%s'", file
);
2668 for (h
=0; h
<NHASH
; h
++) {
2674 any_extrastdmac
= (extrastdmac
!= NULL
);
2680 static char *pp_getline (void) {
2693 * Fetch a tokenised line, either from the macro-expansion
2694 * buffer or from the input file.
2697 while (istk
->expansion
&& istk
->expansion
->finishes
) {
2698 Line
*l
= istk
->expansion
;
2699 if (!l
->finishes
->name
&& l
->finishes
->in_progress
> 1) {
2703 * This is a macro-end marker for a macro with no
2704 * name, which means it's not really a macro at all
2705 * but a %rep block, and the `in_progress' field is
2706 * more than 1, meaning that we still need to
2707 * repeat. (1 means the natural last repetition; 0
2708 * means termination by %exitrep.) We have
2709 * therefore expanded up to the %endrep, and must
2710 * push the whole block on to the expansion buffer
2711 * again. We don't bother to remove the macro-end
2712 * marker: we'd only have to generate another one
2715 l
->finishes
->in_progress
--;
2716 for (l
= l
->finishes
->expansion
; l
; l
= l
->next
) {
2717 Token
*t
, *tt
, **tail
;
2719 ll
= nasm_malloc(sizeof(Line
));
2720 ll
->next
= istk
->expansion
;
2721 ll
->finishes
= NULL
;
2725 for (t
= l
->first
; t
; t
= t
->next
) {
2727 tt
= *tail
= nasm_malloc(sizeof(Token
));
2731 tt
->text
= nasm_strdup(t
->text
);
2736 istk
->expansion
= ll
;
2741 * Check whether a `%rep' was started and not ended
2742 * within this macro expansion. This can happen and
2743 * should be detected. It's a fatal error because
2744 * I'm too confused to work out how to recover
2750 "defining with name in expansion");
2751 else if (!istk
->mstk
->name
)
2752 error (ERR_PANIC
, "istk->mstk has no name but"
2753 " defining is set at end of expansion");
2755 error (ERR_FATAL
, "`%%rep' without `%%endrep' within"
2756 " expansion of macro `%s'", istk
->mstk
->name
);
2759 if (istk
->mstk
->name
) {
2761 * This was a real macro call, not a %rep, and
2762 * therefore the parameter information needs to
2765 nasm_free(istk
->mstk
->params
);
2766 free_tlist(istk
->mstk
->iline
);
2767 nasm_free(istk
->mstk
->paramlen
);
2769 istk
->mstk
= istk
->mstk
->next_active
;
2770 l
->finishes
->in_progress
= FALSE
;
2771 istk
->expansion
= l
->next
;
2773 list
->downlevel (LIST_MACRO
);
2774 if (!istk
->expansion
)
2778 if (istk
->expansion
) {
2780 Line
*l
= istk
->expansion
;
2782 istk
->expansion
= l
->next
;
2785 list
->line (LIST_MACRO
, p
);
2787 if (!istk
->expansion
)
2793 * The current file has ended; work down the istk
2794 * until we find a file we can read from.
2799 error(ERR_FATAL
, "expected `%%endif' before end of file");
2802 list
->downlevel (LIST_INCLUDE
);
2803 nasm_free (i
->fname
);
2809 update_fileline(3); /* update __FILE__ and __LINE__ */
2812 line
= prepreproc(line
);
2813 tline
= tokenise(line
);
2818 * We must expand MMacro parameters and MMacro-local labels
2819 * _before_ we plunge into directive processing, to cope
2820 * with things like `%define something %1' such as STRUC
2821 * uses. Unless we're _defining_ a MMacro, in which case
2822 * those tokens should be left alone to go into the
2826 tline
= expand_mmac_params(tline
);
2829 * Check the line to see if it's a preprocessor directive.
2831 ret
= do_directive(tline
);
2835 if ((ret
& 2) && !stdmacpos
) {/* give a blank line to the output */
2836 outline
= nasm_strdup("");
2841 } else if (defining
) {
2843 * We're defining a multi-line macro. We emit nothing
2844 * at all, not even a blank line (when we finish
2845 * defining the macro, we'll emit a line-number
2846 * directive so that we keep sync properly), and just
2847 * shove the tokenised line on to the macro definition.
2849 Line
*l
= nasm_malloc(sizeof(Line
));
2850 l
->next
= defining
->expansion
;
2852 l
->finishes
= FALSE
;
2853 defining
->expansion
= l
;
2855 } else if (istk
->conds
&& !emitting(istk
->conds
->state
)) {
2857 * We're in a non-emitting branch of a condition block.
2858 * Emit nothing at all, not even a blank line: when we
2859 * emerge from the condition we'll give a line-number
2860 * directive so we keep our place correctly.
2864 } else if (istk
->mstk
&& !istk
->mstk
->in_progress
) {
2866 * We're in a %rep block which has been terminated, so
2867 * we're walking through to the %endrep without
2868 * emitting anything. Emit nothing at all, not even a
2869 * blank line: when we emerge from the %rep block we'll
2870 * give a line-number directive so we keep our place
2876 tline
= expand_smacro(tline
);
2877 ret
= expand_mmacro(tline
);
2880 * De-tokenise the line again, and emit it.
2882 line
= detoken(tline
);
2889 continue; /* expand_mmacro calls free_tlist */
2895 * Once we're out of this loop, outline _must_ be non-NULL. The
2896 * only question is whether linesync is NULL or not.
2908 static void pp_cleanup (void) {
2912 error (ERR_NONFATAL
, "end of file while still defining macro `%s'",
2914 nasm_free (defining
->name
);
2915 free_tlist (defining
->dlist
);
2916 free_llist (defining
->expansion
);
2917 nasm_free (defining
);
2919 nasm_free (linesync
); /* might just be necessary */
2920 nasm_free (outline
); /* really shouldn't be necessary */
2923 for (h
=0; h
<NHASH
; h
++) {
2924 while (mmacros
[h
]) {
2925 MMacro
*m
= mmacros
[h
];
2926 mmacros
[h
] = mmacros
[h
]->next
;
2927 nasm_free (m
->name
);
2928 free_tlist (m
->dlist
);
2929 nasm_free (m
->defaults
);
2930 free_llist (m
->expansion
);
2933 while (smacros
[h
]) {
2934 SMacro
*s
= smacros
[h
];
2935 smacros
[h
] = smacros
[h
]->next
;
2936 nasm_free (s
->name
);
2937 free_tlist (s
->expansion
);
2945 nasm_free (i
->fname
);
2952 void pp_include_path (char *path
) {
2955 i
= nasm_malloc(sizeof(IncPath
));
2956 i
->path
= nasm_strdup(path
);
2962 void pp_pre_include (char *fname
) {
2963 Token
*inc
, *space
, *name
;
2966 inc
= nasm_malloc(sizeof(Token
));
2967 inc
->next
= space
= nasm_malloc(sizeof(Token
));
2968 space
->next
= name
= nasm_malloc(sizeof(Token
));
2971 inc
->type
= TOK_PREPROC_ID
;
2972 inc
->text
= nasm_strdup("%include");
2973 space
->type
= TOK_WHITESPACE
;
2974 space
->text
= nasm_strdup(" ");
2975 name
->type
= TOK_INTERNAL_STRING
;
2976 name
->text
= nasm_strdup(fname
);
2978 inc
->mac
= space
->mac
= name
->mac
= NULL
;
2980 l
= nasm_malloc(sizeof(Line
));
2983 l
->finishes
= FALSE
;
2987 void pp_pre_define (char *definition
) {
2988 Token
*def
, *space
, *name
;
2992 equals
= strchr(definition
, '=');
2994 def
= nasm_malloc(sizeof(Token
));
2995 def
->next
= space
= nasm_malloc(sizeof(Token
));
2998 space
->next
= name
= tokenise(definition
);
3002 def
->type
= TOK_PREPROC_ID
;
3003 def
->text
= nasm_strdup("%define");
3004 space
->type
= TOK_WHITESPACE
;
3005 space
->text
= nasm_strdup(" ");
3007 def
->mac
= space
->mac
= NULL
;
3009 l
= nasm_malloc(sizeof(Line
));
3012 l
->finishes
= FALSE
;
3016 void pp_extra_stdmac (char **macros
) {
3017 extrastdmac
= macros
;