1 /* preproc.c macro preprocessor for the Netwide Assembler
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
5 * redistributable under the licence given in the file "Licence"
6 * distributed in the NASM archive.
8 * initial version 18/iii/97 by Simon Tatham
11 /* Typical flow of text through preproc
13 * pp_getline gets tokenised lines, either
15 * from a macro expansion
19 * read_line gets raw text from stdmacpos, or predef, or current input file
20 * tokenise converts to tokens
23 * expand_mmac_params is used to expand %1 etc., unless a macro is being
24 * defined or a false conditional is being processed
25 * (%0, %1, %+1, %-1, %%foo
27 * do_directive checks for directives
29 * expand_smacro is used to expand single line macros
31 * expand_mmacro is used to expand multi-line macros
33 * detoken is used to convert the line back to text
47 typedef struct SMacro SMacro
;
48 typedef struct MMacro MMacro
;
49 typedef struct Context Context
;
50 typedef struct Token Token
;
51 typedef struct Blocks Blocks
;
52 typedef struct Line Line
;
53 typedef struct Include Include
;
54 typedef struct Cond Cond
;
55 typedef struct IncPath IncPath
;
58 * 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.
92 int nparam_min
, nparam_max
;
93 int plus
; /* is the last parameter greedy? */
94 int nolist
; /* is this macro listing-inhibited? */
96 Token
*dlist
; /* All defaults as one list */
97 Token
**defaults
; /* Parameter default pointers */
98 int ndefs
; /* number of default parameters */
102 MMacro
*rep_nest
; /* used for nesting %rep */
103 Token
**params
; /* actual parameters */
104 Token
*iline
; /* invocation line */
105 int nparam
, rotate
, *paramlen
;
106 unsigned long unique
;
107 int lineno
; /* Current line number on expansion */
111 * The context stack is composed of a linked list of these.
118 unsigned long number
;
122 * This is the internal form which we break input lines up into.
123 * Typically stored in linked lists.
125 * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
126 * necessarily used as-is, but is intended to denote the number of
127 * the substituted parameter. So in the definition
129 * %define a(x,y) ( (x) & ~(y) )
131 * the token representing `x' will have its type changed to
132 * TOK_SMAC_PARAM, but the one representing `y' will be
135 * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
136 * which doesn't need quotes around it. Used in the pre-include
137 * mechanism as an alternative to trying to find a sensible type of
138 * quote to use on the filename we were passed.
144 SMacro
*mac
; /* associated macro for TOK_SMAC_END */
149 TOK_WHITESPACE
= 1, TOK_COMMENT
, TOK_ID
, TOK_PREPROC_ID
, TOK_STRING
,
150 TOK_NUMBER
, TOK_SMAC_END
, TOK_OTHER
, TOK_SMAC_PARAM
,
155 * Multi-line macro definitions are stored as a linked list of
156 * these, which is essentially a container to allow several linked
159 * Note that in this module, linked lists are treated as stacks
160 * wherever possible. For this reason, Lines are _pushed_ on to the
161 * `expansion' field in MMacro structures, so that the linked list,
162 * if walked, would give the macro lines in reverse order; this
163 * means that we can walk the list when expanding a macro, and thus
164 * push the lines on to the `expansion' field in _istk_ in reverse
165 * order (so that when popped back off they are in the right
166 * order). It may seem cockeyed, and it relies on my design having
167 * an even number of steps in, but it works...
169 * Some of these structures, rather than being actual lines, are
170 * markers delimiting the end of the expansion of a given macro.
171 * This is for use in the cycle-tracking and %rep-handling code.
172 * Such structures have `finishes' non-NULL, and `first' NULL. All
173 * others have `finishes' NULL, but `first' may still be NULL if
184 * To handle an arbitrary level of file inclusion, we maintain a
185 * stack (ie linked list) of these things.
195 MMacro
*mstk
; /* stack of active macros/reps */
199 * Include search path. This is simply a list of strings which get
200 * prepended, in turn, to the name of an include file, in an
201 * attempt to find the file if it's not in the current directory.
210 * Conditional assembly: we maintain a separate stack of these for
211 * each level of file inclusion. (The only reason we keep the
212 * stacks separate is to ensure that a stray `%endif' in a file
213 * included from within the true branch of a `%if' won't terminate
214 * it and cause confusion: instead, rightly, it'll cause an error.)
224 * These states are for use just after %if or %elif: IF_TRUE
225 * means the condition has evaluated to truth so we are
226 * currently emitting, whereas IF_FALSE means we are not
227 * currently emitting but will start doing so if a %else comes
228 * up. In these states, all directives are admissible: %elif,
229 * %else and %endif. (And of course %if.)
231 COND_IF_TRUE
, COND_IF_FALSE
,
233 * These states come up after a %else: ELSE_TRUE means we're
234 * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
235 * any %elif or %else will cause an error.
237 COND_ELSE_TRUE
, COND_ELSE_FALSE
,
239 * This state means that we're not emitting now, and also that
240 * nothing until %endif will be emitted at all. It's for use in
241 * two circumstances: (i) when we've had our moment of emission
242 * and have now started seeing %elifs, and (ii) when the
243 * condition construct in question is contained within a
244 * non-emitting branch of a larger condition construct.
248 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
251 * Condition codes. Note that we use c_ prefix not C_ because C_ is
252 * used in nasm.h for the "real" condition codes. At _this_ level,
253 * we treat CXZ and ECXZ as condition codes, albeit non-invertible
254 * ones, so we need a different enum...
256 static char *conditions
[] = {
257 "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
258 "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
259 "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
263 c_A
, c_AE
, c_B
, c_BE
, c_C
, c_CXZ
, c_E
, c_ECXZ
, c_G
, c_GE
, c_L
, c_LE
,
264 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, c_NE
, c_NG
, c_NGE
, c_NL
, c_NLE
, c_NO
,
265 c_NP
, c_NS
, c_NZ
, c_O
, c_P
, c_PE
, c_PO
, c_S
, c_Z
267 static int inverse_ccs
[] = {
268 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, -1, c_NE
, -1, c_NG
, c_NGE
, c_NL
, c_NLE
,
269 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
,
270 c_Z
, c_NO
, c_NP
, c_PO
, c_PE
, c_NS
, c_NZ
276 static char *directives
[] = {
278 "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
279 "%elifid", "%elifidn", "%elifidni", "%elifnctx", "%elifndef",
280 "%elifnid", "%elifnidn", "%elifnidni", "%elifnnum", "%elifnstr",
281 "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
282 "%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
283 "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifnctx",
284 "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnnum",
285 "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
286 "%ixdefine", "%line",
288 "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
290 "%strlen", "%substr", "%undef", "%xdefine"
295 PP_ASSIGN
, PP_CLEAR
, PP_DEFINE
, PP_ELIF
, PP_ELIFCTX
, PP_ELIFDEF
,
296 PP_ELIFID
, PP_ELIFIDN
, PP_ELIFIDNI
, PP_ELIFNCTX
, PP_ELIFNDEF
,
297 PP_ELIFNID
, PP_ELIFNIDN
, PP_ELIFNIDNI
, PP_ELIFNNUM
, PP_ELIFNSTR
,
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_IFNCTX
,
301 PP_IFNDEF
, PP_IFNID
, PP_IFNIDN
, PP_IFNIDNI
, PP_IFNNUM
,
302 PP_IFNSTR
, PP_IFNUM
, PP_IFSTR
, PP_IMACRO
, PP_INCLUDE
,
303 PP_IXDEFINE
, PP_LINE
,
305 PP_MACRO
, PP_POP
, PP_PUSH
, PP_REP
, PP_REPL
, PP_ROTATE
,
307 PP_STRLEN
, PP_SUBSTR
, PP_UNDEF
, PP_XDEFINE
311 /* For TASM compatibility we need to be able to recognise TASM compatible
312 * conditional compilation directives. Using the NASM pre-processor does
313 * not work, so we look for them specifically from the following list and
314 * then jam in the equivalent NASM directive into the input stream.
318 # define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
323 TM_ARG
, TM_ELIF
, TM_ELSE
, TM_ENDIF
, TM_IF
, TM_IFDEF
, TM_IFDIFI
,
324 TM_IFNDEF
, TM_INCLUDE
, TM_LOCAL
327 static char *tasm_directives
[] = {
328 "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
329 "ifndef", "include", "local"
332 static int StackSize
= 4;
333 static char *StackPointer
= "ebp";
334 static int ArgOffset
= 8;
335 static int LocalOffset
= 4;
338 static Context
*cstk
;
339 static Include
*istk
;
340 static IncPath
*ipath
= NULL
;
342 static efunc __error
; /* Pointer to client-provided error reporting function */
343 static evalfunc evaluate
;
345 static int pass
; /* HACK: pass 0 = generate dependencies only */
347 static unsigned long unique
; /* unique identifier numbers */
349 static Line
*predef
= NULL
;
351 static ListGen
*list
;
354 * The number of hash values we use for the macro lookup tables.
355 * FIXME: We should *really* be able to configure this at run time,
356 * or even have the hash table automatically expanding when necessary.
361 * The current set of multi-line macros we have defined.
363 static MMacro
*mmacros
[NHASH
];
366 * The current set of single-line macros we have defined.
368 static SMacro
*smacros
[NHASH
];
371 * The multi-line macro we are currently defining, or the %rep
372 * block we are currently reading, if any.
374 static MMacro
*defining
;
377 * The number of macro parameters to allocate space for at a time.
379 #define PARAM_DELTA 16
382 * The standard macro set: defined as `static char *stdmac[]'. Also
383 * gives our position in the macro set, when we're processing it.
386 static char **stdmacpos
;
389 * The extra standard macros that come from the object format, if
392 static char **extrastdmac
= NULL
;
396 * Tokens are allocated in blocks to improve speed
398 #define TOKEN_BLOCKSIZE 4096
399 static Token
*freeTokens
= NULL
;
405 static Blocks blocks
= { NULL
, NULL
};
408 * Forward declarations.
410 static Token
*expand_mmac_params(Token
* tline
);
411 static Token
*expand_smacro(Token
* tline
);
412 static Token
*expand_id(Token
* tline
);
413 static Context
*get_ctx(char *name
, int all_contexts
);
414 static void make_tok_num(Token
* tok
, long val
);
415 static void error(int severity
, char *fmt
, ...);
416 static void *new_Block(size_t size
);
417 static void delete_Blocks(void);
418 static Token
*new_Token(Token
* next
, int type
, char *text
, int txtlen
);
419 static Token
*delete_Token(Token
* t
);
422 * Macros for safe checking of token pointers, avoid *(NULL)
424 #define tok_type_(x,t) ((x) && (x)->type == (t))
425 #define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
426 #define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
427 #define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
429 /* Handle TASM specific directives, which do not contain a % in
430 * front of them. We do it here because I could not find any other
431 * place to do it for the moment, and it is a hack (ideally it would
432 * be nice to be able to use the NASM pre-processor to do it).
435 check_tasm_directive(char *line
)
438 char *p
= line
, *oldline
, oldchar
;
440 /* Skip whitespace */
441 while (isspace(*p
) && *p
!= 0)
444 /* Binary search for the directive name */
446 j
= sizeof(tasm_directives
) / sizeof(*tasm_directives
);
448 while (!isspace(p
[len
]) && p
[len
] != 0)
457 m
= nasm_stricmp(p
, tasm_directives
[k
]);
460 /* We have found a directive, so jam a % in front of it
461 * so that NASM will then recognise it as one if it's own.
466 line
= nasm_malloc(len
+ 2);
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");
479 memcpy(line
+ 1, p
, len
+ 1);
497 * The pre-preprocessing stage... This function translates line
498 * number indications as they emerge from GNU cpp (`# lineno "file"
499 * flags') into NASM preprocessor line number indications (`%line
503 prepreproc(char *line
)
506 char *fname
, *oldline
;
508 if (line
[0] == '#' && line
[1] == ' ')
512 lineno
= atoi(fname
);
513 fname
+= strspn(fname
, "0123456789 ");
516 fnlen
= strcspn(fname
, "\"");
517 line
= nasm_malloc(20 + fnlen
);
518 sprintf(line
, "%%line %d %.*s", lineno
, fnlen
, fname
);
521 if (tasm_compatible_mode
)
522 return check_tasm_directive(line
);
527 * The hash function for macro lookups. Note that due to some
528 * macros having case-insensitive names, the hash function must be
529 * invariant under case changes. We implement this by applying a
530 * perfectly normal hash function to the uppercase of the string.
538 * Powers of three, mod 31.
540 static const int multipliers
[] = {
541 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
542 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
548 h
+= multipliers
[i
] * (unsigned char) (toupper(*s
));
550 if (++i
>= sizeof(multipliers
) / sizeof(*multipliers
))
558 * Free a linked list of tokens.
561 free_tlist(Token
* list
)
565 list
= delete_Token(list
);
570 * Free a linked list of lines.
573 free_llist(Line
* list
)
580 free_tlist(l
->first
);
589 free_mmacro(MMacro
* m
)
592 free_tlist(m
->dlist
);
593 nasm_free(m
->defaults
);
594 free_llist(m
->expansion
);
599 * Pop the context stack.
614 free_tlist(s
->expansion
);
621 #define BUF_DELTA 512
623 * Read a line from the top file in istk, handling multiple CR/LFs
624 * at the end of the line read, and handling spurious ^Zs. Will
625 * return lines from the standard macro set if this has not already
631 char *buffer
, *p
, *q
;
638 char *ret
= nasm_strdup(*stdmacpos
++);
639 if (!*stdmacpos
&& any_extrastdmac
)
641 stdmacpos
= extrastdmac
;
642 any_extrastdmac
= FALSE
;
646 * Nasty hack: here we push the contents of `predef' on
647 * to the top-level expansion stack, since this is the
648 * most convenient way to implement the pre-include and
649 * pre-define features.
654 Token
*head
, **tail
, *t
;
656 for (pd
= predef
; pd
; pd
= pd
->next
)
660 for (t
= pd
->first
; t
; t
= t
->next
)
662 *tail
= new_Token(NULL
, t
->type
, t
->text
, 0);
663 tail
= &(*tail
)->next
;
665 l
= nasm_malloc(sizeof(Line
));
666 l
->next
= istk
->expansion
;
681 buffer
= nasm_malloc(BUF_DELTA
);
685 q
= fgets(p
, bufsize
- (p
- buffer
), istk
->fp
);
689 if (p
> buffer
&& p
[-1] == '\n')
693 if (p
- buffer
> bufsize
- 10)
695 long offset
= p
- buffer
;
696 bufsize
+= BUF_DELTA
;
697 buffer
= nasm_realloc(buffer
, bufsize
);
698 p
= buffer
+ offset
; /* prevent stale-pointer problems */
702 if (!q
&& p
== buffer
)
708 src_set_linnum(src_get_linnum() + istk
->lineinc
);
711 * Play safe: remove CRs as well as LFs, if any of either are
712 * present at the end of the line.
714 while (--p
>= buffer
&& (*p
== '\n' || *p
== '\r'))
718 * Handle spurious ^Z, which may be inserted into source files
719 * by some file transfer utilities.
721 buffer
[strcspn(buffer
, "\032")] = '\0';
723 list
->line(LIST_READ
, buffer
);
729 * Tokenise a line of text. This is a very simple process since we
730 * don't need to parse the value out of e.g. numeric tokens: we
731 * simply split one string into many.
739 Token
*t
, **tail
= &list
;
748 ((*p
== '-' || *p
== '+') && isdigit(p
[1])) ||
749 ((*p
== '+') && (isspace(p
[1]) || !p
[1])))
756 type
= TOK_PREPROC_ID
;
761 while (*p
&& *p
!= '}')
769 type
= TOK_PREPROC_ID
;
771 else if (isidchar(*p
) ||
772 ((*p
== '!' || *p
== '%' || *p
== '$') &&
779 while (isidchar(*p
));
780 type
= TOK_PREPROC_ID
;
789 else if (isidstart(*p
) || (*p
== '$' && isidstart(p
[1])))
793 while (*p
&& isidchar(*p
))
796 else if (*p
== '\'' || *p
== '"')
804 while (*p
&& *p
!= c
)
812 error(ERR_WARNING
, "unterminated string");
815 else if (isnumstart(*p
))
822 while (*p
&& isnumchar(*p
))
825 else if (isspace(*p
))
827 type
= TOK_WHITESPACE
;
829 while (*p
&& isspace(*p
))
832 * Whitespace just before end-of-line is discarded by
833 * pretending it's a comment; whitespace just before a
834 * comment gets lumped into the comment.
836 if (!*p
|| *p
== ';')
852 * Anything else is an operator of some kind. We check
853 * for all the double-character operators (>>, <<, //,
854 * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
855 * else is a single-character operator.
858 if ((p
[0] == '>' && p
[1] == '>') ||
859 (p
[0] == '<' && p
[1] == '<') ||
860 (p
[0] == '/' && p
[1] == '/') ||
861 (p
[0] == '<' && p
[1] == '=') ||
862 (p
[0] == '>' && p
[1] == '=') ||
863 (p
[0] == '=' && p
[1] == '=') ||
864 (p
[0] == '!' && p
[1] == '=') ||
865 (p
[0] == '<' && p
[1] == '>') ||
866 (p
[0] == '&' && p
[1] == '&') ||
867 (p
[0] == '|' && p
[1] == '|') ||
868 (p
[0] == '^' && p
[1] == '^'))
874 if (type
!= TOK_COMMENT
)
876 *tail
= t
= new_Token(NULL
, type
, line
, p
- line
);
885 * this function allocates a new managed block of memory and
886 * returns a pointer to the block. The managed blocks are
887 * deleted only all at once by the delete_Blocks function.
890 new_Block(size_t size
)
894 /* first, get to the end of the linked list */
897 /* now allocate the requested chunk */
898 b
->chunk
= nasm_malloc(size
);
900 /* now allocate a new block for the next request */
901 b
->next
= nasm_malloc(sizeof(Blocks
));
902 /* and initialize the contents of the new block */
903 b
->next
->next
= NULL
;
904 b
->next
->chunk
= NULL
;
909 * this function deletes all managed blocks of memory
914 Blocks
*a
,*b
= &blocks
;
917 * keep in mind that the first block, pointed to by blocks
918 * is a static and not dynamically allocated, so we don't
933 * this function creates a new Token and passes a pointer to it
934 * back to the caller. It sets the type and text elements, and
935 * also the mac and next elements to NULL.
938 new_Token(Token
* next
, int type
, char *text
, int txtlen
)
943 if (freeTokens
== NULL
)
945 freeTokens
= (Token
*)new_Block(TOKEN_BLOCKSIZE
* sizeof(Token
));
946 for (i
= 0; i
< TOKEN_BLOCKSIZE
- 1; i
++)
947 freeTokens
[i
].next
= &freeTokens
[i
+ 1];
948 freeTokens
[i
].next
= NULL
;
951 freeTokens
= t
->next
;
955 if (type
== TOK_WHITESPACE
|| text
== NULL
)
962 txtlen
= strlen(text
);
963 t
->text
= nasm_malloc(1 + txtlen
);
964 strncpy(t
->text
, text
, txtlen
);
965 t
->text
[txtlen
] = '\0';
971 delete_Token(Token
* t
)
973 Token
*next
= t
->next
;
975 t
->next
= freeTokens
;
981 * Convert a line of tokens back into text.
982 * If expand_locals is not zero, identifiers of the form "%$*xxx"
983 * will be transformed into ..@ctxnum.xxx
986 detoken(Token
* tlist
, int expand_locals
)
993 for (t
= tlist
; t
; t
= t
->next
)
995 if (t
->type
== TOK_PREPROC_ID
&& t
->text
[1] == '!')
997 char *p
= getenv(t
->text
+ 2);
1000 t
->text
= nasm_strdup(p
);
1004 /* Expand local macros here and not during preprocessing */
1005 if (expand_locals
&&
1006 t
->type
== TOK_PREPROC_ID
&& t
->text
&&
1007 t
->text
[0] == '%' && t
->text
[1] == '$')
1009 Context
*ctx
= get_ctx(t
->text
, FALSE
);
1013 char *p
, *q
= t
->text
+ 2;
1015 q
+= strspn(q
, "$");
1016 sprintf(buffer
, "..@%lu.", ctx
->number
);
1017 p
= nasm_strcat(buffer
, q
);
1022 if (t
->type
== TOK_WHITESPACE
)
1028 len
+= strlen(t
->text
);
1031 p
= line
= nasm_malloc(len
+ 1);
1032 for (t
= tlist
; t
; t
= t
->next
)
1034 if (t
->type
== TOK_WHITESPACE
)
1051 * A scanner, suitable for use by the expression evaluator, which
1052 * operates on a line of Tokens. Expects a pointer to a pointer to
1053 * the first token in the line to be passed in as its private_data
1057 ppscan(void *private_data
, struct tokenval
*tokval
)
1059 Token
**tlineptr
= private_data
;
1065 *tlineptr
= tline
? tline
->next
: NULL
;
1067 while (tline
&& (tline
->type
== TOK_WHITESPACE
||
1068 tline
->type
== TOK_COMMENT
));
1071 return tokval
->t_type
= TOKEN_EOS
;
1073 if (tline
->text
[0] == '$' && !tline
->text
[1])
1074 return tokval
->t_type
= TOKEN_HERE
;
1075 if (tline
->text
[0] == '$' && tline
->text
[1] == '$' && !tline
->text
[1])
1076 return tokval
->t_type
= TOKEN_BASE
;
1078 if (tline
->type
== TOK_ID
)
1080 tokval
->t_charptr
= tline
->text
;
1081 if (tline
->text
[0] == '$')
1083 tokval
->t_charptr
++;
1084 return tokval
->t_type
= TOKEN_ID
;
1088 * This is the only special case we actually need to worry
1089 * about in this restricted context.
1091 if (!nasm_stricmp(tline
->text
, "seg"))
1092 return tokval
->t_type
= TOKEN_SEG
;
1094 return tokval
->t_type
= TOKEN_ID
;
1097 if (tline
->type
== TOK_NUMBER
)
1101 tokval
->t_integer
= readnum(tline
->text
, &rn_error
);
1103 return tokval
->t_type
= TOKEN_ERRNUM
;
1104 tokval
->t_charptr
= NULL
;
1105 return tokval
->t_type
= TOKEN_NUM
;
1108 if (tline
->type
== TOK_STRING
)
1118 if (l
== 0 || r
[l
- 1] != q
)
1119 return tokval
->t_type
= TOKEN_ERRNUM
;
1120 tokval
->t_integer
= readstrnum(r
, l
- 1, &rn_warn
);
1122 error(ERR_WARNING
| ERR_PASS1
, "character constant too long");
1123 tokval
->t_charptr
= NULL
;
1124 return tokval
->t_type
= TOKEN_NUM
;
1127 if (tline
->type
== TOK_OTHER
)
1129 if (!strcmp(tline
->text
, "<<"))
1130 return tokval
->t_type
= TOKEN_SHL
;
1131 if (!strcmp(tline
->text
, ">>"))
1132 return tokval
->t_type
= TOKEN_SHR
;
1133 if (!strcmp(tline
->text
, "//"))
1134 return tokval
->t_type
= TOKEN_SDIV
;
1135 if (!strcmp(tline
->text
, "%%"))
1136 return tokval
->t_type
= TOKEN_SMOD
;
1137 if (!strcmp(tline
->text
, "=="))
1138 return tokval
->t_type
= TOKEN_EQ
;
1139 if (!strcmp(tline
->text
, "<>"))
1140 return tokval
->t_type
= TOKEN_NE
;
1141 if (!strcmp(tline
->text
, "!="))
1142 return tokval
->t_type
= TOKEN_NE
;
1143 if (!strcmp(tline
->text
, "<="))
1144 return tokval
->t_type
= TOKEN_LE
;
1145 if (!strcmp(tline
->text
, ">="))
1146 return tokval
->t_type
= TOKEN_GE
;
1147 if (!strcmp(tline
->text
, "&&"))
1148 return tokval
->t_type
= TOKEN_DBL_AND
;
1149 if (!strcmp(tline
->text
, "^^"))
1150 return tokval
->t_type
= TOKEN_DBL_XOR
;
1151 if (!strcmp(tline
->text
, "||"))
1152 return tokval
->t_type
= TOKEN_DBL_OR
;
1156 * We have no other options: just return the first character of
1159 return tokval
->t_type
= tline
->text
[0];
1163 * Compare a string to the name of an existing macro; this is a
1164 * simple wrapper which calls either strcmp or nasm_stricmp
1165 * depending on the value of the `casesense' parameter.
1168 mstrcmp(char *p
, char *q
, int casesense
)
1170 return casesense
? strcmp(p
, q
) : nasm_stricmp(p
, q
);
1174 * Return the Context structure associated with a %$ token. Return
1175 * NULL, having _already_ reported an error condition, if the
1176 * context stack isn't deep enough for the supplied number of $
1178 * If all_contexts == TRUE, contexts that enclose current are
1179 * also scanned for such smacro, until it is found; if not -
1180 * only the context that directly results from the number of $'s
1181 * in variable's name.
1184 get_ctx(char *name
, int all_contexts
)
1190 if (!name
|| name
[0] != '%' || name
[1] != '$')
1195 error(ERR_NONFATAL
, "`%s': context stack is empty", name
);
1199 for (i
= strspn(name
+ 2, "$"), ctx
= cstk
; (i
> 0) && ctx
; i
--)
1206 error(ERR_NONFATAL
, "`%s': context stack is only"
1207 " %d level%s deep", name
, i
- 1, (i
== 2 ? "" : "s"));
1215 /* Search for this smacro in found context */
1219 if (!mstrcmp(m
->name
, name
, m
->casesense
))
1229 /* Add a slash to the end of a path if it is missing. We use the
1230 * forward slash to make it compatible with Unix systems.
1235 int pos
= strlen(s
);
1236 if (s
[pos
- 1] != '\\' && s
[pos
- 1] != '/')
1244 * Open an include file. This routine must always return a valid
1245 * file pointer if it returns - it's responsible for throwing an
1246 * ERR_FATAL and bombing out completely if not. It should also try
1247 * the include path one by one until it finds the file or reaches
1248 * the end of the path.
1251 inc_fopen(char *file
)
1254 char *prefix
= "", *combine
;
1255 IncPath
*ip
= ipath
;
1256 static int namelen
= 0;
1257 int len
= strlen(file
);
1261 combine
= nasm_malloc(strlen(prefix
) + 1 + len
+ 1);
1262 strcpy(combine
, prefix
);
1265 strcat(combine
, file
);
1266 fp
= fopen(combine
, "r");
1267 if (pass
== 0 && fp
)
1269 namelen
+= strlen(combine
) + 1;
1275 printf(" %s", combine
);
1286 error(ERR_FATAL
, "unable to open include file `%s'", file
);
1287 return NULL
; /* never reached - placate compilers */
1291 * Determine if we should warn on defining a single-line macro of
1292 * name `name', with `nparam' parameters. If nparam is 0 or -1, will
1293 * return TRUE if _any_ single-line macro of that name is defined.
1294 * Otherwise, will return TRUE if a single-line macro with either
1295 * `nparam' or no parameters is defined.
1297 * If a macro with precisely the right number of parameters is
1298 * defined, or nparam is -1, the address of the definition structure
1299 * will be returned in `defn'; otherwise NULL will be returned. If `defn'
1300 * is NULL, no action will be taken regarding its contents, and no
1303 * Note that this is also called with nparam zero to resolve
1306 * If you already know which context macro belongs to, you can pass
1307 * the context pointer as first parameter; if you won't but name begins
1308 * with %$ the context will be automatically computed. If all_contexts
1309 * is true, macro will be searched in outer contexts as well.
1312 smacro_defined(Context
* ctx
, char *name
, int nparam
, SMacro
** defn
,
1319 else if (name
[0] == '%' && name
[1] == '$')
1322 ctx
= get_ctx(name
, FALSE
);
1324 return FALSE
; /* got to return _something_ */
1328 m
= smacros
[hash(name
)];
1332 if (!mstrcmp(m
->name
, name
, m
->casesense
&& nocase
) &&
1333 (nparam
<= 0 || m
->nparam
== 0 || nparam
== m
->nparam
))
1337 if (nparam
== m
->nparam
|| nparam
== -1)
1351 * Count and mark off the parameters in a multi-line macro call.
1352 * This is called both from within the multi-line macro expansion
1353 * code, and also to mark off the default parameters when provided
1354 * in a %macro definition line.
1357 count_mmac_params(Token
* t
, int *nparam
, Token
*** params
)
1359 int paramsize
, brace
;
1361 *nparam
= paramsize
= 0;
1365 if (*nparam
>= paramsize
)
1367 paramsize
+= PARAM_DELTA
;
1368 *params
= nasm_realloc(*params
, sizeof(**params
) * paramsize
);
1372 if (tok_is_(t
, "{"))
1374 (*params
)[(*nparam
)++] = t
;
1375 while (tok_isnt_(t
, brace
? "}" : ","))
1378 { /* got a comma/brace */
1383 * Now we've found the closing brace, look further
1387 if (tok_isnt_(t
, ","))
1390 "braces do not enclose all of macro parameter");
1391 while (tok_isnt_(t
, ","))
1395 t
= t
->next
; /* eat the comma */
1402 * Determine whether one of the various `if' conditions is true or
1405 * We must free the tline we get passed.
1408 if_condition(Token
* tline
, int i
)
1411 Token
*t
, *tt
, **tptr
, *origline
;
1412 struct tokenval tokval
;
1423 j
= FALSE
; /* have we matched yet? */
1424 while (cstk
&& tline
)
1427 if (!tline
|| tline
->type
!= TOK_ID
)
1430 "`%s' expects context identifiers",
1432 free_tlist(origline
);
1435 if (!nasm_stricmp(tline
->text
, cstk
->name
))
1437 tline
= tline
->next
;
1439 if (i
== PP_IFNCTX
|| i
== PP_ELIFNCTX
)
1441 free_tlist(origline
);
1448 j
= FALSE
; /* have we matched yet? */
1452 if (!tline
|| (tline
->type
!= TOK_ID
&&
1453 (tline
->type
!= TOK_PREPROC_ID
||
1454 tline
->text
[1] != '$')))
1457 "`%%if%sdef' expects macro identifiers",
1458 (i
== PP_ELIFNDEF
? "n" : ""));
1459 free_tlist(origline
);
1462 if (smacro_defined(NULL
, tline
->text
, 0, NULL
, 1))
1464 tline
= tline
->next
;
1466 if (i
== PP_IFNDEF
|| i
== PP_ELIFNDEF
)
1468 free_tlist(origline
);
1479 tline
= expand_smacro(tline
);
1481 while (tok_isnt_(tt
, ","))
1486 "`%s' expects two comma-separated arguments",
1492 casesense
= (i
== PP_IFIDN
|| i
== PP_ELIFIDN
||
1493 i
== PP_IFNIDN
|| i
== PP_ELIFNIDN
);
1494 j
= TRUE
; /* assume equality unless proved not */
1495 while ((t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ",")) && tt
)
1497 if (tt
->type
== TOK_OTHER
&& !strcmp(tt
->text
, ","))
1499 error(ERR_NONFATAL
, "`%s': more than one comma on line",
1504 if (t
->type
== TOK_WHITESPACE
)
1509 else if (tt
->type
== TOK_WHITESPACE
)
1514 else if (tt
->type
!= t
->type
||
1515 mstrcmp(tt
->text
, t
->text
, casesense
))
1517 j
= FALSE
; /* found mismatching tokens */
1527 if ((t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ",")) || tt
)
1528 j
= FALSE
; /* trailing gunk on one end or other */
1529 if (i
== PP_IFNIDN
|| i
== PP_ELIFNIDN
||
1530 i
== PP_IFNIDNI
|| i
== PP_ELIFNIDNI
)
1547 tline
= expand_smacro(tline
);
1549 while (tok_type_(t
, TOK_WHITESPACE
))
1551 j
= FALSE
; /* placate optimiser */
1559 j
= (t
->type
== TOK_ID
);
1565 j
= (t
->type
== TOK_NUMBER
);
1571 j
= (t
->type
== TOK_STRING
);
1574 if (i
== PP_IFNID
|| i
== PP_ELIFNID
||
1575 i
== PP_IFNNUM
|| i
== PP_ELIFNNUM
||
1576 i
== PP_IFNSTR
|| i
== PP_ELIFNSTR
)
1583 t
= tline
= expand_smacro(tline
);
1585 tokval
.t_type
= TOKEN_INVALID
;
1586 evalresult
= evaluate(ppscan
, tptr
, &tokval
,
1587 NULL
, pass
| CRITICAL
, error
, NULL
);
1593 "trailing garbage after expression ignored");
1594 if (!is_simple(evalresult
))
1597 "non-constant value given to `%s'", directives
[i
]);
1600 return reloc_value(evalresult
) != 0;
1604 "preprocessor directive `%s' not yet implemented",
1606 free_tlist(origline
);
1607 return -1; /* yeah, right */
1612 * Expand macros in a string. Used in %error and %include directives.
1613 * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
1614 * The returned variable should ALWAYS be freed after usage.
1617 expand_macros_in_string(char **p
)
1619 Token
*line
= tokenise(*p
);
1620 line
= expand_smacro(line
);
1621 *p
= detoken(line
, FALSE
);
1625 * Find out if a line contains a preprocessor directive, and deal
1628 * If a directive _is_ found, we are expected to free_tlist() the
1631 * Return values go like this:
1633 * bit 0 is set if a directive was found (so the line gets freed)
1636 do_directive(Token
* tline
)
1638 int i
, j
, k
, m
, nparam
, nolist
;
1644 SMacro
*smac
, **smhead
;
1646 Token
*t
, *tt
, *param_start
, *macro_start
, *last
, **tptr
, *origline
;
1648 struct tokenval tokval
;
1650 MMacro
*tmp_defining
; /* Used when manipulating rep_nest */
1655 if (!tok_type_(tline
, TOK_PREPROC_ID
) ||
1656 (tline
->text
[1] == '%' || tline
->text
[1] == '$'
1657 || tline
->text
[1] == '!'))
1661 j
= sizeof(directives
) / sizeof(*directives
);
1665 m
= nasm_stricmp(tline
->text
, directives
[k
]);
1667 if (tasm_compatible_mode
) {
1670 } else if (k
!= PP_ARG
&& k
!= PP_LOCAL
&& k
!= PP_STACKSIZE
) {
1684 * If we're in a non-emitting branch of a condition construct,
1685 * or walking to the end of an already terminated %rep block,
1686 * we should ignore all directives except for condition
1689 if (((istk
->conds
&& !emitting(istk
->conds
->state
)) ||
1690 (istk
->mstk
&& !istk
->mstk
->in_progress
)) &&
1691 i
!= PP_IF
&& i
!= PP_ELIF
&&
1692 i
!= PP_IFCTX
&& i
!= PP_ELIFCTX
&&
1693 i
!= PP_IFDEF
&& i
!= PP_ELIFDEF
&&
1694 i
!= PP_IFID
&& i
!= PP_ELIFID
&&
1695 i
!= PP_IFIDN
&& i
!= PP_ELIFIDN
&&
1696 i
!= PP_IFIDNI
&& i
!= PP_ELIFIDNI
&&
1697 i
!= PP_IFNCTX
&& i
!= PP_ELIFNCTX
&&
1698 i
!= PP_IFNDEF
&& i
!= PP_ELIFNDEF
&&
1699 i
!= PP_IFNID
&& i
!= PP_ELIFNID
&&
1700 i
!= PP_IFNIDN
&& i
!= PP_ELIFNIDN
&&
1701 i
!= PP_IFNIDNI
&& i
!= PP_ELIFNIDNI
&&
1702 i
!= PP_IFNNUM
&& i
!= PP_ELIFNNUM
&&
1703 i
!= PP_IFNSTR
&& i
!= PP_ELIFNSTR
&&
1704 i
!= PP_IFNUM
&& i
!= PP_ELIFNUM
&&
1705 i
!= PP_IFSTR
&& i
!= PP_ELIFSTR
&& i
!= PP_ELSE
&& i
!= PP_ENDIF
)
1711 * If we're defining a macro or reading a %rep block, we should
1712 * ignore all directives except for %macro/%imacro (which
1713 * generate an error), %endm/%endmacro, and (only if we're in a
1714 * %rep block) %endrep. If we're in a %rep block, another %rep
1715 * causes an error, so should be let through.
1717 if (defining
&& i
!= PP_MACRO
&& i
!= PP_IMACRO
&&
1718 i
!= PP_ENDMACRO
&& i
!= PP_ENDM
&&
1719 (defining
->name
|| (i
!= PP_ENDREP
&& i
!= PP_REP
)))
1726 error(ERR_NONFATAL
, "unknown preprocessor directive `%s'",
1728 return 0; /* didn't get it */
1734 /* Directive to tell NASM what the default stack size is. The
1735 * default is for a 16-bit stack, and this can be overriden with
1737 * the following form:
1739 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1741 tline
= tline
->next
;
1742 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1743 tline
= tline
->next
;
1744 if (!tline
|| tline
->type
!= TOK_ID
)
1746 error(ERR_NONFATAL
, "`%%stacksize' missing size parameter");
1747 free_tlist(origline
);
1750 if (nasm_stricmp(tline
->text
, "flat") == 0)
1752 /* All subsequent ARG directives are for a 32-bit stack */
1754 StackPointer
= "ebp";
1758 else if (nasm_stricmp(tline
->text
, "large") == 0)
1760 /* All subsequent ARG directives are for a 16-bit stack,
1761 * far function call.
1764 StackPointer
= "bp";
1768 else if (nasm_stricmp(tline
->text
, "small") == 0)
1770 /* All subsequent ARG directives are for a 16-bit stack,
1771 * far function call. We don't support near functions.
1774 StackPointer
= "bp";
1780 error(ERR_NONFATAL
, "`%%stacksize' invalid size type");
1781 free_tlist(origline
);
1784 free_tlist(origline
);
1788 /* TASM like ARG directive to define arguments to functions, in
1789 * the following form:
1791 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1796 char *arg
, directive
[256];
1797 int size
= StackSize
;
1799 /* Find the argument name */
1800 tline
= tline
->next
;
1801 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1802 tline
= tline
->next
;
1803 if (!tline
|| tline
->type
!= TOK_ID
)
1805 error(ERR_NONFATAL
, "`%%arg' missing argument parameter");
1806 free_tlist(origline
);
1811 /* Find the argument size type */
1812 tline
= tline
->next
;
1813 if (!tline
|| tline
->type
!= TOK_OTHER
1814 || tline
->text
[0] != ':')
1817 "Syntax error processing `%%arg' directive");
1818 free_tlist(origline
);
1821 tline
= tline
->next
;
1822 if (!tline
|| tline
->type
!= TOK_ID
)
1825 "`%%arg' missing size type parameter");
1826 free_tlist(origline
);
1830 /* Allow macro expansion of type parameter */
1831 tt
= tokenise(tline
->text
);
1832 tt
= expand_smacro(tt
);
1833 if (nasm_stricmp(tt
->text
, "byte") == 0)
1835 size
= MAX(StackSize
, 1);
1837 else if (nasm_stricmp(tt
->text
, "word") == 0)
1839 size
= MAX(StackSize
, 2);
1841 else if (nasm_stricmp(tt
->text
, "dword") == 0)
1843 size
= MAX(StackSize
, 4);
1845 else if (nasm_stricmp(tt
->text
, "qword") == 0)
1847 size
= MAX(StackSize
, 8);
1849 else if (nasm_stricmp(tt
->text
, "tword") == 0)
1851 size
= MAX(StackSize
, 10);
1856 "Invalid size type for `%%arg' missing directive");
1858 free_tlist(origline
);
1863 /* Now define the macro for the argument */
1864 sprintf(directive
, "%%define %s (%s+%d)", arg
, StackPointer
,
1866 do_directive(tokenise(directive
));
1869 /* Move to the next argument in the list */
1870 tline
= tline
->next
;
1871 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1872 tline
= tline
->next
;
1874 while (tline
&& tline
->type
== TOK_OTHER
1875 && tline
->text
[0] == ',');
1876 free_tlist(origline
);
1880 /* TASM like LOCAL directive to define local variables for a
1881 * function, in the following form:
1883 * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1885 * The '= LocalSize' at the end is ignored by NASM, but is
1886 * required by TASM to define the local parameter size (and used
1887 * by the TASM macro package).
1889 offset
= LocalOffset
;
1892 char *local
, directive
[256];
1893 int size
= StackSize
;
1895 /* Find the argument name */
1896 tline
= tline
->next
;
1897 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1898 tline
= tline
->next
;
1899 if (!tline
|| tline
->type
!= TOK_ID
)
1902 "`%%local' missing argument parameter");
1903 free_tlist(origline
);
1906 local
= tline
->text
;
1908 /* Find the argument size type */
1909 tline
= tline
->next
;
1910 if (!tline
|| tline
->type
!= TOK_OTHER
1911 || tline
->text
[0] != ':')
1914 "Syntax error processing `%%local' directive");
1915 free_tlist(origline
);
1918 tline
= tline
->next
;
1919 if (!tline
|| tline
->type
!= TOK_ID
)
1922 "`%%local' missing size type parameter");
1923 free_tlist(origline
);
1927 /* Allow macro expansion of type parameter */
1928 tt
= tokenise(tline
->text
);
1929 tt
= expand_smacro(tt
);
1930 if (nasm_stricmp(tt
->text
, "byte") == 0)
1932 size
= MAX(StackSize
, 1);
1934 else if (nasm_stricmp(tt
->text
, "word") == 0)
1936 size
= MAX(StackSize
, 2);
1938 else if (nasm_stricmp(tt
->text
, "dword") == 0)
1940 size
= MAX(StackSize
, 4);
1942 else if (nasm_stricmp(tt
->text
, "qword") == 0)
1944 size
= MAX(StackSize
, 8);
1946 else if (nasm_stricmp(tt
->text
, "tword") == 0)
1948 size
= MAX(StackSize
, 10);
1953 "Invalid size type for `%%local' missing directive");
1955 free_tlist(origline
);
1960 /* Now define the macro for the argument */
1961 sprintf(directive
, "%%define %s (%s-%d)", local
, StackPointer
,
1963 do_directive(tokenise(directive
));
1966 /* Now define the assign to setup the enter_c macro correctly */
1967 sprintf(directive
, "%%assign %%$localsize %%$localsize+%d",
1969 do_directive(tokenise(directive
));
1971 /* Move to the next argument in the list */
1972 tline
= tline
->next
;
1973 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1974 tline
= tline
->next
;
1976 while (tline
&& tline
->type
== TOK_OTHER
1977 && tline
->text
[0] == ',');
1978 free_tlist(origline
);
1984 "trailing garbage after `%%clear' ignored");
1985 for (j
= 0; j
< NHASH
; j
++)
1989 MMacro
*m
= mmacros
[j
];
1990 mmacros
[j
] = m
->next
;
1995 SMacro
*s
= smacros
[j
];
1996 smacros
[j
] = smacros
[j
]->next
;
1998 free_tlist(s
->expansion
);
2002 free_tlist(origline
);
2006 tline
= tline
->next
;
2008 if (!tline
|| (tline
->type
!= TOK_STRING
&&
2009 tline
->type
!= TOK_INTERNAL_STRING
))
2011 error(ERR_NONFATAL
, "`%%include' expects a file name");
2012 free_tlist(origline
);
2013 return 3; /* but we did _something_ */
2017 "trailing garbage after `%%include' ignored");
2018 if (tline
->type
!= TOK_INTERNAL_STRING
)
2020 p
= tline
->text
+ 1; /* point past the quote to the name */
2021 p
[strlen(p
) - 1] = '\0'; /* remove the trailing quote */
2024 p
= tline
->text
; /* internal_string is easier */
2025 expand_macros_in_string(&p
);
2026 inc
= nasm_malloc(sizeof(Include
));
2029 inc
->fp
= inc_fopen(p
);
2030 inc
->fname
= src_set_fname(p
);
2031 inc
->lineno
= src_set_linnum(0);
2033 inc
->expansion
= NULL
;
2036 list
->uplevel(LIST_INCLUDE
);
2037 free_tlist(origline
);
2041 tline
= tline
->next
;
2043 tline
= expand_id(tline
);
2044 if (!tok_type_(tline
, TOK_ID
))
2046 error(ERR_NONFATAL
, "`%%push' expects a context identifier");
2047 free_tlist(origline
);
2048 return 3; /* but we did _something_ */
2051 error(ERR_WARNING
, "trailing garbage after `%%push' ignored");
2052 ctx
= nasm_malloc(sizeof(Context
));
2054 ctx
->localmac
= NULL
;
2055 ctx
->name
= nasm_strdup(tline
->text
);
2056 ctx
->number
= unique
++;
2058 free_tlist(origline
);
2062 tline
= tline
->next
;
2064 tline
= expand_id(tline
);
2065 if (!tok_type_(tline
, TOK_ID
))
2067 error(ERR_NONFATAL
, "`%%repl' expects a context identifier");
2068 free_tlist(origline
);
2069 return 3; /* but we did _something_ */
2072 error(ERR_WARNING
, "trailing garbage after `%%repl' ignored");
2074 error(ERR_NONFATAL
, "`%%repl': context stack is empty");
2077 nasm_free(cstk
->name
);
2078 cstk
->name
= nasm_strdup(tline
->text
);
2080 free_tlist(origline
);
2085 error(ERR_WARNING
, "trailing garbage after `%%pop' ignored");
2088 "`%%pop': context stack is already empty");
2091 free_tlist(origline
);
2095 tline
->next
= expand_smacro(tline
->next
);
2096 tline
= tline
->next
;
2098 if (tok_type_(tline
, TOK_STRING
))
2100 p
= tline
->text
+ 1; /* point past the quote to the name */
2101 p
[strlen(p
) - 1] = '\0'; /* remove the trailing quote */
2102 expand_macros_in_string(&p
);
2103 error(ERR_NONFATAL
, "%s", p
);
2108 p
= detoken(tline
, FALSE
);
2109 error(ERR_WARNING
, "%s", p
);
2112 free_tlist(origline
);
2130 if (istk
->conds
&& !emitting(istk
->conds
->state
))
2134 j
= if_condition(tline
->next
, i
);
2135 tline
->next
= NULL
; /* it got freed */
2136 free_tlist(origline
);
2137 j
= j
< 0 ? COND_NEVER
: j
? COND_IF_TRUE
: COND_IF_FALSE
;
2139 cond
= nasm_malloc(sizeof(Cond
));
2140 cond
->next
= istk
->conds
;
2143 return (j
== COND_IF_TRUE
? 3 : 1);
2161 error(ERR_FATAL
, "`%s': no matching `%%if'", directives
[i
]);
2162 if (emitting(istk
->conds
->state
)
2163 || istk
->conds
->state
== COND_NEVER
)
2164 istk
->conds
->state
= COND_NEVER
;
2167 j
= if_condition(expand_mmac_params(tline
->next
), i
);
2168 tline
->next
= NULL
; /* it got freed */
2169 free_tlist(origline
);
2170 istk
->conds
->state
=
2171 j
< 0 ? COND_NEVER
: j
? COND_IF_TRUE
: COND_IF_FALSE
;
2173 return (istk
->conds
->state
== COND_IF_TRUE
? 5 : 1);
2177 error(ERR_WARNING
, "trailing garbage after `%%else' ignored");
2179 error(ERR_FATAL
, "`%%else': no matching `%%if'");
2180 if (emitting(istk
->conds
->state
)
2181 || istk
->conds
->state
== COND_NEVER
)
2182 istk
->conds
->state
= COND_ELSE_FALSE
;
2184 istk
->conds
->state
= COND_ELSE_TRUE
;
2185 free_tlist(origline
);
2191 "trailing garbage after `%%endif' ignored");
2193 error(ERR_FATAL
, "`%%endif': no matching `%%if'");
2195 istk
->conds
= cond
->next
;
2197 free_tlist(origline
);
2204 "`%%%smacro': already defining a macro",
2205 (i
== PP_IMACRO
? "i" : ""));
2206 tline
= tline
->next
;
2208 tline
= expand_id(tline
);
2209 if (!tok_type_(tline
, TOK_ID
))
2212 "`%%%smacro' expects a macro name",
2213 (i
== PP_IMACRO
? "i" : ""));
2216 defining
= nasm_malloc(sizeof(MMacro
));
2217 defining
->name
= nasm_strdup(tline
->text
);
2218 defining
->casesense
= (i
== PP_MACRO
);
2219 defining
->plus
= FALSE
;
2220 defining
->nolist
= FALSE
;
2221 defining
->in_progress
= FALSE
;
2222 defining
->rep_nest
= NULL
;
2223 tline
= expand_smacro(tline
->next
);
2225 if (!tok_type_(tline
, TOK_NUMBER
))
2228 "`%%%smacro' expects a parameter count",
2229 (i
== PP_IMACRO
? "i" : ""));
2230 defining
->nparam_min
= defining
->nparam_max
= 0;
2234 defining
->nparam_min
= defining
->nparam_max
=
2235 readnum(tline
->text
, &j
);
2238 "unable to parse parameter count `%s'",
2241 if (tline
&& tok_is_(tline
->next
, "-"))
2243 tline
= tline
->next
->next
;
2244 if (tok_is_(tline
, "*"))
2245 defining
->nparam_max
= INT_MAX
;
2246 else if (!tok_type_(tline
, TOK_NUMBER
))
2248 "`%%%smacro' expects a parameter count after `-'",
2249 (i
== PP_IMACRO
? "i" : ""));
2252 defining
->nparam_max
= readnum(tline
->text
, &j
);
2255 "unable to parse parameter count `%s'",
2257 if (defining
->nparam_min
> defining
->nparam_max
)
2259 "minimum parameter count exceeds maximum");
2262 if (tline
&& tok_is_(tline
->next
, "+"))
2264 tline
= tline
->next
;
2265 defining
->plus
= TRUE
;
2267 if (tline
&& tok_type_(tline
->next
, TOK_ID
) &&
2268 !nasm_stricmp(tline
->next
->text
, ".nolist"))
2270 tline
= tline
->next
;
2271 defining
->nolist
= TRUE
;
2273 mmac
= mmacros
[hash(defining
->name
)];
2276 if (!strcmp(mmac
->name
, defining
->name
) &&
2277 (mmac
->nparam_min
<= defining
->nparam_max
2279 && (defining
->nparam_min
<= mmac
->nparam_max
2283 "redefining multi-line macro `%s'",
2290 * Handle default parameters.
2292 if (tline
&& tline
->next
)
2294 defining
->dlist
= tline
->next
;
2296 count_mmac_params(defining
->dlist
, &defining
->ndefs
,
2297 &defining
->defaults
);
2301 defining
->dlist
= NULL
;
2302 defining
->defaults
= NULL
;
2304 defining
->expansion
= NULL
;
2305 free_tlist(origline
);
2312 error(ERR_NONFATAL
, "`%s': not defining a macro",
2316 k
= hash(defining
->name
);
2317 defining
->next
= mmacros
[k
];
2318 mmacros
[k
] = defining
;
2320 free_tlist(origline
);
2324 if (tline
->next
&& tline
->next
->type
== TOK_WHITESPACE
)
2325 tline
= tline
->next
;
2326 t
= expand_smacro(tline
->next
);
2328 free_tlist(origline
);
2331 tokval
.t_type
= TOKEN_INVALID
;
2333 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2339 "trailing garbage after expression ignored");
2340 if (!is_simple(evalresult
))
2342 error(ERR_NONFATAL
, "non-constant value given to `%%rotate'");
2346 while (mmac
&& !mmac
->name
) /* avoid mistaking %reps for macros */
2347 mmac
= mmac
->next_active
;
2350 "`%%rotate' invoked outside a macro call");
2351 mmac
->rotate
= mmac
->rotate
+ reloc_value(evalresult
);
2352 if (mmac
->rotate
< 0)
2353 mmac
->rotate
= mmac
->nparam
- (-mmac
->rotate
) % mmac
->nparam
;
2354 mmac
->rotate
%= mmac
->nparam
;
2359 tline
= tline
->next
;
2360 if (tline
->next
&& tline
->next
->type
== TOK_WHITESPACE
)
2361 tline
= tline
->next
;
2362 if (tline
->next
&& tline
->next
->type
== TOK_ID
&&
2363 !nasm_stricmp(tline
->next
->text
, ".nolist"))
2365 tline
= tline
->next
;
2368 t
= expand_smacro(tline
->next
);
2370 free_tlist(origline
);
2373 tokval
.t_type
= TOKEN_INVALID
;
2375 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2381 "trailing garbage after expression ignored");
2382 if (!is_simple(evalresult
))
2384 error(ERR_NONFATAL
, "non-constant value given to `%%rep'");
2387 tmp_defining
= defining
;
2388 defining
= nasm_malloc(sizeof(MMacro
));
2389 defining
->name
= NULL
; /* flags this macro as a %rep block */
2390 defining
->casesense
= 0;
2391 defining
->plus
= FALSE
;
2392 defining
->nolist
= nolist
;
2393 defining
->in_progress
= reloc_value(evalresult
) + 1;
2394 defining
->nparam_min
= defining
->nparam_max
= 0;
2395 defining
->defaults
= NULL
;
2396 defining
->dlist
= NULL
;
2397 defining
->expansion
= NULL
;
2398 defining
->next_active
= istk
->mstk
;
2399 defining
->rep_nest
= tmp_defining
;
2403 if (!defining
|| defining
->name
)
2405 error(ERR_NONFATAL
, "`%%endrep': no matching `%%rep'");
2410 * Now we have a "macro" defined - although it has no name
2411 * and we won't be entering it in the hash tables - we must
2412 * push a macro-end marker for it on to istk->expansion.
2413 * After that, it will take care of propagating itself (a
2414 * macro-end marker line for a macro which is really a %rep
2415 * block will cause the macro to be re-expanded, complete
2416 * with another macro-end marker to ensure the process
2417 * continues) until the whole expansion is forcibly removed
2418 * from istk->expansion by a %exitrep.
2420 l
= nasm_malloc(sizeof(Line
));
2421 l
->next
= istk
->expansion
;
2422 l
->finishes
= defining
;
2424 istk
->expansion
= l
;
2426 istk
->mstk
= defining
;
2428 list
->uplevel(defining
->nolist
? LIST_MACRO_NOLIST
: LIST_MACRO
);
2429 tmp_defining
= defining
;
2430 defining
= defining
->rep_nest
;
2431 free_tlist(origline
);
2436 * We must search along istk->expansion until we hit a
2437 * macro-end marker for a macro with no name. Then we set
2438 * its `in_progress' flag to 0.
2440 for (l
= istk
->expansion
; l
; l
= l
->next
)
2441 if (l
->finishes
&& !l
->finishes
->name
)
2445 l
->finishes
->in_progress
= 0;
2447 error(ERR_NONFATAL
, "`%%exitrep' not within `%%rep' block");
2448 free_tlist(origline
);
2455 tline
= tline
->next
;
2457 tline
= expand_id(tline
);
2458 if (!tline
|| (tline
->type
!= TOK_ID
&&
2459 (tline
->type
!= TOK_PREPROC_ID
||
2460 tline
->text
[1] != '$')))
2463 "`%%%s%sdefine' expects a macro identifier",
2464 ((i
== PP_IDEFINE
|| i
== PP_IXDEFINE
) ? "i" : ""),
2465 ((i
== PP_XDEFINE
|| i
== PP_IXDEFINE
) ? "x" : ""));
2466 free_tlist(origline
);
2470 ctx
= get_ctx(tline
->text
, FALSE
);
2472 smhead
= &smacros
[hash(tline
->text
)];
2474 smhead
= &ctx
->localmac
;
2475 mname
= tline
->text
;
2477 param_start
= tline
= tline
->next
;
2480 /* Expand the macro definition now for %xdefine and %ixdefine */
2481 if ((i
== PP_XDEFINE
) || (i
== PP_IXDEFINE
))
2482 tline
= expand_smacro(tline
);
2484 if (tok_is_(tline
, "("))
2487 * This macro has parameters.
2490 tline
= tline
->next
;
2496 error(ERR_NONFATAL
, "parameter identifier expected");
2497 free_tlist(origline
);
2500 if (tline
->type
!= TOK_ID
)
2503 "`%s': parameter identifier expected",
2505 free_tlist(origline
);
2508 tline
->type
= TOK_SMAC_PARAM
+ nparam
++;
2509 tline
= tline
->next
;
2511 if (tok_is_(tline
, ","))
2513 tline
= tline
->next
;
2516 if (!tok_is_(tline
, ")"))
2519 "`)' expected to terminate macro template");
2520 free_tlist(origline
);
2526 tline
= tline
->next
;
2528 if (tok_type_(tline
, TOK_WHITESPACE
))
2529 last
= tline
, tline
= tline
->next
;
2535 if (t
->type
== TOK_ID
)
2537 for (tt
= param_start
; tt
; tt
= tt
->next
)
2538 if (tt
->type
>= TOK_SMAC_PARAM
&&
2539 !strcmp(tt
->text
, t
->text
))
2543 t
->next
= macro_start
;
2548 * Good. We now have a macro name, a parameter count, and a
2549 * token list (in reverse order) for an expansion. We ought
2550 * to be OK just to create an SMacro, store it, and let
2551 * free_tlist have the rest of the line (which we have
2552 * carefully re-terminated after chopping off the expansion
2555 if (smacro_defined(ctx
, mname
, nparam
, &smac
, i
== PP_DEFINE
))
2560 "single-line macro `%s' defined both with and"
2561 " without parameters", mname
);
2562 free_tlist(origline
);
2563 free_tlist(macro_start
);
2569 * We're redefining, so we have to take over an
2570 * existing SMacro structure. This means freeing
2571 * what was already in it.
2573 nasm_free(smac
->name
);
2574 free_tlist(smac
->expansion
);
2579 smac
= nasm_malloc(sizeof(SMacro
));
2580 smac
->next
= *smhead
;
2583 smac
->name
= nasm_strdup(mname
);
2584 smac
->casesense
= ((i
== PP_DEFINE
) || (i
== PP_XDEFINE
));
2585 smac
->nparam
= nparam
;
2586 smac
->expansion
= macro_start
;
2587 smac
->in_progress
= FALSE
;
2588 free_tlist(origline
);
2592 tline
= tline
->next
;
2594 tline
= expand_id(tline
);
2595 if (!tline
|| (tline
->type
!= TOK_ID
&&
2596 (tline
->type
!= TOK_PREPROC_ID
||
2597 tline
->text
[1] != '$')))
2599 error(ERR_NONFATAL
, "`%%undef' expects a macro identifier");
2600 free_tlist(origline
);
2606 "trailing garbage after macro name ignored");
2609 /* Find the context that symbol belongs to */
2610 ctx
= get_ctx(tline
->text
, FALSE
);
2612 smhead
= &smacros
[hash(tline
->text
)];
2614 smhead
= &ctx
->localmac
;
2616 mname
= tline
->text
;
2621 * We now have a macro name... go hunt for it.
2623 while (smacro_defined(ctx
, mname
, -1, &smac
, 1))
2625 /* Defined, so we need to find its predecessor and nuke it */
2627 for (s
= smhead
; *s
&& *s
!= smac
; s
= &(*s
)->next
);
2631 nasm_free(smac
->name
);
2632 free_tlist(smac
->expansion
);
2636 free_tlist(origline
);
2640 tline
= tline
->next
;
2642 tline
= expand_id(tline
);
2643 if (!tline
|| (tline
->type
!= TOK_ID
&&
2644 (tline
->type
!= TOK_PREPROC_ID
||
2645 tline
->text
[1] != '$')))
2648 "`%%strlen' expects a macro identifier as first parameter");
2649 free_tlist(origline
);
2652 ctx
= get_ctx(tline
->text
, FALSE
);
2654 smhead
= &smacros
[hash(tline
->text
)];
2656 smhead
= &ctx
->localmac
;
2657 mname
= tline
->text
;
2659 tline
= expand_smacro(tline
->next
);
2663 while (tok_type_(t
, TOK_WHITESPACE
))
2665 /* t should now point to the string */
2666 if (t
->type
!= TOK_STRING
)
2669 "`%%strlen` requires string as second parameter");
2671 free_tlist(origline
);
2675 macro_start
= nasm_malloc(sizeof(*macro_start
));
2676 macro_start
->next
= NULL
;
2677 make_tok_num(macro_start
, strlen(t
->text
) - 2);
2678 macro_start
->mac
= NULL
;
2681 * We now have a macro name, an implicit parameter count of
2682 * zero, and a numeric token to use as an expansion. Create
2683 * and store an SMacro.
2685 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_STRLEN
))
2689 "single-line macro `%s' defined both with and"
2690 " without parameters", mname
);
2694 * We're redefining, so we have to take over an
2695 * existing SMacro structure. This means freeing
2696 * what was already in it.
2698 nasm_free(smac
->name
);
2699 free_tlist(smac
->expansion
);
2704 smac
= nasm_malloc(sizeof(SMacro
));
2705 smac
->next
= *smhead
;
2708 smac
->name
= nasm_strdup(mname
);
2709 smac
->casesense
= (i
== PP_STRLEN
);
2711 smac
->expansion
= macro_start
;
2712 smac
->in_progress
= FALSE
;
2714 free_tlist(origline
);
2718 tline
= tline
->next
;
2720 tline
= expand_id(tline
);
2721 if (!tline
|| (tline
->type
!= TOK_ID
&&
2722 (tline
->type
!= TOK_PREPROC_ID
||
2723 tline
->text
[1] != '$')))
2726 "`%%substr' expects a macro identifier as first parameter");
2727 free_tlist(origline
);
2730 ctx
= get_ctx(tline
->text
, FALSE
);
2732 smhead
= &smacros
[hash(tline
->text
)];
2734 smhead
= &ctx
->localmac
;
2735 mname
= tline
->text
;
2737 tline
= expand_smacro(tline
->next
);
2741 while (tok_type_(t
, TOK_WHITESPACE
))
2744 /* t should now point to the string */
2745 if (t
->type
!= TOK_STRING
)
2748 "`%%substr` requires string as second parameter");
2750 free_tlist(origline
);
2756 tokval
.t_type
= TOKEN_INVALID
;
2758 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2762 free_tlist(origline
);
2765 if (!is_simple(evalresult
))
2767 error(ERR_NONFATAL
, "non-constant value given to `%%substr`");
2769 free_tlist(origline
);
2773 macro_start
= nasm_malloc(sizeof(*macro_start
));
2774 macro_start
->next
= NULL
;
2775 macro_start
->text
= nasm_strdup("'''");
2776 if (evalresult
->value
> 0
2777 && evalresult
->value
< strlen(t
->text
) - 1)
2779 macro_start
->text
[1] = t
->text
[evalresult
->value
];
2783 macro_start
->text
[2] = '\0';
2785 macro_start
->type
= TOK_STRING
;
2786 macro_start
->mac
= NULL
;
2789 * We now have a macro name, an implicit parameter count of
2790 * zero, and a numeric token to use as an expansion. Create
2791 * and store an SMacro.
2793 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_SUBSTR
))
2797 "single-line macro `%s' defined both with and"
2798 " without parameters", mname
);
2802 * We're redefining, so we have to take over an
2803 * existing SMacro structure. This means freeing
2804 * what was already in it.
2806 nasm_free(smac
->name
);
2807 free_tlist(smac
->expansion
);
2812 smac
= nasm_malloc(sizeof(SMacro
));
2813 smac
->next
= *smhead
;
2816 smac
->name
= nasm_strdup(mname
);
2817 smac
->casesense
= (i
== PP_SUBSTR
);
2819 smac
->expansion
= macro_start
;
2820 smac
->in_progress
= FALSE
;
2822 free_tlist(origline
);
2828 tline
= tline
->next
;
2830 tline
= expand_id(tline
);
2831 if (!tline
|| (tline
->type
!= TOK_ID
&&
2832 (tline
->type
!= TOK_PREPROC_ID
||
2833 tline
->text
[1] != '$')))
2836 "`%%%sassign' expects a macro identifier",
2837 (i
== PP_IASSIGN
? "i" : ""));
2838 free_tlist(origline
);
2841 ctx
= get_ctx(tline
->text
, FALSE
);
2843 smhead
= &smacros
[hash(tline
->text
)];
2845 smhead
= &ctx
->localmac
;
2846 mname
= tline
->text
;
2848 tline
= expand_smacro(tline
->next
);
2853 tokval
.t_type
= TOKEN_INVALID
;
2855 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2859 free_tlist(origline
);
2865 "trailing garbage after expression ignored");
2867 if (!is_simple(evalresult
))
2870 "non-constant value given to `%%%sassign'",
2871 (i
== PP_IASSIGN
? "i" : ""));
2872 free_tlist(origline
);
2876 macro_start
= nasm_malloc(sizeof(*macro_start
));
2877 macro_start
->next
= NULL
;
2878 make_tok_num(macro_start
, reloc_value(evalresult
));
2879 macro_start
->mac
= NULL
;
2882 * We now have a macro name, an implicit parameter count of
2883 * zero, and a numeric token to use as an expansion. Create
2884 * and store an SMacro.
2886 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_ASSIGN
))
2890 "single-line macro `%s' defined both with and"
2891 " without parameters", mname
);
2895 * We're redefining, so we have to take over an
2896 * existing SMacro structure. This means freeing
2897 * what was already in it.
2899 nasm_free(smac
->name
);
2900 free_tlist(smac
->expansion
);
2905 smac
= nasm_malloc(sizeof(SMacro
));
2906 smac
->next
= *smhead
;
2909 smac
->name
= nasm_strdup(mname
);
2910 smac
->casesense
= (i
== PP_ASSIGN
);
2912 smac
->expansion
= macro_start
;
2913 smac
->in_progress
= FALSE
;
2914 free_tlist(origline
);
2919 * Syntax is `%line nnn[+mmm] [filename]'
2921 tline
= tline
->next
;
2923 if (!tok_type_(tline
, TOK_NUMBER
))
2925 error(ERR_NONFATAL
, "`%%line' expects line number");
2926 free_tlist(origline
);
2929 k
= readnum(tline
->text
, &j
);
2931 tline
= tline
->next
;
2932 if (tok_is_(tline
, "+"))
2934 tline
= tline
->next
;
2935 if (!tok_type_(tline
, TOK_NUMBER
))
2937 error(ERR_NONFATAL
, "`%%line' expects line increment");
2938 free_tlist(origline
);
2941 m
= readnum(tline
->text
, &j
);
2942 tline
= tline
->next
;
2949 nasm_free(src_set_fname(detoken(tline
, FALSE
)));
2951 free_tlist(origline
);
2956 "preprocessor directive `%s' not yet implemented",
2964 * Ensure that a macro parameter contains a condition code and
2965 * nothing else. Return the condition code index if so, or -1
2975 if (t
->type
!= TOK_ID
)
2979 if (tt
&& (tt
->type
!= TOK_OTHER
|| strcmp(tt
->text
, ",")))
2983 j
= sizeof(conditions
) / sizeof(*conditions
);
2987 m
= nasm_stricmp(t
->text
, conditions
[k
]);
3007 * Expand MMacro-local things: parameter references (%0, %n, %+n,
3008 * %-n) and MMacro-local identifiers (%%foo).
3011 expand_mmac_params(Token
* tline
)
3013 Token
*t
, *tt
, **tail
, *thead
;
3020 if (tline
->type
== TOK_PREPROC_ID
&&
3021 (((tline
->text
[1] == '+' || tline
->text
[1] == '-')
3022 && tline
->text
[2]) || tline
->text
[1] == '%'
3023 || (tline
->text
[1] >= '0' && tline
->text
[1] <= '9')))
3026 int type
= 0, cc
; /* type = 0 to placate optimisers */
3032 tline
= tline
->next
;
3035 while (mac
&& !mac
->name
) /* avoid mistaking %reps for macros */
3036 mac
= mac
->next_active
;
3038 error(ERR_NONFATAL
, "`%s': not in a macro call", t
->text
);
3043 * We have to make a substitution of one of the
3044 * forms %1, %-1, %+1, %%foo, %0.
3048 sprintf(tmpbuf
, "%d", mac
->nparam
);
3049 text
= nasm_strdup(tmpbuf
);
3053 sprintf(tmpbuf
, "..@%lu.", mac
->unique
);
3054 text
= nasm_strcat(tmpbuf
, t
->text
+ 2);
3057 n
= atoi(t
->text
+ 2) - 1;
3058 if (n
>= mac
->nparam
)
3062 if (mac
->nparam
> 1)
3063 n
= (n
+ mac
->rotate
) % mac
->nparam
;
3064 tt
= mac
->params
[n
];
3070 "macro parameter %d is not a condition code",
3077 if (inverse_ccs
[cc
] == -1)
3080 "condition code `%s' is not invertible",
3086 nasm_strdup(conditions
[inverse_ccs
3091 n
= atoi(t
->text
+ 2) - 1;
3092 if (n
>= mac
->nparam
)
3096 if (mac
->nparam
> 1)
3097 n
= (n
+ mac
->rotate
) % mac
->nparam
;
3098 tt
= mac
->params
[n
];
3104 "macro parameter %d is not a condition code",
3111 text
= nasm_strdup(conditions
[cc
]);
3115 n
= atoi(t
->text
+ 1) - 1;
3116 if (n
>= mac
->nparam
)
3120 if (mac
->nparam
> 1)
3121 n
= (n
+ mac
->rotate
) % mac
->nparam
;
3122 tt
= mac
->params
[n
];
3126 for (i
= 0; i
< mac
->paramlen
[n
]; i
++)
3129 new_Token(NULL
, tt
->type
, tt
->text
,
3131 tail
= &(*tail
)->next
;
3135 text
= NULL
; /* we've done it here */
3156 tline
= tline
->next
;
3163 for (; t
&& (tt
= t
->next
) != NULL
; t
= t
->next
)
3166 case TOK_WHITESPACE
:
3167 if (tt
->type
== TOK_WHITESPACE
)
3169 t
->next
= delete_Token(tt
);
3173 if (tt
->type
== TOK_ID
|| tt
->type
== TOK_NUMBER
)
3175 char *tmp
= nasm_strcat(t
->text
, tt
->text
);
3178 t
->next
= delete_Token(tt
);
3182 if (tt
->type
== TOK_NUMBER
)
3184 char *tmp
= nasm_strcat(t
->text
, tt
->text
);
3187 t
->next
= delete_Token(tt
);
3196 * Expand all single-line macro calls made in the given line.
3197 * Return the expanded version of the line. The original is deemed
3198 * to be destroyed in the process. (In reality we'll just move
3199 * Tokens from input to output a lot of the time, rather than
3200 * actually bothering to destroy and replicate.)
3203 expand_smacro(Token
* tline
)
3205 Token
*t
, *tt
, *mstart
, **tail
, *thead
;
3206 SMacro
*head
= NULL
, *m
;
3209 int nparam
, sparam
, brackets
, rescan
;
3210 Token
*org_tline
= tline
;
3215 * Trick: we should avoid changing the start token pointer since it can
3216 * be contained in "next" field of other token. Because of this
3217 * we allocate a copy of first token and work with it; at the end of
3218 * routine we copy it back
3223 new_Token(org_tline
->next
, org_tline
->type
, org_tline
->text
,
3225 tline
->mac
= org_tline
->mac
;
3226 nasm_free(org_tline
->text
);
3227 org_tline
->text
= NULL
;
3235 { /* main token loop */
3236 if ((mname
= tline
->text
))
3238 /* if this token is a local macro, look in local context */
3239 if (tline
->type
== TOK_ID
|| tline
->type
== TOK_PREPROC_ID
)
3240 ctx
= get_ctx(mname
, TRUE
);
3244 head
= smacros
[hash(mname
)];
3246 head
= ctx
->localmac
;
3248 * We've hit an identifier. As in is_mmacro below, we first
3249 * check whether the identifier is a single-line macro at
3250 * all, then think about checking for parameters if
3253 for (m
= head
; m
; m
= m
->next
)
3254 if (!mstrcmp(m
->name
, mname
, m
->casesense
))
3264 * Simple case: the macro is parameterless. Discard the
3265 * one token that the macro call took, and push the
3266 * expansion back on the to-do stack.
3270 if (!strcmp("__FILE__", m
->name
))
3273 src_get(&num
, &(tline
->text
));
3274 nasm_quote(&(tline
->text
));
3275 tline
->type
= TOK_STRING
;
3278 if (!strcmp("__LINE__", m
->name
))
3280 nasm_free(tline
->text
);
3281 make_tok_num(tline
, src_get_linnum());
3284 tline
= delete_Token(tline
);
3291 * Complicated case: at least one macro with this name
3292 * exists and takes parameters. We must find the
3293 * parameters in the call, count them, find the SMacro
3294 * that corresponds to that form of the macro call, and
3295 * substitute for the parameters when we expand. What a
3298 tline
= tline
->next
;
3300 if (!tok_is_(tline
, "("))
3303 * This macro wasn't called with parameters: ignore
3304 * the call. (Behaviour borrowed from gnu cpp.)
3315 tline
= tline
->next
;
3316 sparam
= PARAM_DELTA
;
3317 params
= nasm_malloc(sparam
* sizeof(Token
*));
3319 paramsize
= nasm_malloc(sparam
* sizeof(int));
3321 for (;; tline
= tline
->next
)
3322 { /* parameter loop */
3326 "macro call expects terminating `)'");
3329 if (tline
->type
== TOK_WHITESPACE
3332 if (paramsize
[nparam
])
3335 params
[nparam
] = tline
->next
;
3336 continue; /* parameter loop */
3338 if (tline
->type
== TOK_OTHER
3339 && tline
->text
[1] == 0)
3341 char ch
= tline
->text
[0];
3342 if (ch
== ',' && !paren
&& brackets
<= 0)
3344 if (++nparam
>= sparam
)
3346 sparam
+= PARAM_DELTA
;
3347 params
= nasm_realloc(params
,
3348 sparam
* sizeof(Token
*));
3349 paramsize
= nasm_realloc(paramsize
,
3350 sparam
* sizeof(int));
3352 params
[nparam
] = tline
->next
;
3353 paramsize
[nparam
] = 0;
3355 continue; /* parameter loop */
3358 (brackets
> 0 || (brackets
== 0 &&
3359 !paramsize
[nparam
])))
3363 params
[nparam
] = tline
->next
;
3364 continue; /* parameter loop */
3367 if (ch
== '}' && brackets
> 0)
3368 if (--brackets
== 0)
3371 continue; /* parameter loop */
3373 if (ch
== '(' && !brackets
)
3375 if (ch
== ')' && brackets
<= 0)
3382 error(ERR_NONFATAL
, "braces do not "
3383 "enclose all of macro parameter");
3385 paramsize
[nparam
] += white
+ 1;
3387 } /* parameter loop */
3389 while (m
&& (m
->nparam
!= nparam
||
3390 mstrcmp(m
->name
, mname
,
3394 error(ERR_WARNING
| ERR_WARN_MNP
,
3395 "macro `%s' exists, "
3396 "but not taking %d parameters",
3397 mstart
->text
, nparam
);
3400 if (m
&& m
->in_progress
)
3402 if (!m
) /* in progess or didn't find '(' or wrong nparam */
3405 * Design question: should we handle !tline, which
3406 * indicates missing ')' here, or expand those
3407 * macros anyway, which requires the (t) test a few
3411 nasm_free(paramsize
);
3417 * Expand the macro: we are placed on the last token of the
3418 * call, so that we can easily split the call from the
3419 * following tokens. We also start by pushing an SMAC_END
3420 * token for the cycle removal.
3428 tt
= new_Token(tline
, TOK_SMAC_END
, NULL
, 0);
3430 m
->in_progress
= TRUE
;
3432 for (t
= m
->expansion
; t
; t
= t
->next
)
3434 if (t
->type
>= TOK_SMAC_PARAM
)
3436 Token
*pcopy
= tline
, **ptail
= &pcopy
;
3440 ttt
= params
[t
->type
- TOK_SMAC_PARAM
];
3441 for (i
= paramsize
[t
->type
- TOK_SMAC_PARAM
];
3445 new_Token(tline
, ttt
->type
, ttt
->text
,
3454 tt
= new_Token(tline
, t
->type
, t
->text
, 0);
3460 * Having done that, get rid of the macro call, and clean
3461 * up the parameters.
3464 nasm_free(paramsize
);
3466 continue; /* main token loop */
3471 if (tline
->type
== TOK_SMAC_END
)
3473 tline
->mac
->in_progress
= FALSE
;
3474 tline
= delete_Token(tline
);
3479 tline
= tline
->next
;
3487 * Now scan the entire line and look for successive TOK_IDs that resulted
3488 * after expansion (they can't be produced by tokenise()). The successive
3489 * TOK_IDs should be concatenated.
3490 * Also we look for %+ tokens and concatenate the tokens before and after
3491 * them (without white spaces in between).
3497 while (t
&& t
->type
!= TOK_ID
&& t
->type
!= TOK_PREPROC_ID
)
3501 if (t
->next
->type
== TOK_ID
||
3502 t
->next
->type
== TOK_PREPROC_ID
||
3503 t
->next
->type
== TOK_NUMBER
)
3505 char *p
= nasm_strcat(t
->text
, t
->next
->text
);
3507 t
->next
= delete_Token(t
->next
);
3511 else if (t
->next
->type
== TOK_WHITESPACE
&& t
->next
->next
&&
3512 t
->next
->next
->type
== TOK_PREPROC_ID
&&
3513 strcmp(t
->next
->next
->text
, "%+") == 0)
3515 /* free the next whitespace, the %+ token and next whitespace */
3517 for (i
= 1; i
<= 3; i
++)
3519 if (!t
->next
|| (i
!= 2 && t
->next
->type
!= TOK_WHITESPACE
))
3521 t
->next
= delete_Token(t
->next
);
3527 /* If we concatenaded something, re-scan the line for macros */
3538 *org_tline
= *thead
;
3539 /* since we just gave text to org_line, don't free it */
3541 delete_Token(thead
);
3545 /* the expression expanded to empty line;
3546 we can't return NULL for some reasons
3547 we just set the line to a single WHITESPACE token. */
3548 memset(org_tline
, 0, sizeof(*org_tline
));
3549 org_tline
->text
= NULL
;
3550 org_tline
->type
= TOK_WHITESPACE
;
3559 * Similar to expand_smacro but used exclusively with macro identifiers
3560 * right before they are fetched in. The reason is that there can be
3561 * identifiers consisting of several subparts. We consider that if there
3562 * are more than one element forming the name, user wants a expansion,
3563 * otherwise it will be left as-is. Example:
3567 * the identifier %$abc will be left as-is so that the handler for %define
3568 * will suck it and define the corresponding value. Other case:
3570 * %define _%$abc cde
3572 * In this case user wants name to be expanded *before* %define starts
3573 * working, so we'll expand %$abc into something (if it has a value;
3574 * otherwise it will be left as-is) then concatenate all successive
3578 expand_id(Token
* tline
)
3580 Token
*cur
, *oldnext
= NULL
;
3582 if (!tline
|| !tline
->next
)
3587 (cur
->next
->type
== TOK_ID
||
3588 cur
->next
->type
== TOK_PREPROC_ID
|| cur
->next
->type
== TOK_NUMBER
))
3591 /* If identifier consists of just one token, don't expand */
3597 oldnext
= cur
->next
; /* Detach the tail past identifier */
3598 cur
->next
= NULL
; /* so that expand_smacro stops here */
3601 tline
= expand_smacro(tline
);
3605 /* expand_smacro possibly changhed tline; re-scan for EOL */
3607 while (cur
&& cur
->next
)
3610 cur
->next
= oldnext
;
3617 * Determine whether the given line constitutes a multi-line macro
3618 * call, and return the MMacro structure called if so. Doesn't have
3619 * to check for an initial label - that's taken care of in
3620 * expand_mmacro - but must check numbers of parameters. Guaranteed
3621 * to be called with tline->type == TOK_ID, so the putative macro
3622 * name is easy to find.
3625 is_mmacro(Token
* tline
, Token
*** params_array
)
3631 head
= mmacros
[hash(tline
->text
)];
3634 * Efficiency: first we see if any macro exists with the given
3635 * name. If not, we can return NULL immediately. _Then_ we
3636 * count the parameters, and then we look further along the
3637 * list if necessary to find the proper MMacro.
3639 for (m
= head
; m
; m
= m
->next
)
3640 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
3646 * OK, we have a potential macro. Count and demarcate the
3649 count_mmac_params(tline
->next
, &nparam
, ¶ms
);
3652 * So we know how many parameters we've got. Find the MMacro
3653 * structure that handles this number.
3657 if (m
->nparam_min
<= nparam
&& (m
->plus
|| nparam
<= m
->nparam_max
))
3660 * This one is right. Just check if cycle removal
3661 * prohibits us using it before we actually celebrate...
3667 "self-reference in multi-line macro `%s'", m
->name
);
3673 * It's right, and we can use it. Add its default
3674 * parameters to the end of our list if necessary.
3676 if (m
->defaults
&& nparam
< m
->nparam_min
+ m
->ndefs
)
3679 nasm_realloc(params
,
3680 ((m
->nparam_min
+ m
->ndefs
+ 1) * sizeof(*params
)));
3681 while (nparam
< m
->nparam_min
+ m
->ndefs
)
3683 params
[nparam
] = m
->defaults
[nparam
- m
->nparam_min
];
3688 * If we've gone over the maximum parameter count (and
3689 * we're in Plus mode), ignore parameters beyond
3692 if (m
->plus
&& nparam
> m
->nparam_max
)
3693 nparam
= m
->nparam_max
;
3695 * Then terminate the parameter list, and leave.
3698 { /* need this special case */
3699 params
= nasm_malloc(sizeof(*params
));
3702 params
[nparam
] = NULL
;
3703 *params_array
= params
;
3707 * This one wasn't right: look for the next one with the
3710 for (m
= m
->next
; m
; m
= m
->next
)
3711 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
3716 * After all that, we didn't find one with the right number of
3717 * parameters. Issue a warning, and fail to expand the macro.
3719 error(ERR_WARNING
| ERR_WARN_MNP
,
3720 "macro `%s' exists, but not taking %d parameters",
3721 tline
->text
, nparam
);
3727 * Expand the multi-line macro call made by the given line, if
3728 * there is one to be expanded. If there is, push the expansion on
3729 * istk->expansion and return 1. Otherwise return 0.
3732 expand_mmacro(Token
* tline
)
3734 Token
*startline
= tline
;
3735 Token
*label
= NULL
;
3736 int dont_prepend
= 0;
3737 Token
**params
, *t
, *tt
;
3740 int i
, nparam
, *paramlen
;
3744 if (!tok_type_(t
, TOK_ID
))
3746 m
= is_mmacro(t
, ¶ms
);
3751 * We have an id which isn't a macro call. We'll assume
3752 * it might be a label; we'll also check to see if a
3753 * colon follows it. Then, if there's another id after
3754 * that lot, we'll check it again for macro-hood.
3758 if (tok_type_(t
, TOK_WHITESPACE
))
3759 last
= t
, t
= t
->next
;
3760 if (tok_is_(t
, ":"))
3763 last
= t
, t
= t
->next
;
3764 if (tok_type_(t
, TOK_WHITESPACE
))
3765 last
= t
, t
= t
->next
;
3767 if (!tok_type_(t
, TOK_ID
) || (m
= is_mmacro(t
, ¶ms
)) == NULL
)
3774 * Fix up the parameters: this involves stripping leading and
3775 * trailing whitespace, then stripping braces if they are
3778 for (nparam
= 0; params
[nparam
]; nparam
++)
3780 paramlen
= nparam
? nasm_malloc(nparam
* sizeof(*paramlen
)) : NULL
;
3782 for (i
= 0; params
[i
]; i
++)
3785 int comma
= (!m
->plus
|| i
< nparam
- 1);
3789 if (tok_is_(t
, "{"))
3790 t
= t
->next
, brace
= TRUE
, comma
= FALSE
;
3795 if (comma
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, ","))
3796 break; /* ... because we have hit a comma */
3797 if (comma
&& t
->type
== TOK_WHITESPACE
&& tok_is_(t
->next
, ","))
3798 break; /* ... or a space then a comma */
3799 if (brace
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "}"))
3800 break; /* ... or a brace */
3807 * OK, we have a MMacro structure together with a set of
3808 * parameters. We must now go through the expansion and push
3809 * copies of each Line on to istk->expansion. Substitution of
3810 * parameter tokens and macro-local tokens doesn't get done
3811 * until the single-line macro substitution process; this is
3812 * because delaying them allows us to change the semantics
3813 * later through %rotate.
3815 * First, push an end marker on to istk->expansion, mark this
3816 * macro as in progress, and set up its invocation-specific
3819 ll
= nasm_malloc(sizeof(Line
));
3820 ll
->next
= istk
->expansion
;
3823 istk
->expansion
= ll
;
3825 m
->in_progress
= TRUE
;
3830 m
->paramlen
= paramlen
;
3831 m
->unique
= unique
++;
3834 m
->next_active
= istk
->mstk
;
3837 for (l
= m
->expansion
; l
; l
= l
->next
)
3841 ll
= nasm_malloc(sizeof(Line
));
3842 ll
->finishes
= NULL
;
3843 ll
->next
= istk
->expansion
;
3844 istk
->expansion
= ll
;
3847 for (t
= l
->first
; t
; t
= t
->next
)
3850 if (t
->type
== TOK_PREPROC_ID
&&
3851 t
->text
[1] == '0' && t
->text
[2] == '0')
3858 tt
= *tail
= new_Token(NULL
, x
->type
, x
->text
, 0);
3865 * If we had a label, push it on as the first line of
3866 * the macro expansion.
3870 if (dont_prepend
< 0)
3871 free_tlist(startline
);
3874 ll
= nasm_malloc(sizeof(Line
));
3875 ll
->finishes
= NULL
;
3876 ll
->next
= istk
->expansion
;
3877 istk
->expansion
= ll
;
3878 ll
->first
= startline
;
3882 label
= label
->next
;
3883 label
->next
= tt
= new_Token(NULL
, TOK_OTHER
, ":", 0);
3888 list
->uplevel(m
->nolist
? LIST_MACRO_NOLIST
: LIST_MACRO
);
3894 * Since preprocessor always operate only on the line that didn't
3895 * arrived yet, we should always use ERR_OFFBY1. Also since user
3896 * won't want to see same error twice (preprocessing is done once
3897 * per pass) we will want to show errors only during pass one.
3900 error(int severity
, char *fmt
, ...)
3905 /* If we're in a dead branch of IF or something like it, ignore the error */
3906 if (istk
->conds
&& !emitting(istk
->conds
->state
))
3910 vsprintf(buff
, fmt
, arg
);
3913 if (istk
->mstk
&& istk
->mstk
->name
)
3914 __error(severity
| ERR_PASS1
, "(%s:%d) %s", istk
->mstk
->name
,
3915 istk
->mstk
->lineno
, buff
);
3917 __error(severity
| ERR_PASS1
, "%s", buff
);
3921 pp_reset(char *file
, int apass
, efunc errfunc
, evalfunc eval
,
3928 istk
= nasm_malloc(sizeof(Include
));
3931 istk
->expansion
= NULL
;
3933 istk
->fp
= fopen(file
, "r");
3935 src_set_fname(nasm_strdup(file
));
3939 error(ERR_FATAL
| ERR_NOFILE
, "unable to open input file `%s'", file
);
3941 for (h
= 0; h
< NHASH
; h
++)
3947 if (tasm_compatible_mode
) {
3950 stdmacpos
= &stdmac
[TASM_MACRO_COUNT
];
3952 any_extrastdmac
= (extrastdmac
!= NULL
);
3967 * Fetch a tokenised line, either from the macro-expansion
3968 * buffer or from the input file.
3971 while (istk
->expansion
&& istk
->expansion
->finishes
)
3973 Line
*l
= istk
->expansion
;
3974 if (!l
->finishes
->name
&& l
->finishes
->in_progress
> 1)
3979 * This is a macro-end marker for a macro with no
3980 * name, which means it's not really a macro at all
3981 * but a %rep block, and the `in_progress' field is
3982 * more than 1, meaning that we still need to
3983 * repeat. (1 means the natural last repetition; 0
3984 * means termination by %exitrep.) We have
3985 * therefore expanded up to the %endrep, and must
3986 * push the whole block on to the expansion buffer
3987 * again. We don't bother to remove the macro-end
3988 * marker: we'd only have to generate another one
3991 l
->finishes
->in_progress
--;
3992 for (l
= l
->finishes
->expansion
; l
; l
= l
->next
)
3994 Token
*t
, *tt
, **tail
;
3996 ll
= nasm_malloc(sizeof(Line
));
3997 ll
->next
= istk
->expansion
;
3998 ll
->finishes
= NULL
;
4002 for (t
= l
->first
; t
; t
= t
->next
)
4004 if (t
->text
|| t
->type
== TOK_WHITESPACE
)
4006 tt
= *tail
= new_Token(NULL
, t
->type
, t
->text
, 0);
4011 istk
->expansion
= ll
;
4017 * Check whether a `%rep' was started and not ended
4018 * within this macro expansion. This can happen and
4019 * should be detected. It's a fatal error because
4020 * I'm too confused to work out how to recover
4026 error(ERR_PANIC
, "defining with name in expansion");
4027 else if (istk
->mstk
->name
)
4028 error(ERR_FATAL
, "`%%rep' without `%%endrep' within"
4029 " expansion of macro `%s'", istk
->mstk
->name
);
4033 * FIXME: investigate the relationship at this point between
4034 * istk->mstk and l->finishes
4037 MMacro
*m
= istk
->mstk
;
4038 istk
->mstk
= m
->next_active
;
4042 * This was a real macro call, not a %rep, and
4043 * therefore the parameter information needs to
4046 nasm_free(m
->params
);
4047 free_tlist(m
->iline
);
4048 nasm_free(m
->paramlen
);
4049 l
->finishes
->in_progress
= FALSE
;
4054 istk
->expansion
= l
->next
;
4056 list
->downlevel(LIST_MACRO
);
4060 { /* until we get a line we can use */
4062 if (istk
->expansion
)
4063 { /* from a macro expansion */
4065 Line
*l
= istk
->expansion
;
4067 istk
->mstk
->lineno
++;
4069 istk
->expansion
= l
->next
;
4071 p
= detoken(tline
, FALSE
);
4072 list
->line(LIST_MACRO
, p
);
4078 { /* from the current input file */
4079 line
= prepreproc(line
);
4080 tline
= tokenise(line
);
4085 * The current file has ended; work down the istk
4091 error(ERR_FATAL
, "expected `%%endif' before end of file");
4093 list
->downlevel(LIST_INCLUDE
);
4094 src_set_linnum(i
->lineno
);
4095 nasm_free(src_set_fname(i
->fname
));
4103 * We must expand MMacro parameters and MMacro-local labels
4104 * _before_ we plunge into directive processing, to cope
4105 * with things like `%define something %1' such as STRUC
4106 * uses. Unless we're _defining_ a MMacro, in which case
4107 * those tokens should be left alone to go into the
4108 * definition; and unless we're in a non-emitting
4109 * condition, in which case we don't want to meddle with
4112 if (!defining
&& !(istk
->conds
&& !emitting(istk
->conds
->state
)))
4113 tline
= expand_mmac_params(tline
);
4116 * Check the line to see if it's a preprocessor directive.
4118 if (do_directive(tline
) & 1)
4125 * We're defining a multi-line macro. We emit nothing
4127 * shove the tokenised line on to the macro definition.
4129 Line
*l
= nasm_malloc(sizeof(Line
));
4130 l
->next
= defining
->expansion
;
4132 l
->finishes
= FALSE
;
4133 defining
->expansion
= l
;
4136 else if (istk
->conds
&& !emitting(istk
->conds
->state
))
4139 * We're in a non-emitting branch of a condition block.
4140 * Emit nothing at all, not even a blank line: when we
4141 * emerge from the condition we'll give a line-number
4142 * directive so we keep our place correctly.
4147 else if (istk
->mstk
&& !istk
->mstk
->in_progress
)
4150 * We're in a %rep block which has been terminated, so
4151 * we're walking through to the %endrep without
4152 * emitting anything. Emit nothing at all, not even a
4153 * blank line: when we emerge from the %rep block we'll
4154 * give a line-number directive so we keep our place
4162 tline
= expand_smacro(tline
);
4163 if (!expand_mmacro(tline
))
4166 * De-tokenise the line again, and emit it.
4168 line
= detoken(tline
, TRUE
);
4174 continue; /* expand_mmacro calls free_tlist */
4183 pp_cleanup(int pass
)
4189 error(ERR_NONFATAL
, "end of file while still defining macro `%s'",
4191 free_mmacro(defining
);
4195 for (h
= 0; h
< NHASH
; h
++)
4199 MMacro
*m
= mmacros
[h
];
4200 mmacros
[h
] = mmacros
[h
]->next
;
4205 SMacro
*s
= smacros
[h
];
4206 smacros
[h
] = smacros
[h
]->next
;
4208 free_tlist(s
->expansion
);
4217 nasm_free(i
->fname
);
4230 pp_include_path(char *path
)
4234 i
= nasm_malloc(sizeof(IncPath
));
4235 i
->path
= nasm_strdup(path
);
4241 pp_pre_include(char *fname
)
4243 Token
*inc
, *space
, *name
;
4246 name
= new_Token(NULL
, TOK_INTERNAL_STRING
, fname
, 0);
4247 space
= new_Token(name
, TOK_WHITESPACE
, NULL
, 0);
4248 inc
= new_Token(space
, TOK_PREPROC_ID
, "%include", 0);
4250 l
= nasm_malloc(sizeof(Line
));
4253 l
->finishes
= FALSE
;
4258 pp_pre_define(char *definition
)
4264 equals
= strchr(definition
, '=');
4265 space
= new_Token(NULL
, TOK_WHITESPACE
, NULL
, 0);
4266 def
= new_Token(space
, TOK_PREPROC_ID
, "%define", 0);
4269 space
->next
= tokenise(definition
);
4273 l
= nasm_malloc(sizeof(Line
));
4276 l
->finishes
= FALSE
;
4281 pp_pre_undefine(char *definition
)
4286 space
= new_Token(NULL
, TOK_WHITESPACE
, NULL
, 0);
4287 def
= new_Token(space
, TOK_PREPROC_ID
, "%undef", 0);
4289 l
= nasm_malloc(sizeof(Line
));
4292 l
->finishes
= FALSE
;
4297 pp_extra_stdmac(char **macros
)
4299 extrastdmac
= macros
;
4303 make_tok_num(Token
* tok
, long val
)
4306 sprintf(numbuf
, "%ld", val
);
4307 tok
->text
= nasm_strdup(numbuf
);
4308 tok
->type
= TOK_NUMBER
;