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 Line Line
;
52 typedef struct Include Include
;
53 typedef struct Cond Cond
;
54 typedef struct IncPath IncPath
;
57 * Store the definition of a single-line macro.
70 * Store the definition of a multi-line macro. This is also used to
71 * store the interiors of `%rep...%endrep' blocks, which are
72 * effectively self-re-invoking multi-line macros which simply
73 * don't have a name or bother to appear in the hash tables. %rep
74 * blocks are signified by having a NULL `name' field.
76 * In a MMacro describing a `%rep' block, the `in_progress' field
77 * isn't merely boolean, but gives the number of repeats left to
80 * The `next' field is used for storing MMacros in hash tables; the
81 * `next_active' field is for stacking them on istk entries.
83 * When a MMacro is being expanded, `params', `iline', `nparam',
84 * `paramlen', `rotate' and `unique' are local to the invocation.
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.
117 unsigned long number
;
121 * This is the internal form which we break input lines up into.
122 * Typically stored in linked lists.
124 * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
125 * necessarily used as-is, but is intended to denote the number of
126 * the substituted parameter. So in the definition
128 * %define a(x,y) ( (x) & ~(y) )
130 * the token representing `x' will have its type changed to
131 * TOK_SMAC_PARAM, but the one representing `y' will be
134 * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
135 * which doesn't need quotes around it. Used in the pre-include
136 * mechanism as an alternative to trying to find a sensible type of
137 * quote to use on the filename we were passed.
143 SMacro
*mac
; /* associated macro for TOK_SMAC_END */
148 TOK_WHITESPACE
= 1, TOK_COMMENT
, TOK_ID
, TOK_PREPROC_ID
, TOK_STRING
,
149 TOK_NUMBER
, TOK_SMAC_END
, TOK_OTHER
, TOK_SMAC_PARAM
,
154 * Multi-line macro definitions are stored as a linked list of
155 * these, which is essentially a container to allow several linked
158 * Note that in this module, linked lists are treated as stacks
159 * wherever possible. For this reason, Lines are _pushed_ on to the
160 * `expansion' field in MMacro structures, so that the linked list,
161 * if walked, would give the macro lines in reverse order; this
162 * means that we can walk the list when expanding a macro, and thus
163 * push the lines on to the `expansion' field in _istk_ in reverse
164 * order (so that when popped back off they are in the right
165 * order). It may seem cockeyed, and it relies on my design having
166 * an even number of steps in, but it works...
168 * Some of these structures, rather than being actual lines, are
169 * markers delimiting the end of the expansion of a given macro.
170 * This is for use in the cycle-tracking and %rep-handling code.
171 * Such structures have `finishes' non-NULL, and `first' NULL. All
172 * others have `finishes' NULL, but `first' may still be NULL if
183 * To handle an arbitrary level of file inclusion, we maintain a
184 * stack (ie linked list) of these things.
194 MMacro
*mstk
; /* stack of active macros/reps */
198 * Include search path. This is simply a list of strings which get
199 * prepended, in turn, to the name of an include file, in an
200 * attempt to find the file if it's not in the current directory.
209 * Conditional assembly: we maintain a separate stack of these for
210 * each level of file inclusion. (The only reason we keep the
211 * stacks separate is to ensure that a stray `%endif' in a file
212 * included from within the true branch of a `%if' won't terminate
213 * it and cause confusion: instead, rightly, it'll cause an error.)
223 * These states are for use just after %if or %elif: IF_TRUE
224 * means the condition has evaluated to truth so we are
225 * currently emitting, whereas IF_FALSE means we are not
226 * currently emitting but will start doing so if a %else comes
227 * up. In these states, all directives are admissible: %elif,
228 * %else and %endif. (And of course %if.)
230 COND_IF_TRUE
, COND_IF_FALSE
,
232 * These states come up after a %else: ELSE_TRUE means we're
233 * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
234 * any %elif or %else will cause an error.
236 COND_ELSE_TRUE
, COND_ELSE_FALSE
,
238 * This state means that we're not emitting now, and also that
239 * nothing until %endif will be emitted at all. It's for use in
240 * two circumstances: (i) when we've had our moment of emission
241 * and have now started seeing %elifs, and (ii) when the
242 * condition construct in question is contained within a
243 * non-emitting branch of a larger condition construct.
247 #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
250 * Condition codes. Note that we use c_ prefix not C_ because C_ is
251 * used in nasm.h for the "real" condition codes. At _this_ level,
252 * we treat CXZ and ECXZ as condition codes, albeit non-invertible
253 * ones, so we need a different enum...
255 static char *conditions
[] = {
256 "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
257 "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
258 "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
262 c_A
, c_AE
, c_B
, c_BE
, c_C
, c_CXZ
, c_E
, c_ECXZ
, c_G
, c_GE
, c_L
, c_LE
,
263 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, c_NE
, c_NG
, c_NGE
, c_NL
, c_NLE
, c_NO
,
264 c_NP
, c_NS
, c_NZ
, c_O
, c_P
, c_PE
, c_PO
, c_S
, c_Z
266 static int inverse_ccs
[] = {
267 c_NA
, c_NAE
, c_NB
, c_NBE
, c_NC
, -1, c_NE
, -1, c_NG
, c_NGE
, c_NL
, c_NLE
,
268 c_A
, c_AE
, c_B
, c_BE
, c_C
, c_E
, c_G
, c_GE
, c_L
, c_LE
, c_O
, c_P
, c_S
,
269 c_Z
, c_NO
, c_NP
, c_PO
, c_PE
, c_NS
, c_NZ
275 static char *directives
[] = {
277 "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
278 "%elifid", "%elifidn", "%elifidni", "%elifnctx", "%elifndef",
279 "%elifnid", "%elifnidn", "%elifnidni", "%elifnnum", "%elifnstr",
280 "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
281 "%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
282 "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifnctx",
283 "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnnum",
284 "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
285 "%ixdefine", "%line",
287 "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
289 "%strlen", "%substr", "%undef", "%xdefine"
294 PP_ASSIGN
, PP_CLEAR
, PP_DEFINE
, PP_ELIF
, PP_ELIFCTX
, PP_ELIFDEF
,
295 PP_ELIFID
, PP_ELIFIDN
, PP_ELIFIDNI
, PP_ELIFNCTX
, PP_ELIFNDEF
,
296 PP_ELIFNID
, PP_ELIFNIDN
, PP_ELIFNIDNI
, PP_ELIFNNUM
, PP_ELIFNSTR
,
297 PP_ELIFNUM
, PP_ELIFSTR
, PP_ELSE
, PP_ENDIF
, PP_ENDM
, PP_ENDMACRO
,
298 PP_ENDREP
, PP_ERROR
, PP_EXITREP
, PP_IASSIGN
, PP_IDEFINE
, PP_IF
,
299 PP_IFCTX
, PP_IFDEF
, PP_IFID
, PP_IFIDN
, PP_IFIDNI
, PP_IFNCTX
,
300 PP_IFNDEF
, PP_IFNID
, PP_IFNIDN
, PP_IFNIDNI
, PP_IFNNUM
,
301 PP_IFNSTR
, PP_IFNUM
, PP_IFSTR
, PP_IMACRO
, PP_INCLUDE
,
302 PP_IXDEFINE
, PP_LINE
,
304 PP_MACRO
, PP_POP
, PP_PUSH
, PP_REP
, PP_REPL
, PP_ROTATE
,
306 PP_STRLEN
, PP_SUBSTR
, PP_UNDEF
, PP_XDEFINE
310 /* For TASM compatibility we need to be able to recognise TASM compatible
311 * conditional compilation directives. Using the NASM pre-processor does
312 * not work, so we look for them specifically from the following list and
313 * then jam in the equivalent NASM directive into the input stream.
317 # define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
322 TM_ARG
, TM_ELIF
, TM_ELSE
, TM_ENDIF
, TM_IF
, TM_IFDEF
, TM_IFDIFI
,
323 TM_IFNDEF
, TM_INCLUDE
, TM_LOCAL
326 static char *tasm_directives
[] = {
327 "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
328 "ifndef", "include", "local"
331 static int StackSize
= 4;
332 static char *StackPointer
= "ebp";
333 static int ArgOffset
= 8;
334 static int LocalOffset
= 4;
337 static Context
*cstk
;
338 static Include
*istk
;
339 static IncPath
*ipath
= NULL
;
341 static efunc __error
; /* Pointer to client-provided error reporting function */
342 static evalfunc evaluate
;
344 static int pass
; /* HACK: pass 0 = generate dependencies only */
346 static unsigned long unique
; /* unique identifier numbers */
348 static Line
*predef
= NULL
;
350 static ListGen
*list
;
353 * The number of hash values we use for the macro lookup tables.
354 * FIXME: We should *really* be able to configure this at run time,
355 * or even have the hash table automatically expanding when necessary.
360 * The current set of multi-line macros we have defined.
362 static MMacro
*mmacros
[NHASH
];
365 * The current set of single-line macros we have defined.
367 static SMacro
*smacros
[NHASH
];
370 * The multi-line macro we are currently defining, or the %rep
371 * block we are currently reading, if any.
373 static MMacro
*defining
;
376 * The number of macro parameters to allocate space for at a time.
378 #define PARAM_DELTA 16
381 * The standard macro set: defined as `static char *stdmac[]'. Also
382 * gives our position in the macro set, when we're processing it.
385 static char **stdmacpos
;
388 * The extra standard macros that come from the object format, if
391 static char **extrastdmac
= NULL
;
395 * Tokens are allocated in blocks to improve speed
397 #define TOKEN_BLOCKSIZE 4096
398 static Token
*freeTokens
= NULL
;
401 * Forward declarations.
403 static Token
*expand_mmac_params(Token
* tline
);
404 static Token
*expand_smacro(Token
* tline
);
405 static Token
*expand_id(Token
* tline
);
406 static Context
*get_ctx(char *name
, int all_contexts
);
407 static void make_tok_num(Token
* tok
, long val
);
408 static void error(int severity
, char *fmt
, ...);
409 static Token
*new_Token(Token
* next
, int type
, char *text
, int txtlen
);
410 static Token
*delete_Token(Token
* t
);
413 * Macros for safe checking of token pointers, avoid *(NULL)
415 #define tok_type_(x,t) ((x) && (x)->type == (t))
416 #define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
417 #define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
418 #define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
420 /* Handle TASM specific directives, which do not contain a % in
421 * front of them. We do it here because I could not find any other
422 * place to do it for the moment, and it is a hack (ideally it would
423 * be nice to be able to use the NASM pre-processor to do it).
426 check_tasm_directive(char *line
)
429 char *p
= line
, *oldline
, oldchar
;
431 /* Skip whitespace */
432 while (isspace(*p
) && *p
!= 0)
435 /* Binary search for the directive name */
437 j
= sizeof(tasm_directives
) / sizeof(*tasm_directives
);
439 while (!isspace(p
[len
]) && p
[len
] != 0)
448 m
= nasm_stricmp(p
, tasm_directives
[k
]);
451 /* We have found a directive, so jam a % in front of it
452 * so that NASM will then recognise it as one if it's own.
457 line
= nasm_malloc(len
+ 2);
461 /* NASM does not recognise IFDIFI, so we convert it to
462 * %ifdef BOGUS. This is not used in NASM comaptible
463 * code, but does need to parse for the TASM macro
466 strcpy(line
+ 1, "ifdef BOGUS");
470 memcpy(line
+ 1, p
, len
+ 1);
488 * The pre-preprocessing stage... This function translates line
489 * number indications as they emerge from GNU cpp (`# lineno "file"
490 * flags') into NASM preprocessor line number indications (`%line
494 prepreproc(char *line
)
497 char *fname
, *oldline
;
499 if (line
[0] == '#' && line
[1] == ' ')
503 lineno
= atoi(fname
);
504 fname
+= strspn(fname
, "0123456789 ");
507 fnlen
= strcspn(fname
, "\"");
508 line
= nasm_malloc(20 + fnlen
);
509 sprintf(line
, "%%line %d %.*s", lineno
, fnlen
, fname
);
512 if (tasm_compatible_mode
)
513 return check_tasm_directive(line
);
518 * The hash function for macro lookups. Note that due to some
519 * macros having case-insensitive names, the hash function must be
520 * invariant under case changes. We implement this by applying a
521 * perfectly normal hash function to the uppercase of the string.
529 * Powers of three, mod 31.
531 static const int multipliers
[] = {
532 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
533 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
539 h
+= multipliers
[i
] * (unsigned char) (toupper(*s
));
541 if (++i
>= sizeof(multipliers
) / sizeof(*multipliers
))
549 * Free a linked list of tokens.
552 free_tlist(Token
* list
)
556 list
= delete_Token(list
);
561 * Free a linked list of lines.
564 free_llist(Line
* list
)
571 free_tlist(l
->first
);
580 free_mmacro(MMacro
* m
)
583 free_tlist(m
->dlist
);
584 nasm_free(m
->defaults
);
585 free_llist(m
->expansion
);
590 * Pop the context stack.
605 free_tlist(s
->expansion
);
612 #define BUF_DELTA 512
614 * Read a line from the top file in istk, handling multiple CR/LFs
615 * at the end of the line read, and handling spurious ^Zs. Will
616 * return lines from the standard macro set if this has not already
622 char *buffer
, *p
, *q
;
629 char *ret
= nasm_strdup(*stdmacpos
++);
630 if (!*stdmacpos
&& any_extrastdmac
)
632 stdmacpos
= extrastdmac
;
633 any_extrastdmac
= FALSE
;
637 * Nasty hack: here we push the contents of `predef' on
638 * to the top-level expansion stack, since this is the
639 * most convenient way to implement the pre-include and
640 * pre-define features.
645 Token
*head
, **tail
, *t
;
647 for (pd
= predef
; pd
; pd
= pd
->next
)
651 for (t
= pd
->first
; t
; t
= t
->next
)
653 *tail
= new_Token(NULL
, t
->type
, t
->text
, 0);
654 tail
= &(*tail
)->next
;
656 l
= nasm_malloc(sizeof(Line
));
657 l
->next
= istk
->expansion
;
672 buffer
= nasm_malloc(BUF_DELTA
);
676 q
= fgets(p
, bufsize
- (p
- buffer
), istk
->fp
);
680 if (p
> buffer
&& p
[-1] == '\n')
684 if (p
- buffer
> bufsize
- 10)
686 long offset
= p
- buffer
;
687 bufsize
+= BUF_DELTA
;
688 buffer
= nasm_realloc(buffer
, bufsize
);
689 p
= buffer
+ offset
; /* prevent stale-pointer problems */
693 if (!q
&& p
== buffer
)
699 src_set_linnum(src_get_linnum() + istk
->lineinc
);
702 * Play safe: remove CRs as well as LFs, if any of either are
703 * present at the end of the line.
705 while (--p
>= buffer
&& (*p
== '\n' || *p
== '\r'))
709 * Handle spurious ^Z, which may be inserted into source files
710 * by some file transfer utilities.
712 buffer
[strcspn(buffer
, "\032")] = '\0';
714 list
->line(LIST_READ
, buffer
);
720 * Tokenise a line of text. This is a very simple process since we
721 * don't need to parse the value out of e.g. numeric tokens: we
722 * simply split one string into many.
730 Token
*t
, **tail
= &list
;
739 ((*p
== '-' || *p
== '+') && isdigit(p
[1])) ||
740 ((*p
== '+') && (isspace(p
[1]) || !p
[1])))
747 type
= TOK_PREPROC_ID
;
752 while (*p
&& *p
!= '}')
760 type
= TOK_PREPROC_ID
;
762 else if (isidchar(*p
) ||
763 ((*p
== '!' || *p
== '%' || *p
== '$') &&
770 while (isidchar(*p
));
771 type
= TOK_PREPROC_ID
;
780 else if (isidstart(*p
) || (*p
== '$' && isidstart(p
[1])))
784 while (*p
&& isidchar(*p
))
787 else if (*p
== '\'' || *p
== '"')
795 while (*p
&& *p
!= c
)
803 error(ERR_WARNING
, "unterminated string");
806 else if (isnumstart(*p
))
813 while (*p
&& isnumchar(*p
))
816 else if (isspace(*p
))
818 type
= TOK_WHITESPACE
;
820 while (*p
&& isspace(*p
))
823 * Whitespace just before end-of-line is discarded by
824 * pretending it's a comment; whitespace just before a
825 * comment gets lumped into the comment.
827 if (!*p
|| *p
== ';')
843 * Anything else is an operator of some kind. We check
844 * for all the double-character operators (>>, <<, //,
845 * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
846 * else is a single-character operator.
849 if ((p
[0] == '>' && p
[1] == '>') ||
850 (p
[0] == '<' && p
[1] == '<') ||
851 (p
[0] == '/' && p
[1] == '/') ||
852 (p
[0] == '<' && p
[1] == '=') ||
853 (p
[0] == '>' && p
[1] == '=') ||
854 (p
[0] == '=' && p
[1] == '=') ||
855 (p
[0] == '!' && p
[1] == '=') ||
856 (p
[0] == '<' && p
[1] == '>') ||
857 (p
[0] == '&' && p
[1] == '&') ||
858 (p
[0] == '|' && p
[1] == '|') ||
859 (p
[0] == '^' && p
[1] == '^'))
865 if (type
!= TOK_COMMENT
)
867 *tail
= t
= new_Token(NULL
, type
, line
, p
- line
);
878 * this function creates a new Token and passes a pointer to it
879 * back to the caller. It sets the type and text elements, and
880 * also the mac and next elements to NULL.
883 new_Token(Token
* next
, int type
, char *text
, int txtlen
)
888 if (freeTokens
== NULL
)
890 freeTokens
= nasm_malloc(TOKEN_BLOCKSIZE
* sizeof(Token
));
891 for (i
= 0; i
< TOKEN_BLOCKSIZE
- 1; i
++)
892 freeTokens
[i
].next
= &freeTokens
[i
+ 1];
893 freeTokens
[i
].next
= NULL
;
896 freeTokens
= t
->next
;
900 if (type
== TOK_WHITESPACE
|| text
== NULL
)
907 txtlen
= strlen(text
);
908 t
->text
= nasm_malloc(1 + txtlen
);
909 strncpy(t
->text
, text
, txtlen
);
910 t
->text
[txtlen
] = '\0';
916 delete_Token(Token
* t
)
918 Token
*next
= t
->next
;
920 t
->next
= freeTokens
? freeTokens
->next
: NULL
;
926 * Convert a line of tokens back into text.
927 * If expand_locals is not zero, identifiers of the form "%$*xxx"
928 * will be transformed into ..@ctxnum.xxx
931 detoken(Token
* tlist
, int expand_locals
)
938 for (t
= tlist
; t
; t
= t
->next
)
940 if (t
->type
== TOK_PREPROC_ID
&& t
->text
[1] == '!')
942 char *p
= getenv(t
->text
+ 2);
945 t
->text
= nasm_strdup(p
);
949 /* Expand local macros here and not during preprocessing */
951 t
->type
== TOK_PREPROC_ID
&& t
->text
&&
952 t
->text
[0] == '%' && t
->text
[1] == '$')
954 Context
*ctx
= get_ctx(t
->text
, FALSE
);
958 char *p
, *q
= t
->text
+ 2;
961 sprintf(buffer
, "..@%lu.", ctx
->number
);
962 p
= nasm_strcat(buffer
, q
);
967 if (t
->type
== TOK_WHITESPACE
)
973 len
+= strlen(t
->text
);
976 p
= line
= nasm_malloc(len
+ 1);
977 for (t
= tlist
; t
; t
= t
->next
)
979 if (t
->type
== TOK_WHITESPACE
)
996 * A scanner, suitable for use by the expression evaluator, which
997 * operates on a line of Tokens. Expects a pointer to a pointer to
998 * the first token in the line to be passed in as its private_data
1002 ppscan(void *private_data
, struct tokenval
*tokval
)
1004 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
[1])
1021 return tokval
->t_type
= TOKEN_BASE
;
1023 if (tline
->type
== TOK_ID
)
1025 tokval
->t_charptr
= tline
->text
;
1026 if (tline
->text
[0] == '$')
1028 tokval
->t_charptr
++;
1029 return tokval
->t_type
= TOKEN_ID
;
1033 * This is the only special case we actually need to worry
1034 * about in this restricted context.
1036 if (!nasm_stricmp(tline
->text
, "seg"))
1037 return tokval
->t_type
= TOKEN_SEG
;
1039 return tokval
->t_type
= TOKEN_ID
;
1042 if (tline
->type
== TOK_NUMBER
)
1046 tokval
->t_integer
= readnum(tline
->text
, &rn_error
);
1048 return tokval
->t_type
= TOKEN_ERRNUM
;
1049 tokval
->t_charptr
= NULL
;
1050 return tokval
->t_type
= TOKEN_NUM
;
1053 if (tline
->type
== TOK_STRING
)
1063 if (l
== 0 || r
[l
- 1] != q
)
1064 return tokval
->t_type
= TOKEN_ERRNUM
;
1065 tokval
->t_integer
= readstrnum(r
, l
- 1, &rn_warn
);
1067 error(ERR_WARNING
| ERR_PASS1
, "character constant too long");
1068 tokval
->t_charptr
= NULL
;
1069 return tokval
->t_type
= TOKEN_NUM
;
1072 if (tline
->type
== TOK_OTHER
)
1074 if (!strcmp(tline
->text
, "<<"))
1075 return tokval
->t_type
= TOKEN_SHL
;
1076 if (!strcmp(tline
->text
, ">>"))
1077 return tokval
->t_type
= TOKEN_SHR
;
1078 if (!strcmp(tline
->text
, "//"))
1079 return tokval
->t_type
= TOKEN_SDIV
;
1080 if (!strcmp(tline
->text
, "%%"))
1081 return tokval
->t_type
= TOKEN_SMOD
;
1082 if (!strcmp(tline
->text
, "=="))
1083 return tokval
->t_type
= TOKEN_EQ
;
1084 if (!strcmp(tline
->text
, "<>"))
1085 return tokval
->t_type
= TOKEN_NE
;
1086 if (!strcmp(tline
->text
, "!="))
1087 return tokval
->t_type
= TOKEN_NE
;
1088 if (!strcmp(tline
->text
, "<="))
1089 return tokval
->t_type
= TOKEN_LE
;
1090 if (!strcmp(tline
->text
, ">="))
1091 return tokval
->t_type
= TOKEN_GE
;
1092 if (!strcmp(tline
->text
, "&&"))
1093 return tokval
->t_type
= TOKEN_DBL_AND
;
1094 if (!strcmp(tline
->text
, "^^"))
1095 return tokval
->t_type
= TOKEN_DBL_XOR
;
1096 if (!strcmp(tline
->text
, "||"))
1097 return tokval
->t_type
= TOKEN_DBL_OR
;
1101 * We have no other options: just return the first character of
1104 return tokval
->t_type
= tline
->text
[0];
1108 * Compare a string to the name of an existing macro; this is a
1109 * simple wrapper which calls either strcmp or nasm_stricmp
1110 * depending on the value of the `casesense' parameter.
1113 mstrcmp(char *p
, char *q
, int casesense
)
1115 return casesense
? strcmp(p
, q
) : nasm_stricmp(p
, q
);
1119 * Return the Context structure associated with a %$ token. Return
1120 * NULL, having _already_ reported an error condition, if the
1121 * context stack isn't deep enough for the supplied number of $
1123 * If all_contexts == TRUE, contexts that enclose current are
1124 * also scanned for such smacro, until it is found; if not -
1125 * only the context that directly results from the number of $'s
1126 * in variable's name.
1129 get_ctx(char *name
, int all_contexts
)
1135 if (!name
|| name
[0] != '%' || name
[1] != '$')
1140 error(ERR_NONFATAL
, "`%s': context stack is empty", name
);
1144 for (i
= strspn(name
+ 2, "$"), ctx
= cstk
; (i
> 0) && ctx
; i
--)
1151 error(ERR_NONFATAL
, "`%s': context stack is only"
1152 " %d level%s deep", name
, i
- 1, (i
== 2 ? "" : "s"));
1160 /* Search for this smacro in found context */
1164 if (!mstrcmp(m
->name
, name
, m
->casesense
))
1174 /* Add a slash to the end of a path if it is missing. We use the
1175 * forward slash to make it compatible with Unix systems.
1180 int pos
= strlen(s
);
1181 if (s
[pos
- 1] != '\\' && s
[pos
- 1] != '/')
1189 * Open an include file. This routine must always return a valid
1190 * file pointer if it returns - it's responsible for throwing an
1191 * ERR_FATAL and bombing out completely if not. It should also try
1192 * the include path one by one until it finds the file or reaches
1193 * the end of the path.
1196 inc_fopen(char *file
)
1199 char *prefix
= "", *combine
;
1200 IncPath
*ip
= ipath
;
1201 static int namelen
= 0;
1202 int len
= strlen(file
);
1206 combine
= nasm_malloc(strlen(prefix
) + 1 + len
+ 1);
1207 strcpy(combine
, prefix
);
1210 strcat(combine
, file
);
1211 fp
= fopen(combine
, "r");
1212 if (pass
== 0 && fp
)
1214 namelen
+= strlen(combine
) + 1;
1220 printf(" %s", combine
);
1231 error(ERR_FATAL
, "unable to open include file `%s'", file
);
1232 return NULL
; /* never reached - placate compilers */
1236 * Determine if we should warn on defining a single-line macro of
1237 * name `name', with `nparam' parameters. If nparam is 0 or -1, will
1238 * return TRUE if _any_ single-line macro of that name is defined.
1239 * Otherwise, will return TRUE if a single-line macro with either
1240 * `nparam' or no parameters is defined.
1242 * If a macro with precisely the right number of parameters is
1243 * defined, or nparam is -1, the address of the definition structure
1244 * will be returned in `defn'; otherwise NULL will be returned. If `defn'
1245 * is NULL, no action will be taken regarding its contents, and no
1248 * Note that this is also called with nparam zero to resolve
1251 * If you already know which context macro belongs to, you can pass
1252 * the context pointer as first parameter; if you won't but name begins
1253 * with %$ the context will be automatically computed. If all_contexts
1254 * is true, macro will be searched in outer contexts as well.
1257 smacro_defined(Context
* ctx
, char *name
, int nparam
, SMacro
** defn
,
1264 else if (name
[0] == '%' && name
[1] == '$')
1267 ctx
= get_ctx(name
, FALSE
);
1269 return FALSE
; /* got to return _something_ */
1273 m
= smacros
[hash(name
)];
1277 if (!mstrcmp(m
->name
, name
, m
->casesense
&& nocase
) &&
1278 (nparam
<= 0 || m
->nparam
== 0 || nparam
== m
->nparam
))
1282 if (nparam
== m
->nparam
|| nparam
== -1)
1296 * Count and mark off the parameters in a multi-line macro call.
1297 * This is called both from within the multi-line macro expansion
1298 * code, and also to mark off the default parameters when provided
1299 * in a %macro definition line.
1302 count_mmac_params(Token
* t
, int *nparam
, Token
*** params
)
1304 int paramsize
, brace
;
1306 *nparam
= paramsize
= 0;
1310 if (*nparam
>= paramsize
)
1312 paramsize
+= PARAM_DELTA
;
1313 *params
= nasm_realloc(*params
, sizeof(**params
) * paramsize
);
1317 if (tok_is_(t
, "{"))
1319 (*params
)[(*nparam
)++] = t
;
1320 while (tok_isnt_(t
, brace
? "}" : ","))
1323 { /* got a comma/brace */
1328 * Now we've found the closing brace, look further
1332 if (tok_isnt_(t
, ","))
1335 "braces do not enclose all of macro parameter");
1336 while (tok_isnt_(t
, ","))
1340 t
= t
->next
; /* eat the comma */
1347 * Determine whether one of the various `if' conditions is true or
1350 * We must free the tline we get passed.
1353 if_condition(Token
* tline
, int i
)
1356 Token
*t
, *tt
, **tptr
, *origline
;
1357 struct tokenval tokval
;
1368 j
= FALSE
; /* have we matched yet? */
1369 while (cstk
&& tline
)
1372 if (!tline
|| tline
->type
!= TOK_ID
)
1375 "`%s' expects context identifiers",
1377 free_tlist(origline
);
1380 if (!nasm_stricmp(tline
->text
, cstk
->name
))
1382 tline
= tline
->next
;
1384 if (i
== PP_IFNCTX
|| i
== PP_ELIFNCTX
)
1386 free_tlist(origline
);
1393 j
= FALSE
; /* have we matched yet? */
1397 if (!tline
|| (tline
->type
!= TOK_ID
&&
1398 (tline
->type
!= TOK_PREPROC_ID
||
1399 tline
->text
[1] != '$')))
1402 "`%%if%sdef' expects macro identifiers",
1403 (i
== PP_ELIFNDEF
? "n" : ""));
1404 free_tlist(origline
);
1407 if (smacro_defined(NULL
, tline
->text
, 0, NULL
, 1))
1409 tline
= tline
->next
;
1411 if (i
== PP_IFNDEF
|| i
== PP_ELIFNDEF
)
1413 free_tlist(origline
);
1424 tline
= expand_smacro(tline
);
1426 while (tok_isnt_(tt
, ","))
1431 "`%s' expects two comma-separated arguments",
1437 casesense
= (i
== PP_IFIDN
|| i
== PP_ELIFIDN
||
1438 i
== PP_IFNIDN
|| i
== PP_ELIFNIDN
);
1439 j
= TRUE
; /* assume equality unless proved not */
1440 while ((t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ",")) && tt
)
1442 if (tt
->type
== TOK_OTHER
&& !strcmp(tt
->text
, ","))
1444 error(ERR_NONFATAL
, "`%s': more than one comma on line",
1449 if (t
->type
== TOK_WHITESPACE
)
1454 else if (tt
->type
== TOK_WHITESPACE
)
1459 else if (tt
->type
!= t
->type
||
1460 mstrcmp(tt
->text
, t
->text
, casesense
))
1462 j
= FALSE
; /* found mismatching tokens */
1472 if ((t
->type
!= TOK_OTHER
|| strcmp(t
->text
, ",")) || tt
)
1473 j
= FALSE
; /* trailing gunk on one end or other */
1474 if (i
== PP_IFNIDN
|| i
== PP_ELIFNIDN
||
1475 i
== PP_IFNIDNI
|| i
== PP_ELIFNIDNI
)
1492 tline
= expand_smacro(tline
);
1494 while (tok_type_(t
, TOK_WHITESPACE
))
1496 j
= FALSE
; /* placate optimiser */
1504 j
= (t
->type
== TOK_ID
);
1510 j
= (t
->type
== TOK_NUMBER
);
1516 j
= (t
->type
== TOK_STRING
);
1519 if (i
== PP_IFNID
|| i
== PP_ELIFNID
||
1520 i
== PP_IFNNUM
|| i
== PP_ELIFNNUM
||
1521 i
== PP_IFNSTR
|| i
== PP_ELIFNSTR
)
1528 t
= tline
= expand_smacro(tline
);
1530 tokval
.t_type
= TOKEN_INVALID
;
1531 evalresult
= evaluate(ppscan
, tptr
, &tokval
,
1532 NULL
, pass
| CRITICAL
, error
, NULL
);
1538 "trailing garbage after expression ignored");
1539 if (!is_simple(evalresult
))
1542 "non-constant value given to `%s'", directives
[i
]);
1545 return reloc_value(evalresult
) != 0;
1549 "preprocessor directive `%s' not yet implemented",
1551 free_tlist(origline
);
1552 return -1; /* yeah, right */
1557 * Expand macros in a string. Used in %error and %include directives.
1558 * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
1559 * The returned variable should ALWAYS be freed after usage.
1562 expand_macros_in_string(char **p
)
1564 Token
*line
= tokenise(*p
);
1565 line
= expand_smacro(line
);
1566 *p
= detoken(line
, FALSE
);
1570 * Find out if a line contains a preprocessor directive, and deal
1573 * If a directive _is_ found, we are expected to free_tlist() the
1576 * Return values go like this:
1578 * bit 0 is set if a directive was found (so the line gets freed)
1581 do_directive(Token
* tline
)
1583 int i
, j
, k
, m
, nparam
, nolist
;
1589 SMacro
*smac
, **smhead
;
1591 Token
*t
, *tt
, *param_start
, *macro_start
, *last
, **tptr
, *origline
;
1593 struct tokenval tokval
;
1595 MMacro
*tmp_defining
; /* Used when manipulating rep_nest */
1600 if (!tok_type_(tline
, TOK_PREPROC_ID
) ||
1601 (tline
->text
[1] == '%' || tline
->text
[1] == '$'
1602 || tline
->text
[1] == '!'))
1606 j
= sizeof(directives
) / sizeof(*directives
);
1610 m
= nasm_stricmp(tline
->text
, directives
[k
]);
1612 if (tasm_compatible_mode
) {
1615 } else if (k
!= PP_ARG
&& k
!= PP_LOCAL
&& k
!= PP_STACKSIZE
) {
1629 * If we're in a non-emitting branch of a condition construct,
1630 * or walking to the end of an already terminated %rep block,
1631 * we should ignore all directives except for condition
1634 if (((istk
->conds
&& !emitting(istk
->conds
->state
)) ||
1635 (istk
->mstk
&& !istk
->mstk
->in_progress
)) &&
1636 i
!= PP_IF
&& i
!= PP_ELIF
&&
1637 i
!= PP_IFCTX
&& i
!= PP_ELIFCTX
&&
1638 i
!= PP_IFDEF
&& i
!= PP_ELIFDEF
&&
1639 i
!= PP_IFID
&& i
!= PP_ELIFID
&&
1640 i
!= PP_IFIDN
&& i
!= PP_ELIFIDN
&&
1641 i
!= PP_IFIDNI
&& i
!= PP_ELIFIDNI
&&
1642 i
!= PP_IFNCTX
&& i
!= PP_ELIFNCTX
&&
1643 i
!= PP_IFNDEF
&& i
!= PP_ELIFNDEF
&&
1644 i
!= PP_IFNID
&& i
!= PP_ELIFNID
&&
1645 i
!= PP_IFNIDN
&& i
!= PP_ELIFNIDN
&&
1646 i
!= PP_IFNIDNI
&& i
!= PP_ELIFNIDNI
&&
1647 i
!= PP_IFNNUM
&& i
!= PP_ELIFNNUM
&&
1648 i
!= PP_IFNSTR
&& i
!= PP_ELIFNSTR
&&
1649 i
!= PP_IFNUM
&& i
!= PP_ELIFNUM
&&
1650 i
!= PP_IFSTR
&& i
!= PP_ELIFSTR
&& i
!= PP_ELSE
&& i
!= PP_ENDIF
)
1656 * If we're defining a macro or reading a %rep block, we should
1657 * ignore all directives except for %macro/%imacro (which
1658 * generate an error), %endm/%endmacro, and (only if we're in a
1659 * %rep block) %endrep. If we're in a %rep block, another %rep
1660 * causes an error, so should be let through.
1662 if (defining
&& i
!= PP_MACRO
&& i
!= PP_IMACRO
&&
1663 i
!= PP_ENDMACRO
&& i
!= PP_ENDM
&&
1664 (defining
->name
|| (i
!= PP_ENDREP
&& i
!= PP_REP
)))
1671 error(ERR_NONFATAL
, "unknown preprocessor directive `%s'",
1673 return 0; /* didn't get it */
1679 /* Directive to tell NASM what the default stack size is. The
1680 * default is for a 16-bit stack, and this can be overriden with
1682 * the following form:
1684 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1686 tline
= tline
->next
;
1687 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1688 tline
= tline
->next
;
1689 if (!tline
|| tline
->type
!= TOK_ID
)
1691 error(ERR_NONFATAL
, "`%%stacksize' missing size parameter");
1692 free_tlist(origline
);
1695 if (nasm_stricmp(tline
->text
, "flat") == 0)
1697 /* All subsequent ARG directives are for a 32-bit stack */
1699 StackPointer
= "ebp";
1703 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";
1713 else if (nasm_stricmp(tline
->text
, "small") == 0)
1715 /* All subsequent ARG directives are for a 16-bit stack,
1716 * far function call. We don't support near functions.
1719 StackPointer
= "bp";
1725 error(ERR_NONFATAL
, "`%%stacksize' invalid size type");
1726 free_tlist(origline
);
1729 free_tlist(origline
);
1733 /* TASM like ARG directive to define arguments to functions, in
1734 * the following form:
1736 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1741 char *arg
, directive
[256];
1742 int size
= StackSize
;
1744 /* Find the argument name */
1745 tline
= tline
->next
;
1746 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1747 tline
= tline
->next
;
1748 if (!tline
|| tline
->type
!= TOK_ID
)
1750 error(ERR_NONFATAL
, "`%%arg' missing argument parameter");
1751 free_tlist(origline
);
1756 /* Find the argument size type */
1757 tline
= tline
->next
;
1758 if (!tline
|| tline
->type
!= TOK_OTHER
1759 || tline
->text
[0] != ':')
1762 "Syntax error processing `%%arg' directive");
1763 free_tlist(origline
);
1766 tline
= tline
->next
;
1767 if (!tline
|| tline
->type
!= TOK_ID
)
1770 "`%%arg' missing size type parameter");
1771 free_tlist(origline
);
1775 /* Allow macro expansion of type parameter */
1776 tt
= tokenise(tline
->text
);
1777 tt
= expand_smacro(tt
);
1778 if (nasm_stricmp(tt
->text
, "byte") == 0)
1780 size
= MAX(StackSize
, 1);
1782 else if (nasm_stricmp(tt
->text
, "word") == 0)
1784 size
= MAX(StackSize
, 2);
1786 else if (nasm_stricmp(tt
->text
, "dword") == 0)
1788 size
= MAX(StackSize
, 4);
1790 else if (nasm_stricmp(tt
->text
, "qword") == 0)
1792 size
= MAX(StackSize
, 8);
1794 else if (nasm_stricmp(tt
->text
, "tword") == 0)
1796 size
= MAX(StackSize
, 10);
1801 "Invalid size type for `%%arg' missing directive");
1803 free_tlist(origline
);
1808 /* Now define the macro for the argument */
1809 sprintf(directive
, "%%define %s (%s+%d)", arg
, StackPointer
,
1811 do_directive(tokenise(directive
));
1814 /* Move to the next argument in the list */
1815 tline
= tline
->next
;
1816 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1817 tline
= tline
->next
;
1819 while (tline
&& tline
->type
== TOK_OTHER
1820 && tline
->text
[0] == ',');
1821 free_tlist(origline
);
1825 /* TASM like LOCAL directive to define local variables for a
1826 * function, in the following form:
1828 * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1830 * The '= LocalSize' at the end is ignored by NASM, but is
1831 * required by TASM to define the local parameter size (and used
1832 * by the TASM macro package).
1834 offset
= LocalOffset
;
1837 char *local
, directive
[256];
1838 int size
= StackSize
;
1840 /* Find the argument name */
1841 tline
= tline
->next
;
1842 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1843 tline
= tline
->next
;
1844 if (!tline
|| tline
->type
!= TOK_ID
)
1847 "`%%local' missing argument parameter");
1848 free_tlist(origline
);
1851 local
= tline
->text
;
1853 /* Find the argument size type */
1854 tline
= tline
->next
;
1855 if (!tline
|| tline
->type
!= TOK_OTHER
1856 || tline
->text
[0] != ':')
1859 "Syntax error processing `%%local' directive");
1860 free_tlist(origline
);
1863 tline
= tline
->next
;
1864 if (!tline
|| tline
->type
!= TOK_ID
)
1867 "`%%local' missing size type parameter");
1868 free_tlist(origline
);
1872 /* Allow macro expansion of type parameter */
1873 tt
= tokenise(tline
->text
);
1874 tt
= expand_smacro(tt
);
1875 if (nasm_stricmp(tt
->text
, "byte") == 0)
1877 size
= MAX(StackSize
, 1);
1879 else if (nasm_stricmp(tt
->text
, "word") == 0)
1881 size
= MAX(StackSize
, 2);
1883 else if (nasm_stricmp(tt
->text
, "dword") == 0)
1885 size
= MAX(StackSize
, 4);
1887 else if (nasm_stricmp(tt
->text
, "qword") == 0)
1889 size
= MAX(StackSize
, 8);
1891 else if (nasm_stricmp(tt
->text
, "tword") == 0)
1893 size
= MAX(StackSize
, 10);
1898 "Invalid size type for `%%local' missing directive");
1900 free_tlist(origline
);
1905 /* Now define the macro for the argument */
1906 sprintf(directive
, "%%define %s (%s-%d)", local
, StackPointer
,
1908 do_directive(tokenise(directive
));
1911 /* Now define the assign to setup the enter_c macro correctly */
1912 sprintf(directive
, "%%assign %%$localsize %%$localsize+%d",
1914 do_directive(tokenise(directive
));
1916 /* Move to the next argument in the list */
1917 tline
= tline
->next
;
1918 if (tline
&& tline
->type
== TOK_WHITESPACE
)
1919 tline
= tline
->next
;
1921 while (tline
&& tline
->type
== TOK_OTHER
1922 && tline
->text
[0] == ',');
1923 free_tlist(origline
);
1929 "trailing garbage after `%%clear' ignored");
1930 for (j
= 0; j
< NHASH
; j
++)
1934 MMacro
*m
= mmacros
[j
];
1935 mmacros
[j
] = m
->next
;
1940 SMacro
*s
= smacros
[j
];
1941 smacros
[j
] = smacros
[j
]->next
;
1943 free_tlist(s
->expansion
);
1947 free_tlist(origline
);
1951 tline
= tline
->next
;
1953 if (!tline
|| (tline
->type
!= TOK_STRING
&&
1954 tline
->type
!= TOK_INTERNAL_STRING
))
1956 error(ERR_NONFATAL
, "`%%include' expects a file name");
1957 free_tlist(origline
);
1958 return 3; /* but we did _something_ */
1962 "trailing garbage after `%%include' ignored");
1963 if (tline
->type
!= TOK_INTERNAL_STRING
)
1965 p
= tline
->text
+ 1; /* point past the quote to the name */
1966 p
[strlen(p
) - 1] = '\0'; /* remove the trailing quote */
1969 p
= tline
->text
; /* internal_string is easier */
1970 expand_macros_in_string(&p
);
1971 inc
= nasm_malloc(sizeof(Include
));
1974 inc
->fp
= inc_fopen(p
);
1975 inc
->fname
= src_set_fname(p
);
1976 inc
->lineno
= src_set_linnum(0);
1978 inc
->expansion
= NULL
;
1981 list
->uplevel(LIST_INCLUDE
);
1982 free_tlist(origline
);
1986 tline
= tline
->next
;
1988 tline
= expand_id(tline
);
1989 if (!tok_type_(tline
, TOK_ID
))
1991 error(ERR_NONFATAL
, "`%%push' expects a context identifier");
1992 free_tlist(origline
);
1993 return 3; /* but we did _something_ */
1996 error(ERR_WARNING
, "trailing garbage after `%%push' ignored");
1997 ctx
= nasm_malloc(sizeof(Context
));
1999 ctx
->localmac
= NULL
;
2000 ctx
->name
= nasm_strdup(tline
->text
);
2001 ctx
->number
= unique
++;
2003 free_tlist(origline
);
2007 tline
= tline
->next
;
2009 tline
= expand_id(tline
);
2010 if (!tok_type_(tline
, TOK_ID
))
2012 error(ERR_NONFATAL
, "`%%repl' expects a context identifier");
2013 free_tlist(origline
);
2014 return 3; /* but we did _something_ */
2017 error(ERR_WARNING
, "trailing garbage after `%%repl' ignored");
2019 error(ERR_NONFATAL
, "`%%repl': context stack is empty");
2022 nasm_free(cstk
->name
);
2023 cstk
->name
= nasm_strdup(tline
->text
);
2025 free_tlist(origline
);
2030 error(ERR_WARNING
, "trailing garbage after `%%pop' ignored");
2033 "`%%pop': context stack is already empty");
2036 free_tlist(origline
);
2040 tline
->next
= expand_smacro(tline
->next
);
2041 tline
= tline
->next
;
2043 if (tok_type_(tline
, TOK_STRING
))
2045 p
= tline
->text
+ 1; /* point past the quote to the name */
2046 p
[strlen(p
) - 1] = '\0'; /* remove the trailing quote */
2047 expand_macros_in_string(&p
);
2048 error(ERR_NONFATAL
, "%s", p
);
2053 p
= detoken(tline
, FALSE
);
2054 error(ERR_WARNING
, "%s", p
);
2057 free_tlist(origline
);
2075 if (istk
->conds
&& !emitting(istk
->conds
->state
))
2079 j
= if_condition(tline
->next
, i
);
2080 tline
->next
= NULL
; /* it got freed */
2081 free_tlist(origline
);
2082 j
= j
< 0 ? COND_NEVER
: j
? COND_IF_TRUE
: COND_IF_FALSE
;
2084 cond
= nasm_malloc(sizeof(Cond
));
2085 cond
->next
= istk
->conds
;
2088 return (j
== COND_IF_TRUE
? 3 : 1);
2106 error(ERR_FATAL
, "`%s': no matching `%%if'", directives
[i
]);
2107 if (emitting(istk
->conds
->state
)
2108 || istk
->conds
->state
== COND_NEVER
)
2109 istk
->conds
->state
= COND_NEVER
;
2112 j
= if_condition(expand_mmac_params(tline
->next
), i
);
2113 tline
->next
= NULL
; /* it got freed */
2114 free_tlist(origline
);
2115 istk
->conds
->state
=
2116 j
< 0 ? COND_NEVER
: j
? COND_IF_TRUE
: COND_IF_FALSE
;
2118 return (istk
->conds
->state
== COND_IF_TRUE
? 5 : 1);
2122 error(ERR_WARNING
, "trailing garbage after `%%else' ignored");
2124 error(ERR_FATAL
, "`%%else': no matching `%%if'");
2125 if (emitting(istk
->conds
->state
)
2126 || istk
->conds
->state
== COND_NEVER
)
2127 istk
->conds
->state
= COND_ELSE_FALSE
;
2129 istk
->conds
->state
= COND_ELSE_TRUE
;
2130 free_tlist(origline
);
2136 "trailing garbage after `%%endif' ignored");
2138 error(ERR_FATAL
, "`%%endif': no matching `%%if'");
2140 istk
->conds
= cond
->next
;
2142 free_tlist(origline
);
2149 "`%%%smacro': already defining a macro",
2150 (i
== PP_IMACRO
? "i" : ""));
2151 tline
= tline
->next
;
2153 tline
= expand_id(tline
);
2154 if (!tok_type_(tline
, TOK_ID
))
2157 "`%%%smacro' expects a macro name",
2158 (i
== PP_IMACRO
? "i" : ""));
2161 defining
= nasm_malloc(sizeof(MMacro
));
2162 defining
->name
= nasm_strdup(tline
->text
);
2163 defining
->casesense
= (i
== PP_MACRO
);
2164 defining
->plus
= FALSE
;
2165 defining
->nolist
= FALSE
;
2166 defining
->in_progress
= FALSE
;
2167 defining
->rep_nest
= NULL
;
2168 tline
= expand_smacro(tline
->next
);
2170 if (!tok_type_(tline
, TOK_NUMBER
))
2173 "`%%%smacro' expects a parameter count",
2174 (i
== PP_IMACRO
? "i" : ""));
2175 defining
->nparam_min
= defining
->nparam_max
= 0;
2179 defining
->nparam_min
= defining
->nparam_max
=
2180 readnum(tline
->text
, &j
);
2183 "unable to parse parameter count `%s'",
2186 if (tline
&& tok_is_(tline
->next
, "-"))
2188 tline
= tline
->next
->next
;
2189 if (tok_is_(tline
, "*"))
2190 defining
->nparam_max
= INT_MAX
;
2191 else if (!tok_type_(tline
, TOK_NUMBER
))
2193 "`%%%smacro' expects a parameter count after `-'",
2194 (i
== PP_IMACRO
? "i" : ""));
2197 defining
->nparam_max
= readnum(tline
->text
, &j
);
2200 "unable to parse parameter count `%s'",
2202 if (defining
->nparam_min
> defining
->nparam_max
)
2204 "minimum parameter count exceeds maximum");
2207 if (tline
&& tok_is_(tline
->next
, "+"))
2209 tline
= tline
->next
;
2210 defining
->plus
= TRUE
;
2212 if (tline
&& tok_type_(tline
->next
, TOK_ID
) &&
2213 !nasm_stricmp(tline
->next
->text
, ".nolist"))
2215 tline
= tline
->next
;
2216 defining
->nolist
= TRUE
;
2218 mmac
= mmacros
[hash(defining
->name
)];
2221 if (!strcmp(mmac
->name
, defining
->name
) &&
2222 (mmac
->nparam_min
<= defining
->nparam_max
2224 && (defining
->nparam_min
<= mmac
->nparam_max
2228 "redefining multi-line macro `%s'",
2235 * Handle default parameters.
2237 if (tline
&& tline
->next
)
2239 defining
->dlist
= tline
->next
;
2241 count_mmac_params(defining
->dlist
, &defining
->ndefs
,
2242 &defining
->defaults
);
2246 defining
->dlist
= NULL
;
2247 defining
->defaults
= NULL
;
2249 defining
->expansion
= NULL
;
2250 free_tlist(origline
);
2257 error(ERR_NONFATAL
, "`%s': not defining a macro",
2261 k
= hash(defining
->name
);
2262 defining
->next
= mmacros
[k
];
2263 mmacros
[k
] = defining
;
2265 free_tlist(origline
);
2269 if (tline
->next
&& tline
->next
->type
== TOK_WHITESPACE
)
2270 tline
= tline
->next
;
2271 t
= expand_smacro(tline
->next
);
2273 free_tlist(origline
);
2276 tokval
.t_type
= TOKEN_INVALID
;
2278 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2284 "trailing garbage after expression ignored");
2285 if (!is_simple(evalresult
))
2287 error(ERR_NONFATAL
, "non-constant value given to `%%rotate'");
2291 while (mmac
&& !mmac
->name
) /* avoid mistaking %reps for macros */
2292 mmac
= mmac
->next_active
;
2295 "`%%rotate' invoked outside a macro call");
2296 mmac
->rotate
= mmac
->rotate
+ reloc_value(evalresult
);
2297 if (mmac
->rotate
< 0)
2298 mmac
->rotate
= mmac
->nparam
- (-mmac
->rotate
) % mmac
->nparam
;
2299 mmac
->rotate
%= mmac
->nparam
;
2304 tline
= tline
->next
;
2305 if (tline
->next
&& tline
->next
->type
== TOK_WHITESPACE
)
2306 tline
= tline
->next
;
2307 if (tline
->next
&& tline
->next
->type
== TOK_ID
&&
2308 !nasm_stricmp(tline
->next
->text
, ".nolist"))
2310 tline
= tline
->next
;
2313 t
= expand_smacro(tline
->next
);
2315 free_tlist(origline
);
2318 tokval
.t_type
= TOKEN_INVALID
;
2320 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2326 "trailing garbage after expression ignored");
2327 if (!is_simple(evalresult
))
2329 error(ERR_NONFATAL
, "non-constant value given to `%%rep'");
2332 tmp_defining
= defining
;
2333 defining
= nasm_malloc(sizeof(MMacro
));
2334 defining
->name
= NULL
; /* flags this macro as a %rep block */
2335 defining
->casesense
= 0;
2336 defining
->plus
= FALSE
;
2337 defining
->nolist
= nolist
;
2338 defining
->in_progress
= reloc_value(evalresult
) + 1;
2339 defining
->nparam_min
= defining
->nparam_max
= 0;
2340 defining
->defaults
= NULL
;
2341 defining
->dlist
= NULL
;
2342 defining
->expansion
= NULL
;
2343 defining
->next_active
= istk
->mstk
;
2344 defining
->rep_nest
= tmp_defining
;
2348 if (!defining
|| defining
->name
)
2350 error(ERR_NONFATAL
, "`%%endrep': no matching `%%rep'");
2355 * Now we have a "macro" defined - although it has no name
2356 * and we won't be entering it in the hash tables - we must
2357 * push a macro-end marker for it on to istk->expansion.
2358 * After that, it will take care of propagating itself (a
2359 * macro-end marker line for a macro which is really a %rep
2360 * block will cause the macro to be re-expanded, complete
2361 * with another macro-end marker to ensure the process
2362 * continues) until the whole expansion is forcibly removed
2363 * from istk->expansion by a %exitrep.
2365 l
= nasm_malloc(sizeof(Line
));
2366 l
->next
= istk
->expansion
;
2367 l
->finishes
= defining
;
2369 istk
->expansion
= l
;
2371 istk
->mstk
= defining
;
2373 list
->uplevel(defining
->nolist
? LIST_MACRO_NOLIST
: LIST_MACRO
);
2374 tmp_defining
= defining
;
2375 defining
= defining
->rep_nest
;
2376 free_tlist(origline
);
2381 * We must search along istk->expansion until we hit a
2382 * macro-end marker for a macro with no name. Then we set
2383 * its `in_progress' flag to 0.
2385 for (l
= istk
->expansion
; l
; l
= l
->next
)
2386 if (l
->finishes
&& !l
->finishes
->name
)
2390 l
->finishes
->in_progress
= 0;
2392 error(ERR_NONFATAL
, "`%%exitrep' not within `%%rep' block");
2393 free_tlist(origline
);
2400 tline
= tline
->next
;
2402 tline
= expand_id(tline
);
2403 if (!tline
|| (tline
->type
!= TOK_ID
&&
2404 (tline
->type
!= TOK_PREPROC_ID
||
2405 tline
->text
[1] != '$')))
2408 "`%%%s%sdefine' expects a macro identifier",
2409 ((i
== PP_IDEFINE
|| i
== PP_IXDEFINE
) ? "i" : ""),
2410 ((i
== PP_XDEFINE
|| i
== PP_IXDEFINE
) ? "x" : ""));
2411 free_tlist(origline
);
2415 ctx
= get_ctx(tline
->text
, FALSE
);
2417 smhead
= &smacros
[hash(tline
->text
)];
2419 smhead
= &ctx
->localmac
;
2420 mname
= tline
->text
;
2422 param_start
= tline
= tline
->next
;
2425 /* Expand the macro definition now for %xdefine and %ixdefine */
2426 if ((i
== PP_XDEFINE
) || (i
== PP_IXDEFINE
))
2427 tline
= expand_smacro(tline
);
2429 if (tok_is_(tline
, "("))
2432 * This macro has parameters.
2435 tline
= tline
->next
;
2441 error(ERR_NONFATAL
, "parameter identifier expected");
2442 free_tlist(origline
);
2445 if (tline
->type
!= TOK_ID
)
2448 "`%s': parameter identifier expected",
2450 free_tlist(origline
);
2453 tline
->type
= TOK_SMAC_PARAM
+ nparam
++;
2454 tline
= tline
->next
;
2456 if (tok_is_(tline
, ","))
2458 tline
= tline
->next
;
2461 if (!tok_is_(tline
, ")"))
2464 "`)' expected to terminate macro template");
2465 free_tlist(origline
);
2471 tline
= tline
->next
;
2473 if (tok_type_(tline
, TOK_WHITESPACE
))
2474 last
= tline
, tline
= tline
->next
;
2480 if (t
->type
== TOK_ID
)
2482 for (tt
= param_start
; tt
; tt
= tt
->next
)
2483 if (tt
->type
>= TOK_SMAC_PARAM
&&
2484 !strcmp(tt
->text
, t
->text
))
2488 t
->next
= macro_start
;
2493 * Good. We now have a macro name, a parameter count, and a
2494 * token list (in reverse order) for an expansion. We ought
2495 * to be OK just to create an SMacro, store it, and let
2496 * free_tlist have the rest of the line (which we have
2497 * carefully re-terminated after chopping off the expansion
2500 if (smacro_defined(ctx
, mname
, nparam
, &smac
, i
== PP_DEFINE
))
2505 "single-line macro `%s' defined both with and"
2506 " without parameters", mname
);
2507 free_tlist(origline
);
2508 free_tlist(macro_start
);
2514 * We're redefining, so we have to take over an
2515 * existing SMacro structure. This means freeing
2516 * what was already in it.
2518 nasm_free(smac
->name
);
2519 free_tlist(smac
->expansion
);
2524 smac
= nasm_malloc(sizeof(SMacro
));
2525 smac
->next
= *smhead
;
2528 smac
->name
= nasm_strdup(mname
);
2529 smac
->casesense
= ((i
== PP_DEFINE
) || (i
== PP_XDEFINE
));
2530 smac
->nparam
= nparam
;
2531 smac
->expansion
= macro_start
;
2532 smac
->in_progress
= FALSE
;
2533 free_tlist(origline
);
2537 tline
= tline
->next
;
2539 tline
= expand_id(tline
);
2540 if (!tline
|| (tline
->type
!= TOK_ID
&&
2541 (tline
->type
!= TOK_PREPROC_ID
||
2542 tline
->text
[1] != '$')))
2544 error(ERR_NONFATAL
, "`%%undef' expects a macro identifier");
2545 free_tlist(origline
);
2551 "trailing garbage after macro name ignored");
2554 /* Find the context that symbol belongs to */
2555 ctx
= get_ctx(tline
->text
, FALSE
);
2557 smhead
= &smacros
[hash(tline
->text
)];
2559 smhead
= &ctx
->localmac
;
2561 mname
= tline
->text
;
2566 * We now have a macro name... go hunt for it.
2568 while (smacro_defined(ctx
, mname
, -1, &smac
, 1))
2570 /* Defined, so we need to find its predecessor and nuke it */
2572 for (s
= smhead
; *s
&& *s
!= smac
; s
= &(*s
)->next
);
2576 nasm_free(smac
->name
);
2577 free_tlist(smac
->expansion
);
2581 free_tlist(origline
);
2585 tline
= tline
->next
;
2587 tline
= expand_id(tline
);
2588 if (!tline
|| (tline
->type
!= TOK_ID
&&
2589 (tline
->type
!= TOK_PREPROC_ID
||
2590 tline
->text
[1] != '$')))
2593 "`%%strlen' expects a macro identifier as first parameter");
2594 free_tlist(origline
);
2597 ctx
= get_ctx(tline
->text
, FALSE
);
2599 smhead
= &smacros
[hash(tline
->text
)];
2601 smhead
= &ctx
->localmac
;
2602 mname
= tline
->text
;
2604 tline
= expand_smacro(tline
->next
);
2608 while (tok_type_(t
, TOK_WHITESPACE
))
2610 /* t should now point to the string */
2611 if (t
->type
!= TOK_STRING
)
2614 "`%%strlen` requires string as second parameter");
2616 free_tlist(origline
);
2620 macro_start
= nasm_malloc(sizeof(*macro_start
));
2621 macro_start
->next
= NULL
;
2622 make_tok_num(macro_start
, strlen(t
->text
) - 2);
2623 macro_start
->mac
= NULL
;
2626 * We now have a macro name, an implicit parameter count of
2627 * zero, and a numeric token to use as an expansion. Create
2628 * and store an SMacro.
2630 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_STRLEN
))
2634 "single-line macro `%s' defined both with and"
2635 " without parameters", mname
);
2639 * We're redefining, so we have to take over an
2640 * existing SMacro structure. This means freeing
2641 * what was already in it.
2643 nasm_free(smac
->name
);
2644 free_tlist(smac
->expansion
);
2649 smac
= nasm_malloc(sizeof(SMacro
));
2650 smac
->next
= *smhead
;
2653 smac
->name
= nasm_strdup(mname
);
2654 smac
->casesense
= (i
== PP_STRLEN
);
2656 smac
->expansion
= macro_start
;
2657 smac
->in_progress
= FALSE
;
2659 free_tlist(origline
);
2663 tline
= tline
->next
;
2665 tline
= expand_id(tline
);
2666 if (!tline
|| (tline
->type
!= TOK_ID
&&
2667 (tline
->type
!= TOK_PREPROC_ID
||
2668 tline
->text
[1] != '$')))
2671 "`%%substr' expects a macro identifier as first parameter");
2672 free_tlist(origline
);
2675 ctx
= get_ctx(tline
->text
, FALSE
);
2677 smhead
= &smacros
[hash(tline
->text
)];
2679 smhead
= &ctx
->localmac
;
2680 mname
= tline
->text
;
2682 tline
= expand_smacro(tline
->next
);
2686 while (tok_type_(t
, TOK_WHITESPACE
))
2689 /* t should now point to the string */
2690 if (t
->type
!= TOK_STRING
)
2693 "`%%substr` requires string as second parameter");
2695 free_tlist(origline
);
2701 tokval
.t_type
= TOKEN_INVALID
;
2703 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2707 free_tlist(origline
);
2710 if (!is_simple(evalresult
))
2712 error(ERR_NONFATAL
, "non-constant value given to `%%substr`");
2714 free_tlist(origline
);
2718 macro_start
= nasm_malloc(sizeof(*macro_start
));
2719 macro_start
->next
= NULL
;
2720 macro_start
->text
= nasm_strdup("'''");
2721 if (evalresult
->value
> 0
2722 && evalresult
->value
< strlen(t
->text
) - 1)
2724 macro_start
->text
[1] = t
->text
[evalresult
->value
];
2728 macro_start
->text
[2] = '\0';
2730 macro_start
->type
= TOK_STRING
;
2731 macro_start
->mac
= NULL
;
2734 * We now have a macro name, an implicit parameter count of
2735 * zero, and a numeric token to use as an expansion. Create
2736 * and store an SMacro.
2738 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_SUBSTR
))
2742 "single-line macro `%s' defined both with and"
2743 " without parameters", mname
);
2747 * We're redefining, so we have to take over an
2748 * existing SMacro structure. This means freeing
2749 * what was already in it.
2751 nasm_free(smac
->name
);
2752 free_tlist(smac
->expansion
);
2757 smac
= nasm_malloc(sizeof(SMacro
));
2758 smac
->next
= *smhead
;
2761 smac
->name
= nasm_strdup(mname
);
2762 smac
->casesense
= (i
== PP_SUBSTR
);
2764 smac
->expansion
= macro_start
;
2765 smac
->in_progress
= FALSE
;
2767 free_tlist(origline
);
2773 tline
= tline
->next
;
2775 tline
= expand_id(tline
);
2776 if (!tline
|| (tline
->type
!= TOK_ID
&&
2777 (tline
->type
!= TOK_PREPROC_ID
||
2778 tline
->text
[1] != '$')))
2781 "`%%%sassign' expects a macro identifier",
2782 (i
== PP_IASSIGN
? "i" : ""));
2783 free_tlist(origline
);
2786 ctx
= get_ctx(tline
->text
, FALSE
);
2788 smhead
= &smacros
[hash(tline
->text
)];
2790 smhead
= &ctx
->localmac
;
2791 mname
= tline
->text
;
2793 tline
= expand_smacro(tline
->next
);
2798 tokval
.t_type
= TOKEN_INVALID
;
2800 evaluate(ppscan
, tptr
, &tokval
, NULL
, pass
, error
, NULL
);
2804 free_tlist(origline
);
2810 "trailing garbage after expression ignored");
2812 if (!is_simple(evalresult
))
2815 "non-constant value given to `%%%sassign'",
2816 (i
== PP_IASSIGN
? "i" : ""));
2817 free_tlist(origline
);
2821 macro_start
= nasm_malloc(sizeof(*macro_start
));
2822 macro_start
->next
= NULL
;
2823 make_tok_num(macro_start
, reloc_value(evalresult
));
2824 macro_start
->mac
= NULL
;
2827 * We now have a macro name, an implicit parameter count of
2828 * zero, and a numeric token to use as an expansion. Create
2829 * and store an SMacro.
2831 if (smacro_defined(ctx
, mname
, 0, &smac
, i
== PP_ASSIGN
))
2835 "single-line macro `%s' defined both with and"
2836 " without parameters", mname
);
2840 * We're redefining, so we have to take over an
2841 * existing SMacro structure. This means freeing
2842 * what was already in it.
2844 nasm_free(smac
->name
);
2845 free_tlist(smac
->expansion
);
2850 smac
= nasm_malloc(sizeof(SMacro
));
2851 smac
->next
= *smhead
;
2854 smac
->name
= nasm_strdup(mname
);
2855 smac
->casesense
= (i
== PP_ASSIGN
);
2857 smac
->expansion
= macro_start
;
2858 smac
->in_progress
= FALSE
;
2859 free_tlist(origline
);
2864 * Syntax is `%line nnn[+mmm] [filename]'
2866 tline
= tline
->next
;
2868 if (!tok_type_(tline
, TOK_NUMBER
))
2870 error(ERR_NONFATAL
, "`%%line' expects line number");
2871 free_tlist(origline
);
2874 k
= readnum(tline
->text
, &j
);
2876 tline
= tline
->next
;
2877 if (tok_is_(tline
, "+"))
2879 tline
= tline
->next
;
2880 if (!tok_type_(tline
, TOK_NUMBER
))
2882 error(ERR_NONFATAL
, "`%%line' expects line increment");
2883 free_tlist(origline
);
2886 m
= readnum(tline
->text
, &j
);
2887 tline
= tline
->next
;
2894 nasm_free(src_set_fname(detoken(tline
, FALSE
)));
2896 free_tlist(origline
);
2901 "preprocessor directive `%s' not yet implemented",
2909 * Ensure that a macro parameter contains a condition code and
2910 * nothing else. Return the condition code index if so, or -1
2920 if (t
->type
!= TOK_ID
)
2924 if (tt
&& (tt
->type
!= TOK_OTHER
|| strcmp(tt
->text
, ",")))
2928 j
= sizeof(conditions
) / sizeof(*conditions
);
2932 m
= nasm_stricmp(t
->text
, conditions
[k
]);
2952 * Expand MMacro-local things: parameter references (%0, %n, %+n,
2953 * %-n) and MMacro-local identifiers (%%foo).
2956 expand_mmac_params(Token
* tline
)
2958 Token
*t
, *tt
, **tail
, *thead
;
2965 if (tline
->type
== TOK_PREPROC_ID
&&
2966 (((tline
->text
[1] == '+' || tline
->text
[1] == '-')
2967 && tline
->text
[2]) || tline
->text
[1] == '%'
2968 || (tline
->text
[1] >= '0' && tline
->text
[1] <= '9')))
2971 int type
= 0, cc
; /* type = 0 to placate optimisers */
2977 tline
= tline
->next
;
2980 while (mac
&& !mac
->name
) /* avoid mistaking %reps for macros */
2981 mac
= mac
->next_active
;
2983 error(ERR_NONFATAL
, "`%s': not in a macro call", t
->text
);
2988 * We have to make a substitution of one of the
2989 * forms %1, %-1, %+1, %%foo, %0.
2993 sprintf(tmpbuf
, "%d", mac
->nparam
);
2994 text
= nasm_strdup(tmpbuf
);
2998 sprintf(tmpbuf
, "..@%lu.", mac
->unique
);
2999 text
= nasm_strcat(tmpbuf
, t
->text
+ 2);
3002 n
= atoi(t
->text
+ 2) - 1;
3003 if (n
>= mac
->nparam
)
3007 if (mac
->nparam
> 1)
3008 n
= (n
+ mac
->rotate
) % mac
->nparam
;
3009 tt
= mac
->params
[n
];
3015 "macro parameter %d is not a condition code",
3022 if (inverse_ccs
[cc
] == -1)
3025 "condition code `%s' is not invertible",
3031 nasm_strdup(conditions
[inverse_ccs
3036 n
= atoi(t
->text
+ 2) - 1;
3037 if (n
>= mac
->nparam
)
3041 if (mac
->nparam
> 1)
3042 n
= (n
+ mac
->rotate
) % mac
->nparam
;
3043 tt
= mac
->params
[n
];
3049 "macro parameter %d is not a condition code",
3056 text
= nasm_strdup(conditions
[cc
]);
3060 n
= atoi(t
->text
+ 1) - 1;
3061 if (n
>= mac
->nparam
)
3065 if (mac
->nparam
> 1)
3066 n
= (n
+ mac
->rotate
) % mac
->nparam
;
3067 tt
= mac
->params
[n
];
3071 for (i
= 0; i
< mac
->paramlen
[n
]; i
++)
3074 new_Token(NULL
, tt
->type
, tt
->text
,
3076 tail
= &(*tail
)->next
;
3080 text
= NULL
; /* we've done it here */
3101 tline
= tline
->next
;
3108 for (; t
&& (tt
= t
->next
) != NULL
; t
= t
->next
)
3111 case TOK_WHITESPACE
:
3112 if (tt
->type
== TOK_WHITESPACE
)
3114 t
->next
= delete_Token(tt
);
3118 if (tt
->type
== TOK_ID
|| tt
->type
== TOK_NUMBER
)
3120 char *tmp
= nasm_strcat(t
->text
, tt
->text
);
3123 t
->next
= delete_Token(tt
);
3127 if (tt
->type
== TOK_NUMBER
)
3129 char *tmp
= nasm_strcat(t
->text
, tt
->text
);
3132 t
->next
= delete_Token(tt
);
3141 * Expand all single-line macro calls made in the given line.
3142 * Return the expanded version of the line. The original is deemed
3143 * to be destroyed in the process. (In reality we'll just move
3144 * Tokens from input to output a lot of the time, rather than
3145 * actually bothering to destroy and replicate.)
3148 expand_smacro(Token
* tline
)
3150 Token
*t
, *tt
, *mstart
, **tail
, *thead
;
3151 SMacro
*head
= NULL
, *m
;
3154 int nparam
, sparam
, brackets
, rescan
;
3155 Token
*org_tline
= tline
;
3160 * Trick: we should avoid changing the start token pointer since it can
3161 * be contained in "next" field of other token. Because of this
3162 * we allocate a copy of first token and work with it; at the end of
3163 * routine we copy it back
3168 new_Token(org_tline
->next
, org_tline
->type
, org_tline
->text
,
3170 tline
->mac
= org_tline
->mac
;
3178 { /* main token loop */
3179 if ((mname
= tline
->text
))
3181 /* if this token is a local macro, look in local context */
3182 if (tline
->type
== TOK_ID
|| tline
->type
== TOK_PREPROC_ID
)
3183 ctx
= get_ctx(mname
, TRUE
);
3187 head
= smacros
[hash(mname
)];
3189 head
= ctx
->localmac
;
3191 * We've hit an identifier. As in is_mmacro below, we first
3192 * check whether the identifier is a single-line macro at
3193 * all, then think about checking for parameters if
3196 for (m
= head
; m
; m
= m
->next
)
3197 if (!mstrcmp(m
->name
, mname
, m
->casesense
))
3207 * Simple case: the macro is parameterless. Discard the
3208 * one token that the macro call took, and push the
3209 * expansion back on the to-do stack.
3213 if (!strcmp("__FILE__", m
->name
))
3216 src_get(&num
, &(tline
->text
));
3217 nasm_quote(&(tline
->text
));
3218 tline
->type
= TOK_STRING
;
3221 if (!strcmp("__LINE__", m
->name
))
3223 nasm_free(tline
->text
);
3224 make_tok_num(tline
, src_get_linnum());
3227 tline
= delete_Token(tline
);
3234 * Complicated case: at least one macro with this name
3235 * exists and takes parameters. We must find the
3236 * parameters in the call, count them, find the SMacro
3237 * that corresponds to that form of the macro call, and
3238 * substitute for the parameters when we expand. What a
3241 tline
= tline
->next
;
3243 if (!tok_is_(tline
, "("))
3246 * This macro wasn't called with parameters: ignore
3247 * the call. (Behaviour borrowed from gnu cpp.)
3258 tline
= tline
->next
;
3259 sparam
= PARAM_DELTA
;
3260 params
= nasm_malloc(sparam
* sizeof(Token
*));
3262 paramsize
= nasm_malloc(sparam
* sizeof(int));
3264 for (;; tline
= tline
->next
)
3265 { /* parameter loop */
3269 "macro call expects terminating `)'");
3272 if (tline
->type
== TOK_WHITESPACE
3275 if (paramsize
[nparam
])
3278 params
[nparam
] = tline
->next
;
3279 continue; /* parameter loop */
3281 if (tline
->type
== TOK_OTHER
3282 && tline
->text
[1] == 0)
3284 char ch
= tline
->text
[0];
3285 if (ch
== ',' && !paren
&& brackets
<= 0)
3287 if (++nparam
>= sparam
)
3289 sparam
+= PARAM_DELTA
;
3290 params
= nasm_realloc(params
,
3291 sparam
* sizeof(Token
*));
3292 paramsize
= nasm_realloc(paramsize
,
3293 sparam
* sizeof(int));
3295 params
[nparam
] = tline
->next
;
3296 paramsize
[nparam
] = 0;
3298 continue; /* parameter loop */
3301 (brackets
> 0 || (brackets
== 0 &&
3302 !paramsize
[nparam
])))
3306 params
[nparam
] = tline
->next
;
3307 continue; /* parameter loop */
3310 if (ch
== '}' && brackets
> 0)
3311 if (--brackets
== 0)
3314 continue; /* parameter loop */
3316 if (ch
== '(' && !brackets
)
3318 if (ch
== ')' && brackets
<= 0)
3325 error(ERR_NONFATAL
, "braces do not "
3326 "enclose all of macro parameter");
3328 paramsize
[nparam
] += white
+ 1;
3330 } /* parameter loop */
3332 while (m
&& (m
->nparam
!= nparam
||
3333 mstrcmp(m
->name
, mname
,
3337 error(ERR_WARNING
| ERR_WARN_MNP
,
3338 "macro `%s' exists, "
3339 "but not taking %d parameters",
3340 mstart
->text
, nparam
);
3343 if (m
&& m
->in_progress
)
3345 if (!m
) /* in progess or didn't find '(' or wrong nparam */
3348 * Design question: should we handle !tline, which
3349 * indicates missing ')' here, or expand those
3350 * macros anyway, which requires the (t) test a few
3354 nasm_free(paramsize
);
3360 * Expand the macro: we are placed on the last token of the
3361 * call, so that we can easily split the call from the
3362 * following tokens. We also start by pushing an SMAC_END
3363 * token for the cycle removal.
3371 tt
= new_Token(tline
, TOK_SMAC_END
, NULL
, 0);
3373 m
->in_progress
= TRUE
;
3375 for (t
= m
->expansion
; t
; t
= t
->next
)
3377 if (t
->type
>= TOK_SMAC_PARAM
)
3379 Token
*pcopy
= tline
, **ptail
= &pcopy
;
3383 ttt
= params
[t
->type
- TOK_SMAC_PARAM
];
3384 for (i
= paramsize
[t
->type
- TOK_SMAC_PARAM
];
3388 new_Token(tline
, ttt
->type
, ttt
->text
,
3397 tt
= new_Token(tline
, t
->type
, t
->text
, 0);
3403 * Having done that, get rid of the macro call, and clean
3404 * up the parameters.
3407 nasm_free(paramsize
);
3409 continue; /* main token loop */
3414 if (tline
->type
== TOK_SMAC_END
)
3416 tline
->mac
->in_progress
= FALSE
;
3417 tline
= delete_Token(tline
);
3422 tline
= tline
->next
;
3430 * Now scan the entire line and look for successive TOK_IDs that resulted
3431 * after expansion (they can't be produced by tokenise()). The successive
3432 * TOK_IDs should be concatenated.
3433 * Also we look for %+ tokens and concatenate the tokens before and after
3434 * them (without white spaces in between).
3440 while (t
&& t
->type
!= TOK_ID
&& t
->type
!= TOK_PREPROC_ID
)
3444 if (t
->next
->type
== TOK_ID
||
3445 t
->next
->type
== TOK_PREPROC_ID
||
3446 t
->next
->type
== TOK_NUMBER
)
3448 char *p
= nasm_strcat(t
->text
, t
->next
->text
);
3450 t
->next
= delete_Token(t
->next
);
3454 else if (t
->next
->type
== TOK_WHITESPACE
&& t
->next
->next
&&
3455 t
->next
->next
->type
== TOK_PREPROC_ID
&&
3456 strcmp(t
->next
->next
->text
, "%+") == 0)
3458 /* free the next whitespace, the %+ token and next whitespace */
3460 for (i
= 1; i
<= 3; i
++)
3462 if (!t
->next
|| (i
!= 2 && t
->next
->type
!= TOK_WHITESPACE
))
3464 t
->next
= delete_Token(t
->next
);
3470 /* If we concatenaded something, re-scan the line for macros */
3481 *org_tline
= *thead
;
3482 /* since we just gave text to org_line, don't free it */
3484 delete_Token(thead
);
3488 /* the expression expanded to empty line;
3489 we can't return NULL for some reasons
3490 we just set the line to a single WHITESPACE token. */
3491 memset(org_tline
, 0, sizeof(*org_tline
));
3492 org_tline
->text
= NULL
;
3493 org_tline
->type
= TOK_WHITESPACE
;
3502 * Similar to expand_smacro but used exclusively with macro identifiers
3503 * right before they are fetched in. The reason is that there can be
3504 * identifiers consisting of several subparts. We consider that if there
3505 * are more than one element forming the name, user wants a expansion,
3506 * otherwise it will be left as-is. Example:
3510 * the identifier %$abc will be left as-is so that the handler for %define
3511 * will suck it and define the corresponding value. Other case:
3513 * %define _%$abc cde
3515 * In this case user wants name to be expanded *before* %define starts
3516 * working, so we'll expand %$abc into something (if it has a value;
3517 * otherwise it will be left as-is) then concatenate all successive
3521 expand_id(Token
* tline
)
3523 Token
*cur
, *oldnext
= NULL
;
3525 if (!tline
|| !tline
->next
)
3530 (cur
->next
->type
== TOK_ID
||
3531 cur
->next
->type
== TOK_PREPROC_ID
|| cur
->next
->type
== TOK_NUMBER
))
3534 /* If identifier consists of just one token, don't expand */
3540 oldnext
= cur
->next
; /* Detach the tail past identifier */
3541 cur
->next
= NULL
; /* so that expand_smacro stops here */
3544 tline
= expand_smacro(tline
);
3548 /* expand_smacro possibly changhed tline; re-scan for EOL */
3550 while (cur
&& cur
->next
)
3553 cur
->next
= oldnext
;
3560 * Determine whether the given line constitutes a multi-line macro
3561 * call, and return the MMacro structure called if so. Doesn't have
3562 * to check for an initial label - that's taken care of in
3563 * expand_mmacro - but must check numbers of parameters. Guaranteed
3564 * to be called with tline->type == TOK_ID, so the putative macro
3565 * name is easy to find.
3568 is_mmacro(Token
* tline
, Token
*** params_array
)
3574 head
= mmacros
[hash(tline
->text
)];
3577 * Efficiency: first we see if any macro exists with the given
3578 * name. If not, we can return NULL immediately. _Then_ we
3579 * count the parameters, and then we look further along the
3580 * list if necessary to find the proper MMacro.
3582 for (m
= head
; m
; m
= m
->next
)
3583 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
3589 * OK, we have a potential macro. Count and demarcate the
3592 count_mmac_params(tline
->next
, &nparam
, ¶ms
);
3595 * So we know how many parameters we've got. Find the MMacro
3596 * structure that handles this number.
3600 if (m
->nparam_min
<= nparam
&& (m
->plus
|| nparam
<= m
->nparam_max
))
3603 * This one is right. Just check if cycle removal
3604 * prohibits us using it before we actually celebrate...
3610 "self-reference in multi-line macro `%s'", m
->name
);
3616 * It's right, and we can use it. Add its default
3617 * parameters to the end of our list if necessary.
3619 if (m
->defaults
&& nparam
< m
->nparam_min
+ m
->ndefs
)
3622 nasm_realloc(params
,
3623 ((m
->nparam_min
+ m
->ndefs
+ 1) * sizeof(*params
)));
3624 while (nparam
< m
->nparam_min
+ m
->ndefs
)
3626 params
[nparam
] = m
->defaults
[nparam
- m
->nparam_min
];
3631 * If we've gone over the maximum parameter count (and
3632 * we're in Plus mode), ignore parameters beyond
3635 if (m
->plus
&& nparam
> m
->nparam_max
)
3636 nparam
= m
->nparam_max
;
3638 * Then terminate the parameter list, and leave.
3641 { /* need this special case */
3642 params
= nasm_malloc(sizeof(*params
));
3645 params
[nparam
] = NULL
;
3646 *params_array
= params
;
3650 * This one wasn't right: look for the next one with the
3653 for (m
= m
->next
; m
; m
= m
->next
)
3654 if (!mstrcmp(m
->name
, tline
->text
, m
->casesense
))
3659 * After all that, we didn't find one with the right number of
3660 * parameters. Issue a warning, and fail to expand the macro.
3662 error(ERR_WARNING
| ERR_WARN_MNP
,
3663 "macro `%s' exists, but not taking %d parameters",
3664 tline
->text
, nparam
);
3670 * Expand the multi-line macro call made by the given line, if
3671 * there is one to be expanded. If there is, push the expansion on
3672 * istk->expansion and return 1. Otherwise return 0.
3675 expand_mmacro(Token
* tline
)
3677 Token
*startline
= tline
;
3678 Token
*label
= NULL
;
3679 int dont_prepend
= 0;
3680 Token
**params
, *t
, *tt
;
3683 int i
, nparam
, *paramlen
;
3687 if (!tok_type_(t
, TOK_ID
))
3689 m
= is_mmacro(t
, ¶ms
);
3694 * We have an id which isn't a macro call. We'll assume
3695 * it might be a label; we'll also check to see if a
3696 * colon follows it. Then, if there's another id after
3697 * that lot, we'll check it again for macro-hood.
3701 if (tok_type_(t
, TOK_WHITESPACE
))
3702 last
= t
, t
= t
->next
;
3703 if (tok_is_(t
, ":"))
3706 last
= t
, t
= t
->next
;
3707 if (tok_type_(t
, TOK_WHITESPACE
))
3708 last
= t
, t
= t
->next
;
3710 if (!tok_type_(t
, TOK_ID
) || (m
= is_mmacro(t
, ¶ms
)) == NULL
)
3717 * Fix up the parameters: this involves stripping leading and
3718 * trailing whitespace, then stripping braces if they are
3721 for (nparam
= 0; params
[nparam
]; nparam
++)
3723 paramlen
= nparam
? nasm_malloc(nparam
* sizeof(*paramlen
)) : NULL
;
3725 for (i
= 0; params
[i
]; i
++)
3728 int comma
= (!m
->plus
|| i
< nparam
- 1);
3732 if (tok_is_(t
, "{"))
3733 t
= t
->next
, brace
= TRUE
, comma
= FALSE
;
3738 if (comma
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, ","))
3739 break; /* ... because we have hit a comma */
3740 if (comma
&& t
->type
== TOK_WHITESPACE
&& tok_is_(t
->next
, ","))
3741 break; /* ... or a space then a comma */
3742 if (brace
&& t
->type
== TOK_OTHER
&& !strcmp(t
->text
, "}"))
3743 break; /* ... or a brace */
3750 * OK, we have a MMacro structure together with a set of
3751 * parameters. We must now go through the expansion and push
3752 * copies of each Line on to istk->expansion. Substitution of
3753 * parameter tokens and macro-local tokens doesn't get done
3754 * until the single-line macro substitution process; this is
3755 * because delaying them allows us to change the semantics
3756 * later through %rotate.
3758 * First, push an end marker on to istk->expansion, mark this
3759 * macro as in progress, and set up its invocation-specific
3762 ll
= nasm_malloc(sizeof(Line
));
3763 ll
->next
= istk
->expansion
;
3766 istk
->expansion
= ll
;
3768 m
->in_progress
= TRUE
;
3773 m
->paramlen
= paramlen
;
3774 m
->unique
= unique
++;
3777 m
->next_active
= istk
->mstk
;
3780 for (l
= m
->expansion
; l
; l
= l
->next
)
3784 ll
= nasm_malloc(sizeof(Line
));
3785 ll
->finishes
= NULL
;
3786 ll
->next
= istk
->expansion
;
3787 istk
->expansion
= ll
;
3790 for (t
= l
->first
; t
; t
= t
->next
)
3793 if (t
->type
== TOK_PREPROC_ID
&&
3794 t
->text
[1] == '0' && t
->text
[2] == '0')
3801 tt
= *tail
= new_Token(NULL
, x
->type
, x
->text
, 0);
3808 * If we had a label, push it on as the first line of
3809 * the macro expansion.
3813 if (dont_prepend
< 0)
3814 free_tlist(startline
);
3817 ll
= nasm_malloc(sizeof(Line
));
3818 ll
->finishes
= NULL
;
3819 ll
->next
= istk
->expansion
;
3820 istk
->expansion
= ll
;
3821 ll
->first
= startline
;
3825 label
= label
->next
;
3826 label
->next
= tt
= new_Token(NULL
, TOK_OTHER
, ":", 0);
3831 list
->uplevel(m
->nolist
? LIST_MACRO_NOLIST
: LIST_MACRO
);
3837 * Since preprocessor always operate only on the line that didn't
3838 * arrived yet, we should always use ERR_OFFBY1. Also since user
3839 * won't want to see same error twice (preprocessing is done once
3840 * per pass) we will want to show errors only during pass one.
3843 error(int severity
, char *fmt
, ...)
3848 /* If we're in a dead branch of IF or something like it, ignore the error */
3849 if (istk
->conds
&& !emitting(istk
->conds
->state
))
3853 vsprintf(buff
, fmt
, arg
);
3856 if (istk
->mstk
&& istk
->mstk
->name
)
3857 __error(severity
| ERR_PASS1
, "(%s:%d) %s", istk
->mstk
->name
,
3858 istk
->mstk
->lineno
, buff
);
3860 __error(severity
| ERR_PASS1
, "%s", buff
);
3864 pp_reset(char *file
, int apass
, efunc errfunc
, evalfunc eval
,
3871 istk
= nasm_malloc(sizeof(Include
));
3874 istk
->expansion
= NULL
;
3876 istk
->fp
= fopen(file
, "r");
3878 src_set_fname(nasm_strdup(file
));
3882 error(ERR_FATAL
| ERR_NOFILE
, "unable to open input file `%s'", file
);
3884 for (h
= 0; h
< NHASH
; h
++)
3890 if (tasm_compatible_mode
) {
3893 stdmacpos
= &stdmac
[TASM_MACRO_COUNT
];
3895 any_extrastdmac
= (extrastdmac
!= NULL
);
3910 * Fetch a tokenised line, either from the macro-expansion
3911 * buffer or from the input file.
3914 while (istk
->expansion
&& istk
->expansion
->finishes
)
3916 Line
*l
= istk
->expansion
;
3917 if (!l
->finishes
->name
&& l
->finishes
->in_progress
> 1)
3922 * This is a macro-end marker for a macro with no
3923 * name, which means it's not really a macro at all
3924 * but a %rep block, and the `in_progress' field is
3925 * more than 1, meaning that we still need to
3926 * repeat. (1 means the natural last repetition; 0
3927 * means termination by %exitrep.) We have
3928 * therefore expanded up to the %endrep, and must
3929 * push the whole block on to the expansion buffer
3930 * again. We don't bother to remove the macro-end
3931 * marker: we'd only have to generate another one
3934 l
->finishes
->in_progress
--;
3935 for (l
= l
->finishes
->expansion
; l
; l
= l
->next
)
3937 Token
*t
, *tt
, **tail
;
3939 ll
= nasm_malloc(sizeof(Line
));
3940 ll
->next
= istk
->expansion
;
3941 ll
->finishes
= NULL
;
3945 for (t
= l
->first
; t
; t
= t
->next
)
3947 if (t
->text
|| t
->type
== TOK_WHITESPACE
)
3949 tt
= *tail
= new_Token(NULL
, t
->type
, t
->text
, 0);
3954 istk
->expansion
= ll
;
3960 * Check whether a `%rep' was started and not ended
3961 * within this macro expansion. This can happen and
3962 * should be detected. It's a fatal error because
3963 * I'm too confused to work out how to recover
3969 error(ERR_PANIC
, "defining with name in expansion");
3970 else if (istk
->mstk
->name
)
3971 error(ERR_FATAL
, "`%%rep' without `%%endrep' within"
3972 " expansion of macro `%s'", istk
->mstk
->name
);
3976 * FIXME: investigate the relationship at this point between
3977 * istk->mstk and l->finishes
3980 MMacro
*m
= istk
->mstk
;
3981 istk
->mstk
= m
->next_active
;
3985 * This was a real macro call, not a %rep, and
3986 * therefore the parameter information needs to
3989 nasm_free(m
->params
);
3990 free_tlist(m
->iline
);
3991 nasm_free(m
->paramlen
);
3992 l
->finishes
->in_progress
= FALSE
;
3997 istk
->expansion
= l
->next
;
3999 list
->downlevel(LIST_MACRO
);
4003 { /* until we get a line we can use */
4005 if (istk
->expansion
)
4006 { /* from a macro expansion */
4008 Line
*l
= istk
->expansion
;
4010 istk
->mstk
->lineno
++;
4012 istk
->expansion
= l
->next
;
4014 p
= detoken(tline
, FALSE
);
4015 list
->line(LIST_MACRO
, p
);
4021 { /* from the current input file */
4022 line
= prepreproc(line
);
4023 tline
= tokenise(line
);
4028 * The current file has ended; work down the istk
4034 error(ERR_FATAL
, "expected `%%endif' before end of file");
4036 list
->downlevel(LIST_INCLUDE
);
4037 src_set_linnum(i
->lineno
);
4038 nasm_free(src_set_fname(i
->fname
));
4046 * We must expand MMacro parameters and MMacro-local labels
4047 * _before_ we plunge into directive processing, to cope
4048 * with things like `%define something %1' such as STRUC
4049 * uses. Unless we're _defining_ a MMacro, in which case
4050 * those tokens should be left alone to go into the
4051 * definition; and unless we're in a non-emitting
4052 * condition, in which case we don't want to meddle with
4055 if (!defining
&& !(istk
->conds
&& !emitting(istk
->conds
->state
)))
4056 tline
= expand_mmac_params(tline
);
4059 * Check the line to see if it's a preprocessor directive.
4061 if (do_directive(tline
) & 1)
4068 * We're defining a multi-line macro. We emit nothing
4070 * shove the tokenised line on to the macro definition.
4072 Line
*l
= nasm_malloc(sizeof(Line
));
4073 l
->next
= defining
->expansion
;
4075 l
->finishes
= FALSE
;
4076 defining
->expansion
= l
;
4079 else if (istk
->conds
&& !emitting(istk
->conds
->state
))
4082 * We're in a non-emitting branch of a condition block.
4083 * Emit nothing at all, not even a blank line: when we
4084 * emerge from the condition we'll give a line-number
4085 * directive so we keep our place correctly.
4090 else if (istk
->mstk
&& !istk
->mstk
->in_progress
)
4093 * We're in a %rep block which has been terminated, so
4094 * we're walking through to the %endrep without
4095 * emitting anything. Emit nothing at all, not even a
4096 * blank line: when we emerge from the %rep block we'll
4097 * give a line-number directive so we keep our place
4105 tline
= expand_smacro(tline
);
4106 if (!expand_mmacro(tline
))
4109 * De-tokenise the line again, and emit it.
4111 line
= detoken(tline
, TRUE
);
4117 continue; /* expand_mmacro calls free_tlist */
4132 error(ERR_NONFATAL
, "end of file while still defining macro `%s'",
4134 free_mmacro(defining
);
4138 for (h
= 0; h
< NHASH
; h
++)
4142 MMacro
*m
= mmacros
[h
];
4143 mmacros
[h
] = mmacros
[h
]->next
;
4148 SMacro
*s
= smacros
[h
];
4149 smacros
[h
] = smacros
[h
]->next
;
4151 free_tlist(s
->expansion
);
4160 nasm_free(i
->fname
);
4168 pp_include_path(char *path
)
4172 i
= nasm_malloc(sizeof(IncPath
));
4173 i
->path
= nasm_strdup(path
);
4179 pp_pre_include(char *fname
)
4181 Token
*inc
, *space
, *name
;
4184 name
= new_Token(NULL
, TOK_INTERNAL_STRING
, fname
, 0);
4185 space
= new_Token(name
, TOK_WHITESPACE
, NULL
, 0);
4186 inc
= new_Token(space
, TOK_PREPROC_ID
, "%include", 0);
4188 l
= nasm_malloc(sizeof(Line
));
4191 l
->finishes
= FALSE
;
4196 pp_pre_define(char *definition
)
4202 equals
= strchr(definition
, '=');
4203 space
= new_Token(NULL
, TOK_WHITESPACE
, NULL
, 0);
4204 def
= new_Token(space
, TOK_PREPROC_ID
, "%define", 0);
4207 space
->next
= tokenise(definition
);
4211 l
= nasm_malloc(sizeof(Line
));
4214 l
->finishes
= FALSE
;
4219 pp_pre_undefine(char *definition
)
4224 space
= new_Token(NULL
, TOK_WHITESPACE
, NULL
, 0);
4225 def
= new_Token(space
, TOK_PREPROC_ID
, "%undef", 0);
4227 l
= nasm_malloc(sizeof(Line
));
4230 l
->finishes
= FALSE
;
4235 pp_extra_stdmac(char **macros
)
4237 extrastdmac
= macros
;
4241 make_tok_num(Token
* tok
, long val
)
4244 sprintf(numbuf
, "%ld", val
);
4245 tok
->text
= nasm_strdup(numbuf
);
4246 tok
->type
= TOK_NUMBER
;