1 /* -*- mode: c; c-file-style: "bsd" -*- */
2 /* preproc.c macro preprocessor for the Netwide Assembler
4 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
5 * Julian Hall. All rights reserved. The software is
6 * redistributable under the licence given in the file "Licence"
7 * distributed in the NASM archive.
9 * initial version 18/iii/97 by Simon Tatham
12 /* Typical flow of text through preproc
14 * pp_getline gets tokenised lines, either
16 * from a macro expansion
20 * read_line gets raw text from stdmacpos, or predef, or current input file
21 * tokenise converts to tokens
24 * expand_mmac_params is used to expand %1 etc., unless a macro is being
25 * defined or a false conditional is being processed
26 * (%0, %1, %+1, %-1, %%foo
28 * do_directive checks for directives
30 * expand_smacro is used to expand single line macros
32 * expand_mmacro is used to expand multi-line macros
34 * detoken is used to convert the line back to text
48 typedef struct SMacro SMacro
;
49 typedef struct MMacro MMacro
;
50 typedef struct Context Context
;
51 typedef struct Token Token
;
52 typedef struct Blocks Blocks
;
53 typedef struct Line Line
;
54 typedef struct Include Include
;
55 typedef struct Cond Cond
;
56 typedef struct IncPath IncPath
;
59 * Store the definition of a single-line macro.
71 * Store the definition of a multi-line macro. This is also used to
72 * store the interiors of `%rep...%endrep' blocks, which are
73 * effectively self-re-invoking multi-line macros which simply
74 * don't have a name or bother to appear in the hash tables. %rep
75 * blocks are signified by having a NULL `name' field.
77 * In a MMacro describing a `%rep' block, the `in_progress' field
78 * isn't merely boolean, but gives the number of repeats left to
81 * The `next' field is used for storing MMacros in hash tables; the
82 * `next_active' field is for stacking them on istk entries.
84 * When a MMacro is being expanded, `params', `iline', `nparam',
85 * `paramlen', `rotate' and `unique' are local to the invocation.
91 int nparam_min
, nparam_max
;
92 int plus
; /* is the last parameter greedy? */
93 int nolist
; /* is this macro listing-inhibited? */
95 Token
*dlist
; /* All defaults as one list */
96 Token
**defaults
; /* Parameter default pointers */
97 int ndefs
; /* number of default parameters */
101 MMacro
*rep_nest
; /* used for nesting %rep */
102 Token
**params
; /* actual parameters */
103 Token
*iline
; /* invocation line */
104 int nparam
, rotate
, *paramlen
;
105 unsigned long unique
;
106 int lineno
; /* Current line number on expansion */
110 * The context stack is composed of a linked list of these.
116 unsigned long number
;
120 * This is the internal form which we break input lines up into.
121 * Typically stored in linked lists.
123 * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
124 * necessarily used as-is, but is intended to denote the number of
125 * the substituted parameter. So in the definition
127 * %define a(x,y) ( (x) & ~(y) )
129 * the token representing `x' will have its type changed to
130 * TOK_SMAC_PARAM, but the one representing `y' will be
133 * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
134 * which doesn't need quotes around it. Used in the pre-include
135 * mechanism as an alternative to trying to find a sensible type of
136 * quote to use on the filename we were passed.
141 SMacro
*mac
; /* associated macro for TOK_SMAC_END */
145 TOK_WHITESPACE
= 1, TOK_COMMENT
, TOK_ID
, TOK_PREPROC_ID
, TOK_STRING
,
146 TOK_NUMBER
, TOK_SMAC_END
, TOK_OTHER
, TOK_SMAC_PARAM
,
151 * Multi-line macro definitions are stored as a linked list of
152 * these, which is essentially a container to allow several linked
155 * Note that in this module, linked lists are treated as stacks
156 * wherever possible. For this reason, Lines are _pushed_ on to the
157 * `expansion' field in MMacro structures, so that the linked list,
158 * if walked, would give the macro lines in reverse order; this
159 * means that we can walk the list when expanding a macro, and thus
160 * push the lines on to the `expansion' field in _istk_ in reverse
161 * order (so that when popped back off they are in the right
162 * order). It may seem cockeyed, and it relies on my design having
163 * an even number of steps in, but it works...
165 * Some of these structures, rather than being actual lines, are
166 * markers delimiting the end of the expansion of a given macro.
167 * This is for use in the cycle-tracking and %rep-handling code.
168 * Such structures have `finishes' non-NULL, and `first' NULL. All
169 * others have `finishes' NULL, but `first' may still be NULL if
179 * To handle an arbitrary level of file inclusion, we maintain a
180 * stack (ie linked list) of these things.
189 MMacro
*mstk
; /* stack of active macros/reps */
193 * Include search path. This is simply a list of strings which get
194 * prepended, in turn, to the name of an include file, in an
195 * attempt to find the file if it's not in the current directory.
203 * Conditional assembly: we maintain a separate stack of these for
204 * each level of file inclusion. (The only reason we keep the
205 * stacks separate is to ensure that a stray `%endif' in a file
206 * included from within the true branch of a `%if' won't terminate
207 * it and cause confusion: instead, rightly, it'll cause an error.)
215 * These states are for use just after %if or %elif: IF_TRUE
216 * means the condition has evaluated to truth so we are
217 * currently emitting, whereas IF_FALSE means we are not
218 * currently emitting but will start doing so if a %else comes
219 * up. In these states, all directives are admissible: %elif,
220 * %else and %endif. (And of course %if.)
222 COND_IF_TRUE
, COND_IF_FALSE
,
224 * These states come up after a %else: ELSE_TRUE means we're
225 * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
226 * any %elif or %else will cause an error.
228 COND_ELSE_TRUE
, COND_ELSE_FALSE
,
230 * This state means that we're not emitting now, and also that
231 * nothing until %endif will be emitted at all. It's for use in
232 * two circumstances: (i) when we've had our moment of emission
233 * and have now started seeing %elifs, and (ii) when the
234 * condition construct in question is contained within a
235 * non-emitting branch of a larger condition construct.
239 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
242 * These defines are used as the possible return values for do_directive
244 #define NO_DIRECTIVE_FOUND 0
245 #define DIRECTIVE_FOUND 1
248 * Condition codes. Note that we use c_ prefix not C_ because C_ is
249 * used in nasm.h for the "real" condition codes. At _this_ level,
250 * we treat CXZ and ECXZ as condition codes, albeit non-invertible
251 * ones, so we need a different enum...
253 static const char *conditions
[] = {
254 "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
255 "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
256 "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
259 c_A
, c_AE
, c_B
, c_BE
, c_C
, c_CXZ
, c_E
, c_ECXZ
, c_G
, c_GE
, c_L
, c_LE
,
260 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, c_NE
, c_NG
, c_NGE
, c_NL
, c_NLE
, c_NO
,
261 c_NP
, c_NS
, c_NZ
, c_O
, c_P
, c_PE
, c_PO
, c_S
, c_Z
263 static int inverse_ccs
[] = {
264 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, -1, c_NE
, -1, c_NG
, c_NGE
, c_NL
, c_NLE
,
265 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
,
266 c_Z
, c_NO
, c_NP
, c_PO
, c_PE
, c_NS
, c_NZ
272 static const char *directives
[] = {
274 "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
275 "%elifid", "%elifidn", "%elifidni", "%elifmacro", "%elifnctx",
277 "%elifnid", "%elifnidn", "%elifnidni", "%elifnmacro", "%elifnnum",
279 "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
280 "%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
281 "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifmacro",
283 "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnmacro", "%ifnnum",
284 "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
285 "%ixdefine", "%line",
287 "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
289 "%strlen", "%substr", "%undef", "%xdefine"
293 PP_ASSIGN
, PP_CLEAR
, PP_DEFINE
, PP_ELIF
, PP_ELIFCTX
, PP_ELIFDEF
,
294 PP_ELIFID
, PP_ELIFIDN
, PP_ELIFIDNI
, PP_ELIFMACRO
, PP_ELIFNCTX
,
296 PP_ELIFNID
, PP_ELIFNIDN
, PP_ELIFNIDNI
, PP_ELIFNMACRO
, PP_ELIFNNUM
,
298 PP_ELIFNUM
, PP_ELIFSTR
, PP_ELSE
, PP_ENDIF
, PP_ENDM
, PP_ENDMACRO
,
299 PP_ENDREP
, PP_ERROR
, PP_EXITREP
, PP_IASSIGN
, PP_IDEFINE
, PP_IF
,
300 PP_IFCTX
, PP_IFDEF
, PP_IFID
, PP_IFIDN
, PP_IFIDNI
, PP_IFMACRO
,
302 PP_IFNDEF
, PP_IFNID
, PP_IFNIDN
, PP_IFNIDNI
, PP_IFNMACRO
, PP_IFNNUM
,
303 PP_IFNSTR
, PP_IFNUM
, PP_IFSTR
, PP_IMACRO
, PP_INCLUDE
,
304 PP_IXDEFINE
, PP_LINE
,
306 PP_MACRO
, PP_POP
, PP_PUSH
, PP_REP
, PP_REPL
, PP_ROTATE
,
308 PP_STRLEN
, PP_SUBSTR
, PP_UNDEF
, PP_XDEFINE
311 /* If this is a an IF, ELIF, ELSE or ENDIF keyword */
312 static int is_condition(int arg
)
314 return ((arg
>= PP_ELIF
) && (arg
<= PP_ENDIF
)) ||
315 ((arg
>= PP_IF
) && (arg
<= PP_IFSTR
));
318 /* For TASM compatibility we need to be able to recognise TASM compatible
319 * conditional compilation directives. Using the NASM pre-processor does
320 * not work, so we look for them specifically from the following list and
321 * then jam in the equivalent NASM directive into the input stream.
325 # define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
329 TM_ARG
, TM_ELIF
, TM_ELSE
, TM_ENDIF
, TM_IF
, TM_IFDEF
, TM_IFDIFI
,
330 TM_IFNDEF
, TM_INCLUDE
, TM_LOCAL
333 static const char *tasm_directives
[] = {
334 "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
335 "ifndef", "include", "local"
338 static int StackSize
= 4;
339 static char *StackPointer
= "ebp";
340 static int ArgOffset
= 8;
341 static int LocalOffset
= 4;
343 static Context
*cstk
;
344 static Include
*istk
;
345 static IncPath
*ipath
= NULL
;
347 static efunc _error
; /* Pointer to client-provided error reporting function */
348 static evalfunc evaluate
;
350 static int pass
; /* HACK: pass 0 = generate dependencies only */
352 static unsigned long unique
; /* unique identifier numbers */
354 static Line
*predef
= NULL
;
356 static ListGen
*list
;
359 * The number of hash values we use for the macro lookup tables.
360 * FIXME: We should *really* be able to configure this at run time,
361 * or even have the hash table automatically expanding when necessary.
366 * The current set of multi-line macros we have defined.
368 static MMacro
*mmacros
[NHASH
];
371 * The current set of single-line macros we have defined.
373 static SMacro
*smacros
[NHASH
];
376 * The multi-line macro we are currently defining, or the %rep
377 * block we are currently reading, if any.
379 static MMacro
*defining
;
382 * The number of macro parameters to allocate space for at a time.
384 #define PARAM_DELTA 16
387 * The standard macro set: defined as `static char *stdmac[]'. Also
388 * gives our position in the macro set, when we're processing it.
391 static const char **stdmacpos
;
394 * The extra standard macros that come from the object format, if
397 static const char **extrastdmac
= NULL
;
401 * Tokens are allocated in blocks to improve speed
403 #define TOKEN_BLOCKSIZE 4096
404 static Token
*freeTokens
= NULL
;
410 static Blocks blocks
= { NULL
, NULL
};
413 * Forward declarations.
415 static Token
*expand_mmac_params(Token
* tline
);
416 static Token
*expand_smacro(Token
* tline
);
417 static Token
*expand_id(Token
* tline
);
418 static Context
*get_ctx(char *name
, int all_contexts
);
419 static void make_tok_num(Token
* tok
, long val
);
420 static void error(int severity
, const char *fmt
, ...);
421 static void *new_Block(size_t size
);
422 static void delete_Blocks(void);
423 static Token
*new_Token(Token
* next
, int type
, char *text
, int txtlen
);
424 static Token
*delete_Token(Token
* t
);
427 * Macros for safe checking of token pointers, avoid *(NULL)
429 #define tok_type_(x,t) ((x) && (x)->type == (t))
430 #define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
431 #define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
432 #define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
434 /* Handle TASM specific directives, which do not contain a % in
435 * front of them. We do it here because I could not find any other
436 * place to do it for the moment, and it is a hack (ideally it would
437 * be nice to be able to use the NASM pre-processor to do it).
439 static char *check_tasm_directive(char *line
)
442 char *p
= line
, *oldline
, oldchar
;
444 /* Skip whitespace */
445 while (isspace(*p
) && *p
!= 0)
448 /* Binary search for the directive name */
450 j
= elements(tasm_directives
);
452 while (!isspace(p
[len
]) && p
[len
] != 0)
459 m
= nasm_stricmp(p
, tasm_directives
[k
]);
461 /* We have found a directive, so jam a % in front of it
462 * so that NASM will then recognise it as one if it's own.
467 line
= nasm_malloc(len
+ 2);
469 if (k
== TM_IFDIFI
) {
470 /* NASM does not recognise IFDIFI, so we convert it to
471 * %ifdef BOGUS. This is not used in NASM comaptible
472 * code, but does need to parse for the TASM macro
475 strcpy(line
+ 1, "ifdef BOGUS");
477 memcpy(line
+ 1, p
, len
+ 1);
492 * The pre-preprocessing stage... This function translates line
493 * number indications as they emerge from GNU cpp (`# lineno "file"
494 * flags') into NASM preprocessor line number indications (`%line
497 static char *prepreproc(char *line
)
500 char *fname
, *oldline
;
502 if (line
[0] == '#' && line
[1] == ' ') {
505 lineno
= atoi(fname
);
506 fname
+= strspn(fname
, "0123456789 ");
509 fnlen
= strcspn(fname
, "\"");
510 line
= nasm_malloc(20 + fnlen
);
511 snprintf(line
, 20 + fnlen
, "%%line %d %.*s", lineno
, fnlen
, fname
);
514 if (tasm_compatible_mode
)
515 return check_tasm_directive(line
);
520 * The hash function for macro lookups. Note that due to some
521 * macros having case-insensitive names, the hash function must be
522 * invariant under case changes. We implement this by applying a
523 * perfectly normal hash function to the uppercase of the string.
525 static int hash(char *s
)
530 * Powers of three, mod 31.
532 static const int multipliers
[] = {
533 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
534 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
538 h
+= multipliers
[i
] * (unsigned char)(toupper(*s
));
540 if (++i
>= elements(multipliers
))
548 * Free a linked list of tokens.
550 static void free_tlist(Token
* list
)
553 list
= delete_Token(list
);
558 * Free a linked list of lines.
560 static void free_llist(Line
* list
)
566 free_tlist(l
->first
);
574 static void free_mmacro(MMacro
* m
)
577 free_tlist(m
->dlist
);
578 nasm_free(m
->defaults
);
579 free_llist(m
->expansion
);
584 * Pop the context stack.
586 static void ctx_pop(void)
597 free_tlist(s
->expansion
);
604 #define BUF_DELTA 512
606 * Read a line from the top file in istk, handling multiple CR/LFs
607 * at the end of the line read, and handling spurious ^Zs. Will
608 * return lines from the standard macro set if this has not already
611 static char *read_line(void)
613 char *buffer
, *p
, *q
;
614 int bufsize
, continued_count
;
618 char *ret
= nasm_strdup(*stdmacpos
++);
619 if (!*stdmacpos
&& any_extrastdmac
) {
620 stdmacpos
= extrastdmac
;
621 any_extrastdmac
= FALSE
;
625 * Nasty hack: here we push the contents of `predef' on
626 * to the top-level expansion stack, since this is the
627 * most convenient way to implement the pre-include and
628 * pre-define features.
632 Token
*head
, **tail
, *t
;
634 for (pd
= predef
; pd
; pd
= pd
->next
) {
637 for (t
= pd
->first
; t
; t
= t
->next
) {
638 *tail
= new_Token(NULL
, t
->type
, t
->text
, 0);
639 tail
= &(*tail
)->next
;
641 l
= nasm_malloc(sizeof(Line
));
642 l
->next
= istk
->expansion
;
655 buffer
= nasm_malloc(BUF_DELTA
);
659 q
= fgets(p
, bufsize
- (p
- buffer
), istk
->fp
);
663 if (p
> buffer
&& p
[-1] == '\n') {
664 /* Convert backslash-CRLF line continuation sequences into
665 nothing at all (for DOS and Windows) */
666 if (((p
- 2) > buffer
) && (p
[-3] == '\\') && (p
[-2] == '\r')) {
671 /* Also convert backslash-LF line continuation sequences into
672 nothing at all (for Unix) */
673 else if (((p
- 1) > buffer
) && (p
[-2] == '\\')) {
681 if (p
- buffer
> bufsize
- 10) {
682 long offset
= p
- buffer
;
683 bufsize
+= BUF_DELTA
;
684 buffer
= nasm_realloc(buffer
, bufsize
);
685 p
= buffer
+ offset
; /* prevent stale-pointer problems */
689 if (!q
&& p
== buffer
) {
694 src_set_linnum(src_get_linnum() + istk
->lineinc
+
695 (continued_count
* istk
->lineinc
));
698 * Play safe: remove CRs as well as LFs, if any of either are
699 * present at the end of the line.
701 while (--p
>= buffer
&& (*p
== '\n' || *p
== '\r'))
705 * Handle spurious ^Z, which may be inserted into source files
706 * by some file transfer utilities.
708 buffer
[strcspn(buffer
, "\032")] = '\0';
710 list
->line(LIST_READ
, buffer
);
716 * Tokenise a line of text. This is a very simple process since we
717 * don't need to parse the value out of e.g. numeric tokens: we
718 * simply split one string into many.
720 static Token
*tokenise(char *line
)
725 Token
*t
, **tail
= &list
;
732 ((*p
== '-' || *p
== '+') && isdigit(p
[1])) ||
733 ((*p
== '+') && (isspace(p
[1]) || !p
[1]))) {
738 type
= TOK_PREPROC_ID
;
739 } else if (*p
== '{') {
741 while (*p
&& *p
!= '}') {
748 type
= TOK_PREPROC_ID
;
749 } else if (isidchar(*p
) ||
750 ((*p
== '!' || *p
== '%' || *p
== '$') &&
755 while (isidchar(*p
));
756 type
= TOK_PREPROC_ID
;
762 } else if (isidstart(*p
) || (*p
== '$' && isidstart(p
[1]))) {
765 while (*p
&& isidchar(*p
))
767 } else if (*p
== '\'' || *p
== '"') {
774 while (*p
&& *p
!= c
)
780 error(ERR_WARNING
, "unterminated string");
781 /* Handling unterminated strings by UNV */
784 } else if (isnumstart(*p
)) {
790 while (*p
&& isnumchar(*p
))
792 } else if (isspace(*p
)) {
793 type
= TOK_WHITESPACE
;
795 while (*p
&& isspace(*p
))
798 * Whitespace just before end-of-line is discarded by
799 * pretending it's a comment; whitespace just before a
800 * comment gets lumped into the comment.
802 if (!*p
|| *p
== ';') {
807 } else if (*p
== ';') {
813 * Anything else is an operator of some kind. We check
814 * for all the double-character operators (>>, <<, //,
815 * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
816 * else is a single-character operator.
819 if ((p
[0] == '>' && p
[1] == '>') ||
820 (p
[0] == '<' && p
[1] == '<') ||
821 (p
[0] == '/' && p
[1] == '/') ||
822 (p
[0] == '<' && p
[1] == '=') ||
823 (p
[0] == '>' && p
[1] == '=') ||
824 (p
[0] == '=' && p
[1] == '=') ||
825 (p
[0] == '!' && p
[1] == '=') ||
826 (p
[0] == '<' && p
[1] == '>') ||
827 (p
[0] == '&' && p
[1] == '&') ||
828 (p
[0] == '|' && p
[1] == '|') ||
829 (p
[0] == '^' && p
[1] == '^')) {
835 /* Handling unterminated string by UNV */
838 *tail = t = new_Token(NULL, TOK_STRING, line, p-line+1);
839 t->text[p-line] = *line;
843 if (type
!= TOK_COMMENT
) {
844 *tail
= t
= new_Token(NULL
, type
, line
, p
- line
);
853 * this function allocates a new managed block of memory and
854 * returns a pointer to the block. The managed blocks are
855 * deleted only all at once by the delete_Blocks function.
857 static void *new_Block(size_t size
)
861 /* first, get to the end of the linked list */
864 /* now allocate the requested chunk */
865 b
->chunk
= nasm_malloc(size
);
867 /* now allocate a new block for the next request */
868 b
->next
= nasm_malloc(sizeof(Blocks
));
869 /* and initialize the contents of the new block */
870 b
->next
->next
= NULL
;
871 b
->next
->chunk
= NULL
;
876 * this function deletes all managed blocks of memory
878 static void delete_Blocks(void)
880 Blocks
*a
, *b
= &blocks
;
883 * keep in mind that the first block, pointed to by blocks
884 * is a static and not dynamically allocated, so we don't
898 * this function creates a new Token and passes a pointer to it
899 * back to the caller. It sets the type and text elements, and
900 * also the mac and next elements to NULL.
902 static Token
*new_Token(Token
* next
, int type
, char *text
, int txtlen
)
907 if (freeTokens
== NULL
) {
908 freeTokens
= (Token
*) new_Block(TOKEN_BLOCKSIZE
* sizeof(Token
));
909 for (i
= 0; i
< TOKEN_BLOCKSIZE
- 1; i
++)
910 freeTokens
[i
].next
= &freeTokens
[i
+ 1];
911 freeTokens
[i
].next
= NULL
;
914 freeTokens
= t
->next
;
918 if (type
== TOK_WHITESPACE
|| text
== NULL
) {
922 txtlen
= strlen(text
);
923 t
->text
= nasm_malloc(1 + txtlen
);
924 strncpy(t
->text
, text
, txtlen
);
925 t
->text
[txtlen
] = '\0';
930 static Token
*delete_Token(Token
* t
)
932 Token
*next
= t
->next
;
934 t
->next
= freeTokens
;
940 * Convert a line of tokens back into text.
941 * If expand_locals is not zero, identifiers of the form "%$*xxx"
942 * will be transformed into ..@ctxnum.xxx
944 static char *detoken(Token
* tlist
, int expand_locals
)
951 for (t
= tlist
; t
; t
= t
->next
) {
952 if (t
->type
== TOK_PREPROC_ID
&& t
->text
[1] == '!') {
953 char *p
= getenv(t
->text
+ 2);
956 t
->text
= nasm_strdup(p
);
960 /* Expand local macros here and not during preprocessing */
962 t
->type
== TOK_PREPROC_ID
&& t
->text
&&
963 t
->text
[0] == '%' && t
->text
[1] == '$') {
964 Context
*ctx
= get_ctx(t
->text
, FALSE
);
967 char *p
, *q
= t
->text
+ 2;
970 snprintf(buffer
, sizeof(buffer
), "..@%lu.", ctx
->number
);
971 p
= nasm_strcat(buffer
, q
);
976 if (t
->type
== TOK_WHITESPACE
) {
978 } else if (t
->text
) {
979 len
+= strlen(t
->text
);
982 p
= line
= nasm_malloc(len
+ 1);
983 for (t
= tlist
; t
; t
= t
->next
) {
984 if (t
->type
== TOK_WHITESPACE
) {
988 } else if (t
->text
) {
998 * A scanner, suitable for use by the expression evaluator, which
999 * operates on a line of Tokens. Expects a pointer to a pointer to
1000 * the first token in the line to be passed in as its private_data
1003 static int ppscan(void *private_data
, struct tokenval
*tokval
)
1005 Token
**tlineptr
= private_data
;
1010 *tlineptr
= tline
? tline
->next
: NULL
;
1012 while (tline
&& (tline
->type
== TOK_WHITESPACE
||
1013 tline
->type
== TOK_COMMENT
));
1016 return tokval
->t_type
= TOKEN_EOS
;
1018 if (tline
->text
[0] == '$' && !tline
->text
[1])
1019 return tokval
->t_type
= TOKEN_HERE
;
1020 if (tline
->text
[0] == '$' && tline
->text
[1] == '$' && !tline
->text
[2])
1021 return tokval
->t_type
= TOKEN_BASE
;
1023 if (tline
->type
== TOK_ID
) {
1024 tokval
->t_charptr
= tline
->text
;
1025 if (tline
->text
[0] == '$') {
1026 tokval
->t_charptr
++;
1027 return tokval
->t_type
= TOKEN_ID
;
1031 * This is the only special case we actually need to worry
1032 * about in this restricted context.
1034 if (!nasm_stricmp(tline
->text
, "seg"))
1035 return tokval
->t_type
= TOKEN_SEG
;
1037 return tokval
->t_type
= TOKEN_ID
;
1040 if (tline
->type
== TOK_NUMBER
) {
1043 tokval
->t_integer
= readnum(tline
->text
, &rn_error
);
1045 return tokval
->t_type
= TOKEN_ERRNUM
;
1046 tokval
->t_charptr
= NULL
;
1047 return tokval
->t_type
= TOKEN_NUM
;
1050 if (tline
->type
== TOK_STRING
) {
1059 if (l
== 0 || r
[l
- 1] != q
)
1060 return tokval
->t_type
= TOKEN_ERRNUM
;
1061 tokval
->t_integer
= readstrnum(r
, l
- 1, &rn_warn
);
1063 error(ERR_WARNING
| ERR_PASS1
, "character constant too long");
1064 tokval
->t_charptr
= NULL
;
1065 return tokval
->t_type
= TOKEN_NUM
;
1068 if (tline
->type
== TOK_OTHER
) {
1069 if (!strcmp(tline
->text
, "<<"))
1070 return tokval
->t_type
= TOKEN_SHL
;
1071 if (!strcmp(tline
->text
, ">>"))
1072 return tokval
->t_type
= TOKEN_SHR
;
1073 if (!strcmp(tline
->text
, "//"))
1074 return tokval
->t_type
= TOKEN_SDIV
;
1075 if (!strcmp(tline
->text
, "%%"))
1076 return tokval
->t_type
= TOKEN_SMOD
;
1077 if (!strcmp(tline
->text
, "=="))
1078 return tokval
->t_type
= TOKEN_EQ
;
1079 if (!strcmp(tline
->text
, "<>"))
1080 return tokval
->t_type
= TOKEN_NE
;
1081 if (!strcmp(tline
->text
, "!="))
1082 return tokval
->t_type
= TOKEN_NE
;
1083 if (!strcmp(tline
->text
, "<="))
1084 return tokval
->t_type
= TOKEN_LE
;
1085 if (!strcmp(tline
->text
, ">="))
1086 return tokval
->t_type
= TOKEN_GE
;
1087 if (!strcmp(tline
->text
, "&&"))
1088 return tokval
->t_type
= TOKEN_DBL_AND
;
1089 if (!strcmp(tline
->text
, "^^"))
1090 return tokval
->t_type
= TOKEN_DBL_XOR
;
1091 if (!strcmp(tline
->text
, "||"))
1092 return tokval
->t_type
= TOKEN_DBL_OR
;
1096 * We have no other options: just return the first character of
1099 return tokval
->t_type
= tline
->text
[0];
1103 * Compare a string to the name of an existing macro; this is a
1104 * simple wrapper which calls either strcmp or nasm_stricmp
1105 * depending on the value of the `casesense' parameter.
1107 static int mstrcmp(char *p
, char *q
, int casesense
)
1109 return casesense
? strcmp(p
, q
) : nasm_stricmp(p
, q
);
1113 * Return the Context structure associated with a %$ token. Return
1114 * NULL, having _already_ reported an error condition, if the
1115 * context stack isn't deep enough for the supplied number of $
1117 * If all_contexts == TRUE, contexts that enclose current are
1118 * also scanned for such smacro, until it is found; if not -
1119 * only the context that directly results from the number of $'s
1120 * in variable's name.
1122 static Context
*get_ctx(char *name
, int all_contexts
)
1128 if (!name
|| name
[0] != '%' || name
[1] != '$')
1132 error(ERR_NONFATAL
, "`%s': context stack is empty", name
);
1136 for (i
= strspn(name
+ 2, "$"), ctx
= cstk
; (i
> 0) && ctx
; i
--) {
1138 /* i--; Lino - 02/25/02 */
1141 error(ERR_NONFATAL
, "`%s': context stack is only"
1142 " %d level%s deep", name
, i
- 1, (i
== 2 ? "" : "s"));
1149 /* Search for this smacro in found context */
1152 if (!mstrcmp(m
->name
, name
, m
->casesense
))
1163 * Open an include file. This routine must always return a valid
1164 * file pointer if it returns - it's responsible for throwing an
1165 * ERR_FATAL and bombing out completely if not. It should also try
1166 * the include path one by one until it finds the file or reaches
1167 * the end of the path.
1169 static FILE *inc_fopen(char *file
)
1172 char *prefix
= "", *combine
;
1173 IncPath
*ip
= ipath
;
1174 static int namelen
= 0;
1175 int len
= strlen(file
);
1178 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
1179 strcpy(combine
, prefix
);
1180 strcat(combine
, file
);
1181 fp
= fopen(combine
, "r");
1182 if (pass
== 0 && fp
) {
1183 namelen
+= strlen(combine
) + 1;
1188 printf(" %s", combine
);
1199 error(ERR_FATAL
, "unable to open include file `%s'", file
);
1200 return NULL
; /* never reached - placate compilers */
1204 * Determine if we should warn on defining a single-line macro of
1205 * name `name', with `nparam' parameters. If nparam is 0 or -1, will
1206 * return TRUE if _any_ single-line macro of that name is defined.
1207 * Otherwise, will return TRUE if a single-line macro with either
1208 * `nparam' or no parameters is defined.
1210 * If a macro with precisely the right number of parameters is
1211 * defined, or nparam is -1, the address of the definition structure
1212 * will be returned in `defn'; otherwise NULL will be returned. If `defn'
1213 * is NULL, no action will be taken regarding its contents, and no
1216 * Note that this is also called with nparam zero to resolve
1219 * If you already know which context macro belongs to, you can pass
1220 * the context pointer as first parameter; if you won't but name begins
1221 * with %$ the context will be automatically computed. If all_contexts
1222 * is true, macro will be searched in outer contexts as well.
1225 smacro_defined(Context
* ctx
, char *name
, int nparam
, SMacro
** defn
,
1232 else if (name
[0] == '%' && name
[1] == '$') {
1234 ctx
= get_ctx(name
, FALSE
);
1236 return FALSE
; /* got to return _something_ */
1239 m
= smacros
[hash(name
)];
1242 if (!mstrcmp(m
->name
, name
, m
->casesense
&& nocase
) &&
1243 (nparam
<= 0 || m
->nparam
== 0 || nparam
== m
->nparam
)) {
1245 if (nparam
== m
->nparam
|| nparam
== -1)
1259 * Count and mark off the parameters in a multi-line macro call.
1260 * This is called both from within the multi-line macro expansion
1261 * code, and also to mark off the default parameters when provided
1262 * in a %macro definition line.
1264 static void count_mmac_params(Token
* t
, int *nparam
, Token
*** params
)
1266 int paramsize
, brace
;
1268 *nparam
= paramsize
= 0;
1271 if (*nparam
>= paramsize
) {
1272 paramsize
+= PARAM_DELTA
;
1273 *params
= nasm_realloc(*params
, sizeof(**params
) * paramsize
);
1277 if (tok_is_(t
, "{"))
1279 (*params
)[(*nparam
)++] = t
;
1280 while (tok_isnt_(t
, brace
? "}" : ","))
1282 if (t
) { /* got a comma/brace */
1286 * Now we've found the closing brace, look further
1290 if (tok_isnt_(t
, ",")) {
1292 "braces do not enclose all of macro parameter");
1293 while (tok_isnt_(t
, ","))
1297 t
= t
->next
; /* eat the comma */
1304 * Determine whether one of the various `if' conditions is true or
1307 * We must free the tline we get passed.
1309 static int if_condition(Token
* tline
, int i
)
1312 Token
*t
, *tt
, **tptr
, *origline
;
1313 struct tokenval tokval
;
1323 j
= FALSE
; /* have we matched yet? */
1324 while (cstk
&& tline
) {
1326 if (!tline
|| tline
->type
!= TOK_ID
) {
1328 "`%s' expects context identifiers", directives
[i
]);
1329 free_tlist(origline
);
1332 if (!nasm_stricmp(tline
->text
, cstk
->name
))
1334 tline
= tline
->next
;
1336 if (i
== PP_IFNCTX
|| i
== PP_ELIFNCTX
)
1338 free_tlist(origline
);
1345 j
= FALSE
; /* have we matched yet? */
1348 if (!tline
|| (tline
->type
!= TOK_ID
&&
1349 (tline
->type
!= TOK_PREPROC_ID
||
1350 tline
->text
[1] != '$'))) {
1352 "`%s' expects macro identifiers", directives
[i
]);
1353 free_tlist(origline
);
1356 if (smacro_defined(NULL
, tline
->text
, 0, NULL
, 1))
1358 tline
= tline
->next
;
1360 if (i
== PP_IFNDEF
|| i
== PP_ELIFNDEF
)
1362 free_tlist(origline
);
1373 tline
= expand_smacro(tline
);
1375 while (tok_isnt_(tt
, ","))
1379 "`%s' expects two comma-separated arguments",
1385 casesense
= (i
== PP_IFIDN
|| i
== PP_ELIFIDN
||
1386 i
== PP_IFNIDN
|| i
== PP_ELIFNIDN
);
1387 j
= TRUE
; /* assume equality unless proved not */
1388 while ((t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ",")) && tt
) {
1389 if (tt
->type
== TOK_OTHER
&& !strcmp(tt
->text
, ",")) {
1390 error(ERR_NONFATAL
, "`%s': more than one comma on line",
1395 if (t
->type
== TOK_WHITESPACE
) {
1399 if (tt
->type
== TOK_WHITESPACE
) {
1403 if (tt
->type
!= t
->type
) {
1404 j
= FALSE
; /* found mismatching tokens */
1407 /* Unify surrounding quotes for strings */
1408 if (t
->type
== TOK_STRING
) {
1409 tt
->text
[0] = t
->text
[0];
1410 tt
->text
[strlen(tt
->text
) - 1] = t
->text
[0];
1412 if (mstrcmp(tt
->text
, t
->text
, casesense
) != 0) {
1413 j
= FALSE
; /* found mismatching tokens */
1420 if ((t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ",")) || tt
)
1421 j
= FALSE
; /* trailing gunk on one end or other */
1422 if (i
== PP_IFNIDN
|| i
== PP_ELIFNIDN
||
1423 i
== PP_IFNIDNI
|| i
== PP_ELIFNIDNI
)
1434 MMacro searching
, *mmac
;
1436 tline
= tline
->next
;
1438 tline
= expand_id(tline
);
1439 if (!tok_type_(tline
, TOK_ID
)) {
1441 "`%s' expects a macro name", directives
[i
]);
1444 searching
.name
= nasm_strdup(tline
->text
);
1445 searching
.casesense
= (i
== PP_MACRO
);
1446 searching
.plus
= FALSE
;
1447 searching
.nolist
= FALSE
;
1448 searching
.in_progress
= FALSE
;
1449 searching
.rep_nest
= NULL
;
1450 searching
.nparam_min
= 0;
1451 searching
.nparam_max
= INT_MAX
;
1452 tline
= expand_smacro(tline
->next
);
1455 } else if (!tok_type_(tline
, TOK_NUMBER
)) {
1457 "`%s' expects a parameter count or nothing",
1460 searching
.nparam_min
= searching
.nparam_max
=
1461 readnum(tline
->text
, &j
);
1464 "unable to parse parameter count `%s'",
1467 if (tline
&& tok_is_(tline
->next
, "-")) {
1468 tline
= tline
->next
->next
;
1469 if (tok_is_(tline
, "*"))
1470 searching
.nparam_max
= INT_MAX
;
1471 else if (!tok_type_(tline
, TOK_NUMBER
))
1473 "`%s' expects a parameter count after `-'",
1476 searching
.nparam_max
= readnum(tline
->text
, &j
);
1479 "unable to parse parameter count `%s'",
1481 if (searching
.nparam_min
> searching
.nparam_max
)
1483 "minimum parameter count exceeds maximum");
1486 if (tline
&& tok_is_(tline
->next
, "+")) {
1487 tline
= tline
->next
;
1488 searching
.plus
= TRUE
;
1490 mmac
= mmacros
[hash(searching
.name
)];
1492 if (!strcmp(mmac
->name
, searching
.name
) &&
1493 (mmac
->nparam_min
<= searching
.nparam_max
1495 && (searching
.nparam_min
<= mmac
->nparam_max
1502 nasm_free(searching
.name
);
1503 free_tlist(origline
);
1504 if (i
== PP_IFNMACRO
|| i
== PP_ELIFNMACRO
)
1521 tline
= expand_smacro(tline
);
1523 while (tok_type_(t
, TOK_WHITESPACE
))
1525 j
= FALSE
; /* placate optimiser */
1532 j
= (t
->type
== TOK_ID
);
1538 j
= (t
->type
== TOK_NUMBER
);
1544 j
= (t
->type
== TOK_STRING
);
1547 if (i
== PP_IFNID
|| i
== PP_ELIFNID
||
1548 i
== PP_IFNNUM
|| i
== PP_ELIFNNUM
||
1549 i
== PP_IFNSTR
|| i
== PP_ELIFNSTR
)
1556 t
= tline
= expand_smacro(tline
);
1558 tokval
.t_type
= TOKEN_INVALID
;
1559 evalresult
= evaluate(ppscan
, tptr
, &tokval
,
1560 NULL
, pass
| CRITICAL
, error
, NULL
);
1566 "trailing garbage after expression ignored");
1567 if (!is_simple(evalresult
)) {
1569 "non-constant value given to `%s'", directives
[i
]);
1572 return reloc_value(evalresult
) != 0;
1576 "preprocessor directive `%s' not yet implemented",
1578 free_tlist(origline
);
1579 return -1; /* yeah, right */
1584 * Expand macros in a string. Used in %error and %include directives.
1585 * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
1586 * The returned variable should ALWAYS be freed after usage.
1588 void expand_macros_in_string(char **p
)
1590 Token
*line
= tokenise(*p
);
1591 line
= expand_smacro(line
);
1592 *p
= detoken(line
, FALSE
);
1596 * find and process preprocessor directive in passed line
1597 * Find out if a line contains a preprocessor directive, and deal
1600 * If a directive _is_ found, it is the responsibility of this routine
1601 * (and not the caller) to free_tlist() the line.
1603 * @param tline a pointer to the current tokeninzed line linked list
1604 * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND
1607 static int do_directive(Token
* tline
)
1609 int i
, j
, k
, m
, nparam
, nolist
;
1615 SMacro
*smac
, **smhead
;
1617 Token
*t
, *tt
, *param_start
, *macro_start
, *last
, **tptr
, *origline
;
1619 struct tokenval tokval
;
1621 MMacro
*tmp_defining
; /* Used when manipulating rep_nest */
1626 if (!tok_type_(tline
, TOK_PREPROC_ID
) ||
1627 (tline
->text
[1] == '%' || tline
->text
[1] == '$'
1628 || tline
->text
[1] == '!'))
1629 return NO_DIRECTIVE_FOUND
;
1632 j
= elements(directives
);
1635 m
= nasm_stricmp(tline
->text
, directives
[k
]);
1637 if (tasm_compatible_mode
) {
1640 } else if (k
!= PP_ARG
&& k
!= PP_LOCAL
&& k
!= PP_STACKSIZE
) {
1652 * If we're in a non-emitting branch of a condition construct,
1653 * or walking to the end of an already terminated %rep block,
1654 * we should ignore all directives except for condition
1657 if (((istk
->conds
&& !emitting(istk
->conds
->state
)) ||
1658 (istk
->mstk
&& !istk
->mstk
->in_progress
)) && !is_condition(i
)) {
1659 return NO_DIRECTIVE_FOUND
;
1663 * If we're defining a macro or reading a %rep block, we should
1664 * ignore all directives except for %macro/%imacro (which
1665 * generate an error), %endm/%endmacro, and (only if we're in a
1666 * %rep block) %endrep. If we're in a %rep block, another %rep
1667 * causes an error, so should be let through.
1669 if (defining
&& i
!= PP_MACRO
&& i
!= PP_IMACRO
&&
1670 i
!= PP_ENDMACRO
&& i
!= PP_ENDM
&&
1671 (defining
->name
|| (i
!= PP_ENDREP
&& i
!= PP_REP
))) {
1672 return NO_DIRECTIVE_FOUND
;
1676 error(ERR_NONFATAL
, "unknown preprocessor directive `%s'",
1678 return NO_DIRECTIVE_FOUND
; /* didn't get it */
1683 /* Directive to tell NASM what the default stack size is. The
1684 * default is for a 16-bit stack, and this can be overriden with
1686 * the following form:
1688 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1690 tline
= tline
->next
;
1691 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1692 tline
= tline
->next
;
1693 if (!tline
|| tline
->type
!= TOK_ID
) {
1694 error(ERR_NONFATAL
, "`%%stacksize' missing size parameter");
1695 free_tlist(origline
);
1696 return DIRECTIVE_FOUND
;
1698 if (nasm_stricmp(tline
->text
, "flat") == 0) {
1699 /* All subsequent ARG directives are for a 32-bit stack */
1701 StackPointer
= "ebp";
1704 } else if (nasm_stricmp(tline
->text
, "large") == 0) {
1705 /* All subsequent ARG directives are for a 16-bit stack,
1706 * far function call.
1709 StackPointer
= "bp";
1712 } else if (nasm_stricmp(tline
->text
, "small") == 0) {
1713 /* All subsequent ARG directives are for a 16-bit stack,
1714 * far function call. We don't support near functions.
1717 StackPointer
= "bp";
1721 error(ERR_NONFATAL
, "`%%stacksize' invalid size type");
1722 free_tlist(origline
);
1723 return DIRECTIVE_FOUND
;
1725 free_tlist(origline
);
1726 return DIRECTIVE_FOUND
;
1729 /* TASM like ARG directive to define arguments to functions, in
1730 * the following form:
1732 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1736 char *arg
, directive
[256];
1737 int size
= StackSize
;
1739 /* Find the argument name */
1740 tline
= tline
->next
;
1741 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1742 tline
= tline
->next
;
1743 if (!tline
|| tline
->type
!= TOK_ID
) {
1744 error(ERR_NONFATAL
, "`%%arg' missing argument parameter");
1745 free_tlist(origline
);
1746 return DIRECTIVE_FOUND
;
1750 /* Find the argument size type */
1751 tline
= tline
->next
;
1752 if (!tline
|| tline
->type
!= TOK_OTHER
1753 || tline
->text
[0] != ':') {
1755 "Syntax error processing `%%arg' directive");
1756 free_tlist(origline
);
1757 return DIRECTIVE_FOUND
;
1759 tline
= tline
->next
;
1760 if (!tline
|| tline
->type
!= TOK_ID
) {
1761 error(ERR_NONFATAL
, "`%%arg' missing size type parameter");
1762 free_tlist(origline
);
1763 return DIRECTIVE_FOUND
;
1766 /* Allow macro expansion of type parameter */
1767 tt
= tokenise(tline
->text
);
1768 tt
= expand_smacro(tt
);
1769 if (nasm_stricmp(tt
->text
, "byte") == 0) {
1770 size
= MAX(StackSize
, 1);
1771 } else if (nasm_stricmp(tt
->text
, "word") == 0) {
1772 size
= MAX(StackSize
, 2);
1773 } else if (nasm_stricmp(tt
->text
, "dword") == 0) {
1774 size
= MAX(StackSize
, 4);
1775 } else if (nasm_stricmp(tt
->text
, "qword") == 0) {
1776 size
= MAX(StackSize
, 8);
1777 } else if (nasm_stricmp(tt
->text
, "tword") == 0) {
1778 size
= MAX(StackSize
, 10);
1781 "Invalid size type for `%%arg' missing directive");
1783 free_tlist(origline
);
1784 return DIRECTIVE_FOUND
;
1788 /* Now define the macro for the argument */
1789 snprintf(directive
, sizeof(directive
), "%%define %s (%s+%d)",
1790 arg
, StackPointer
, offset
);
1791 do_directive(tokenise(directive
));
1794 /* Move to the next argument in the list */
1795 tline
= tline
->next
;
1796 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1797 tline
= tline
->next
;
1799 while (tline
&& tline
->type
== TOK_OTHER
&& tline
->text
[0] == ',');
1800 free_tlist(origline
);
1801 return DIRECTIVE_FOUND
;
1804 /* TASM like LOCAL directive to define local variables for a
1805 * function, in the following form:
1807 * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1809 * The '= LocalSize' at the end is ignored by NASM, but is
1810 * required by TASM to define the local parameter size (and used
1811 * by the TASM macro package).
1813 offset
= LocalOffset
;
1815 char *local
, directive
[256];
1816 int size
= StackSize
;
1818 /* Find the argument name */
1819 tline
= tline
->next
;
1820 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1821 tline
= tline
->next
;
1822 if (!tline
|| tline
->type
!= TOK_ID
) {
1824 "`%%local' missing argument parameter");
1825 free_tlist(origline
);
1826 return DIRECTIVE_FOUND
;
1828 local
= tline
->text
;
1830 /* Find the argument size type */
1831 tline
= tline
->next
;
1832 if (!tline
|| tline
->type
!= TOK_OTHER
1833 || tline
->text
[0] != ':') {
1835 "Syntax error processing `%%local' directive");
1836 free_tlist(origline
);
1837 return DIRECTIVE_FOUND
;
1839 tline
= tline
->next
;
1840 if (!tline
|| tline
->type
!= TOK_ID
) {
1842 "`%%local' missing size type parameter");
1843 free_tlist(origline
);
1844 return DIRECTIVE_FOUND
;
1847 /* Allow macro expansion of type parameter */
1848 tt
= tokenise(tline
->text
);
1849 tt
= expand_smacro(tt
);
1850 if (nasm_stricmp(tt
->text
, "byte") == 0) {
1851 size
= MAX(StackSize
, 1);
1852 } else if (nasm_stricmp(tt
->text
, "word") == 0) {
1853 size
= MAX(StackSize
, 2);
1854 } else if (nasm_stricmp(tt
->text
, "dword") == 0) {
1855 size
= MAX(StackSize
, 4);
1856 } else if (nasm_stricmp(tt
->text
, "qword") == 0) {
1857 size
= MAX(StackSize
, 8);
1858 } else if (nasm_stricmp(tt
->text
, "tword") == 0) {
1859 size
= MAX(StackSize
, 10);
1862 "Invalid size type for `%%local' missing directive");
1864 free_tlist(origline
);
1865 return DIRECTIVE_FOUND
;
1869 /* Now define the macro for the argument */
1870 snprintf(directive
, sizeof(directive
), "%%define %s (%s-%d)",
1871 local
, StackPointer
, offset
);
1872 do_directive(tokenise(directive
));
1875 /* Now define the assign to setup the enter_c macro correctly */
1876 snprintf(directive
, sizeof(directive
),
1877 "%%assign %%$localsize %%$localsize+%d", size
);
1878 do_directive(tokenise(directive
));
1880 /* Move to the next argument in the list */
1881 tline
= tline
->next
;
1882 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1883 tline
= tline
->next
;
1885 while (tline
&& tline
->type
== TOK_OTHER
&& tline
->text
[0] == ',');
1886 free_tlist(origline
);
1887 return DIRECTIVE_FOUND
;
1891 error(ERR_WARNING
, "trailing garbage after `%%clear' ignored");
1892 for (j
= 0; j
< NHASH
; j
++) {
1893 while (mmacros
[j
]) {
1894 MMacro
*m
= mmacros
[j
];
1895 mmacros
[j
] = m
->next
;
1898 while (smacros
[j
]) {
1899 SMacro
*s
= smacros
[j
];
1900 smacros
[j
] = smacros
[j
]->next
;
1902 free_tlist(s
->expansion
);
1906 free_tlist(origline
);
1907 return DIRECTIVE_FOUND
;
1910 tline
= tline
->next
;
1912 if (!tline
|| (tline
->type
!= TOK_STRING
&&
1913 tline
->type
!= TOK_INTERNAL_STRING
)) {
1914 error(ERR_NONFATAL
, "`%%include' expects a file name");
1915 free_tlist(origline
);
1916 return DIRECTIVE_FOUND
; /* but we did _something_ */
1920 "trailing garbage after `%%include' ignored");
1921 if (tline
->type
!= TOK_INTERNAL_STRING
) {
1922 p
= tline
->text
+ 1; /* point past the quote to the name */
1923 p
[strlen(p
) - 1] = '\0'; /* remove the trailing quote */
1925 p
= tline
->text
; /* internal_string is easier */
1926 expand_macros_in_string(&p
);
1927 inc
= nasm_malloc(sizeof(Include
));
1930 inc
->fp
= inc_fopen(p
);
1931 inc
->fname
= src_set_fname(p
);
1932 inc
->lineno
= src_set_linnum(0);
1934 inc
->expansion
= NULL
;
1937 list
->uplevel(LIST_INCLUDE
);
1938 free_tlist(origline
);
1939 return DIRECTIVE_FOUND
;
1942 tline
= tline
->next
;
1944 tline
= expand_id(tline
);
1945 if (!tok_type_(tline
, TOK_ID
)) {
1946 error(ERR_NONFATAL
, "`%%push' expects a context identifier");
1947 free_tlist(origline
);
1948 return DIRECTIVE_FOUND
; /* but we did _something_ */
1951 error(ERR_WARNING
, "trailing garbage after `%%push' ignored");
1952 ctx
= nasm_malloc(sizeof(Context
));
1954 ctx
->localmac
= NULL
;
1955 ctx
->name
= nasm_strdup(tline
->text
);
1956 ctx
->number
= unique
++;
1958 free_tlist(origline
);
1962 tline
= tline
->next
;
1964 tline
= expand_id(tline
);
1965 if (!tok_type_(tline
, TOK_ID
)) {
1966 error(ERR_NONFATAL
, "`%%repl' expects a context identifier");
1967 free_tlist(origline
);
1968 return DIRECTIVE_FOUND
; /* but we did _something_ */
1971 error(ERR_WARNING
, "trailing garbage after `%%repl' ignored");
1973 error(ERR_NONFATAL
, "`%%repl': context stack is empty");
1975 nasm_free(cstk
->name
);
1976 cstk
->name
= nasm_strdup(tline
->text
);
1978 free_tlist(origline
);
1983 error(ERR_WARNING
, "trailing garbage after `%%pop' ignored");
1985 error(ERR_NONFATAL
, "`%%pop': context stack is already empty");
1988 free_tlist(origline
);
1992 tline
->next
= expand_smacro(tline
->next
);
1993 tline
= tline
->next
;
1995 if (tok_type_(tline
, TOK_STRING
)) {
1996 p
= tline
->text
+ 1; /* point past the quote to the name */
1997 p
[strlen(p
) - 1] = '\0'; /* remove the trailing quote */
1998 expand_macros_in_string(&p
);
1999 error(ERR_NONFATAL
, "%s", p
);
2002 p
= detoken(tline
, FALSE
);
2003 error(ERR_WARNING
, "%s", p
);
2006 free_tlist(origline
);
2026 if (istk
->conds
&& !emitting(istk
->conds
->state
))
2029 j
= if_condition(tline
->next
, i
);
2030 tline
->next
= NULL
; /* it got freed */
2031 free_tlist(origline
);
2032 j
= j
< 0 ? COND_NEVER
: j
? COND_IF_TRUE
: COND_IF_FALSE
;
2034 cond
= nasm_malloc(sizeof(Cond
));
2035 cond
->next
= istk
->conds
;
2038 return DIRECTIVE_FOUND
;
2058 error(ERR_FATAL
, "`%s': no matching `%%if'", directives
[i
]);
2059 if (emitting(istk
->conds
->state
)
2060 || istk
->conds
->state
== COND_NEVER
)
2061 istk
->conds
->state
= COND_NEVER
;
2064 * IMPORTANT: In the case of %if, we will already have
2065 * called expand_mmac_params(); however, if we're
2066 * processing an %elif we must have been in a
2067 * non-emitting mode, which would have inhibited
2068 * the normal invocation of expand_mmac_params(). Therefore,
2069 * we have to do it explicitly here.
2071 j
= if_condition(expand_mmac_params(tline
->next
), i
);
2072 tline
->next
= NULL
; /* it got freed */
2073 free_tlist(origline
);
2074 istk
->conds
->state
=
2075 j
< 0 ? COND_NEVER
: j
? COND_IF_TRUE
: COND_IF_FALSE
;
2077 return DIRECTIVE_FOUND
;
2081 error(ERR_WARNING
, "trailing garbage after `%%else' ignored");
2083 error(ERR_FATAL
, "`%%else': no matching `%%if'");
2084 if (emitting(istk
->conds
->state
)
2085 || istk
->conds
->state
== COND_NEVER
)
2086 istk
->conds
->state
= COND_ELSE_FALSE
;
2088 istk
->conds
->state
= COND_ELSE_TRUE
;
2089 free_tlist(origline
);
2090 return DIRECTIVE_FOUND
;
2094 error(ERR_WARNING
, "trailing garbage after `%%endif' ignored");
2096 error(ERR_FATAL
, "`%%endif': no matching `%%if'");
2098 istk
->conds
= cond
->next
;
2100 free_tlist(origline
);
2101 return DIRECTIVE_FOUND
;
2107 "`%%%smacro': already defining a macro",
2108 (i
== PP_IMACRO
? "i" : ""));
2109 tline
= tline
->next
;
2111 tline
= expand_id(tline
);
2112 if (!tok_type_(tline
, TOK_ID
)) {
2114 "`%%%smacro' expects a macro name",
2115 (i
== PP_IMACRO
? "i" : ""));
2116 return DIRECTIVE_FOUND
;
2118 defining
= nasm_malloc(sizeof(MMacro
));
2119 defining
->name
= nasm_strdup(tline
->text
);
2120 defining
->casesense
= (i
== PP_MACRO
);
2121 defining
->plus
= FALSE
;
2122 defining
->nolist
= FALSE
;
2123 defining
->in_progress
= FALSE
;
2124 defining
->rep_nest
= NULL
;
2125 tline
= expand_smacro(tline
->next
);
2127 if (!tok_type_(tline
, TOK_NUMBER
)) {
2129 "`%%%smacro' expects a parameter count",
2130 (i
== PP_IMACRO
? "i" : ""));
2131 defining
->nparam_min
= defining
->nparam_max
= 0;
2133 defining
->nparam_min
= defining
->nparam_max
=
2134 readnum(tline
->text
, &j
);
2137 "unable to parse parameter count `%s'", tline
->text
);
2139 if (tline
&& tok_is_(tline
->next
, "-")) {
2140 tline
= tline
->next
->next
;
2141 if (tok_is_(tline
, "*"))
2142 defining
->nparam_max
= INT_MAX
;
2143 else if (!tok_type_(tline
, TOK_NUMBER
))
2145 "`%%%smacro' expects a parameter count after `-'",
2146 (i
== PP_IMACRO
? "i" : ""));
2148 defining
->nparam_max
= readnum(tline
->text
, &j
);
2151 "unable to parse parameter count `%s'",
2153 if (defining
->nparam_min
> defining
->nparam_max
)
2155 "minimum parameter count exceeds maximum");
2158 if (tline
&& tok_is_(tline
->next
, "+")) {
2159 tline
= tline
->next
;
2160 defining
->plus
= TRUE
;
2162 if (tline
&& tok_type_(tline
->next
, TOK_ID
) &&
2163 !nasm_stricmp(tline
->next
->text
, ".nolist")) {
2164 tline
= tline
->next
;
2165 defining
->nolist
= TRUE
;
2167 mmac
= mmacros
[hash(defining
->name
)];
2169 if (!strcmp(mmac
->name
, defining
->name
) &&
2170 (mmac
->nparam_min
<= defining
->nparam_max
2172 && (defining
->nparam_min
<= mmac
->nparam_max
2175 "redefining multi-line macro `%s'", defining
->name
);
2181 * Handle default parameters.
2183 if (tline
&& tline
->next
) {
2184 defining
->dlist
= tline
->next
;
2186 count_mmac_params(defining
->dlist
, &defining
->ndefs
,
2187 &defining
->defaults
);
2189 defining
->dlist
= NULL
;
2190 defining
->defaults
= NULL
;
2192 defining
->expansion
= NULL
;
2193 free_tlist(origline
);
2194 return DIRECTIVE_FOUND
;
2199 error(ERR_NONFATAL
, "`%s': not defining a macro", tline
->text
);
2200 return DIRECTIVE_FOUND
;
2202 k
= hash(defining
->name
);
2203 defining
->next
= mmacros
[k
];
2204 mmacros
[k
] = defining
;
2206 free_tlist(origline
);
2207 return DIRECTIVE_FOUND
;
2210 if (tline
->next
&& tline
->next
->type
== TOK_WHITESPACE
)
2211 tline
= tline
->next
;
2212 if (tline
->next
== NULL
) {
2213 free_tlist(origline
);
2214 error(ERR_NONFATAL
, "`%%rotate' missing rotate count");
2215 return DIRECTIVE_FOUND
;
2217 t
= expand_smacro(tline
->next
);
2219 free_tlist(origline
);
2222 tokval
.t_type
= TOKEN_INVALID
;
2224 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2227 return DIRECTIVE_FOUND
;
2230 "trailing garbage after expression ignored");
2231 if (!is_simple(evalresult
)) {
2232 error(ERR_NONFATAL
, "non-constant value given to `%%rotate'");
2233 return DIRECTIVE_FOUND
;
2236 while (mmac
&& !mmac
->name
) /* avoid mistaking %reps for macros */
2237 mmac
= mmac
->next_active
;
2239 error(ERR_NONFATAL
, "`%%rotate' invoked outside a macro call");
2240 } else if (mmac
->nparam
== 0) {
2242 "`%%rotate' invoked within macro without parameters");
2244 mmac
->rotate
= mmac
->rotate
+ reloc_value(evalresult
);
2246 if (mmac
->rotate
< 0)
2248 mmac
->nparam
- (-mmac
->rotate
) % mmac
->nparam
;
2249 mmac
->rotate
%= mmac
->nparam
;
2251 return DIRECTIVE_FOUND
;
2256 tline
= tline
->next
;
2257 } while (tok_type_(tline
, TOK_WHITESPACE
));
2259 if (tok_type_(tline
, TOK_ID
) &&
2260 nasm_stricmp(tline
->text
, ".nolist") == 0) {
2263 tline
= tline
->next
;
2264 } while (tok_type_(tline
, TOK_WHITESPACE
));
2268 t
= expand_smacro(tline
);
2270 tokval
.t_type
= TOKEN_INVALID
;
2272 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2274 free_tlist(origline
);
2275 return DIRECTIVE_FOUND
;
2279 "trailing garbage after expression ignored");
2280 if (!is_simple(evalresult
)) {
2281 error(ERR_NONFATAL
, "non-constant value given to `%%rep'");
2282 return DIRECTIVE_FOUND
;
2284 i
= (int)reloc_value(evalresult
) + 1;
2286 error(ERR_NONFATAL
, "`%%rep' expects a repeat count");
2289 free_tlist(origline
);
2291 tmp_defining
= defining
;
2292 defining
= nasm_malloc(sizeof(MMacro
));
2293 defining
->name
= NULL
; /* flags this macro as a %rep block */
2294 defining
->casesense
= 0;
2295 defining
->plus
= FALSE
;
2296 defining
->nolist
= nolist
;
2297 defining
->in_progress
= i
;
2298 defining
->nparam_min
= defining
->nparam_max
= 0;
2299 defining
->defaults
= NULL
;
2300 defining
->dlist
= NULL
;
2301 defining
->expansion
= NULL
;
2302 defining
->next_active
= istk
->mstk
;
2303 defining
->rep_nest
= tmp_defining
;
2304 return DIRECTIVE_FOUND
;
2307 if (!defining
|| defining
->name
) {
2308 error(ERR_NONFATAL
, "`%%endrep': no matching `%%rep'");
2309 return DIRECTIVE_FOUND
;
2313 * Now we have a "macro" defined - although it has no name
2314 * and we won't be entering it in the hash tables - we must
2315 * push a macro-end marker for it on to istk->expansion.
2316 * After that, it will take care of propagating itself (a
2317 * macro-end marker line for a macro which is really a %rep
2318 * block will cause the macro to be re-expanded, complete
2319 * with another macro-end marker to ensure the process
2320 * continues) until the whole expansion is forcibly removed
2321 * from istk->expansion by a %exitrep.
2323 l
= nasm_malloc(sizeof(Line
));
2324 l
->next
= istk
->expansion
;
2325 l
->finishes
= defining
;
2327 istk
->expansion
= l
;
2329 istk
->mstk
= defining
;
2331 list
->uplevel(defining
->nolist
? LIST_MACRO_NOLIST
: LIST_MACRO
);
2332 tmp_defining
= defining
;
2333 defining
= defining
->rep_nest
;
2334 free_tlist(origline
);
2335 return DIRECTIVE_FOUND
;
2339 * We must search along istk->expansion until we hit a
2340 * macro-end marker for a macro with no name. Then we set
2341 * its `in_progress' flag to 0.
2343 for (l
= istk
->expansion
; l
; l
= l
->next
)
2344 if (l
->finishes
&& !l
->finishes
->name
)
2348 l
->finishes
->in_progress
= 0;
2350 error(ERR_NONFATAL
, "`%%exitrep' not within `%%rep' block");
2351 free_tlist(origline
);
2352 return DIRECTIVE_FOUND
;
2358 tline
= tline
->next
;
2360 tline
= expand_id(tline
);
2361 if (!tline
|| (tline
->type
!= TOK_ID
&&
2362 (tline
->type
!= TOK_PREPROC_ID
||
2363 tline
->text
[1] != '$'))) {
2365 "`%%%s%sdefine' expects a macro identifier",
2366 ((i
== PP_IDEFINE
|| i
== PP_IXDEFINE
) ? "i" : ""),
2367 ((i
== PP_XDEFINE
|| i
== PP_IXDEFINE
) ? "x" : ""));
2368 free_tlist(origline
);
2369 return DIRECTIVE_FOUND
;
2372 ctx
= get_ctx(tline
->text
, FALSE
);
2374 smhead
= &smacros
[hash(tline
->text
)];
2376 smhead
= &ctx
->localmac
;
2377 mname
= tline
->text
;
2379 param_start
= tline
= tline
->next
;
2382 /* Expand the macro definition now for %xdefine and %ixdefine */
2383 if ((i
== PP_XDEFINE
) || (i
== PP_IXDEFINE
))
2384 tline
= expand_smacro(tline
);
2386 if (tok_is_(tline
, "(")) {
2388 * This macro has parameters.
2391 tline
= tline
->next
;
2395 error(ERR_NONFATAL
, "parameter identifier expected");
2396 free_tlist(origline
);
2397 return DIRECTIVE_FOUND
;
2399 if (tline
->type
!= TOK_ID
) {
2401 "`%s': parameter identifier expected",
2403 free_tlist(origline
);
2404 return DIRECTIVE_FOUND
;
2406 tline
->type
= TOK_SMAC_PARAM
+ nparam
++;
2407 tline
= tline
->next
;
2409 if (tok_is_(tline
, ",")) {
2410 tline
= tline
->next
;
2413 if (!tok_is_(tline
, ")")) {
2415 "`)' expected to terminate macro template");
2416 free_tlist(origline
);
2417 return DIRECTIVE_FOUND
;
2422 tline
= tline
->next
;
2424 if (tok_type_(tline
, TOK_WHITESPACE
))
2425 last
= tline
, tline
= tline
->next
;
2430 if (t
->type
== TOK_ID
) {
2431 for (tt
= param_start
; tt
; tt
= tt
->next
)
2432 if (tt
->type
>= TOK_SMAC_PARAM
&&
2433 !strcmp(tt
->text
, t
->text
))
2437 t
->next
= macro_start
;
2442 * Good. We now have a macro name, a parameter count, and a
2443 * token list (in reverse order) for an expansion. We ought
2444 * to be OK just to create an SMacro, store it, and let
2445 * free_tlist have the rest of the line (which we have
2446 * carefully re-terminated after chopping off the expansion
2449 if (smacro_defined(ctx
, mname
, nparam
, &smac
, i
== PP_DEFINE
)) {
2452 "single-line macro `%s' defined both with and"
2453 " without parameters", mname
);
2454 free_tlist(origline
);
2455 free_tlist(macro_start
);
2456 return DIRECTIVE_FOUND
;
2459 * We're redefining, so we have to take over an
2460 * existing SMacro structure. This means freeing
2461 * what was already in it.
2463 nasm_free(smac
->name
);
2464 free_tlist(smac
->expansion
);
2467 smac
= nasm_malloc(sizeof(SMacro
));
2468 smac
->next
= *smhead
;
2471 smac
->name
= nasm_strdup(mname
);
2472 smac
->casesense
= ((i
== PP_DEFINE
) || (i
== PP_XDEFINE
));
2473 smac
->nparam
= nparam
;
2474 smac
->expansion
= macro_start
;
2475 smac
->in_progress
= FALSE
;
2476 free_tlist(origline
);
2477 return DIRECTIVE_FOUND
;
2480 tline
= tline
->next
;
2482 tline
= expand_id(tline
);
2483 if (!tline
|| (tline
->type
!= TOK_ID
&&
2484 (tline
->type
!= TOK_PREPROC_ID
||
2485 tline
->text
[1] != '$'))) {
2486 error(ERR_NONFATAL
, "`%%undef' expects a macro identifier");
2487 free_tlist(origline
);
2488 return DIRECTIVE_FOUND
;
2492 "trailing garbage after macro name ignored");
2495 /* Find the context that symbol belongs to */
2496 ctx
= get_ctx(tline
->text
, FALSE
);
2498 smhead
= &smacros
[hash(tline
->text
)];
2500 smhead
= &ctx
->localmac
;
2502 mname
= tline
->text
;
2507 * We now have a macro name... go hunt for it.
2509 while (smacro_defined(ctx
, mname
, -1, &smac
, 1)) {
2510 /* Defined, so we need to find its predecessor and nuke it */
2512 for (s
= smhead
; *s
&& *s
!= smac
; s
= &(*s
)->next
) ;
2515 nasm_free(smac
->name
);
2516 free_tlist(smac
->expansion
);
2520 free_tlist(origline
);
2521 return DIRECTIVE_FOUND
;
2524 tline
= tline
->next
;
2526 tline
= expand_id(tline
);
2527 if (!tline
|| (tline
->type
!= TOK_ID
&&
2528 (tline
->type
!= TOK_PREPROC_ID
||
2529 tline
->text
[1] != '$'))) {
2531 "`%%strlen' expects a macro identifier as first parameter");
2532 free_tlist(origline
);
2533 return DIRECTIVE_FOUND
;
2535 ctx
= get_ctx(tline
->text
, FALSE
);
2537 smhead
= &smacros
[hash(tline
->text
)];
2539 smhead
= &ctx
->localmac
;
2540 mname
= tline
->text
;
2542 tline
= expand_smacro(tline
->next
);
2546 while (tok_type_(t
, TOK_WHITESPACE
))
2548 /* t should now point to the string */
2549 if (t
->type
!= TOK_STRING
) {
2551 "`%%strlen` requires string as second parameter");
2553 free_tlist(origline
);
2554 return DIRECTIVE_FOUND
;
2557 macro_start
= nasm_malloc(sizeof(*macro_start
));
2558 macro_start
->next
= NULL
;
2559 make_tok_num(macro_start
, strlen(t
->text
) - 2);
2560 macro_start
->mac
= NULL
;
2563 * We now have a macro name, an implicit parameter count of
2564 * zero, and a numeric token to use as an expansion. Create
2565 * and store an SMacro.
2567 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_STRLEN
)) {
2570 "single-line macro `%s' defined both with and"
2571 " without parameters", mname
);
2574 * We're redefining, so we have to take over an
2575 * existing SMacro structure. This means freeing
2576 * what was already in it.
2578 nasm_free(smac
->name
);
2579 free_tlist(smac
->expansion
);
2582 smac
= nasm_malloc(sizeof(SMacro
));
2583 smac
->next
= *smhead
;
2586 smac
->name
= nasm_strdup(mname
);
2587 smac
->casesense
= (i
== PP_STRLEN
);
2589 smac
->expansion
= macro_start
;
2590 smac
->in_progress
= FALSE
;
2592 free_tlist(origline
);
2593 return DIRECTIVE_FOUND
;
2596 tline
= tline
->next
;
2598 tline
= expand_id(tline
);
2599 if (!tline
|| (tline
->type
!= TOK_ID
&&
2600 (tline
->type
!= TOK_PREPROC_ID
||
2601 tline
->text
[1] != '$'))) {
2603 "`%%substr' expects a macro identifier as first parameter");
2604 free_tlist(origline
);
2605 return DIRECTIVE_FOUND
;
2607 ctx
= get_ctx(tline
->text
, FALSE
);
2609 smhead
= &smacros
[hash(tline
->text
)];
2611 smhead
= &ctx
->localmac
;
2612 mname
= tline
->text
;
2614 tline
= expand_smacro(tline
->next
);
2618 while (tok_type_(t
, TOK_WHITESPACE
))
2621 /* t should now point to the string */
2622 if (t
->type
!= TOK_STRING
) {
2624 "`%%substr` requires string as second parameter");
2626 free_tlist(origline
);
2627 return DIRECTIVE_FOUND
;
2632 tokval
.t_type
= TOKEN_INVALID
;
2634 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2637 free_tlist(origline
);
2638 return DIRECTIVE_FOUND
;
2640 if (!is_simple(evalresult
)) {
2641 error(ERR_NONFATAL
, "non-constant value given to `%%substr`");
2643 free_tlist(origline
);
2644 return DIRECTIVE_FOUND
;
2647 macro_start
= nasm_malloc(sizeof(*macro_start
));
2648 macro_start
->next
= NULL
;
2649 macro_start
->text
= nasm_strdup("'''");
2650 if (evalresult
->value
> 0
2651 && evalresult
->value
< strlen(t
->text
) - 1) {
2652 macro_start
->text
[1] = t
->text
[evalresult
->value
];
2654 macro_start
->text
[2] = '\0';
2656 macro_start
->type
= TOK_STRING
;
2657 macro_start
->mac
= NULL
;
2660 * We now have a macro name, an implicit parameter count of
2661 * zero, and a numeric token to use as an expansion. Create
2662 * and store an SMacro.
2664 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_SUBSTR
)) {
2667 "single-line macro `%s' defined both with and"
2668 " without parameters", mname
);
2671 * We're redefining, so we have to take over an
2672 * existing SMacro structure. This means freeing
2673 * what was already in it.
2675 nasm_free(smac
->name
);
2676 free_tlist(smac
->expansion
);
2679 smac
= nasm_malloc(sizeof(SMacro
));
2680 smac
->next
= *smhead
;
2683 smac
->name
= nasm_strdup(mname
);
2684 smac
->casesense
= (i
== PP_SUBSTR
);
2686 smac
->expansion
= macro_start
;
2687 smac
->in_progress
= FALSE
;
2689 free_tlist(origline
);
2690 return DIRECTIVE_FOUND
;
2694 tline
= tline
->next
;
2696 tline
= expand_id(tline
);
2697 if (!tline
|| (tline
->type
!= TOK_ID
&&
2698 (tline
->type
!= TOK_PREPROC_ID
||
2699 tline
->text
[1] != '$'))) {
2701 "`%%%sassign' expects a macro identifier",
2702 (i
== PP_IASSIGN
? "i" : ""));
2703 free_tlist(origline
);
2704 return DIRECTIVE_FOUND
;
2706 ctx
= get_ctx(tline
->text
, FALSE
);
2708 smhead
= &smacros
[hash(tline
->text
)];
2710 smhead
= &ctx
->localmac
;
2711 mname
= tline
->text
;
2713 tline
= expand_smacro(tline
->next
);
2718 tokval
.t_type
= TOKEN_INVALID
;
2720 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2723 free_tlist(origline
);
2724 return DIRECTIVE_FOUND
;
2729 "trailing garbage after expression ignored");
2731 if (!is_simple(evalresult
)) {
2733 "non-constant value given to `%%%sassign'",
2734 (i
== PP_IASSIGN
? "i" : ""));
2735 free_tlist(origline
);
2736 return DIRECTIVE_FOUND
;
2739 macro_start
= nasm_malloc(sizeof(*macro_start
));
2740 macro_start
->next
= NULL
;
2741 make_tok_num(macro_start
, reloc_value(evalresult
));
2742 macro_start
->mac
= NULL
;
2745 * We now have a macro name, an implicit parameter count of
2746 * zero, and a numeric token to use as an expansion. Create
2747 * and store an SMacro.
2749 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_ASSIGN
)) {
2752 "single-line macro `%s' defined both with and"
2753 " without parameters", mname
);
2756 * We're redefining, so we have to take over an
2757 * existing SMacro structure. This means freeing
2758 * what was already in it.
2760 nasm_free(smac
->name
);
2761 free_tlist(smac
->expansion
);
2764 smac
= nasm_malloc(sizeof(SMacro
));
2765 smac
->next
= *smhead
;
2768 smac
->name
= nasm_strdup(mname
);
2769 smac
->casesense
= (i
== PP_ASSIGN
);
2771 smac
->expansion
= macro_start
;
2772 smac
->in_progress
= FALSE
;
2773 free_tlist(origline
);
2774 return DIRECTIVE_FOUND
;
2778 * Syntax is `%line nnn[+mmm] [filename]'
2780 tline
= tline
->next
;
2782 if (!tok_type_(tline
, TOK_NUMBER
)) {
2783 error(ERR_NONFATAL
, "`%%line' expects line number");
2784 free_tlist(origline
);
2785 return DIRECTIVE_FOUND
;
2787 k
= readnum(tline
->text
, &j
);
2789 tline
= tline
->next
;
2790 if (tok_is_(tline
, "+")) {
2791 tline
= tline
->next
;
2792 if (!tok_type_(tline
, TOK_NUMBER
)) {
2793 error(ERR_NONFATAL
, "`%%line' expects line increment");
2794 free_tlist(origline
);
2795 return DIRECTIVE_FOUND
;
2797 m
= readnum(tline
->text
, &j
);
2798 tline
= tline
->next
;
2804 nasm_free(src_set_fname(detoken(tline
, FALSE
)));
2806 free_tlist(origline
);
2807 return DIRECTIVE_FOUND
;
2811 "preprocessor directive `%s' not yet implemented",
2815 return DIRECTIVE_FOUND
;
2819 * Ensure that a macro parameter contains a condition code and
2820 * nothing else. Return the condition code index if so, or -1
2823 static int find_cc(Token
* t
)
2829 if (t
->type
!= TOK_ID
)
2833 if (tt
&& (tt
->type
!= TOK_OTHER
|| strcmp(tt
->text
, ",")))
2837 j
= elements(conditions
);
2840 m
= nasm_stricmp(t
->text
, conditions
[k
]);
2856 * Expand MMacro-local things: parameter references (%0, %n, %+n,
2857 * %-n) and MMacro-local identifiers (%%foo).
2859 static Token
*expand_mmac_params(Token
* tline
)
2861 Token
*t
, *tt
, **tail
, *thead
;
2867 if (tline
->type
== TOK_PREPROC_ID
&&
2868 (((tline
->text
[1] == '+' || tline
->text
[1] == '-')
2869 && tline
->text
[2]) || tline
->text
[1] == '%'
2870 || (tline
->text
[1] >= '0' && tline
->text
[1] <= '9'))) {
2872 int type
= 0, cc
; /* type = 0 to placate optimisers */
2878 tline
= tline
->next
;
2881 while (mac
&& !mac
->name
) /* avoid mistaking %reps for macros */
2882 mac
= mac
->next_active
;
2884 error(ERR_NONFATAL
, "`%s': not in a macro call", t
->text
);
2886 switch (t
->text
[1]) {
2888 * We have to make a substitution of one of the
2889 * forms %1, %-1, %+1, %%foo, %0.
2893 snprintf(tmpbuf
, sizeof(tmpbuf
), "%d", mac
->nparam
);
2894 text
= nasm_strdup(tmpbuf
);
2898 snprintf(tmpbuf
, sizeof(tmpbuf
), "..@%lu.",
2900 text
= nasm_strcat(tmpbuf
, t
->text
+ 2);
2903 n
= atoi(t
->text
+ 2) - 1;
2904 if (n
>= mac
->nparam
)
2907 if (mac
->nparam
> 1)
2908 n
= (n
+ mac
->rotate
) % mac
->nparam
;
2909 tt
= mac
->params
[n
];
2914 "macro parameter %d is not a condition code",
2919 if (inverse_ccs
[cc
] == -1) {
2921 "condition code `%s' is not invertible",
2926 nasm_strdup(conditions
[inverse_ccs
[cc
]]);
2930 n
= atoi(t
->text
+ 2) - 1;
2931 if (n
>= mac
->nparam
)
2934 if (mac
->nparam
> 1)
2935 n
= (n
+ mac
->rotate
) % mac
->nparam
;
2936 tt
= mac
->params
[n
];
2941 "macro parameter %d is not a condition code",
2946 text
= nasm_strdup(conditions
[cc
]);
2950 n
= atoi(t
->text
+ 1) - 1;
2951 if (n
>= mac
->nparam
)
2954 if (mac
->nparam
> 1)
2955 n
= (n
+ mac
->rotate
) % mac
->nparam
;
2956 tt
= mac
->params
[n
];
2959 for (i
= 0; i
< mac
->paramlen
[n
]; i
++) {
2960 *tail
= new_Token(NULL
, tt
->type
, tt
->text
, 0);
2961 tail
= &(*tail
)->next
;
2965 text
= NULL
; /* we've done it here */
2981 tline
= tline
->next
;
2988 for (; t
&& (tt
= t
->next
) != NULL
; t
= t
->next
)
2990 case TOK_WHITESPACE
:
2991 if (tt
->type
== TOK_WHITESPACE
) {
2992 t
->next
= delete_Token(tt
);
2996 if (tt
->type
== TOK_ID
|| tt
->type
== TOK_NUMBER
) {
2997 char *tmp
= nasm_strcat(t
->text
, tt
->text
);
3000 t
->next
= delete_Token(tt
);
3004 if (tt
->type
== TOK_NUMBER
) {
3005 char *tmp
= nasm_strcat(t
->text
, tt
->text
);
3008 t
->next
= delete_Token(tt
);
3017 * Expand all single-line macro calls made in the given line.
3018 * Return the expanded version of the line. The original is deemed
3019 * to be destroyed in the process. (In reality we'll just move
3020 * Tokens from input to output a lot of the time, rather than
3021 * actually bothering to destroy and replicate.)
3023 static Token
*expand_smacro(Token
* tline
)
3025 Token
*t
, *tt
, *mstart
, **tail
, *thead
;
3026 SMacro
*head
= NULL
, *m
;
3029 int nparam
, sparam
, brackets
, rescan
;
3030 Token
*org_tline
= tline
;
3035 * Trick: we should avoid changing the start token pointer since it can
3036 * be contained in "next" field of other token. Because of this
3037 * we allocate a copy of first token and work with it; at the end of
3038 * routine we copy it back
3042 new_Token(org_tline
->next
, org_tline
->type
, org_tline
->text
,
3044 tline
->mac
= org_tline
->mac
;
3045 nasm_free(org_tline
->text
);
3046 org_tline
->text
= NULL
;
3053 while (tline
) { /* main token loop */
3054 if ((mname
= tline
->text
)) {
3055 /* if this token is a local macro, look in local context */
3056 if (tline
->type
== TOK_ID
|| tline
->type
== TOK_PREPROC_ID
)
3057 ctx
= get_ctx(mname
, TRUE
);
3061 head
= smacros
[hash(mname
)];
3063 head
= ctx
->localmac
;
3065 * We've hit an identifier. As in is_mmacro below, we first
3066 * check whether the identifier is a single-line macro at
3067 * all, then think about checking for parameters if
3070 for (m
= head
; m
; m
= m
->next
)
3071 if (!mstrcmp(m
->name
, mname
, m
->casesense
))
3077 if (m
->nparam
== 0) {
3079 * Simple case: the macro is parameterless. Discard the
3080 * one token that the macro call took, and push the
3081 * expansion back on the to-do stack.
3083 if (!m
->expansion
) {
3084 if (!strcmp("__FILE__", m
->name
)) {
3086 src_get(&num
, &(tline
->text
));
3087 nasm_quote(&(tline
->text
));
3088 tline
->type
= TOK_STRING
;
3091 if (!strcmp("__LINE__", m
->name
)) {
3092 nasm_free(tline
->text
);
3093 make_tok_num(tline
, src_get_linnum());
3096 tline
= delete_Token(tline
);
3101 * Complicated case: at least one macro with this name
3102 * exists and takes parameters. We must find the
3103 * parameters in the call, count them, find the SMacro
3104 * that corresponds to that form of the macro call, and
3105 * substitute for the parameters when we expand. What a
3108 /*tline = tline->next;
3109 skip_white_(tline); */
3112 while (tok_type_(t
, TOK_SMAC_END
)) {
3113 t
->mac
->in_progress
= FALSE
;
3115 t
= tline
->next
= delete_Token(t
);
3118 } while (tok_type_(tline
, TOK_WHITESPACE
));
3119 if (!tok_is_(tline
, "(")) {
3121 * This macro wasn't called with parameters: ignore
3122 * the call. (Behaviour borrowed from gnu cpp.)
3131 sparam
= PARAM_DELTA
;
3132 params
= nasm_malloc(sparam
* sizeof(Token
*));
3133 params
[0] = tline
->next
;
3134 paramsize
= nasm_malloc(sparam
* sizeof(int));
3136 while (TRUE
) { /* parameter loop */
3138 * For some unusual expansions
3139 * which concatenates function call
3142 while (tok_type_(t
, TOK_SMAC_END
)) {
3143 t
->mac
->in_progress
= FALSE
;
3145 t
= tline
->next
= delete_Token(t
);
3151 "macro call expects terminating `)'");
3154 if (tline
->type
== TOK_WHITESPACE
3156 if (paramsize
[nparam
])
3159 params
[nparam
] = tline
->next
;
3160 continue; /* parameter loop */
3162 if (tline
->type
== TOK_OTHER
3163 && tline
->text
[1] == 0) {
3164 char ch
= tline
->text
[0];
3165 if (ch
== ',' && !paren
&& brackets
<= 0) {
3166 if (++nparam
>= sparam
) {
3167 sparam
+= PARAM_DELTA
;
3168 params
= nasm_realloc(params
,
3173 nasm_realloc(paramsize
,
3177 params
[nparam
] = tline
->next
;
3178 paramsize
[nparam
] = 0;
3180 continue; /* parameter loop */
3183 (brackets
> 0 || (brackets
== 0 &&
3184 !paramsize
[nparam
])))
3186 if (!(brackets
++)) {
3187 params
[nparam
] = tline
->next
;
3188 continue; /* parameter loop */
3191 if (ch
== '}' && brackets
> 0)
3192 if (--brackets
== 0) {
3194 continue; /* parameter loop */
3196 if (ch
== '(' && !brackets
)
3198 if (ch
== ')' && brackets
<= 0)
3204 error(ERR_NONFATAL
, "braces do not "
3205 "enclose all of macro parameter");
3207 paramsize
[nparam
] += white
+ 1;
3209 } /* parameter loop */
3211 while (m
&& (m
->nparam
!= nparam
||
3212 mstrcmp(m
->name
, mname
,
3216 error(ERR_WARNING
| ERR_WARN_MNP
,
3217 "macro `%s' exists, "
3218 "but not taking %d parameters",
3219 mstart
->text
, nparam
);
3222 if (m
&& m
->in_progress
)
3224 if (!m
) { /* in progess or didn't find '(' or wrong nparam */
3226 * Design question: should we handle !tline, which
3227 * indicates missing ')' here, or expand those
3228 * macros anyway, which requires the (t) test a few
3232 nasm_free(paramsize
);
3236 * Expand the macro: we are placed on the last token of the
3237 * call, so that we can easily split the call from the
3238 * following tokens. We also start by pushing an SMAC_END
3239 * token for the cycle removal.
3246 tt
= new_Token(tline
, TOK_SMAC_END
, NULL
, 0);
3248 m
->in_progress
= TRUE
;
3250 for (t
= m
->expansion
; t
; t
= t
->next
) {
3251 if (t
->type
>= TOK_SMAC_PARAM
) {
3252 Token
*pcopy
= tline
, **ptail
= &pcopy
;
3256 ttt
= params
[t
->type
- TOK_SMAC_PARAM
];
3257 for (i
= paramsize
[t
->type
- TOK_SMAC_PARAM
];
3260 new_Token(tline
, ttt
->type
, ttt
->text
,
3267 tt
= new_Token(tline
, t
->type
, t
->text
, 0);
3273 * Having done that, get rid of the macro call, and clean
3274 * up the parameters.
3277 nasm_free(paramsize
);
3279 continue; /* main token loop */
3284 if (tline
->type
== TOK_SMAC_END
) {
3285 tline
->mac
->in_progress
= FALSE
;
3286 tline
= delete_Token(tline
);
3289 tline
= tline
->next
;
3297 * Now scan the entire line and look for successive TOK_IDs that resulted
3298 * after expansion (they can't be produced by tokenise()). The successive
3299 * TOK_IDs should be concatenated.
3300 * Also we look for %+ tokens and concatenate the tokens before and after
3301 * them (without white spaces in between).
3306 while (t
&& t
->type
!= TOK_ID
&& t
->type
!= TOK_PREPROC_ID
)
3310 if (t
->next
->type
== TOK_ID
||
3311 t
->next
->type
== TOK_PREPROC_ID
||
3312 t
->next
->type
== TOK_NUMBER
) {
3313 char *p
= nasm_strcat(t
->text
, t
->next
->text
);
3315 t
->next
= delete_Token(t
->next
);
3318 } else if (t
->next
->type
== TOK_WHITESPACE
&& t
->next
->next
&&
3319 t
->next
->next
->type
== TOK_PREPROC_ID
&&
3320 strcmp(t
->next
->next
->text
, "%+") == 0) {
3321 /* free the next whitespace, the %+ token and next whitespace */
3323 for (i
= 1; i
<= 3; i
++) {
3325 || (i
!= 2 && t
->next
->type
!= TOK_WHITESPACE
))
3327 t
->next
= delete_Token(t
->next
);
3332 /* If we concatenaded something, re-scan the line for macros */
3340 *org_tline
= *thead
;
3341 /* since we just gave text to org_line, don't free it */
3343 delete_Token(thead
);
3345 /* the expression expanded to empty line;
3346 we can't return NULL for some reasons
3347 we just set the line to a single WHITESPACE token. */
3348 memset(org_tline
, 0, sizeof(*org_tline
));
3349 org_tline
->text
= NULL
;
3350 org_tline
->type
= TOK_WHITESPACE
;
3359 * Similar to expand_smacro but used exclusively with macro identifiers
3360 * right before they are fetched in. The reason is that there can be
3361 * identifiers consisting of several subparts. We consider that if there
3362 * are more than one element forming the name, user wants a expansion,
3363 * otherwise it will be left as-is. Example:
3367 * the identifier %$abc will be left as-is so that the handler for %define
3368 * will suck it and define the corresponding value. Other case:
3370 * %define _%$abc cde
3372 * In this case user wants name to be expanded *before* %define starts
3373 * working, so we'll expand %$abc into something (if it has a value;
3374 * otherwise it will be left as-is) then concatenate all successive
3377 static Token
*expand_id(Token
* tline
)
3379 Token
*cur
, *oldnext
= NULL
;
3381 if (!tline
|| !tline
->next
)
3386 (cur
->next
->type
== TOK_ID
||
3387 cur
->next
->type
== TOK_PREPROC_ID
3388 || cur
->next
->type
== TOK_NUMBER
))
3391 /* If identifier consists of just one token, don't expand */
3396 oldnext
= cur
->next
; /* Detach the tail past identifier */
3397 cur
->next
= NULL
; /* so that expand_smacro stops here */
3400 tline
= expand_smacro(tline
);
3403 /* expand_smacro possibly changhed tline; re-scan for EOL */
3405 while (cur
&& cur
->next
)
3408 cur
->next
= oldnext
;
3415 * Determine whether the given line constitutes a multi-line macro
3416 * call, and return the MMacro structure called if so. Doesn't have
3417 * to check for an initial label - that's taken care of in
3418 * expand_mmacro - but must check numbers of parameters. Guaranteed
3419 * to be called with tline->type == TOK_ID, so the putative macro
3420 * name is easy to find.
3422 static MMacro
*is_mmacro(Token
* tline
, Token
*** params_array
)
3428 head
= mmacros
[hash(tline
->text
)];
3431 * Efficiency: first we see if any macro exists with the given
3432 * name. If not, we can return NULL immediately. _Then_ we
3433 * count the parameters, and then we look further along the
3434 * list if necessary to find the proper MMacro.
3436 for (m
= head
; m
; m
= m
->next
)
3437 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
3443 * OK, we have a potential macro. Count and demarcate the
3446 count_mmac_params(tline
->next
, &nparam
, ¶ms
);
3449 * So we know how many parameters we've got. Find the MMacro
3450 * structure that handles this number.
3453 if (m
->nparam_min
<= nparam
3454 && (m
->plus
|| nparam
<= m
->nparam_max
)) {
3456 * This one is right. Just check if cycle removal
3457 * prohibits us using it before we actually celebrate...
3459 if (m
->in_progress
) {
3462 "self-reference in multi-line macro `%s'", m
->name
);
3468 * It's right, and we can use it. Add its default
3469 * parameters to the end of our list if necessary.
3471 if (m
->defaults
&& nparam
< m
->nparam_min
+ m
->ndefs
) {
3473 nasm_realloc(params
,
3474 ((m
->nparam_min
+ m
->ndefs
+
3475 1) * sizeof(*params
)));
3476 while (nparam
< m
->nparam_min
+ m
->ndefs
) {
3477 params
[nparam
] = m
->defaults
[nparam
- m
->nparam_min
];
3482 * If we've gone over the maximum parameter count (and
3483 * we're in Plus mode), ignore parameters beyond
3486 if (m
->plus
&& nparam
> m
->nparam_max
)
3487 nparam
= m
->nparam_max
;
3489 * Then terminate the parameter list, and leave.
3491 if (!params
) { /* need this special case */
3492 params
= nasm_malloc(sizeof(*params
));
3495 params
[nparam
] = NULL
;
3496 *params_array
= params
;
3500 * This one wasn't right: look for the next one with the
3503 for (m
= m
->next
; m
; m
= m
->next
)
3504 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
3509 * After all that, we didn't find one with the right number of
3510 * parameters. Issue a warning, and fail to expand the macro.
3512 error(ERR_WARNING
| ERR_WARN_MNP
,
3513 "macro `%s' exists, but not taking %d parameters",
3514 tline
->text
, nparam
);
3520 * Expand the multi-line macro call made by the given line, if
3521 * there is one to be expanded. If there is, push the expansion on
3522 * istk->expansion and return 1. Otherwise return 0.
3524 static int expand_mmacro(Token
* tline
)
3526 Token
*startline
= tline
;
3527 Token
*label
= NULL
;
3528 int dont_prepend
= 0;
3529 Token
**params
, *t
, *tt
;
3532 int i
, nparam
, *paramlen
;
3536 /* if (!tok_type_(t, TOK_ID)) Lino 02/25/02 */
3537 if (!tok_type_(t
, TOK_ID
) && !tok_type_(t
, TOK_PREPROC_ID
))
3539 m
= is_mmacro(t
, ¶ms
);
3543 * We have an id which isn't a macro call. We'll assume
3544 * it might be a label; we'll also check to see if a
3545 * colon follows it. Then, if there's another id after
3546 * that lot, we'll check it again for macro-hood.
3550 if (tok_type_(t
, TOK_WHITESPACE
))
3551 last
= t
, t
= t
->next
;
3552 if (tok_is_(t
, ":")) {
3554 last
= t
, t
= t
->next
;
3555 if (tok_type_(t
, TOK_WHITESPACE
))
3556 last
= t
, t
= t
->next
;
3558 if (!tok_type_(t
, TOK_ID
) || (m
= is_mmacro(t
, ¶ms
)) == NULL
)
3565 * Fix up the parameters: this involves stripping leading and
3566 * trailing whitespace, then stripping braces if they are
3569 for (nparam
= 0; params
[nparam
]; nparam
++) ;
3570 paramlen
= nparam
? nasm_malloc(nparam
* sizeof(*paramlen
)) : NULL
;
3572 for (i
= 0; params
[i
]; i
++) {
3574 int comma
= (!m
->plus
|| i
< nparam
- 1);
3578 if (tok_is_(t
, "{"))
3579 t
= t
->next
, brace
= TRUE
, comma
= FALSE
;
3583 if (comma
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, ","))
3584 break; /* ... because we have hit a comma */
3585 if (comma
&& t
->type
== TOK_WHITESPACE
3586 && tok_is_(t
->next
, ","))
3587 break; /* ... or a space then a comma */
3588 if (brace
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "}"))
3589 break; /* ... or a brace */
3596 * OK, we have a MMacro structure together with a set of
3597 * parameters. We must now go through the expansion and push
3598 * copies of each Line on to istk->expansion. Substitution of
3599 * parameter tokens and macro-local tokens doesn't get done
3600 * until the single-line macro substitution process; this is
3601 * because delaying them allows us to change the semantics
3602 * later through %rotate.
3604 * First, push an end marker on to istk->expansion, mark this
3605 * macro as in progress, and set up its invocation-specific
3608 ll
= nasm_malloc(sizeof(Line
));
3609 ll
->next
= istk
->expansion
;
3612 istk
->expansion
= ll
;
3614 m
->in_progress
= TRUE
;
3619 m
->paramlen
= paramlen
;
3620 m
->unique
= unique
++;
3623 m
->next_active
= istk
->mstk
;
3626 for (l
= m
->expansion
; l
; l
= l
->next
) {
3629 ll
= nasm_malloc(sizeof(Line
));
3630 ll
->finishes
= NULL
;
3631 ll
->next
= istk
->expansion
;
3632 istk
->expansion
= ll
;
3635 for (t
= l
->first
; t
; t
= t
->next
) {
3637 if (t
->type
== TOK_PREPROC_ID
&&
3638 t
->text
[1] == '0' && t
->text
[2] == '0') {
3644 tt
= *tail
= new_Token(NULL
, x
->type
, x
->text
, 0);
3651 * If we had a label, push it on as the first line of
3652 * the macro expansion.
3655 if (dont_prepend
< 0)
3656 free_tlist(startline
);
3658 ll
= nasm_malloc(sizeof(Line
));
3659 ll
->finishes
= NULL
;
3660 ll
->next
= istk
->expansion
;
3661 istk
->expansion
= ll
;
3662 ll
->first
= startline
;
3663 if (!dont_prepend
) {
3665 label
= label
->next
;
3666 label
->next
= tt
= new_Token(NULL
, TOK_OTHER
, ":", 0);
3671 list
->uplevel(m
->nolist
? LIST_MACRO_NOLIST
: LIST_MACRO
);
3677 * Since preprocessor always operate only on the line that didn't
3678 * arrived yet, we should always use ERR_OFFBY1. Also since user
3679 * won't want to see same error twice (preprocessing is done once
3680 * per pass) we will want to show errors only during pass one.
3682 static void error(int severity
, const char *fmt
, ...)
3687 /* If we're in a dead branch of IF or something like it, ignore the error */
3688 if (istk
&& istk
->conds
&& !emitting(istk
->conds
->state
))
3692 vsnprintf(buff
, sizeof(buff
), fmt
, arg
);
3695 if (istk
&& istk
->mstk
&& istk
->mstk
->name
)
3696 _error(severity
| ERR_PASS1
, "(%s:%d) %s", istk
->mstk
->name
,
3697 istk
->mstk
->lineno
, buff
);
3699 _error(severity
| ERR_PASS1
, "%s", buff
);
3703 pp_reset(char *file
, int apass
, efunc errfunc
, evalfunc eval
,
3710 istk
= nasm_malloc(sizeof(Include
));
3713 istk
->expansion
= NULL
;
3715 istk
->fp
= fopen(file
, "r");
3717 src_set_fname(nasm_strdup(file
));
3721 error(ERR_FATAL
| ERR_NOFILE
, "unable to open input file `%s'",
3724 for (h
= 0; h
< NHASH
; h
++) {
3729 if (tasm_compatible_mode
) {
3732 stdmacpos
= &stdmac
[TASM_MACRO_COUNT
];
3734 any_extrastdmac
= (extrastdmac
!= NULL
);
3740 static char *pp_getline(void)
3747 * Fetch a tokenised line, either from the macro-expansion
3748 * buffer or from the input file.
3751 while (istk
->expansion
&& istk
->expansion
->finishes
) {
3752 Line
*l
= istk
->expansion
;
3753 if (!l
->finishes
->name
&& l
->finishes
->in_progress
> 1) {
3757 * This is a macro-end marker for a macro with no
3758 * name, which means it's not really a macro at all
3759 * but a %rep block, and the `in_progress' field is
3760 * more than 1, meaning that we still need to
3761 * repeat. (1 means the natural last repetition; 0
3762 * means termination by %exitrep.) We have
3763 * therefore expanded up to the %endrep, and must
3764 * push the whole block on to the expansion buffer
3765 * again. We don't bother to remove the macro-end
3766 * marker: we'd only have to generate another one
3769 l
->finishes
->in_progress
--;
3770 for (l
= l
->finishes
->expansion
; l
; l
= l
->next
) {
3771 Token
*t
, *tt
, **tail
;
3773 ll
= nasm_malloc(sizeof(Line
));
3774 ll
->next
= istk
->expansion
;
3775 ll
->finishes
= NULL
;
3779 for (t
= l
->first
; t
; t
= t
->next
) {
3780 if (t
->text
|| t
->type
== TOK_WHITESPACE
) {
3782 new_Token(NULL
, t
->type
, t
->text
, 0);
3787 istk
->expansion
= ll
;
3791 * Check whether a `%rep' was started and not ended
3792 * within this macro expansion. This can happen and
3793 * should be detected. It's a fatal error because
3794 * I'm too confused to work out how to recover
3800 "defining with name in expansion");
3801 else if (istk
->mstk
->name
)
3803 "`%%rep' without `%%endrep' within"
3804 " expansion of macro `%s'",
3809 * FIXME: investigate the relationship at this point between
3810 * istk->mstk and l->finishes
3813 MMacro
*m
= istk
->mstk
;
3814 istk
->mstk
= m
->next_active
;
3817 * This was a real macro call, not a %rep, and
3818 * therefore the parameter information needs to
3821 nasm_free(m
->params
);
3822 free_tlist(m
->iline
);
3823 nasm_free(m
->paramlen
);
3824 l
->finishes
->in_progress
= FALSE
;
3828 istk
->expansion
= l
->next
;
3830 list
->downlevel(LIST_MACRO
);
3833 while (1) { /* until we get a line we can use */
3835 if (istk
->expansion
) { /* from a macro expansion */
3837 Line
*l
= istk
->expansion
;
3839 istk
->mstk
->lineno
++;
3841 istk
->expansion
= l
->next
;
3843 p
= detoken(tline
, FALSE
);
3844 list
->line(LIST_MACRO
, p
);
3849 if (line
) { /* from the current input file */
3850 line
= prepreproc(line
);
3851 tline
= tokenise(line
);
3856 * The current file has ended; work down the istk
3863 "expected `%%endif' before end of file");
3864 /* only set line and file name if there's a next node */
3866 src_set_linnum(i
->lineno
);
3867 nasm_free(src_set_fname(i
->fname
));
3870 list
->downlevel(LIST_INCLUDE
);
3878 * We must expand MMacro parameters and MMacro-local labels
3879 * _before_ we plunge into directive processing, to cope
3880 * with things like `%define something %1' such as STRUC
3881 * uses. Unless we're _defining_ a MMacro, in which case
3882 * those tokens should be left alone to go into the
3883 * definition; and unless we're in a non-emitting
3884 * condition, in which case we don't want to meddle with
3887 if (!defining
&& !(istk
->conds
&& !emitting(istk
->conds
->state
)))
3888 tline
= expand_mmac_params(tline
);
3891 * Check the line to see if it's a preprocessor directive.
3893 if (do_directive(tline
) == DIRECTIVE_FOUND
) {
3895 } else if (defining
) {
3897 * We're defining a multi-line macro. We emit nothing
3899 * shove the tokenised line on to the macro definition.
3901 Line
*l
= nasm_malloc(sizeof(Line
));
3902 l
->next
= defining
->expansion
;
3904 l
->finishes
= FALSE
;
3905 defining
->expansion
= l
;
3907 } else if (istk
->conds
&& !emitting(istk
->conds
->state
)) {
3909 * We're in a non-emitting branch of a condition block.
3910 * Emit nothing at all, not even a blank line: when we
3911 * emerge from the condition we'll give a line-number
3912 * directive so we keep our place correctly.
3916 } else if (istk
->mstk
&& !istk
->mstk
->in_progress
) {
3918 * We're in a %rep block which has been terminated, so
3919 * we're walking through to the %endrep without
3920 * emitting anything. Emit nothing at all, not even a
3921 * blank line: when we emerge from the %rep block we'll
3922 * give a line-number directive so we keep our place
3928 tline
= expand_smacro(tline
);
3929 if (!expand_mmacro(tline
)) {
3931 * De-tokenise the line again, and emit it.
3933 line
= detoken(tline
, TRUE
);
3937 continue; /* expand_mmacro calls free_tlist */
3945 static void pp_cleanup(int pass
)
3950 error(ERR_NONFATAL
, "end of file while still defining macro `%s'",
3952 free_mmacro(defining
);
3956 for (h
= 0; h
< NHASH
; h
++) {
3957 while (mmacros
[h
]) {
3958 MMacro
*m
= mmacros
[h
];
3959 mmacros
[h
] = mmacros
[h
]->next
;
3962 while (smacros
[h
]) {
3963 SMacro
*s
= smacros
[h
];
3964 smacros
[h
] = smacros
[h
]->next
;
3966 free_tlist(s
->expansion
);
3974 nasm_free(i
->fname
);
3985 void pp_include_path(char *path
)
3988 /* by alexfru: order of path inclusion fixed (was reverse order) */
3989 i
= nasm_malloc(sizeof(IncPath
));
3990 i
->path
= nasm_strdup(path
);
3993 if (ipath
!= NULL
) {
3995 while (j
->next
!= NULL
)
4006 * This function is used to "export" the include paths, e.g.
4007 * the paths specified in the '-I' command switch.
4008 * The need for such exporting is due to the 'incbin' directive,
4009 * which includes raw binary files (unlike '%include', which
4010 * includes text source files). It would be real nice to be
4011 * able to specify paths to search for incbin'ned files also.
4012 * So, this is a simple workaround.
4014 * The function use is simple:
4016 * The 1st call (with NULL argument) returns a pointer to the 1st path
4017 * (char** type) or NULL if none include paths available.
4019 * All subsequent calls take as argument the value returned by this
4020 * function last. The return value is either the next path
4021 * (char** type) or NULL if the end of the paths list is reached.
4023 * It is maybe not the best way to do things, but I didn't want
4024 * to export too much, just one or two functions and no types or
4025 * variables exported.
4027 * Can't say I like the current situation with e.g. this path list either,
4028 * it seems to be never deallocated after creation...
4030 char **pp_get_include_path_ptr(char **pPrevPath
)
4032 /* This macro returns offset of a member of a structure */
4033 #define GetMemberOffset(StructType,MemberName)\
4034 ((size_t)&((StructType*)0)->MemberName)
4037 if (pPrevPath
== NULL
) {
4039 return &ipath
->path
;
4043 i
= (IncPath
*) ((char *)pPrevPath
- GetMemberOffset(IncPath
, path
));
4049 #undef GetMemberOffset
4052 void pp_pre_include(char *fname
)
4054 Token
*inc
, *space
, *name
;
4057 name
= new_Token(NULL
, TOK_INTERNAL_STRING
, fname
, 0);
4058 space
= new_Token(name
, TOK_WHITESPACE
, NULL
, 0);
4059 inc
= new_Token(space
, TOK_PREPROC_ID
, "%include", 0);
4061 l
= nasm_malloc(sizeof(Line
));
4064 l
->finishes
= FALSE
;
4068 void pp_pre_define(char *definition
)
4074 equals
= strchr(definition
, '=');
4075 space
= new_Token(NULL
, TOK_WHITESPACE
, NULL
, 0);
4076 def
= new_Token(space
, TOK_PREPROC_ID
, "%define", 0);
4079 space
->next
= tokenise(definition
);
4083 l
= nasm_malloc(sizeof(Line
));
4086 l
->finishes
= FALSE
;
4090 void pp_pre_undefine(char *definition
)
4095 space
= new_Token(NULL
, TOK_WHITESPACE
, NULL
, 0);
4096 def
= new_Token(space
, TOK_PREPROC_ID
, "%undef", 0);
4097 space
->next
= tokenise(definition
);
4099 l
= nasm_malloc(sizeof(Line
));
4102 l
->finishes
= FALSE
;
4106 void pp_extra_stdmac(const char **macros
)
4108 extrastdmac
= macros
;
4111 static void make_tok_num(Token
* tok
, long val
)
4114 snprintf(numbuf
, sizeof(numbuf
), "%ld", val
);
4115 tok
->text
= nasm_strdup(numbuf
);
4116 tok
->type
= TOK_NUMBER
;