blob: 4ec382697e90814d2223c74d7043f3735e67d174 [file] [log] [blame]
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001/* preproc.c macro preprocessor for the Netwide Assembler
2 *
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.
7 *
8 * initial version 18/iii/97 by Simon Tatham
9 */
10
H. Peter Anvin4836e332002-04-30 20:56:43 +000011/* Typical flow of text through preproc
12 *
13 * pp_getline gets tokenised lines, either
14 *
15 * from a macro expansion
16 *
17 * or
18 * {
19 * read_line gets raw text from stdmacpos, or predef, or current input file
20 * tokenise converts to tokens
21 * }
22 *
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
26 *
27 * do_directive checks for directives
28 *
29 * expand_smacro is used to expand single line macros
30 *
31 * expand_mmacro is used to expand multi-line macros
32 *
33 * detoken is used to convert the line back to text
34 */
H. Peter Anvineba20a72002-04-30 20:53:55 +000035
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000036#include <stdio.h>
H. Peter Anvinaf535c12002-04-30 20:59:21 +000037#include <stdarg.h>
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000038#include <stdlib.h>
39#include <stddef.h>
40#include <string.h>
41#include <ctype.h>
H. Peter Anvin76690a12002-04-30 20:52:49 +000042#include <limits.h>
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000043
44#include "nasm.h"
45#include "nasmlib.h"
46
47typedef struct SMacro SMacro;
48typedef struct MMacro MMacro;
49typedef struct Context Context;
50typedef struct Token Token;
H. Peter Anvince616072002-04-30 21:02:23 +000051typedef struct Blocks Blocks;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000052typedef struct Line Line;
53typedef struct Include Include;
54typedef struct Cond Cond;
H. Peter Anvin6768eb72002-04-30 20:52:26 +000055typedef struct IncPath IncPath;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000056
57/*
58 * Store the definition of a single-line macro.
59 */
H. Peter Anvin734b1882002-04-30 21:01:08 +000060struct SMacro
61{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000062 SMacro *next;
63 char *name;
64 int casesense;
65 int nparam;
66 int in_progress;
67 Token *expansion;
68};
69
70/*
H. Peter Anvin76690a12002-04-30 20:52:49 +000071 * 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.
76 *
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
79 * run.
80 *
81 * The `next' field is used for storing MMacros in hash tables; the
82 * `next_active' field is for stacking them on istk entries.
83 *
84 * When a MMacro is being expanded, `params', `iline', `nparam',
85 * `paramlen', `rotate' and `unique' are local to the invocation.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000086 */
H. Peter Anvin734b1882002-04-30 21:01:08 +000087struct MMacro
88{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000089 MMacro *next;
90 char *name;
91 int casesense;
92 int nparam_min, nparam_max;
H. Peter Anvin734b1882002-04-30 21:01:08 +000093 int plus; /* is the last parameter greedy? */
94 int nolist; /* is this macro listing-inhibited? */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000095 int in_progress;
H. Peter Anvin734b1882002-04-30 21:01:08 +000096 Token *dlist; /* All defaults as one list */
97 Token **defaults; /* Parameter default pointers */
98 int ndefs; /* number of default parameters */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000099 Line *expansion;
H. Peter Anvin76690a12002-04-30 20:52:49 +0000100
101 MMacro *next_active;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000102 MMacro *rep_nest; /* used for nesting %rep */
103 Token **params; /* actual parameters */
104 Token *iline; /* invocation line */
H. Peter Anvin76690a12002-04-30 20:52:49 +0000105 int nparam, rotate, *paramlen;
106 unsigned long unique;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000107 int lineno; /* Current line number on expansion */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000108};
109
110/*
111 * The context stack is composed of a linked list of these.
112 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000113struct Context
114{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000115 Context *next;
116 SMacro *localmac;
117 char *name;
118 unsigned long number;
119};
120
121/*
122 * This is the internal form which we break input lines up into.
123 * Typically stored in linked lists.
124 *
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000125 * 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
128 *
129 * %define a(x,y) ( (x) & ~(y) )
130 *
131 * the token representing `x' will have its type changed to
132 * TOK_SMAC_PARAM, but the one representing `y' will be
133 * TOK_SMAC_PARAM+1.
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000134 *
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.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000139 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000140struct Token
141{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000142 Token *next;
143 char *text;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000144 SMacro *mac; /* associated macro for TOK_SMAC_END */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000145 int type;
146};
H. Peter Anvin734b1882002-04-30 21:01:08 +0000147enum
148{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000149 TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000150 TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM,
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000151 TOK_INTERNAL_STRING
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000152};
153
154/*
155 * Multi-line macro definitions are stored as a linked list of
156 * these, which is essentially a container to allow several linked
157 * lists of Tokens.
158 *
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...
168 *
169 * Some of these structures, rather than being actual lines, are
170 * markers delimiting the end of the expansion of a given macro.
H. Peter Anvin76690a12002-04-30 20:52:49 +0000171 * 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
174 * the line is blank.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000175 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000176struct Line
177{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000178 Line *next;
179 MMacro *finishes;
180 Token *first;
181};
182
183/*
184 * To handle an arbitrary level of file inclusion, we maintain a
185 * stack (ie linked list) of these things.
186 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000187struct Include
188{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000189 Include *next;
190 FILE *fp;
191 Cond *conds;
192 Line *expansion;
193 char *fname;
194 int lineno, lineinc;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000195 MMacro *mstk; /* stack of active macros/reps */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000196};
197
198/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000199 * 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.
202 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000203struct IncPath
204{
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000205 IncPath *next;
206 char *path;
207};
208
209/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000210 * 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.)
215 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000216struct Cond
217{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000218 Cond *next;
219 int state;
220};
H. Peter Anvin734b1882002-04-30 21:01:08 +0000221enum
222{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000223 /*
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.)
230 */
231 COND_IF_TRUE, COND_IF_FALSE,
232 /*
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.
236 */
237 COND_ELSE_TRUE, COND_ELSE_FALSE,
238 /*
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.
245 */
246 COND_NEVER
247};
248#define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
249
250/*
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...
255 */
256static 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"
260};
H. Peter Anvin734b1882002-04-30 21:01:08 +0000261enum
262{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000263 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
266};
267static 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
271};
272
H. Peter Anvin76690a12002-04-30 20:52:49 +0000273/*
274 * Directive names.
275 */
276static char *directives[] = {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000277 "%arg",
H. Peter Anvin76690a12002-04-30 20:52:49 +0000278 "%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",
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000285 "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
286 "%ixdefine", "%line",
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000287 "%local",
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000288 "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000289 "%stacksize",
H. Peter Anvin734b1882002-04-30 21:01:08 +0000290 "%strlen", "%substr", "%undef", "%xdefine"
H. Peter Anvin76690a12002-04-30 20:52:49 +0000291};
H. Peter Anvin734b1882002-04-30 21:01:08 +0000292enum
293{
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000294 PP_ARG,
H. Peter Anvin76690a12002-04-30 20:52:49 +0000295 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,
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000302 PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE,
303 PP_IXDEFINE, PP_LINE,
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000304 PP_LOCAL,
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000305 PP_MACRO, PP_POP, PP_PUSH, PP_REP, PP_REPL, PP_ROTATE,
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000306 PP_STACKSIZE,
H. Peter Anvin734b1882002-04-30 21:01:08 +0000307 PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
H. Peter Anvin76690a12002-04-30 20:52:49 +0000308};
309
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000310
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.
315 */
316
317#ifndef MAX
318# define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
319#endif
320
H. Peter Anvin734b1882002-04-30 21:01:08 +0000321enum
322{
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000323 TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
324 TM_IFNDEF, TM_INCLUDE, TM_LOCAL
325};
326
327static char *tasm_directives[] = {
328 "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
329 "ifndef", "include", "local"
330};
331
332static int StackSize = 4;
333static char *StackPointer = "ebp";
334static int ArgOffset = 8;
335static int LocalOffset = 4;
336
H. Peter Anvin76690a12002-04-30 20:52:49 +0000337
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000338static Context *cstk;
339static Include *istk;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000340static IncPath *ipath = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000341
H. Peter Anvin734b1882002-04-30 21:01:08 +0000342static efunc __error; /* Pointer to client-provided error reporting function */
H. Peter Anvin76690a12002-04-30 20:52:49 +0000343static evalfunc evaluate;
344
H. Peter Anvin620515a2002-04-30 20:57:38 +0000345static int pass; /* HACK: pass 0 = generate dependencies only */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000346
H. Peter Anvin734b1882002-04-30 21:01:08 +0000347static unsigned long unique; /* unique identifier numbers */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000348
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000349static Line *predef = NULL;
350
351static ListGen *list;
352
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000353/*
354 * The number of hash values we use for the macro lookup tables.
H. Peter Anvineba20a72002-04-30 20:53:55 +0000355 * FIXME: We should *really* be able to configure this at run time,
356 * or even have the hash table automatically expanding when necessary.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000357 */
358#define NHASH 31
359
360/*
361 * The current set of multi-line macros we have defined.
362 */
363static MMacro *mmacros[NHASH];
364
365/*
366 * The current set of single-line macros we have defined.
367 */
368static SMacro *smacros[NHASH];
369
370/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000371 * The multi-line macro we are currently defining, or the %rep
372 * block we are currently reading, if any.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000373 */
374static MMacro *defining;
375
376/*
377 * The number of macro parameters to allocate space for at a time.
378 */
379#define PARAM_DELTA 16
380
381/*
382 * The standard macro set: defined as `static char *stdmac[]'. Also
383 * gives our position in the macro set, when we're processing it.
384 */
385#include "macros.c"
386static char **stdmacpos;
387
388/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000389 * The extra standard macros that come from the object format, if
390 * any.
391 */
392static char **extrastdmac = NULL;
393int any_extrastdmac;
394
395/*
H. Peter Anvin734b1882002-04-30 21:01:08 +0000396 * Tokens are allocated in blocks to improve speed
397 */
398#define TOKEN_BLOCKSIZE 4096
399static Token *freeTokens = NULL;
H. Peter Anvince616072002-04-30 21:02:23 +0000400struct Blocks {
401 Blocks *next;
402 void *chunk;
403};
404
405static Blocks blocks = { NULL, NULL };
H. Peter Anvin734b1882002-04-30 21:01:08 +0000406
407/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000408 * Forward declarations.
409 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000410static Token *expand_mmac_params(Token * tline);
411static Token *expand_smacro(Token * tline);
412static Token *expand_id(Token * tline);
413static Context *get_ctx(char *name, int all_contexts);
414static void make_tok_num(Token * tok, long val);
415static void error(int severity, char *fmt, ...);
H. Peter Anvince616072002-04-30 21:02:23 +0000416static void *new_Block(size_t size);
417static void delete_Blocks(void);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000418static Token *new_Token(Token * next, int type, char *text, int txtlen);
419static Token *delete_Token(Token * t);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000420
421/*
422 * Macros for safe checking of token pointers, avoid *(NULL)
423 */
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))))
H. Peter Anvin76690a12002-04-30 20:52:49 +0000428
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000429/* 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).
433 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000434static char *
435check_tasm_directive(char *line)
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000436{
437 int i, j, k, m, len;
438 char *p = line, *oldline, oldchar;
439
440 /* Skip whitespace */
441 while (isspace(*p) && *p != 0)
442 p++;
443
444 /* Binary search for the directive name */
445 i = -1;
446 j = sizeof(tasm_directives) / sizeof(*tasm_directives);
447 len = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000448 while (!isspace(p[len]) && p[len] != 0)
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000449 len++;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000450 if (len)
451 {
452 oldchar = p[len];
453 p[len] = 0;
454 while (j - i > 1)
455 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000456 k = (j + i) / 2;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000457 m = nasm_stricmp(p, tasm_directives[k]);
458 if (m == 0)
459 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000460 /* 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.
462 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000463 p[len] = oldchar;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000464 len = strlen(p);
465 oldline = line;
466 line = nasm_malloc(len + 2);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000467 line[0] = '%';
468 if (k == TM_IFDIFI)
469 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000470 /* 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
473 * package.
474 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000475 strcpy(line + 1, "ifdef BOGUS");
476 }
477 else
478 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000479 memcpy(line + 1, p, len + 1);
480 }
481 nasm_free(oldline);
482 return line;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000483 }
484 else if (m < 0)
485 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000486 j = k;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000487 }
488 else
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000489 i = k;
490 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000491 p[len] = oldchar;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000492 }
493 return line;
494}
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000495
H. Peter Anvin76690a12002-04-30 20:52:49 +0000496/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000497 * 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
500 * lineno file').
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000501 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000502static char *
503prepreproc(char *line)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000504{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000505 int lineno, fnlen;
506 char *fname, *oldline;
507
H. Peter Anvin734b1882002-04-30 21:01:08 +0000508 if (line[0] == '#' && line[1] == ' ')
509 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000510 oldline = line;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000511 fname = oldline + 2;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000512 lineno = atoi(fname);
513 fname += strspn(fname, "0123456789 ");
514 if (*fname == '"')
515 fname++;
516 fnlen = strcspn(fname, "\"");
H. Peter Anvin734b1882002-04-30 21:01:08 +0000517 line = nasm_malloc(20 + fnlen);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000518 sprintf(line, "%%line %d %.*s", lineno, fnlen, fname);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000519 nasm_free(oldline);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000520 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000521 if (tasm_compatible_mode)
522 return check_tasm_directive(line);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000523 return line;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000524}
525
526/*
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.
531 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000532static int
533hash(char *s)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000534{
535 unsigned int h = 0;
536 int i = 0;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000537 /*
538 * Powers of three, mod 31.
539 */
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
543 };
H. Peter Anvineba20a72002-04-30 20:53:55 +0000544
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000545
H. Peter Anvin734b1882002-04-30 21:01:08 +0000546 while (*s)
547 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000548 h += multipliers[i] * (unsigned char) (toupper(*s));
549 s++;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000550 if (++i >= sizeof(multipliers) / sizeof(*multipliers))
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000551 i = 0;
552 }
553 h %= NHASH;
554 return h;
555}
556
557/*
558 * Free a linked list of tokens.
559 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000560static void
561free_tlist(Token * list)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000562{
H. Peter Anvin734b1882002-04-30 21:01:08 +0000563 while (list)
564 {
565 list = delete_Token(list);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000566 }
567}
568
569/*
570 * Free a linked list of lines.
571 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000572static void
573free_llist(Line * list)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000574{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000575 Line *l;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000576 while (list)
577 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000578 l = list;
579 list = list->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000580 free_tlist(l->first);
581 nasm_free(l);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000582 }
583}
584
585/*
H. Peter Anvineba20a72002-04-30 20:53:55 +0000586 * Free an MMacro
587 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000588static void
589free_mmacro(MMacro * m)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000590{
H. Peter Anvin734b1882002-04-30 21:01:08 +0000591 nasm_free(m->name);
592 free_tlist(m->dlist);
593 nasm_free(m->defaults);
594 free_llist(m->expansion);
595 nasm_free(m);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000596}
597
598/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000599 * Pop the context stack.
600 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000601static void
602ctx_pop(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000603{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000604 Context *c = cstk;
605 SMacro *smac, *s;
606
607 cstk = cstk->next;
608 smac = c->localmac;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000609 while (smac)
610 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000611 s = smac;
612 smac = smac->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000613 nasm_free(s->name);
614 free_tlist(s->expansion);
615 nasm_free(s);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000616 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000617 nasm_free(c->name);
618 nasm_free(c);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000619}
620
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000621#define BUF_DELTA 512
622/*
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
626 * been done.
627 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000628static char *
629read_line(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000630{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000631 char *buffer, *p, *q;
632 int bufsize;
633
H. Peter Anvin734b1882002-04-30 21:01:08 +0000634 if (stdmacpos)
635 {
636 if (*stdmacpos)
637 {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000638 char *ret = nasm_strdup(*stdmacpos++);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000639 if (!*stdmacpos && any_extrastdmac)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000640 {
H. Peter Anvin76690a12002-04-30 20:52:49 +0000641 stdmacpos = extrastdmac;
642 any_extrastdmac = FALSE;
643 return ret;
644 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000645 /*
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.
650 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000651 if (!*stdmacpos)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000652 {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000653 Line *pd, *l;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000654 Token *head, **tail, *t;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000655
H. Peter Anvin734b1882002-04-30 21:01:08 +0000656 for (pd = predef; pd; pd = pd->next)
657 {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000658 head = NULL;
659 tail = &head;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000660 for (t = pd->first; t; t = t->next)
661 {
662 *tail = new_Token(NULL, t->type, t->text, 0);
663 tail = &(*tail)->next;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000664 }
665 l = nasm_malloc(sizeof(Line));
666 l->next = istk->expansion;
667 l->first = head;
668 l->finishes = FALSE;
669 istk->expansion = l;
670 }
671 }
672 return ret;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000673 }
674 else
675 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000676 stdmacpos = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000677 }
678 }
679
680 bufsize = BUF_DELTA;
681 buffer = nasm_malloc(BUF_DELTA);
682 p = buffer;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000683 while (1)
684 {
685 q = fgets(p, bufsize - (p - buffer), istk->fp);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000686 if (!q)
687 break;
688 p += strlen(p);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000689 if (p > buffer && p[-1] == '\n')
690 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000691 break;
692 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000693 if (p - buffer > bufsize - 10)
694 {
695 long offset = p - buffer;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000696 bufsize += BUF_DELTA;
697 buffer = nasm_realloc(buffer, bufsize);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000698 p = buffer + offset; /* prevent stale-pointer problems */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000699 }
700 }
701
H. Peter Anvin734b1882002-04-30 21:01:08 +0000702 if (!q && p == buffer)
703 {
704 nasm_free(buffer);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000705 return NULL;
706 }
707
H. Peter Anvineba20a72002-04-30 20:53:55 +0000708 src_set_linnum(src_get_linnum() + istk->lineinc);
709
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000710 /*
711 * Play safe: remove CRs as well as LFs, if any of either are
712 * present at the end of the line.
713 */
H. Peter Anvineba20a72002-04-30 20:53:55 +0000714 while (--p >= buffer && (*p == '\n' || *p == '\r'))
715 *p = '\0';
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000716
717 /*
718 * Handle spurious ^Z, which may be inserted into source files
719 * by some file transfer utilities.
720 */
721 buffer[strcspn(buffer, "\032")] = '\0';
722
H. Peter Anvin734b1882002-04-30 21:01:08 +0000723 list->line(LIST_READ, buffer);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000724
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000725 return buffer;
726}
727
728/*
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.
732 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000733static Token *
734tokenise(char *line)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000735{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000736 char *p = line;
737 int type;
738 Token *list = NULL;
739 Token *t, **tail = &list;
740
H. Peter Anvin734b1882002-04-30 21:01:08 +0000741 while (*line)
742 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000743 p = line;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000744 if (*p == '%')
H. Peter Anvineba20a72002-04-30 20:53:55 +0000745 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000746 p++;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000747 if ( isdigit(*p) ||
748 ((*p == '-' || *p == '+') && isdigit(p[1])) ||
749 ((*p == '+') && (isspace(p[1]) || !p[1])))
750 {
751 do
752 {
753 p++;
754 }
755 while (isdigit(*p));
756 type = TOK_PREPROC_ID;
757 }
758 else if (*p == '{')
759 {
760 p++;
761 while (*p && *p != '}')
762 {
763 p[-1] = *p;
764 p++;
765 }
766 p[-1] = '\0';
767 if (*p)
768 p++;
769 type = TOK_PREPROC_ID;
770 }
771 else if (isidchar(*p) ||
772 ((*p == '!' || *p == '%' || *p == '$') &&
773 isidchar(p[1])))
774 {
775 do
776 {
777 p++;
778 }
779 while (isidchar(*p));
780 type = TOK_PREPROC_ID;
781 }
782 else
783 {
784 type = TOK_OTHER;
785 if (*p == '%')
786 p++;
787 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000788 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000789 else if (isidstart(*p) || (*p == '$' && isidstart(p[1])))
H. Peter Anvineba20a72002-04-30 20:53:55 +0000790 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000791 type = TOK_ID;
792 p++;
793 while (*p && isidchar(*p))
794 p++;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000795 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000796 else if (*p == '\'' || *p == '"')
797 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000798 /*
799 * A string token.
800 */
801 char c = *p;
802 p++;
803 type = TOK_STRING;
804 while (*p && *p != c)
805 p++;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000806 if (*p)
807 {
808 p++;
809 }
810 else
811 {
812 error(ERR_WARNING, "unterminated string");
813 }
814 }
815 else if (isnumstart(*p))
816 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000817 /*
818 * A number token.
819 */
820 type = TOK_NUMBER;
821 p++;
822 while (*p && isnumchar(*p))
823 p++;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000824 }
825 else if (isspace(*p))
826 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000827 type = TOK_WHITESPACE;
828 p++;
829 while (*p && isspace(*p))
830 p++;
831 /*
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.
835 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000836 if (!*p || *p == ';')
837 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000838 type = TOK_COMMENT;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000839 while (*p)
840 p++;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000841 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000842 }
843 else if (*p == ';')
844 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000845 type = TOK_COMMENT;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000846 while (*p)
847 p++;
848 }
849 else
850 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000851 /*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000852 * 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.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000856 */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000857 type = TOK_OTHER;
H. Peter Anvin76690a12002-04-30 20:52:49 +0000858 if ((p[0] == '>' && p[1] == '>') ||
H. Peter Anvin734b1882002-04-30 21:01:08 +0000859 (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] == '^'))
H. Peter Anvineba20a72002-04-30 20:53:55 +0000869 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000870 p++;
H. Peter Anvineba20a72002-04-30 20:53:55 +0000871 }
H. Peter Anvin76690a12002-04-30 20:52:49 +0000872 p++;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000873 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000874 if (type != TOK_COMMENT)
875 {
876 *tail = t = new_Token(NULL, type, line, p - line);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000877 tail = &t->next;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000878 }
879 line = p;
880 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000881 return list;
882}
883
H. Peter Anvince616072002-04-30 21:02:23 +0000884/*
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.
888 */
889static void *
890new_Block(size_t size)
891{
892 Blocks *b = &blocks;
893
894 /* first, get to the end of the linked list */
895 while (b->next)
896 b = b->next;
897 /* now allocate the requested chunk */
898 b->chunk = nasm_malloc(size);
899
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;
905 return b->chunk;
906}
907
908/*
909 * this function deletes all managed blocks of memory
910 */
911static void
912delete_Blocks(void)
913{
914 Blocks *a,*b = &blocks;
915
916 /*
917 * keep in mind that the first block, pointed to by blocks
918 * is a static and not dynamically allocated, so we don't
919 * free it.
920 */
921 while (b)
922 {
923 if (b->chunk)
924 nasm_free(b->chunk);
925 a = b;
926 b = b->next;
H. Peter Anvin9eb185b2002-04-30 21:02:47 +0000927 if (a != &blocks)
H. Peter Anvince616072002-04-30 21:02:23 +0000928 nasm_free(a);
929 }
930}
H. Peter Anvin734b1882002-04-30 21:01:08 +0000931
932/*
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.
936 */
937static Token *
938new_Token(Token * next, int type, char *text, int txtlen)
939{
940 Token *t;
941 int i;
942
943 if (freeTokens == NULL)
944 {
H. Peter Anvince616072002-04-30 21:02:23 +0000945 freeTokens = (Token *)new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
H. Peter Anvin734b1882002-04-30 21:01:08 +0000946 for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
947 freeTokens[i].next = &freeTokens[i + 1];
948 freeTokens[i].next = NULL;
949 }
950 t = freeTokens;
951 freeTokens = t->next;
952 t->next = next;
953 t->mac = NULL;
954 t->type = type;
955 if (type == TOK_WHITESPACE || text == NULL)
956 {
957 t->text = NULL;
958 }
959 else
960 {
961 if (txtlen == 0)
962 txtlen = strlen(text);
963 t->text = nasm_malloc(1 + txtlen);
964 strncpy(t->text, text, txtlen);
965 t->text[txtlen] = '\0';
966 }
967 return t;
968}
969
970static Token *
971delete_Token(Token * t)
972{
973 Token *next = t->next;
974 nasm_free(t->text);
H. Peter Anvin788e6c12002-04-30 21:02:01 +0000975 t->next = freeTokens;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000976 freeTokens = t;
977 return next;
978}
979
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000980/*
981 * Convert a line of tokens back into text.
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000982 * If expand_locals is not zero, identifiers of the form "%$*xxx"
983 * will be transformed into ..@ctxnum.xxx
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000984 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000985static char *
986detoken(Token * tlist, int expand_locals)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000987{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000988 Token *t;
989 int len;
990 char *line, *p;
991
992 len = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000993 for (t = tlist; t; t = t->next)
994 {
995 if (t->type == TOK_PREPROC_ID && t->text[1] == '!')
996 {
997 char *p = getenv(t->text + 2);
998 nasm_free(t->text);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000999 if (p)
1000 t->text = nasm_strdup(p);
1001 else
1002 t->text = NULL;
1003 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001004 /* Expand local macros here and not during preprocessing */
1005 if (expand_locals &&
H. Peter Anvin734b1882002-04-30 21:01:08 +00001006 t->type == TOK_PREPROC_ID && t->text &&
1007 t->text[0] == '%' && t->text[1] == '$')
1008 {
1009 Context *ctx = get_ctx(t->text, FALSE);
1010 if (ctx)
1011 {
1012 char buffer[40];
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001013 char *p, *q = t->text + 2;
1014
H. Peter Anvin734b1882002-04-30 21:01:08 +00001015 q += strspn(q, "$");
1016 sprintf(buffer, "..@%lu.", ctx->number);
1017 p = nasm_strcat(buffer, q);
1018 nasm_free(t->text);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001019 t->text = p;
1020 }
1021 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001022 if (t->type == TOK_WHITESPACE)
1023 {
1024 len++;
1025 }
1026 else if (t->text)
1027 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001028 len += strlen(t->text);
H. Peter Anvin734b1882002-04-30 21:01:08 +00001029 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001030 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001031 p = line = nasm_malloc(len + 1);
1032 for (t = tlist; t; t = t->next)
1033 {
1034 if (t->type == TOK_WHITESPACE)
1035 {
1036 *p = ' ';
1037 p++;
1038 *p = '\0';
1039 }
1040 else if (t->text)
1041 {
1042 strcpy(p, t->text);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001043 p += strlen(p);
1044 }
1045 }
1046 *p = '\0';
1047 return line;
1048}
1049
1050/*
H. Peter Anvin76690a12002-04-30 20:52:49 +00001051 * 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
1054 * field.
1055 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001056static int
1057ppscan(void *private_data, struct tokenval *tokval)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001058{
H. Peter Anvin76690a12002-04-30 20:52:49 +00001059 Token **tlineptr = private_data;
1060 Token *tline;
1061
H. Peter Anvin734b1882002-04-30 21:01:08 +00001062 do
1063 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00001064 tline = *tlineptr;
1065 *tlineptr = tline ? tline->next : NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001066 }
1067 while (tline && (tline->type == TOK_WHITESPACE ||
1068 tline->type == TOK_COMMENT));
H. Peter Anvin76690a12002-04-30 20:52:49 +00001069
1070 if (!tline)
1071 return tokval->t_type = TOKEN_EOS;
1072
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;
1077
H. Peter Anvin734b1882002-04-30 21:01:08 +00001078 if (tline->type == TOK_ID)
1079 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00001080 tokval->t_charptr = tline->text;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001081 if (tline->text[0] == '$')
1082 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00001083 tokval->t_charptr++;
1084 return tokval->t_type = TOKEN_ID;
1085 }
1086
1087 /*
1088 * This is the only special case we actually need to worry
1089 * about in this restricted context.
1090 */
1091 if (!nasm_stricmp(tline->text, "seg"))
1092 return tokval->t_type = TOKEN_SEG;
1093
1094 return tokval->t_type = TOKEN_ID;
1095 }
1096
H. Peter Anvin734b1882002-04-30 21:01:08 +00001097 if (tline->type == TOK_NUMBER)
1098 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00001099 int rn_error;
1100
1101 tokval->t_integer = readnum(tline->text, &rn_error);
1102 if (rn_error)
1103 return tokval->t_type = TOKEN_ERRNUM;
1104 tokval->t_charptr = NULL;
1105 return tokval->t_type = TOKEN_NUM;
1106 }
1107
H. Peter Anvin734b1882002-04-30 21:01:08 +00001108 if (tline->type == TOK_STRING)
1109 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00001110 int rn_warn;
1111 char q, *r;
1112 int l;
1113
1114 r = tline->text;
1115 q = *r++;
1116 l = strlen(r);
1117
H. Peter Anvin734b1882002-04-30 21:01:08 +00001118 if (l == 0 || r[l - 1] != q)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001119 return tokval->t_type = TOKEN_ERRNUM;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001120 tokval->t_integer = readstrnum(r, l - 1, &rn_warn);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001121 if (rn_warn)
H. Peter Anvin734b1882002-04-30 21:01:08 +00001122 error(ERR_WARNING | ERR_PASS1, "character constant too long");
H. Peter Anvineba20a72002-04-30 20:53:55 +00001123 tokval->t_charptr = NULL;
1124 return tokval->t_type = TOKEN_NUM;
1125 }
1126
H. Peter Anvin734b1882002-04-30 21:01:08 +00001127 if (tline->type == TOK_OTHER)
1128 {
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;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001153 }
1154
1155 /*
1156 * We have no other options: just return the first character of
1157 * the token text.
1158 */
1159 return tokval->t_type = tline->text[0];
1160}
1161
1162/*
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001163 * 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.
1166 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001167static int
1168mstrcmp(char *p, char *q, int casesense)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001169{
H. Peter Anvin734b1882002-04-30 21:01:08 +00001170 return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001171}
1172
1173/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001174 * 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 $
1177 * signs.
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001178 * 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.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001182 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001183static Context *
1184get_ctx(char *name, int all_contexts)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001185{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001186 Context *ctx;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001187 SMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001188 int i;
1189
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001190 if (!name || name[0] != '%' || name[1] != '$')
1191 return NULL;
1192
H. Peter Anvin734b1882002-04-30 21:01:08 +00001193 if (!cstk)
1194 {
1195 error(ERR_NONFATAL, "`%s': context stack is empty", name);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001196 return NULL;
1197 }
1198
H. Peter Anvin734b1882002-04-30 21:01:08 +00001199 for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--)
1200 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001201 ctx = ctx->next;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001202 i--;
1203 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001204 if (!ctx)
1205 {
1206 error(ERR_NONFATAL, "`%s': context stack is only"
1207 " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
1208 return NULL;
1209 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001210 if (!all_contexts)
H. Peter Anvin734b1882002-04-30 21:01:08 +00001211 return ctx;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001212
H. Peter Anvin734b1882002-04-30 21:01:08 +00001213 do
1214 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001215 /* Search for this smacro in found context */
1216 m = ctx->localmac;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001217 while (m)
1218 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001219 if (!mstrcmp(m->name, name, m->casesense))
1220 return ctx;
1221 m = m->next;
1222 }
1223 ctx = ctx->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001224 }
1225 while (ctx);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001226 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001227}
1228
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001229/* 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.
1231 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001232static void
1233backslash(char *s)
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001234{
1235 int pos = strlen(s);
H. Peter Anvin734b1882002-04-30 21:01:08 +00001236 if (s[pos - 1] != '\\' && s[pos - 1] != '/')
1237 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001238 s[pos] = '/';
H. Peter Anvin734b1882002-04-30 21:01:08 +00001239 s[pos + 1] = '\0';
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001240 }
1241}
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001242
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001243/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001244 * 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.
1249 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001250static FILE *
1251inc_fopen(char *file)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001252{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001253 FILE *fp;
1254 char *prefix = "", *combine;
1255 IncPath *ip = ipath;
H. Peter Anvin620515a2002-04-30 20:57:38 +00001256 static int namelen = 0;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001257 int len = strlen(file);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001258
H. Peter Anvin734b1882002-04-30 21:01:08 +00001259 while (1)
1260 {
1261 combine = nasm_malloc(strlen(prefix) + 1 + len + 1);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001262 strcpy(combine, prefix);
1263 if (prefix[0] != 0)
1264 backslash(combine);
1265 strcat(combine, file);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001266 fp = fopen(combine, "r");
H. Peter Anvin620515a2002-04-30 20:57:38 +00001267 if (pass == 0 && fp)
1268 {
H. Peter Anvin734b1882002-04-30 21:01:08 +00001269 namelen += strlen(combine) + 1;
1270 if (namelen > 62)
1271 {
1272 printf(" \\\n ");
1273 namelen = 2;
1274 }
1275 printf(" %s", combine);
H. Peter Anvin620515a2002-04-30 20:57:38 +00001276 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001277 nasm_free(combine);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001278 if (fp)
1279 return fp;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001280 if (!ip)
1281 break;
1282 prefix = ip->path;
1283 ip = ip->next;
1284 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001285
H. Peter Anvin734b1882002-04-30 21:01:08 +00001286 error(ERR_FATAL, "unable to open include file `%s'", file);
1287 return NULL; /* never reached - placate compilers */
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001288}
1289
1290/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001291 * Determine if we should warn on defining a single-line macro of
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001292 * name `name', with `nparam' parameters. If nparam is 0 or -1, will
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001293 * 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.
1296 *
1297 * If a macro with precisely the right number of parameters is
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001298 * defined, or nparam is -1, the address of the definition structure
1299 * will be returned in `defn'; otherwise NULL will be returned. If `defn'
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001300 * is NULL, no action will be taken regarding its contents, and no
1301 * error will occur.
1302 *
1303 * Note that this is also called with nparam zero to resolve
1304 * `ifdef'.
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001305 *
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.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001310 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001311static int
1312smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
1313 int nocase)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001314{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001315 SMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001316
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001317 if (ctx)
1318 m = ctx->localmac;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001319 else if (name[0] == '%' && name[1] == '$')
1320 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001321 if (cstk)
H. Peter Anvin734b1882002-04-30 21:01:08 +00001322 ctx = get_ctx(name, FALSE);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001323 if (!ctx)
H. Peter Anvin734b1882002-04-30 21:01:08 +00001324 return FALSE; /* got to return _something_ */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001325 m = ctx->localmac;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001326 }
1327 else
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001328 m = smacros[hash(name)];
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001329
H. Peter Anvin734b1882002-04-30 21:01:08 +00001330 while (m)
1331 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001332 if (!mstrcmp(m->name, name, m->casesense && nocase) &&
H. Peter Anvin734b1882002-04-30 21:01:08 +00001333 (nparam <= 0 || m->nparam == 0 || nparam == m->nparam))
1334 {
1335 if (defn)
1336 {
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001337 if (nparam == m->nparam || nparam == -1)
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001338 *defn = m;
1339 else
1340 *defn = NULL;
1341 }
1342 return TRUE;
1343 }
1344 m = m->next;
1345 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001346
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001347 return FALSE;
1348}
1349
1350/*
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.
1355 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001356static void
1357count_mmac_params(Token * t, int *nparam, Token *** params)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001358{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001359 int paramsize, brace;
1360
1361 *nparam = paramsize = 0;
1362 *params = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001363 while (t)
1364 {
1365 if (*nparam >= paramsize)
1366 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001367 paramsize += PARAM_DELTA;
1368 *params = nasm_realloc(*params, sizeof(**params) * paramsize);
1369 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00001370 skip_white_(t);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001371 brace = FALSE;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001372 if (tok_is_(t, "{"))
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001373 brace = TRUE;
1374 (*params)[(*nparam)++] = t;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001375 while (tok_isnt_(t, brace ? "}" : ","))
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001376 t = t->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001377 if (t)
1378 { /* got a comma/brace */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001379 t = t->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001380 if (brace)
1381 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001382 /*
1383 * Now we've found the closing brace, look further
1384 * for the comma.
1385 */
H. Peter Anvineba20a72002-04-30 20:53:55 +00001386 skip_white_(t);
H. Peter Anvin734b1882002-04-30 21:01:08 +00001387 if (tok_isnt_(t, ","))
1388 {
1389 error(ERR_NONFATAL,
1390 "braces do not enclose all of macro parameter");
H. Peter Anvineba20a72002-04-30 20:53:55 +00001391 while (tok_isnt_(t, ","))
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001392 t = t->next;
1393 }
1394 if (t)
H. Peter Anvin734b1882002-04-30 21:01:08 +00001395 t = t->next; /* eat the comma */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001396 }
1397 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001398 }
1399}
1400
1401/*
H. Peter Anvin76690a12002-04-30 20:52:49 +00001402 * Determine whether one of the various `if' conditions is true or
1403 * not.
1404 *
1405 * We must free the tline we get passed.
1406 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001407static int
1408if_condition(Token * tline, int i)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001409{
H. Peter Anvin734b1882002-04-30 21:01:08 +00001410 int j, casesense;
1411 Token *t, *tt, **tptr, *origline;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001412 struct tokenval tokval;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001413 expr *evalresult;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001414
1415 origline = tline;
1416
H. Peter Anvin734b1882002-04-30 21:01:08 +00001417 switch (i)
1418 {
1419 case PP_IFCTX:
1420 case PP_ELIFCTX:
1421 case PP_IFNCTX:
1422 case PP_ELIFNCTX:
1423 j = FALSE; /* have we matched yet? */
1424 while (cstk && tline)
1425 {
1426 skip_white_(tline);
1427 if (!tline || tline->type != TOK_ID)
1428 {
1429 error(ERR_NONFATAL,
1430 "`%s' expects context identifiers",
1431 directives[i]);
1432 free_tlist(origline);
1433 return -1;
1434 }
1435 if (!nasm_stricmp(tline->text, cstk->name))
1436 j = TRUE;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001437 tline = tline->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001438 }
1439 if (i == PP_IFNCTX || i == PP_ELIFNCTX)
1440 j = !j;
1441 free_tlist(origline);
1442 return j;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001443
H. Peter Anvin734b1882002-04-30 21:01:08 +00001444 case PP_IFDEF:
1445 case PP_ELIFDEF:
1446 case PP_IFNDEF:
1447 case PP_ELIFNDEF:
1448 j = FALSE; /* have we matched yet? */
1449 while (tline)
1450 {
1451 skip_white_(tline);
1452 if (!tline || (tline->type != TOK_ID &&
1453 (tline->type != TOK_PREPROC_ID ||
1454 tline->text[1] != '$')))
1455 {
1456 error(ERR_NONFATAL,
1457 "`%%if%sdef' expects macro identifiers",
1458 (i == PP_ELIFNDEF ? "n" : ""));
1459 free_tlist(origline);
1460 return -1;
1461 }
1462 if (smacro_defined(NULL, tline->text, 0, NULL, 1))
1463 j = TRUE;
1464 tline = tline->next;
1465 }
1466 if (i == PP_IFNDEF || i == PP_ELIFNDEF)
1467 j = !j;
1468 free_tlist(origline);
1469 return j;
1470
1471 case PP_IFIDN:
1472 case PP_ELIFIDN:
1473 case PP_IFNIDN:
1474 case PP_ELIFNIDN:
1475 case PP_IFIDNI:
1476 case PP_ELIFIDNI:
1477 case PP_IFNIDNI:
1478 case PP_ELIFNIDNI:
1479 tline = expand_smacro(tline);
1480 t = tt = tline;
1481 while (tok_isnt_(tt, ","))
1482 tt = tt->next;
1483 if (!tt)
1484 {
1485 error(ERR_NONFATAL,
1486 "`%s' expects two comma-separated arguments",
1487 directives[i]);
1488 free_tlist(tline);
H. Peter Anvin76690a12002-04-30 20:52:49 +00001489 return -1;
1490 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001491 tt = tt->next;
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)
1496 {
1497 if (tt->type == TOK_OTHER && !strcmp(tt->text, ","))
1498 {
1499 error(ERR_NONFATAL, "`%s': more than one comma on line",
1500 directives[i]);
1501 free_tlist(tline);
1502 return -1;
1503 }
1504 if (t->type == TOK_WHITESPACE)
1505 {
1506 t = t->next;
1507 continue;
1508 }
1509 else if (tt->type == TOK_WHITESPACE)
1510 {
1511 tt = tt->next;
1512 continue;
1513 }
1514 else if (tt->type != t->type ||
1515 mstrcmp(tt->text, t->text, casesense))
1516 {
1517 j = FALSE; /* found mismatching tokens */
1518 break;
1519 }
1520 else
1521 {
1522 t = t->next;
1523 tt = tt->next;
1524 continue;
1525 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00001526 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001527 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)
1531 j = !j;
1532 free_tlist(tline);
1533 return j;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001534
H. Peter Anvin734b1882002-04-30 21:01:08 +00001535 case PP_IFID:
1536 case PP_ELIFID:
1537 case PP_IFNID:
1538 case PP_ELIFNID:
1539 case PP_IFNUM:
1540 case PP_ELIFNUM:
1541 case PP_IFNNUM:
1542 case PP_ELIFNNUM:
1543 case PP_IFSTR:
1544 case PP_ELIFSTR:
1545 case PP_IFNSTR:
1546 case PP_ELIFNSTR:
1547 tline = expand_smacro(tline);
1548 t = tline;
1549 while (tok_type_(t, TOK_WHITESPACE))
1550 t = t->next;
1551 j = FALSE; /* placate optimiser */
1552 if (t)
1553 switch (i)
1554 {
1555 case PP_IFID:
1556 case PP_ELIFID:
1557 case PP_IFNID:
1558 case PP_ELIFNID:
1559 j = (t->type == TOK_ID);
1560 break;
1561 case PP_IFNUM:
1562 case PP_ELIFNUM:
1563 case PP_IFNNUM:
1564 case PP_ELIFNNUM:
1565 j = (t->type == TOK_NUMBER);
1566 break;
1567 case PP_IFSTR:
1568 case PP_ELIFSTR:
1569 case PP_IFNSTR:
1570 case PP_ELIFNSTR:
1571 j = (t->type == TOK_STRING);
1572 break;
1573 }
1574 if (i == PP_IFNID || i == PP_ELIFNID ||
1575 i == PP_IFNNUM || i == PP_ELIFNNUM ||
1576 i == PP_IFNSTR || i == PP_ELIFNSTR)
1577 j = !j;
1578 free_tlist(tline);
1579 return j;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001580
H. Peter Anvin734b1882002-04-30 21:01:08 +00001581 case PP_IF:
1582 case PP_ELIF:
1583 t = tline = expand_smacro(tline);
1584 tptr = &t;
1585 tokval.t_type = TOKEN_INVALID;
1586 evalresult = evaluate(ppscan, tptr, &tokval,
1587 NULL, pass | CRITICAL, error, NULL);
1588 free_tlist(tline);
1589 if (!evalresult)
1590 return -1;
1591 if (tokval.t_type)
1592 error(ERR_WARNING,
1593 "trailing garbage after expression ignored");
1594 if (!is_simple(evalresult))
1595 {
1596 error(ERR_NONFATAL,
1597 "non-constant value given to `%s'", directives[i]);
1598 return -1;
1599 }
1600 return reloc_value(evalresult) != 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001601
H. Peter Anvin734b1882002-04-30 21:01:08 +00001602 default:
1603 error(ERR_FATAL,
1604 "preprocessor directive `%s' not yet implemented",
1605 directives[i]);
1606 free_tlist(origline);
1607 return -1; /* yeah, right */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001608 }
1609}
1610
1611/*
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001612 * 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.
1615 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001616void
1617expand_macros_in_string(char **p)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001618{
H. Peter Anvin734b1882002-04-30 21:01:08 +00001619 Token *line = tokenise(*p);
1620 line = expand_smacro(line);
1621 *p = detoken(line, FALSE);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001622}
1623
1624/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001625 * Find out if a line contains a preprocessor directive, and deal
1626 * with it if so.
1627 *
H. Peter Anvin76690a12002-04-30 20:52:49 +00001628 * If a directive _is_ found, we are expected to free_tlist() the
1629 * line.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001630 *
1631 * Return values go like this:
1632 *
H. Peter Anvin76690a12002-04-30 20:52:49 +00001633 * bit 0 is set if a directive was found (so the line gets freed)
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001634 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001635static int
1636do_directive(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001637{
H. Peter Anvin76690a12002-04-30 20:52:49 +00001638 int i, j, k, m, nparam, nolist;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001639 int offset;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001640 char *p, *mname;
1641 Include *inc;
1642 Context *ctx;
1643 Cond *cond;
1644 SMacro *smac, **smhead;
1645 MMacro *mmac;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001646 Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
1647 Line *l;
1648 struct tokenval tokval;
1649 expr *evalresult;
H. Peter Anvinb64535f2002-04-30 20:55:37 +00001650 MMacro *tmp_defining; /* Used when manipulating rep_nest */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001651
1652 origline = tline;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001653
H. Peter Anvineba20a72002-04-30 20:53:55 +00001654 skip_white_(tline);
1655 if (!tok_type_(tline, TOK_PREPROC_ID) ||
H. Peter Anvin734b1882002-04-30 21:01:08 +00001656 (tline->text[1] == '%' || tline->text[1] == '$'
1657 || tline->text[1] == '!'))
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001658 return 0;
1659
1660 i = -1;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001661 j = sizeof(directives) / sizeof(*directives);
1662 while (j - i > 1)
1663 {
1664 k = (j + i) / 2;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001665 m = nasm_stricmp(tline->text, directives[k]);
1666 if (m == 0) {
H. Peter Anvin734b1882002-04-30 21:01:08 +00001667 if (tasm_compatible_mode) {
1668 i = k;
1669 j = -2;
1670 } else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) {
1671 i = k;
1672 j = -2;
1673 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001674 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001675 }
1676 else if (m < 0) {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001677 j = k;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001678 }
1679 else
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001680 i = k;
1681 }
1682
1683 /*
1684 * If we're in a non-emitting branch of a condition construct,
H. Peter Anvin76690a12002-04-30 20:52:49 +00001685 * or walking to the end of an already terminated %rep block,
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001686 * we should ignore all directives except for condition
1687 * directives.
1688 */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001689 if (((istk->conds && !emitting(istk->conds->state)) ||
H. Peter Anvin734b1882002-04-30 21:01:08 +00001690 (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)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001706 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001707 return 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001708 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001709
1710 /*
H. Peter Anvin76690a12002-04-30 20:52:49 +00001711 * 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
H. Peter Anvineba20a72002-04-30 20:53:55 +00001714 * %rep block) %endrep. If we're in a %rep block, another %rep
1715 * causes an error, so should be let through.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001716 */
1717 if (defining && i != PP_MACRO && i != PP_IMACRO &&
H. Peter Anvin734b1882002-04-30 21:01:08 +00001718 i != PP_ENDMACRO && i != PP_ENDM &&
1719 (defining->name || (i != PP_ENDREP && i != PP_REP)))
H. Peter Anvineba20a72002-04-30 20:53:55 +00001720 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001721 return 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001722 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001723
H. Peter Anvin734b1882002-04-30 21:01:08 +00001724 if (j != -2)
1725 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00001726 error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
H. Peter Anvin734b1882002-04-30 21:01:08 +00001727 tline->text);
1728 return 0; /* didn't get it */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001729 }
1730
H. Peter Anvin734b1882002-04-30 21:01:08 +00001731 switch (i)
1732 {
1733 case PP_STACKSIZE:
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
1736 * %stacksize large.
1737 * the following form:
1738 *
1739 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001740 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001741 tline = tline->next;
1742 if (tline && tline->type == TOK_WHITESPACE)
1743 tline = tline->next;
1744 if (!tline || tline->type != TOK_ID)
1745 {
1746 error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
1747 free_tlist(origline);
1748 return 3;
1749 }
1750 if (nasm_stricmp(tline->text, "flat") == 0)
1751 {
1752 /* All subsequent ARG directives are for a 32-bit stack */
1753 StackSize = 4;
1754 StackPointer = "ebp";
1755 ArgOffset = 8;
1756 LocalOffset = 4;
1757 }
1758 else if (nasm_stricmp(tline->text, "large") == 0)
1759 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001760 /* All subsequent ARG directives are for a 16-bit stack,
H. Peter Anvin734b1882002-04-30 21:01:08 +00001761 * far function call.
1762 */
1763 StackSize = 2;
1764 StackPointer = "bp";
1765 ArgOffset = 4;
1766 LocalOffset = 2;
1767 }
1768 else if (nasm_stricmp(tline->text, "small") == 0)
1769 {
1770 /* All subsequent ARG directives are for a 16-bit stack,
1771 * far function call. We don't support near functions.
1772 */
1773 StackSize = 2;
1774 StackPointer = "bp";
1775 ArgOffset = 6;
1776 LocalOffset = 2;
1777 }
1778 else
1779 {
1780 error(ERR_NONFATAL, "`%%stacksize' invalid size type");
1781 free_tlist(origline);
1782 return 3;
1783 }
1784 free_tlist(origline);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001785 return 3;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001786
H. Peter Anvin734b1882002-04-30 21:01:08 +00001787 case PP_ARG:
1788 /* TASM like ARG directive to define arguments to functions, in
1789 * the following form:
1790 *
1791 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1792 */
1793 offset = ArgOffset;
1794 do
1795 {
1796 char *arg, directive[256];
1797 int size = StackSize;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001798
H. Peter Anvin734b1882002-04-30 21:01:08 +00001799 /* Find the argument name */
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001800 tline = tline->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001801 if (tline && tline->type == TOK_WHITESPACE)
1802 tline = tline->next;
1803 if (!tline || tline->type != TOK_ID)
1804 {
1805 error(ERR_NONFATAL, "`%%arg' missing argument parameter");
1806 free_tlist(origline);
1807 return 3;
1808 }
1809 arg = tline->text;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001810
H. Peter Anvin734b1882002-04-30 21:01:08 +00001811 /* Find the argument size type */
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001812 tline = tline->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001813 if (!tline || tline->type != TOK_OTHER
1814 || tline->text[0] != ':')
1815 {
1816 error(ERR_NONFATAL,
1817 "Syntax error processing `%%arg' directive");
1818 free_tlist(origline);
1819 return 3;
1820 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001821 tline = tline->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001822 if (!tline || tline->type != TOK_ID)
1823 {
1824 error(ERR_NONFATAL,
1825 "`%%arg' missing size type parameter");
1826 free_tlist(origline);
1827 return 3;
1828 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001829
H. Peter Anvin734b1882002-04-30 21:01:08 +00001830 /* Allow macro expansion of type parameter */
1831 tt = tokenise(tline->text);
1832 tt = expand_smacro(tt);
1833 if (nasm_stricmp(tt->text, "byte") == 0)
1834 {
1835 size = MAX(StackSize, 1);
1836 }
1837 else if (nasm_stricmp(tt->text, "word") == 0)
1838 {
1839 size = MAX(StackSize, 2);
1840 }
1841 else if (nasm_stricmp(tt->text, "dword") == 0)
1842 {
1843 size = MAX(StackSize, 4);
1844 }
1845 else if (nasm_stricmp(tt->text, "qword") == 0)
1846 {
1847 size = MAX(StackSize, 8);
1848 }
1849 else if (nasm_stricmp(tt->text, "tword") == 0)
1850 {
1851 size = MAX(StackSize, 10);
1852 }
1853 else
1854 {
1855 error(ERR_NONFATAL,
1856 "Invalid size type for `%%arg' missing directive");
1857 free_tlist(tt);
1858 free_tlist(origline);
1859 return 3;
1860 }
1861 free_tlist(tt);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001862
H. Peter Anvin734b1882002-04-30 21:01:08 +00001863 /* Now define the macro for the argument */
1864 sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer,
1865 offset);
1866 do_directive(tokenise(directive));
1867 offset += size;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001868
H. Peter Anvin734b1882002-04-30 21:01:08 +00001869 /* Move to the next argument in the list */
1870 tline = tline->next;
1871 if (tline && tline->type == TOK_WHITESPACE)
1872 tline = tline->next;
1873 }
1874 while (tline && tline->type == TOK_OTHER
1875 && tline->text[0] == ',');
1876 free_tlist(origline);
1877 return 3;
1878
1879 case PP_LOCAL:
1880 /* TASM like LOCAL directive to define local variables for a
1881 * function, in the following form:
1882 *
1883 * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1884 *
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).
1888 */
1889 offset = LocalOffset;
1890 do
1891 {
1892 char *local, directive[256];
1893 int size = StackSize;
1894
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)
1900 {
1901 error(ERR_NONFATAL,
1902 "`%%local' missing argument parameter");
1903 free_tlist(origline);
1904 return 3;
1905 }
1906 local = tline->text;
1907
1908 /* Find the argument size type */
1909 tline = tline->next;
1910 if (!tline || tline->type != TOK_OTHER
1911 || tline->text[0] != ':')
1912 {
1913 error(ERR_NONFATAL,
1914 "Syntax error processing `%%local' directive");
1915 free_tlist(origline);
1916 return 3;
1917 }
1918 tline = tline->next;
1919 if (!tline || tline->type != TOK_ID)
1920 {
1921 error(ERR_NONFATAL,
1922 "`%%local' missing size type parameter");
1923 free_tlist(origline);
1924 return 3;
1925 }
1926
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)
1931 {
1932 size = MAX(StackSize, 1);
1933 }
1934 else if (nasm_stricmp(tt->text, "word") == 0)
1935 {
1936 size = MAX(StackSize, 2);
1937 }
1938 else if (nasm_stricmp(tt->text, "dword") == 0)
1939 {
1940 size = MAX(StackSize, 4);
1941 }
1942 else if (nasm_stricmp(tt->text, "qword") == 0)
1943 {
1944 size = MAX(StackSize, 8);
1945 }
1946 else if (nasm_stricmp(tt->text, "tword") == 0)
1947 {
1948 size = MAX(StackSize, 10);
1949 }
1950 else
1951 {
1952 error(ERR_NONFATAL,
1953 "Invalid size type for `%%local' missing directive");
1954 free_tlist(tt);
1955 free_tlist(origline);
1956 return 3;
1957 }
1958 free_tlist(tt);
1959
1960 /* Now define the macro for the argument */
1961 sprintf(directive, "%%define %s (%s-%d)", local, StackPointer,
1962 offset);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001963 do_directive(tokenise(directive));
1964 offset += size;
1965
1966 /* Now define the assign to setup the enter_c macro correctly */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001967 sprintf(directive, "%%assign %%$localsize %%$localsize+%d",
1968 size);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001969 do_directive(tokenise(directive));
1970
H. Peter Anvin734b1882002-04-30 21:01:08 +00001971 /* Move to the next argument in the list */
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001972 tline = tline->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001973 if (tline && tline->type == TOK_WHITESPACE)
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001974 tline = tline->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001975 }
1976 while (tline && tline->type == TOK_OTHER
1977 && tline->text[0] == ',');
1978 free_tlist(origline);
1979 return 3;
1980
1981 case PP_CLEAR:
1982 if (tline->next)
1983 error(ERR_WARNING,
1984 "trailing garbage after `%%clear' ignored");
1985 for (j = 0; j < NHASH; j++)
1986 {
1987 while (mmacros[j])
1988 {
1989 MMacro *m = mmacros[j];
1990 mmacros[j] = m->next;
1991 free_mmacro(m);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001992 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001993 while (smacros[j])
1994 {
1995 SMacro *s = smacros[j];
1996 smacros[j] = smacros[j]->next;
1997 nasm_free(s->name);
1998 free_tlist(s->expansion);
1999 nasm_free(s);
2000 }
2001 }
2002 free_tlist(origline);
2003 return 3;
2004
2005 case PP_INCLUDE:
2006 tline = tline->next;
2007 skip_white_(tline);
2008 if (!tline || (tline->type != TOK_STRING &&
2009 tline->type != TOK_INTERNAL_STRING))
2010 {
2011 error(ERR_NONFATAL, "`%%include' expects a file name");
2012 free_tlist(origline);
2013 return 3; /* but we did _something_ */
2014 }
2015 if (tline->next)
2016 error(ERR_WARNING,
2017 "trailing garbage after `%%include' ignored");
2018 if (tline->type != TOK_INTERNAL_STRING)
2019 {
2020 p = tline->text + 1; /* point past the quote to the name */
2021 p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
2022 }
2023 else
2024 p = tline->text; /* internal_string is easier */
2025 expand_macros_in_string(&p);
2026 inc = nasm_malloc(sizeof(Include));
2027 inc->next = istk;
2028 inc->conds = NULL;
2029 inc->fp = inc_fopen(p);
2030 inc->fname = src_set_fname(p);
2031 inc->lineno = src_set_linnum(0);
2032 inc->lineinc = 1;
2033 inc->expansion = NULL;
2034 inc->mstk = NULL;
2035 istk = inc;
2036 list->uplevel(LIST_INCLUDE);
2037 free_tlist(origline);
2038 return 5;
2039
2040 case PP_PUSH:
2041 tline = tline->next;
2042 skip_white_(tline);
2043 tline = expand_id(tline);
2044 if (!tok_type_(tline, TOK_ID))
2045 {
2046 error(ERR_NONFATAL, "`%%push' expects a context identifier");
2047 free_tlist(origline);
2048 return 3; /* but we did _something_ */
2049 }
2050 if (tline->next)
2051 error(ERR_WARNING, "trailing garbage after `%%push' ignored");
2052 ctx = nasm_malloc(sizeof(Context));
2053 ctx->next = cstk;
2054 ctx->localmac = NULL;
2055 ctx->name = nasm_strdup(tline->text);
2056 ctx->number = unique++;
2057 cstk = ctx;
2058 free_tlist(origline);
2059 break;
2060
2061 case PP_REPL:
2062 tline = tline->next;
2063 skip_white_(tline);
2064 tline = expand_id(tline);
2065 if (!tok_type_(tline, TOK_ID))
2066 {
2067 error(ERR_NONFATAL, "`%%repl' expects a context identifier");
2068 free_tlist(origline);
2069 return 3; /* but we did _something_ */
2070 }
2071 if (tline->next)
2072 error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
2073 if (!cstk)
2074 error(ERR_NONFATAL, "`%%repl': context stack is empty");
2075 else
2076 {
2077 nasm_free(cstk->name);
2078 cstk->name = nasm_strdup(tline->text);
2079 }
2080 free_tlist(origline);
2081 break;
2082
2083 case PP_POP:
2084 if (tline->next)
2085 error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
2086 if (!cstk)
2087 error(ERR_NONFATAL,
2088 "`%%pop': context stack is already empty");
2089 else
2090 ctx_pop();
2091 free_tlist(origline);
2092 break;
2093
2094 case PP_ERROR:
2095 tline->next = expand_smacro(tline->next);
2096 tline = tline->next;
2097 skip_white_(tline);
2098 if (tok_type_(tline, TOK_STRING))
2099 {
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);
2104 nasm_free(p);
2105 }
2106 else
2107 {
2108 p = detoken(tline, FALSE);
2109 error(ERR_WARNING, "%s", p);
2110 nasm_free(p);
2111 }
2112 free_tlist(origline);
2113 break;
2114
2115 case PP_IF:
2116 case PP_IFCTX:
2117 case PP_IFDEF:
2118 case PP_IFID:
2119 case PP_IFIDN:
2120 case PP_IFIDNI:
2121 case PP_IFNCTX:
2122 case PP_IFNDEF:
2123 case PP_IFNID:
2124 case PP_IFNIDN:
2125 case PP_IFNIDNI:
2126 case PP_IFNNUM:
2127 case PP_IFNSTR:
2128 case PP_IFNUM:
2129 case PP_IFSTR:
2130 if (istk->conds && !emitting(istk->conds->state))
2131 j = COND_NEVER;
2132 else
2133 {
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;
2138 }
2139 cond = nasm_malloc(sizeof(Cond));
2140 cond->next = istk->conds;
2141 cond->state = j;
2142 istk->conds = cond;
2143 return (j == COND_IF_TRUE ? 3 : 1);
2144
2145 case PP_ELIF:
2146 case PP_ELIFCTX:
2147 case PP_ELIFDEF:
2148 case PP_ELIFID:
2149 case PP_ELIFIDN:
2150 case PP_ELIFIDNI:
2151 case PP_ELIFNCTX:
2152 case PP_ELIFNDEF:
2153 case PP_ELIFNID:
2154 case PP_ELIFNIDN:
2155 case PP_ELIFNIDNI:
2156 case PP_ELIFNNUM:
2157 case PP_ELIFNSTR:
2158 case PP_ELIFNUM:
2159 case PP_ELIFSTR:
2160 if (!istk->conds)
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;
2165 else
2166 {
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;
2172 }
2173 return (istk->conds->state == COND_IF_TRUE ? 5 : 1);
2174
2175 case PP_ELSE:
2176 if (tline->next)
2177 error(ERR_WARNING, "trailing garbage after `%%else' ignored");
2178 if (!istk->conds)
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;
2183 else
2184 istk->conds->state = COND_ELSE_TRUE;
2185 free_tlist(origline);
2186 return 5;
2187
2188 case PP_ENDIF:
2189 if (tline->next)
2190 error(ERR_WARNING,
2191 "trailing garbage after `%%endif' ignored");
2192 if (!istk->conds)
2193 error(ERR_FATAL, "`%%endif': no matching `%%if'");
2194 cond = istk->conds;
2195 istk->conds = cond->next;
2196 nasm_free(cond);
2197 free_tlist(origline);
2198 return 5;
2199
2200 case PP_MACRO:
2201 case PP_IMACRO:
2202 if (defining)
2203 error(ERR_FATAL,
2204 "`%%%smacro': already defining a macro",
2205 (i == PP_IMACRO ? "i" : ""));
2206 tline = tline->next;
2207 skip_white_(tline);
2208 tline = expand_id(tline);
2209 if (!tok_type_(tline, TOK_ID))
2210 {
2211 error(ERR_NONFATAL,
2212 "`%%%smacro' expects a macro name",
2213 (i == PP_IMACRO ? "i" : ""));
2214 return 3;
2215 }
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);
2224 skip_white_(tline);
2225 if (!tok_type_(tline, TOK_NUMBER))
2226 {
2227 error(ERR_NONFATAL,
2228 "`%%%smacro' expects a parameter count",
2229 (i == PP_IMACRO ? "i" : ""));
2230 defining->nparam_min = defining->nparam_max = 0;
2231 }
2232 else
2233 {
2234 defining->nparam_min = defining->nparam_max =
2235 readnum(tline->text, &j);
2236 if (j)
2237 error(ERR_NONFATAL,
2238 "unable to parse parameter count `%s'",
2239 tline->text);
2240 }
2241 if (tline && tok_is_(tline->next, "-"))
2242 {
2243 tline = tline->next->next;
2244 if (tok_is_(tline, "*"))
2245 defining->nparam_max = INT_MAX;
2246 else if (!tok_type_(tline, TOK_NUMBER))
2247 error(ERR_NONFATAL,
2248 "`%%%smacro' expects a parameter count after `-'",
2249 (i == PP_IMACRO ? "i" : ""));
2250 else
2251 {
2252 defining->nparam_max = readnum(tline->text, &j);
2253 if (j)
2254 error(ERR_NONFATAL,
2255 "unable to parse parameter count `%s'",
2256 tline->text);
2257 if (defining->nparam_min > defining->nparam_max)
2258 error(ERR_NONFATAL,
2259 "minimum parameter count exceeds maximum");
2260 }
2261 }
2262 if (tline && tok_is_(tline->next, "+"))
2263 {
2264 tline = tline->next;
2265 defining->plus = TRUE;
2266 }
2267 if (tline && tok_type_(tline->next, TOK_ID) &&
2268 !nasm_stricmp(tline->next->text, ".nolist"))
2269 {
2270 tline = tline->next;
2271 defining->nolist = TRUE;
2272 }
2273 mmac = mmacros[hash(defining->name)];
2274 while (mmac)
2275 {
2276 if (!strcmp(mmac->name, defining->name) &&
2277 (mmac->nparam_min <= defining->nparam_max
2278 || defining->plus)
2279 && (defining->nparam_min <= mmac->nparam_max
2280 || mmac->plus))
2281 {
2282 error(ERR_WARNING,
2283 "redefining multi-line macro `%s'",
2284 defining->name);
2285 break;
2286 }
2287 mmac = mmac->next;
2288 }
2289 /*
2290 * Handle default parameters.
2291 */
2292 if (tline && tline->next)
2293 {
2294 defining->dlist = tline->next;
2295 tline->next = NULL;
2296 count_mmac_params(defining->dlist, &defining->ndefs,
2297 &defining->defaults);
2298 }
2299 else
2300 {
2301 defining->dlist = NULL;
2302 defining->defaults = NULL;
2303 }
2304 defining->expansion = NULL;
2305 free_tlist(origline);
2306 return 1;
2307
2308 case PP_ENDM:
2309 case PP_ENDMACRO:
2310 if (!defining)
2311 {
2312 error(ERR_NONFATAL, "`%s': not defining a macro",
2313 tline->text);
2314 return 3;
2315 }
2316 k = hash(defining->name);
2317 defining->next = mmacros[k];
2318 mmacros[k] = defining;
2319 defining = NULL;
2320 free_tlist(origline);
2321 return 5;
2322
2323 case PP_ROTATE:
2324 if (tline->next && tline->next->type == TOK_WHITESPACE)
2325 tline = tline->next;
2326 t = expand_smacro(tline->next);
2327 tline->next = NULL;
2328 free_tlist(origline);
2329 tline = t;
2330 tptr = &t;
2331 tokval.t_type = TOKEN_INVALID;
2332 evalresult =
2333 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2334 free_tlist(tline);
2335 if (!evalresult)
2336 return 3;
2337 if (tokval.t_type)
2338 error(ERR_WARNING,
2339 "trailing garbage after expression ignored");
2340 if (!is_simple(evalresult))
2341 {
2342 error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
2343 return 3;
2344 }
2345 mmac = istk->mstk;
2346 while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
2347 mmac = mmac->next_active;
2348 if (!mmac)
2349 error(ERR_NONFATAL,
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;
2355 return 1;
2356
2357 case PP_REP:
2358 nolist = FALSE;
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"))
2364 {
2365 tline = tline->next;
2366 nolist = TRUE;
2367 }
2368 t = expand_smacro(tline->next);
2369 tline->next = NULL;
2370 free_tlist(origline);
2371 tline = t;
2372 tptr = &t;
2373 tokval.t_type = TOKEN_INVALID;
2374 evalresult =
2375 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2376 free_tlist(tline);
2377 if (!evalresult)
2378 return 3;
2379 if (tokval.t_type)
2380 error(ERR_WARNING,
2381 "trailing garbage after expression ignored");
2382 if (!is_simple(evalresult))
2383 {
2384 error(ERR_NONFATAL, "non-constant value given to `%%rep'");
2385 return 3;
2386 }
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;
2400 return 1;
2401
2402 case PP_ENDREP:
2403 if (!defining || defining->name)
2404 {
2405 error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
2406 return 3;
2407 }
2408
2409 /*
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.
2419 */
2420 l = nasm_malloc(sizeof(Line));
2421 l->next = istk->expansion;
2422 l->finishes = defining;
2423 l->first = NULL;
2424 istk->expansion = l;
2425
2426 istk->mstk = defining;
2427
2428 list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
2429 tmp_defining = defining;
2430 defining = defining->rep_nest;
2431 free_tlist(origline);
2432 return 1;
2433
2434 case PP_EXITREP:
2435 /*
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.
2439 */
2440 for (l = istk->expansion; l; l = l->next)
2441 if (l->finishes && !l->finishes->name)
2442 break;
2443
2444 if (l)
2445 l->finishes->in_progress = 0;
2446 else
2447 error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
2448 free_tlist(origline);
2449 return 1;
2450
2451 case PP_XDEFINE:
2452 case PP_IXDEFINE:
2453 case PP_DEFINE:
2454 case PP_IDEFINE:
2455 tline = tline->next;
2456 skip_white_(tline);
2457 tline = expand_id(tline);
2458 if (!tline || (tline->type != TOK_ID &&
2459 (tline->type != TOK_PREPROC_ID ||
2460 tline->text[1] != '$')))
2461 {
2462 error(ERR_NONFATAL,
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);
2467 return 3;
2468 }
2469
2470 ctx = get_ctx(tline->text, FALSE);
2471 if (!ctx)
2472 smhead = &smacros[hash(tline->text)];
2473 else
2474 smhead = &ctx->localmac;
2475 mname = tline->text;
2476 last = tline;
2477 param_start = tline = tline->next;
2478 nparam = 0;
2479
2480 /* Expand the macro definition now for %xdefine and %ixdefine */
2481 if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
2482 tline = expand_smacro(tline);
2483
2484 if (tok_is_(tline, "("))
2485 {
2486 /*
2487 * This macro has parameters.
2488 */
2489
2490 tline = tline->next;
2491 while (1)
2492 {
2493 skip_white_(tline);
2494 if (!tline)
2495 {
2496 error(ERR_NONFATAL, "parameter identifier expected");
2497 free_tlist(origline);
2498 return 3;
2499 }
2500 if (tline->type != TOK_ID)
2501 {
2502 error(ERR_NONFATAL,
2503 "`%s': parameter identifier expected",
2504 tline->text);
2505 free_tlist(origline);
2506 return 3;
2507 }
2508 tline->type = TOK_SMAC_PARAM + nparam++;
2509 tline = tline->next;
2510 skip_white_(tline);
2511 if (tok_is_(tline, ","))
2512 {
2513 tline = tline->next;
2514 continue;
2515 }
2516 if (!tok_is_(tline, ")"))
2517 {
2518 error(ERR_NONFATAL,
2519 "`)' expected to terminate macro template");
2520 free_tlist(origline);
2521 return 3;
2522 }
2523 break;
2524 }
2525 last = tline;
2526 tline = tline->next;
2527 }
2528 if (tok_type_(tline, TOK_WHITESPACE))
2529 last = tline, tline = tline->next;
2530 macro_start = NULL;
2531 last->next = NULL;
2532 t = tline;
2533 while (t)
2534 {
2535 if (t->type == TOK_ID)
2536 {
2537 for (tt = param_start; tt; tt = tt->next)
2538 if (tt->type >= TOK_SMAC_PARAM &&
2539 !strcmp(tt->text, t->text))
2540 t->type = tt->type;
2541 }
2542 tt = t->next;
2543 t->next = macro_start;
2544 macro_start = t;
2545 t = tt;
2546 }
2547 /*
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
2553 * from the end).
2554 */
2555 if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE))
2556 {
2557 if (!smac)
2558 {
2559 error(ERR_WARNING,
2560 "single-line macro `%s' defined both with and"
2561 " without parameters", mname);
2562 free_tlist(origline);
2563 free_tlist(macro_start);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002564 return 3;
2565 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002566 else
2567 {
2568 /*
2569 * We're redefining, so we have to take over an
2570 * existing SMacro structure. This means freeing
2571 * what was already in it.
2572 */
2573 nasm_free(smac->name);
2574 free_tlist(smac->expansion);
2575 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002576 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002577 else
2578 {
2579 smac = nasm_malloc(sizeof(SMacro));
2580 smac->next = *smhead;
2581 *smhead = smac;
2582 }
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);
2589 return 3;
2590
2591 case PP_UNDEF:
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002592 tline = tline->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002593 skip_white_(tline);
2594 tline = expand_id(tline);
2595 if (!tline || (tline->type != TOK_ID &&
2596 (tline->type != TOK_PREPROC_ID ||
2597 tline->text[1] != '$')))
2598 {
2599 error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
2600 free_tlist(origline);
H. Peter Anvineba20a72002-04-30 20:53:55 +00002601 return 3;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002602 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002603 if (tline->next)
2604 {
2605 error(ERR_WARNING,
2606 "trailing garbage after macro name ignored");
2607 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00002608
H. Peter Anvin734b1882002-04-30 21:01:08 +00002609 /* Find the context that symbol belongs to */
2610 ctx = get_ctx(tline->text, FALSE);
2611 if (!ctx)
2612 smhead = &smacros[hash(tline->text)];
2613 else
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002614 smhead = &ctx->localmac;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002615
H. Peter Anvin734b1882002-04-30 21:01:08 +00002616 mname = tline->text;
2617 last = tline;
2618 last->next = NULL;
2619
2620 /*
2621 * We now have a macro name... go hunt for it.
2622 */
2623 while (smacro_defined(ctx, mname, -1, &smac, 1))
2624 {
2625 /* Defined, so we need to find its predecessor and nuke it */
2626 SMacro **s;
2627 for (s = smhead; *s && *s != smac; s = &(*s)->next);
2628 if (*s)
2629 {
2630 *s = smac->next;
2631 nasm_free(smac->name);
2632 free_tlist(smac->expansion);
2633 nasm_free(smac);
2634 }
2635 }
2636 free_tlist(origline);
2637 return 3;
2638
2639 case PP_STRLEN:
2640 tline = tline->next;
2641 skip_white_(tline);
2642 tline = expand_id(tline);
2643 if (!tline || (tline->type != TOK_ID &&
2644 (tline->type != TOK_PREPROC_ID ||
2645 tline->text[1] != '$')))
2646 {
2647 error(ERR_NONFATAL,
2648 "`%%strlen' expects a macro identifier as first parameter");
2649 free_tlist(origline);
2650 return 3;
2651 }
2652 ctx = get_ctx(tline->text, FALSE);
2653 if (!ctx)
2654 smhead = &smacros[hash(tline->text)];
2655 else
2656 smhead = &ctx->localmac;
2657 mname = tline->text;
2658 last = tline;
2659 tline = expand_smacro(tline->next);
2660 last->next = NULL;
2661
2662 t = tline;
2663 while (tok_type_(t, TOK_WHITESPACE))
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002664 t = t->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002665 /* t should now point to the string */
2666 if (t->type != TOK_STRING)
2667 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002668 error(ERR_NONFATAL,
2669 "`%%strlen` requires string as second parameter");
2670 free_tlist(tline);
2671 free_tlist(origline);
2672 return 3;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002673 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002674
H. Peter Anvin734b1882002-04-30 21:01:08 +00002675 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;
2679
2680 /*
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.
2684 */
2685 if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN))
2686 {
2687 if (!smac)
2688 error(ERR_WARNING,
2689 "single-line macro `%s' defined both with and"
2690 " without parameters", mname);
2691 else
2692 {
2693 /*
2694 * We're redefining, so we have to take over an
2695 * existing SMacro structure. This means freeing
2696 * what was already in it.
2697 */
2698 nasm_free(smac->name);
2699 free_tlist(smac->expansion);
2700 }
2701 }
2702 else
2703 {
2704 smac = nasm_malloc(sizeof(SMacro));
2705 smac->next = *smhead;
2706 *smhead = smac;
2707 }
2708 smac->name = nasm_strdup(mname);
2709 smac->casesense = (i == PP_STRLEN);
2710 smac->nparam = 0;
2711 smac->expansion = macro_start;
2712 smac->in_progress = FALSE;
2713 free_tlist(tline);
2714 free_tlist(origline);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002715 return 3;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002716
H. Peter Anvin734b1882002-04-30 21:01:08 +00002717 case PP_SUBSTR:
2718 tline = tline->next;
2719 skip_white_(tline);
2720 tline = expand_id(tline);
2721 if (!tline || (tline->type != TOK_ID &&
2722 (tline->type != TOK_PREPROC_ID ||
2723 tline->text[1] != '$')))
2724 {
2725 error(ERR_NONFATAL,
2726 "`%%substr' expects a macro identifier as first parameter");
2727 free_tlist(origline);
2728 return 3;
2729 }
2730 ctx = get_ctx(tline->text, FALSE);
2731 if (!ctx)
2732 smhead = &smacros[hash(tline->text)];
2733 else
2734 smhead = &ctx->localmac;
2735 mname = tline->text;
2736 last = tline;
2737 tline = expand_smacro(tline->next);
2738 last->next = NULL;
2739
2740 t = tline->next;
2741 while (tok_type_(t, TOK_WHITESPACE))
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002742 t = t->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002743
2744 /* t should now point to the string */
2745 if (t->type != TOK_STRING)
2746 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002747 error(ERR_NONFATAL,
2748 "`%%substr` requires string as second parameter");
2749 free_tlist(tline);
2750 free_tlist(origline);
2751 return 3;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002752 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002753
H. Peter Anvin734b1882002-04-30 21:01:08 +00002754 tt = t->next;
2755 tptr = &tt;
2756 tokval.t_type = TOKEN_INVALID;
2757 evalresult =
2758 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2759 if (!evalresult)
2760 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002761 free_tlist(tline);
2762 free_tlist(origline);
2763 return 3;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002764 }
2765 if (!is_simple(evalresult))
2766 {
2767 error(ERR_NONFATAL, "non-constant value given to `%%substr`");
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002768 free_tlist(tline);
2769 free_tlist(origline);
2770 return 3;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002771 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002772
H. Peter Anvin734b1882002-04-30 21:01:08 +00002773 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)
2778 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002779 macro_start->text[1] = t->text[evalresult->value];
H. Peter Anvin734b1882002-04-30 21:01:08 +00002780 }
2781 else
2782 {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002783 macro_start->text[2] = '\0';
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002784 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002785 macro_start->type = TOK_STRING;
2786 macro_start->mac = NULL;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002787
H. Peter Anvin734b1882002-04-30 21:01:08 +00002788 /*
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.
2792 */
2793 if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR))
2794 {
2795 if (!smac)
2796 error(ERR_WARNING,
2797 "single-line macro `%s' defined both with and"
2798 " without parameters", mname);
2799 else
2800 {
2801 /*
2802 * We're redefining, so we have to take over an
2803 * existing SMacro structure. This means freeing
2804 * what was already in it.
2805 */
2806 nasm_free(smac->name);
2807 free_tlist(smac->expansion);
2808 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00002809 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002810 else
2811 {
2812 smac = nasm_malloc(sizeof(SMacro));
2813 smac->next = *smhead;
2814 *smhead = smac;
2815 }
2816 smac->name = nasm_strdup(mname);
2817 smac->casesense = (i == PP_SUBSTR);
2818 smac->nparam = 0;
2819 smac->expansion = macro_start;
2820 smac->in_progress = FALSE;
2821 free_tlist(tline);
2822 free_tlist(origline);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002823 return 3;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002824
2825
2826 case PP_ASSIGN:
2827 case PP_IASSIGN:
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002828 tline = tline->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002829 skip_white_(tline);
2830 tline = expand_id(tline);
2831 if (!tline || (tline->type != TOK_ID &&
2832 (tline->type != TOK_PREPROC_ID ||
2833 tline->text[1] != '$')))
2834 {
2835 error(ERR_NONFATAL,
2836 "`%%%sassign' expects a macro identifier",
2837 (i == PP_IASSIGN ? "i" : ""));
2838 free_tlist(origline);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002839 return 3;
2840 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002841 ctx = get_ctx(tline->text, FALSE);
2842 if (!ctx)
2843 smhead = &smacros[hash(tline->text)];
2844 else
2845 smhead = &ctx->localmac;
2846 mname = tline->text;
2847 last = tline;
2848 tline = expand_smacro(tline->next);
2849 last->next = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002850
H. Peter Anvin734b1882002-04-30 21:01:08 +00002851 t = tline;
2852 tptr = &t;
2853 tokval.t_type = TOKEN_INVALID;
2854 evalresult =
2855 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2856 free_tlist(tline);
2857 if (!evalresult)
2858 {
2859 free_tlist(origline);
2860 return 3;
2861 }
2862
2863 if (tokval.t_type)
2864 error(ERR_WARNING,
2865 "trailing garbage after expression ignored");
2866
2867 if (!is_simple(evalresult))
2868 {
2869 error(ERR_NONFATAL,
2870 "non-constant value given to `%%%sassign'",
2871 (i == PP_IASSIGN ? "i" : ""));
2872 free_tlist(origline);
2873 return 3;
2874 }
2875
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;
2880
2881 /*
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.
2885 */
2886 if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN))
2887 {
2888 if (!smac)
2889 error(ERR_WARNING,
2890 "single-line macro `%s' defined both with and"
2891 " without parameters", mname);
2892 else
2893 {
2894 /*
2895 * We're redefining, so we have to take over an
2896 * existing SMacro structure. This means freeing
2897 * what was already in it.
2898 */
2899 nasm_free(smac->name);
2900 free_tlist(smac->expansion);
2901 }
2902 }
2903 else
2904 {
2905 smac = nasm_malloc(sizeof(SMacro));
2906 smac->next = *smhead;
2907 *smhead = smac;
2908 }
2909 smac->name = nasm_strdup(mname);
2910 smac->casesense = (i == PP_ASSIGN);
2911 smac->nparam = 0;
2912 smac->expansion = macro_start;
2913 smac->in_progress = FALSE;
2914 free_tlist(origline);
2915 return 3;
2916
2917 case PP_LINE:
2918 /*
2919 * Syntax is `%line nnn[+mmm] [filename]'
2920 */
2921 tline = tline->next;
2922 skip_white_(tline);
2923 if (!tok_type_(tline, TOK_NUMBER))
2924 {
2925 error(ERR_NONFATAL, "`%%line' expects line number");
2926 free_tlist(origline);
2927 return 3;
2928 }
2929 k = readnum(tline->text, &j);
2930 m = 1;
2931 tline = tline->next;
2932 if (tok_is_(tline, "+"))
2933 {
2934 tline = tline->next;
2935 if (!tok_type_(tline, TOK_NUMBER))
2936 {
2937 error(ERR_NONFATAL, "`%%line' expects line increment");
2938 free_tlist(origline);
2939 return 3;
2940 }
2941 m = readnum(tline->text, &j);
2942 tline = tline->next;
2943 }
2944 skip_white_(tline);
2945 src_set_linnum(k);
2946 istk->lineinc = m;
2947 if (tline)
2948 {
2949 nasm_free(src_set_fname(detoken(tline, FALSE)));
2950 }
2951 free_tlist(origline);
2952 return 5;
2953
2954 default:
2955 error(ERR_FATAL,
2956 "preprocessor directive `%s' not yet implemented",
2957 directives[i]);
2958 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002959 }
2960 return 3;
2961}
2962
2963/*
H. Peter Anvin76690a12002-04-30 20:52:49 +00002964 * Ensure that a macro parameter contains a condition code and
2965 * nothing else. Return the condition code index if so, or -1
2966 * otherwise.
2967 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00002968static int
2969find_cc(Token * t)
H. Peter Anvineba20a72002-04-30 20:53:55 +00002970{
H. Peter Anvin76690a12002-04-30 20:52:49 +00002971 Token *tt;
2972 int i, j, k, m;
2973
H. Peter Anvineba20a72002-04-30 20:53:55 +00002974 skip_white_(t);
H. Peter Anvin76690a12002-04-30 20:52:49 +00002975 if (t->type != TOK_ID)
2976 return -1;
2977 tt = t->next;
H. Peter Anvineba20a72002-04-30 20:53:55 +00002978 skip_white_(tt);
H. Peter Anvin76690a12002-04-30 20:52:49 +00002979 if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
2980 return -1;
2981
2982 i = -1;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002983 j = sizeof(conditions) / sizeof(*conditions);
2984 while (j - i > 1)
2985 {
2986 k = (j + i) / 2;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002987 m = nasm_stricmp(t->text, conditions[k]);
H. Peter Anvin734b1882002-04-30 21:01:08 +00002988 if (m == 0)
2989 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00002990 i = k;
2991 j = -2;
2992 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002993 }
2994 else if (m < 0)
2995 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00002996 j = k;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002997 }
2998 else
H. Peter Anvin76690a12002-04-30 20:52:49 +00002999 i = k;
3000 }
3001 if (j != -2)
3002 return -1;
3003 return i;
3004}
3005
3006/*
3007 * Expand MMacro-local things: parameter references (%0, %n, %+n,
3008 * %-n) and MMacro-local identifiers (%%foo).
3009 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003010static Token *
3011expand_mmac_params(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003012{
H. Peter Anvin734b1882002-04-30 21:01:08 +00003013 Token *t, *tt, **tail, *thead;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003014
3015 tail = &thead;
3016 thead = NULL;
3017
H. Peter Anvin734b1882002-04-30 21:01:08 +00003018 while (tline)
3019 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00003020 if (tline->type == TOK_PREPROC_ID &&
H. Peter Anvin734b1882002-04-30 21:01:08 +00003021 (((tline->text[1] == '+' || tline->text[1] == '-')
3022 && tline->text[2]) || tline->text[1] == '%'
3023 || (tline->text[1] >= '0' && tline->text[1] <= '9')))
3024 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00003025 char *text = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003026 int type = 0, cc; /* type = 0 to placate optimisers */
H. Peter Anvin76690a12002-04-30 20:52:49 +00003027 char tmpbuf[30];
3028 int n, i;
3029 MMacro *mac;
3030
3031 t = tline;
3032 tline = tline->next;
3033
3034 mac = istk->mstk;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003035 while (mac && !mac->name) /* avoid mistaking %reps for macros */
H. Peter Anvin76690a12002-04-30 20:52:49 +00003036 mac = mac->next_active;
3037 if (!mac)
3038 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
H. Peter Anvin734b1882002-04-30 21:01:08 +00003039 else
3040 switch (t->text[1])
3041 {
3042 /*
3043 * We have to make a substitution of one of the
3044 * forms %1, %-1, %+1, %%foo, %0.
3045 */
3046 case '0':
3047 type = TOK_NUMBER;
3048 sprintf(tmpbuf, "%d", mac->nparam);
3049 text = nasm_strdup(tmpbuf);
3050 break;
3051 case '%':
3052 type = TOK_ID;
3053 sprintf(tmpbuf, "..@%lu.", mac->unique);
3054 text = nasm_strcat(tmpbuf, t->text + 2);
3055 break;
3056 case '-':
3057 n = atoi(t->text + 2) - 1;
3058 if (n >= mac->nparam)
3059 tt = NULL;
3060 else
3061 {
3062 if (mac->nparam > 1)
3063 n = (n + mac->rotate) % mac->nparam;
3064 tt = mac->params[n];
3065 }
3066 cc = find_cc(tt);
3067 if (cc == -1)
3068 {
3069 error(ERR_NONFATAL,
3070 "macro parameter %d is not a condition code",
3071 n + 1);
3072 text = NULL;
3073 }
3074 else
3075 {
3076 type = TOK_ID;
3077 if (inverse_ccs[cc] == -1)
3078 {
3079 error(ERR_NONFATAL,
3080 "condition code `%s' is not invertible",
3081 conditions[cc]);
3082 text = NULL;
3083 }
3084 else
3085 text =
3086 nasm_strdup(conditions[inverse_ccs
3087 [cc]]);
3088 }
3089 break;
3090 case '+':
3091 n = atoi(t->text + 2) - 1;
3092 if (n >= mac->nparam)
3093 tt = NULL;
3094 else
3095 {
3096 if (mac->nparam > 1)
3097 n = (n + mac->rotate) % mac->nparam;
3098 tt = mac->params[n];
3099 }
3100 cc = find_cc(tt);
3101 if (cc == -1)
3102 {
3103 error(ERR_NONFATAL,
3104 "macro parameter %d is not a condition code",
3105 n + 1);
3106 text = NULL;
3107 }
3108 else
3109 {
3110 type = TOK_ID;
3111 text = nasm_strdup(conditions[cc]);
3112 }
3113 break;
3114 default:
3115 n = atoi(t->text + 1) - 1;
3116 if (n >= mac->nparam)
3117 tt = NULL;
3118 else
3119 {
3120 if (mac->nparam > 1)
3121 n = (n + mac->rotate) % mac->nparam;
3122 tt = mac->params[n];
3123 }
3124 if (tt)
3125 {
3126 for (i = 0; i < mac->paramlen[n]; i++)
3127 {
3128 *tail =
3129 new_Token(NULL, tt->type, tt->text,
3130 0);
3131 tail = &(*tail)->next;
3132 tt = tt->next;
3133 }
3134 }
3135 text = NULL; /* we've done it here */
3136 break;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003137 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003138 if (!text)
3139 {
3140 delete_Token(t);
H. Peter Anvin76690a12002-04-30 20:52:49 +00003141 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003142 else
3143 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003144 *tail = t;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003145 tail = &t->next;
3146 t->type = type;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003147 nasm_free(t->text);
H. Peter Anvin76690a12002-04-30 20:52:49 +00003148 t->text = text;
3149 t->mac = NULL;
3150 }
3151 continue;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003152 }
3153 else
3154 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00003155 t = *tail = tline;
3156 tline = tline->next;
3157 t->mac = NULL;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003158 tail = &t->next;
3159 }
3160 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00003161 *tail = NULL;
3162 t = thead;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003163 for (; t && (tt = t->next) != NULL; t = t->next)
3164 switch (t->type)
3165 {
3166 case TOK_WHITESPACE:
3167 if (tt->type == TOK_WHITESPACE)
3168 {
3169 t->next = delete_Token(tt);
3170 }
3171 break;
3172 case TOK_ID:
3173 if (tt->type == TOK_ID || tt->type == TOK_NUMBER)
3174 {
3175 char *tmp = nasm_strcat(t->text, tt->text);
3176 nasm_free(t->text);
3177 t->text = tmp;
3178 t->next = delete_Token(tt);
3179 }
3180 break;
3181 case TOK_NUMBER:
3182 if (tt->type == TOK_NUMBER)
3183 {
3184 char *tmp = nasm_strcat(t->text, tt->text);
3185 nasm_free(t->text);
3186 t->text = tmp;
3187 t->next = delete_Token(tt);
3188 }
3189 break;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003190 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003191
H. Peter Anvin76690a12002-04-30 20:52:49 +00003192 return thead;
3193}
3194
3195/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003196 * 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.)
3201 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003202static Token *
3203expand_smacro(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003204{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003205 Token *t, *tt, *mstart, **tail, *thead;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003206 SMacro *head = NULL, *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003207 Token **params;
3208 int *paramsize;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003209 int nparam, sparam, brackets, rescan;
3210 Token *org_tline = tline;
3211 Context *ctx;
3212 char *mname;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003213
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003214 /*
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
3219 */
3220 if (org_tline)
3221 {
H. Peter Anvin734b1882002-04-30 21:01:08 +00003222 tline =
3223 new_Token(org_tline->next, org_tline->type, org_tline->text,
3224 0);
3225 tline->mac = org_tline->mac;
H. Peter Anvince616072002-04-30 21:02:23 +00003226 nasm_free(org_tline->text);
3227 org_tline->text = NULL;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003228 }
3229
H. Peter Anvin734b1882002-04-30 21:01:08 +00003230 again:
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003231 tail = &thead;
3232 thead = NULL;
3233
H. Peter Anvin734b1882002-04-30 21:01:08 +00003234 while (tline)
3235 { /* main token loop */
3236 if ((mname = tline->text))
3237 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003238 /* if this token is a local macro, look in local context */
3239 if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
H. Peter Anvin734b1882002-04-30 21:01:08 +00003240 ctx = get_ctx(mname, TRUE);
3241 else
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003242 ctx = NULL;
3243 if (!ctx)
3244 head = smacros[hash(mname)];
3245 else
H. Peter Anvineba20a72002-04-30 20:53:55 +00003246 head = ctx->localmac;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003247 /*
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
3251 * necessary.
3252 */
H. Peter Anvineba20a72002-04-30 20:53:55 +00003253 for (m = head; m; m = m->next)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003254 if (!mstrcmp(m->name, mname, m->casesense))
H. Peter Anvineba20a72002-04-30 20:53:55 +00003255 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003256 if (m)
3257 {
3258 mstart = tline;
3259 params = NULL;
3260 paramsize = NULL;
3261 if (m->nparam == 0)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003262 {
H. Peter Anvin734b1882002-04-30 21:01:08 +00003263 /*
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.
3267 */
3268 if (!m->expansion)
3269 {
3270 if (!strcmp("__FILE__", m->name))
3271 {
3272 long num = 0;
3273 src_get(&num, &(tline->text));
3274 nasm_quote(&(tline->text));
3275 tline->type = TOK_STRING;
3276 continue;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003277 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003278 if (!strcmp("__LINE__", m->name))
3279 {
3280 nasm_free(tline->text);
3281 make_tok_num(tline, src_get_linnum());
3282 continue;
3283 }
3284 tline = delete_Token(tline);
3285 continue;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003286 }
3287 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003288 else
3289 {
3290 /*
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
3296 * pain.
3297 */
3298 tline = tline->next;
3299 skip_white_(tline);
3300 if (!tok_is_(tline, "("))
3301 {
3302 /*
3303 * This macro wasn't called with parameters: ignore
3304 * the call. (Behaviour borrowed from gnu cpp.)
3305 */
3306 tline = mstart;
3307 m = NULL;
3308 }
3309 else
3310 {
3311 int paren = 0;
3312 int white = 0;
3313 brackets = 0;
3314 nparam = 0;
3315 tline = tline->next;
3316 sparam = PARAM_DELTA;
3317 params = nasm_malloc(sparam * sizeof(Token *));
3318 params[0] = tline;
3319 paramsize = nasm_malloc(sparam * sizeof(int));
3320 paramsize[0] = 0;
3321 for (;; tline = tline->next)
3322 { /* parameter loop */
3323 if (!tline)
3324 {
3325 error(ERR_NONFATAL,
3326 "macro call expects terminating `)'");
3327 break;
3328 }
3329 if (tline->type == TOK_WHITESPACE
3330 && brackets <= 0)
3331 {
3332 if (paramsize[nparam])
3333 white++;
3334 else
3335 params[nparam] = tline->next;
3336 continue; /* parameter loop */
3337 }
3338 if (tline->type == TOK_OTHER
3339 && tline->text[1] == 0)
3340 {
3341 char ch = tline->text[0];
3342 if (ch == ',' && !paren && brackets <= 0)
3343 {
3344 if (++nparam >= sparam)
3345 {
3346 sparam += PARAM_DELTA;
3347 params = nasm_realloc(params,
3348 sparam * sizeof(Token *));
3349 paramsize = nasm_realloc(paramsize,
3350 sparam * sizeof(int));
3351 }
3352 params[nparam] = tline->next;
3353 paramsize[nparam] = 0;
3354 white = 0;
3355 continue; /* parameter loop */
3356 }
3357 if (ch == '{' &&
3358 (brackets > 0 || (brackets == 0 &&
3359 !paramsize[nparam])))
3360 {
3361 if (!(brackets++))
3362 {
3363 params[nparam] = tline->next;
3364 continue; /* parameter loop */
3365 }
3366 }
3367 if (ch == '}' && brackets > 0)
3368 if (--brackets == 0)
3369 {
3370 brackets = -1;
3371 continue; /* parameter loop */
3372 }
3373 if (ch == '(' && !brackets)
3374 paren++;
3375 if (ch == ')' && brackets <= 0)
3376 if (--paren < 0)
3377 break;
3378 }
3379 if (brackets < 0)
3380 {
3381 brackets = 0;
3382 error(ERR_NONFATAL, "braces do not "
3383 "enclose all of macro parameter");
3384 }
3385 paramsize[nparam] += white + 1;
3386 white = 0;
3387 } /* parameter loop */
3388 nparam++;
3389 while (m && (m->nparam != nparam ||
3390 mstrcmp(m->name, mname,
3391 m->casesense)))
3392 m = m->next;
3393 if (!m)
3394 error(ERR_WARNING | ERR_WARN_MNP,
3395 "macro `%s' exists, "
3396 "but not taking %d parameters",
3397 mstart->text, nparam);
3398 }
3399 }
3400 if (m && m->in_progress)
3401 m = NULL;
3402 if (!m) /* in progess or didn't find '(' or wrong nparam */
3403 {
3404 /*
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
3408 * lines down?
3409 */
3410 nasm_free(params);
3411 nasm_free(paramsize);
3412 tline = mstart;
3413 }
3414 else
3415 {
3416 /*
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.
3421 */
3422 t = tline;
3423 if (t)
3424 {
3425 tline = t->next;
3426 t->next = NULL;
3427 }
3428 tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
3429 tt->mac = m;
3430 m->in_progress = TRUE;
3431 tline = tt;
3432 for (t = m->expansion; t; t = t->next)
3433 {
3434 if (t->type >= TOK_SMAC_PARAM)
3435 {
3436 Token *pcopy = tline, **ptail = &pcopy;
3437 Token *ttt, *pt;
3438 int i;
3439
3440 ttt = params[t->type - TOK_SMAC_PARAM];
3441 for (i = paramsize[t->type - TOK_SMAC_PARAM];
3442 --i >= 0;)
3443 {
3444 pt = *ptail =
3445 new_Token(tline, ttt->type, ttt->text,
3446 0);
3447 ptail = &pt->next;
3448 ttt = ttt->next;
3449 }
3450 tline = pcopy;
3451 }
3452 else
3453 {
3454 tt = new_Token(tline, t->type, t->text, 0);
3455 tline = tt;
3456 }
3457 }
3458
3459 /*
3460 * Having done that, get rid of the macro call, and clean
3461 * up the parameters.
3462 */
3463 nasm_free(params);
3464 nasm_free(paramsize);
3465 free_tlist(mstart);
3466 continue; /* main token loop */
3467 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003468 }
3469 }
3470
H. Peter Anvin734b1882002-04-30 21:01:08 +00003471 if (tline->type == TOK_SMAC_END)
3472 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003473 tline->mac->in_progress = FALSE;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003474 tline = delete_Token(tline);
3475 }
3476 else
3477 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003478 t = *tail = tline;
3479 tline = tline->next;
3480 t->mac = NULL;
3481 t->next = NULL;
3482 tail = &t->next;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003483 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003484 }
3485
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003486 /*
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).
3492 */
3493 t = thead;
3494 rescan = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003495 while (t)
3496 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003497 while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
3498 t = t->next;
3499 if (!t || !t->next)
3500 break;
3501 if (t->next->type == TOK_ID ||
H. Peter Anvin734b1882002-04-30 21:01:08 +00003502 t->next->type == TOK_PREPROC_ID ||
3503 t->next->type == TOK_NUMBER)
3504 {
3505 char *p = nasm_strcat(t->text, t->next->text);
3506 nasm_free(t->text);
3507 t->next = delete_Token(t->next);
3508 t->text = p;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003509 rescan = 1;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003510 }
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)
3514 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003515 /* free the next whitespace, the %+ token and next whitespace */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003516 int i;
3517 for (i = 1; i <= 3; i++)
3518 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003519 if (!t->next || (i != 2 && t->next->type != TOK_WHITESPACE))
3520 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003521 t->next = delete_Token(t->next);
3522 } /* endfor */
3523 }
3524 else
3525 t = t->next;
3526 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003527 /* If we concatenaded something, re-scan the line for macros */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003528 if (rescan)
3529 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003530 tline = thead;
3531 goto again;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003532 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003533
3534 if (org_tline)
3535 {
H. Peter Anvin734b1882002-04-30 21:01:08 +00003536 if (thead)
3537 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003538 *org_tline = *thead;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003539 /* since we just gave text to org_line, don't free it */
3540 thead->text = NULL;
3541 delete_Token(thead);
3542 }
3543 else
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003544 {
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. */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003548 memset(org_tline, 0, sizeof(*org_tline));
3549 org_tline->text = NULL;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003550 org_tline->type = TOK_WHITESPACE;
3551 }
3552 thead = org_tline;
3553 }
3554
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003555 return thead;
3556}
3557
3558/*
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003559 * 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:
3564 *
3565 * %define %$abc cde
3566 *
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:
3569 *
3570 * %define _%$abc cde
3571 *
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
3575 * PP_IDs into one.
3576 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003577static Token *
3578expand_id(Token * tline)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003579{
3580 Token *cur, *oldnext = NULL;
3581
H. Peter Anvin734b1882002-04-30 21:01:08 +00003582 if (!tline || !tline->next)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003583 return tline;
3584
3585 cur = tline;
3586 while (cur->next &&
H. Peter Anvin734b1882002-04-30 21:01:08 +00003587 (cur->next->type == TOK_ID ||
3588 cur->next->type == TOK_PREPROC_ID || cur->next->type == TOK_NUMBER))
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003589 cur = cur->next;
3590
3591 /* If identifier consists of just one token, don't expand */
3592 if (cur == tline)
3593 return tline;
3594
H. Peter Anvin734b1882002-04-30 21:01:08 +00003595 if (cur)
3596 {
3597 oldnext = cur->next; /* Detach the tail past identifier */
3598 cur->next = NULL; /* so that expand_smacro stops here */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003599 }
3600
H. Peter Anvin734b1882002-04-30 21:01:08 +00003601 tline = expand_smacro(tline);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003602
H. Peter Anvin734b1882002-04-30 21:01:08 +00003603 if (cur)
3604 {
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003605 /* expand_smacro possibly changhed tline; re-scan for EOL */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003606 cur = tline;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003607 while (cur && cur->next)
3608 cur = cur->next;
3609 if (cur)
3610 cur->next = oldnext;
3611 }
3612
3613 return tline;
3614}
3615
3616/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003617 * 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.
3623 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003624static MMacro *
3625is_mmacro(Token * tline, Token *** params_array)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003626{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003627 MMacro *head, *m;
3628 Token **params;
3629 int nparam;
3630
3631 head = mmacros[hash(tline->text)];
3632
3633 /*
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.
3638 */
3639 for (m = head; m; m = m->next)
3640 if (!mstrcmp(m->name, tline->text, m->casesense))
3641 break;
3642 if (!m)
3643 return NULL;
3644
3645 /*
3646 * OK, we have a potential macro. Count and demarcate the
3647 * parameters.
3648 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003649 count_mmac_params(tline->next, &nparam, &params);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003650
3651 /*
3652 * So we know how many parameters we've got. Find the MMacro
3653 * structure that handles this number.
3654 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003655 while (m)
3656 {
3657 if (m->nparam_min <= nparam && (m->plus || nparam <= m->nparam_max))
3658 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003659 /*
3660 * This one is right. Just check if cycle removal
3661 * prohibits us using it before we actually celebrate...
3662 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003663 if (m->in_progress)
3664 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003665#if 0
H. Peter Anvin734b1882002-04-30 21:01:08 +00003666 error(ERR_NONFATAL,
3667 "self-reference in multi-line macro `%s'", m->name);
H. Peter Anvineba20a72002-04-30 20:53:55 +00003668#endif
H. Peter Anvin734b1882002-04-30 21:01:08 +00003669 nasm_free(params);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003670 return NULL;
3671 }
3672 /*
3673 * It's right, and we can use it. Add its default
3674 * parameters to the end of our list if necessary.
3675 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003676 if (m->defaults && nparam < m->nparam_min + m->ndefs)
3677 {
3678 params =
3679 nasm_realloc(params,
3680 ((m->nparam_min + m->ndefs + 1) * sizeof(*params)));
3681 while (nparam < m->nparam_min + m->ndefs)
3682 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003683 params[nparam] = m->defaults[nparam - m->nparam_min];
3684 nparam++;
3685 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003686 }
3687 /*
H. Peter Anvin76690a12002-04-30 20:52:49 +00003688 * If we've gone over the maximum parameter count (and
3689 * we're in Plus mode), ignore parameters beyond
3690 * nparam_max.
3691 */
3692 if (m->plus && nparam > m->nparam_max)
3693 nparam = m->nparam_max;
3694 /*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003695 * Then terminate the parameter list, and leave.
3696 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003697 if (!params)
3698 { /* need this special case */
H. Peter Anvin76690a12002-04-30 20:52:49 +00003699 params = nasm_malloc(sizeof(*params));
3700 nparam = 0;
3701 }
3702 params[nparam] = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003703 *params_array = params;
3704 return m;
3705 }
3706 /*
3707 * This one wasn't right: look for the next one with the
3708 * same name.
3709 */
3710 for (m = m->next; m; m = m->next)
3711 if (!mstrcmp(m->name, tline->text, m->casesense))
3712 break;
3713 }
3714
3715 /*
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.
3718 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003719 error(ERR_WARNING | ERR_WARN_MNP,
3720 "macro `%s' exists, but not taking %d parameters",
3721 tline->text, nparam);
3722 nasm_free(params);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003723 return NULL;
3724}
3725
3726/*
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
H. Peter Anvineba20a72002-04-30 20:53:55 +00003729 * istk->expansion and return 1. Otherwise return 0.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003730 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003731static int
3732expand_mmacro(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003733{
3734 Token *startline = tline;
3735 Token *label = NULL;
3736 int dont_prepend = 0;
3737 Token **params, *t, *tt;
3738 MMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003739 Line *l, *ll;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003740 int i, nparam, *paramlen;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003741
3742 t = tline;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003743 skip_white_(t);
3744 if (!tok_type_(t, TOK_ID))
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003745 return 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003746 m = is_mmacro(t, &params);
3747 if (!m)
3748 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003749 Token *last;
3750 /*
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.
3755 */
3756 label = last = t;
3757 t = t->next;
3758 if (tok_type_(t, TOK_WHITESPACE))
3759 last = t, t = t->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003760 if (tok_is_(t, ":"))
3761 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003762 dont_prepend = 1;
3763 last = t, t = t->next;
3764 if (tok_type_(t, TOK_WHITESPACE))
3765 last = t, t = t->next;
3766 }
3767 if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, &params)) == NULL)
3768 return 0;
3769 last->next = NULL;
3770 tline = t;
3771 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003772
3773 /*
3774 * Fix up the parameters: this involves stripping leading and
3775 * trailing whitespace, then stripping braces if they are
3776 * present.
3777 */
H. Peter Anvineba20a72002-04-30 20:53:55 +00003778 for (nparam = 0; params[nparam]; nparam++)
3779 ;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003780 paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003781
H. Peter Anvin734b1882002-04-30 21:01:08 +00003782 for (i = 0; params[i]; i++)
3783 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003784 int brace = FALSE;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003785 int comma = (!m->plus || i < nparam - 1);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003786
3787 t = params[i];
H. Peter Anvineba20a72002-04-30 20:53:55 +00003788 skip_white_(t);
3789 if (tok_is_(t, "{"))
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003790 t = t->next, brace = TRUE, comma = FALSE;
3791 params[i] = t;
3792 paramlen[i] = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003793 while (t)
3794 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003795 if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
H. Peter Anvin734b1882002-04-30 21:01:08 +00003796 break; /* ... because we have hit a comma */
H. Peter Anvineba20a72002-04-30 20:53:55 +00003797 if (comma && t->type == TOK_WHITESPACE && tok_is_(t->next, ","))
H. Peter Anvin734b1882002-04-30 21:01:08 +00003798 break; /* ... or a space then a comma */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003799 if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
H. Peter Anvin734b1882002-04-30 21:01:08 +00003800 break; /* ... or a brace */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003801 t = t->next;
3802 paramlen[i]++;
3803 }
3804 }
3805
3806 /*
3807 * OK, we have a MMacro structure together with a set of
3808 * parameters. We must now go through the expansion and push
H. Peter Anvin76690a12002-04-30 20:52:49 +00003809 * 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.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003814 *
H. Peter Anvin76690a12002-04-30 20:52:49 +00003815 * First, push an end marker on to istk->expansion, mark this
3816 * macro as in progress, and set up its invocation-specific
3817 * variables.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003818 */
3819 ll = nasm_malloc(sizeof(Line));
3820 ll->next = istk->expansion;
3821 ll->finishes = m;
3822 ll->first = NULL;
3823 istk->expansion = ll;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003824
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003825 m->in_progress = TRUE;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003826 m->params = params;
3827 m->iline = tline;
3828 m->nparam = nparam;
3829 m->rotate = 0;
3830 m->paramlen = paramlen;
3831 m->unique = unique++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003832 m->lineno = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003833
3834 m->next_active = istk->mstk;
3835 istk->mstk = m;
3836
H. Peter Anvin734b1882002-04-30 21:01:08 +00003837 for (l = m->expansion; l; l = l->next)
3838 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003839 Token **tail;
3840
3841 ll = nasm_malloc(sizeof(Line));
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003842 ll->finishes = NULL;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003843 ll->next = istk->expansion;
3844 istk->expansion = ll;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003845 tail = &ll->first;
3846
H. Peter Anvin734b1882002-04-30 21:01:08 +00003847 for (t = l->first; t; t = t->next)
3848 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003849 Token *x = t;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003850 if (t->type == TOK_PREPROC_ID &&
3851 t->text[1] == '0' && t->text[2] == '0')
H. Peter Anvineba20a72002-04-30 20:53:55 +00003852 {
3853 dont_prepend = -1;
3854 x = label;
3855 if (!x)
3856 continue;
3857 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003858 tt = *tail = new_Token(NULL, x->type, x->text, 0);
H. Peter Anvin76690a12002-04-30 20:52:49 +00003859 tail = &tt->next;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003860 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00003861 *tail = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003862 }
3863
3864 /*
H. Peter Anvineba20a72002-04-30 20:53:55 +00003865 * If we had a label, push it on as the first line of
3866 * the macro expansion.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003867 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003868 if (label)
3869 {
3870 if (dont_prepend < 0)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003871 free_tlist(startline);
H. Peter Anvin734b1882002-04-30 21:01:08 +00003872 else
3873 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003874 ll = nasm_malloc(sizeof(Line));
3875 ll->finishes = NULL;
3876 ll->next = istk->expansion;
3877 istk->expansion = ll;
3878 ll->first = startline;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003879 if (!dont_prepend)
3880 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003881 while (label->next)
3882 label = label->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003883 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
H. Peter Anvineba20a72002-04-30 20:53:55 +00003884 }
H. Peter Anvin87bc6192002-04-30 20:53:16 +00003885 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003886 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003887
H. Peter Anvin734b1882002-04-30 21:01:08 +00003888 list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00003889
H. Peter Anvineba20a72002-04-30 20:53:55 +00003890 return 1;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003891}
3892
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003893/*
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.
3898 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003899static void
3900error(int severity, char *fmt, ...)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003901{
3902 va_list arg;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003903 char buff[1024];
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003904
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))
3907 return;
3908
H. Peter Anvin734b1882002-04-30 21:01:08 +00003909 va_start(arg, fmt);
3910 vsprintf(buff, fmt, arg);
3911 va_end(arg);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003912
3913 if (istk->mstk && istk->mstk->name)
H. Peter Anvin734b1882002-04-30 21:01:08 +00003914 __error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
3915 istk->mstk->lineno, buff);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003916 else
H. Peter Anvin734b1882002-04-30 21:01:08 +00003917 __error(severity | ERR_PASS1, "%s", buff);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003918}
3919
H. Peter Anvin734b1882002-04-30 21:01:08 +00003920static void
3921pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
3922 ListGen * listgen)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003923{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003924 int h;
3925
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003926 __error = errfunc;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003927 cstk = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003928 istk = nasm_malloc(sizeof(Include));
3929 istk->next = NULL;
3930 istk->conds = NULL;
3931 istk->expansion = NULL;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003932 istk->mstk = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003933 istk->fp = fopen(file, "r");
H. Peter Anvineba20a72002-04-30 20:53:55 +00003934 istk->fname = NULL;
3935 src_set_fname(nasm_strdup(file));
3936 src_set_linnum(0);
3937 istk->lineinc = 1;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003938 if (!istk->fp)
H. Peter Anvin734b1882002-04-30 21:01:08 +00003939 error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'", file);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003940 defining = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003941 for (h = 0; h < NHASH; h++)
3942 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003943 mmacros[h] = NULL;
3944 smacros[h] = NULL;
3945 }
3946 unique = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003947 if (tasm_compatible_mode) {
3948 stdmacpos = stdmac;
3949 } else {
3950 stdmacpos = &stdmac[TASM_MACRO_COUNT];
3951 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00003952 any_extrastdmac = (extrastdmac != NULL);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00003953 list = listgen;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003954 evaluate = eval;
3955 pass = apass;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003956}
3957
H. Peter Anvin734b1882002-04-30 21:01:08 +00003958static char *
3959pp_getline(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003960{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003961 char *line;
3962 Token *tline;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003963
H. Peter Anvin734b1882002-04-30 21:01:08 +00003964 while (1)
3965 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003966 /*
3967 * Fetch a tokenised line, either from the macro-expansion
3968 * buffer or from the input file.
3969 */
3970 tline = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003971 while (istk->expansion && istk->expansion->finishes)
3972 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003973 Line *l = istk->expansion;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003974 if (!l->finishes->name && l->finishes->in_progress > 1)
3975 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00003976 Line *ll;
3977
3978 /*
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
3989 * if we did.
3990 */
3991 l->finishes->in_progress--;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003992 for (l = l->finishes->expansion; l; l = l->next)
3993 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00003994 Token *t, *tt, **tail;
3995
3996 ll = nasm_malloc(sizeof(Line));
3997 ll->next = istk->expansion;
3998 ll->finishes = NULL;
3999 ll->first = NULL;
4000 tail = &ll->first;
4001
H. Peter Anvin734b1882002-04-30 21:01:08 +00004002 for (t = l->first; t; t = t->next)
4003 {
4004 if (t->text || t->type == TOK_WHITESPACE)
4005 {
4006 tt = *tail = new_Token(NULL, t->type, t->text, 0);
H. Peter Anvin76690a12002-04-30 20:52:49 +00004007 tail = &tt->next;
H. Peter Anvin76690a12002-04-30 20:52:49 +00004008 }
4009 }
4010
4011 istk->expansion = ll;
4012 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00004013 }
4014 else
4015 {
H. Peter Anvin87bc6192002-04-30 20:53:16 +00004016 /*
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
4021 * sensibly from it.
4022 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00004023 if (defining)
4024 {
H. Peter Anvin87bc6192002-04-30 20:53:16 +00004025 if (defining->name)
H. Peter Anvin734b1882002-04-30 21:01:08 +00004026 error(ERR_PANIC, "defining with name in expansion");
H. Peter Anvinb64535f2002-04-30 20:55:37 +00004027 else if (istk->mstk->name)
H. Peter Anvin734b1882002-04-30 21:01:08 +00004028 error(ERR_FATAL, "`%%rep' without `%%endrep' within"
4029 " expansion of macro `%s'", istk->mstk->name);
H. Peter Anvin87bc6192002-04-30 20:53:16 +00004030 }
4031
H. Peter Anvin734b1882002-04-30 21:01:08 +00004032 /*
H. Peter Anvineba20a72002-04-30 20:53:55 +00004033 * FIXME: investigate the relationship at this point between
4034 * istk->mstk and l->finishes
4035 */
4036 {
4037 MMacro *m = istk->mstk;
4038 istk->mstk = m->next_active;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004039 if (m->name)
4040 {
H. Peter Anvineba20a72002-04-30 20:53:55 +00004041 /*
4042 * This was a real macro call, not a %rep, and
4043 * therefore the parameter information needs to
4044 * be freed.
4045 */
4046 nasm_free(m->params);
4047 free_tlist(m->iline);
4048 nasm_free(m->paramlen);
4049 l->finishes->in_progress = FALSE;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004050 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00004051 else
4052 free_mmacro(m);
H. Peter Anvin76690a12002-04-30 20:52:49 +00004053 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00004054 istk->expansion = l->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004055 nasm_free(l);
4056 list->downlevel(LIST_MACRO);
H. Peter Anvin76690a12002-04-30 20:52:49 +00004057 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004058 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00004059 while (1)
4060 { /* until we get a line we can use */
H. Peter Anvineba20a72002-04-30 20:53:55 +00004061
H. Peter Anvin734b1882002-04-30 21:01:08 +00004062 if (istk->expansion)
4063 { /* from a macro expansion */
H. Peter Anvineba20a72002-04-30 20:53:55 +00004064 char *p;
4065 Line *l = istk->expansion;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00004066 if (istk->mstk)
4067 istk->mstk->lineno++;
H. Peter Anvineba20a72002-04-30 20:53:55 +00004068 tline = l->first;
4069 istk->expansion = l->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004070 nasm_free(l);
4071 p = detoken(tline, FALSE);
4072 list->line(LIST_MACRO, p);
H. Peter Anvineba20a72002-04-30 20:53:55 +00004073 nasm_free(p);
4074 break;
4075 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004076 line = read_line();
H. Peter Anvin734b1882002-04-30 21:01:08 +00004077 if (line)
4078 { /* from the current input file */
H. Peter Anvineba20a72002-04-30 20:53:55 +00004079 line = prepreproc(line);
4080 tline = tokenise(line);
H. Peter Anvin734b1882002-04-30 21:01:08 +00004081 nasm_free(line);
H. Peter Anvineba20a72002-04-30 20:53:55 +00004082 break;
4083 }
4084 /*
4085 * The current file has ended; work down the istk
4086 */
4087 {
4088 Include *i = istk;
4089 fclose(i->fp);
4090 if (i->conds)
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004091 error(ERR_FATAL, "expected `%%endif' before end of file");
H. Peter Anvineba20a72002-04-30 20:53:55 +00004092 istk = i->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004093 list->downlevel(LIST_INCLUDE);
H. Peter Anvineba20a72002-04-30 20:53:55 +00004094 src_set_linnum(i->lineno);
H. Peter Anvin734b1882002-04-30 21:01:08 +00004095 nasm_free(src_set_fname(i->fname));
4096 nasm_free(i);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004097 if (!istk)
4098 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004099 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004100 }
4101
4102 /*
H. Peter Anvin76690a12002-04-30 20:52:49 +00004103 * 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
H. Peter Anvineba20a72002-04-30 20:53:55 +00004108 * definition; and unless we're in a non-emitting
4109 * condition, in which case we don't want to meddle with
4110 * anything.
H. Peter Anvin76690a12002-04-30 20:52:49 +00004111 */
H. Peter Anvineba20a72002-04-30 20:53:55 +00004112 if (!defining && !(istk->conds && !emitting(istk->conds->state)))
H. Peter Anvin76690a12002-04-30 20:52:49 +00004113 tline = expand_mmac_params(tline);
4114
4115 /*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004116 * Check the line to see if it's a preprocessor directive.
4117 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00004118 if (do_directive(tline) & 1)
4119 {
4120 continue;
4121 }
4122 else if (defining)
4123 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004124 /*
4125 * We're defining a multi-line macro. We emit nothing
H. Peter Anvineba20a72002-04-30 20:53:55 +00004126 * at all, and just
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004127 * shove the tokenised line on to the macro definition.
4128 */
4129 Line *l = nasm_malloc(sizeof(Line));
4130 l->next = defining->expansion;
4131 l->first = tline;
4132 l->finishes = FALSE;
4133 defining->expansion = l;
4134 continue;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004135 }
4136 else if (istk->conds && !emitting(istk->conds->state))
4137 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004138 /*
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.
4143 */
4144 free_tlist(tline);
4145 continue;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004146 }
4147 else if (istk->mstk && !istk->mstk->in_progress)
4148 {
H. Peter Anvin76690a12002-04-30 20:52:49 +00004149 /*
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
4155 * correctly.
4156 */
4157 free_tlist(tline);
4158 continue;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004159 }
4160 else
4161 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004162 tline = expand_smacro(tline);
H. Peter Anvin734b1882002-04-30 21:01:08 +00004163 if (!expand_mmacro(tline))
4164 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004165 /*
4166 * De-tokenise the line again, and emit it.
4167 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00004168 line = detoken(tline, TRUE);
H. Peter Anvin734b1882002-04-30 21:01:08 +00004169 free_tlist(tline);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004170 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004171 }
4172 else
4173 {
4174 continue; /* expand_mmacro calls free_tlist */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004175 }
4176 }
4177 }
4178
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004179 return line;
4180}
4181
H. Peter Anvin734b1882002-04-30 21:01:08 +00004182static void
H. Peter Anvince616072002-04-30 21:02:23 +00004183pp_cleanup(int pass)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004184{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004185 int h;
4186
H. Peter Anvin734b1882002-04-30 21:01:08 +00004187 if (defining)
4188 {
4189 error(ERR_NONFATAL, "end of file while still defining macro `%s'",
4190 defining->name);
4191 free_mmacro(defining);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004192 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004193 while (cstk)
4194 ctx_pop();
H. Peter Anvin734b1882002-04-30 21:01:08 +00004195 for (h = 0; h < NHASH; h++)
4196 {
4197 while (mmacros[h])
4198 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004199 MMacro *m = mmacros[h];
4200 mmacros[h] = mmacros[h]->next;
H. Peter Anvineba20a72002-04-30 20:53:55 +00004201 free_mmacro(m);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004202 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00004203 while (smacros[h])
4204 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004205 SMacro *s = smacros[h];
4206 smacros[h] = smacros[h]->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00004207 nasm_free(s->name);
4208 free_tlist(s->expansion);
4209 nasm_free(s);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004210 }
4211 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00004212 while (istk)
4213 {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004214 Include *i = istk;
4215 istk = istk->next;
4216 fclose(i->fp);
H. Peter Anvin734b1882002-04-30 21:01:08 +00004217 nasm_free(i->fname);
4218 nasm_free(i);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004219 }
4220 while (cstk)
4221 ctx_pop();
H. Peter Anvince616072002-04-30 21:02:23 +00004222 if (pass == 0)
4223 {
4224 free_llist(predef);
4225 delete_Blocks();
4226 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004227}
4228
H. Peter Anvin734b1882002-04-30 21:01:08 +00004229void
4230pp_include_path(char *path)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004231{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004232 IncPath *i;
4233
4234 i = nasm_malloc(sizeof(IncPath));
4235 i->path = nasm_strdup(path);
4236 i->next = ipath;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004237 ipath = i;
4238}
4239
H. Peter Anvin734b1882002-04-30 21:01:08 +00004240void
4241pp_pre_include(char *fname)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004242{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004243 Token *inc, *space, *name;
4244 Line *l;
4245
H. Peter Anvin734b1882002-04-30 21:01:08 +00004246 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);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004249
4250 l = nasm_malloc(sizeof(Line));
4251 l->next = predef;
4252 l->first = inc;
4253 l->finishes = FALSE;
4254 predef = l;
4255}
4256
H. Peter Anvin734b1882002-04-30 21:01:08 +00004257void
4258pp_pre_define(char *definition)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004259{
4260 Token *def, *space;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004261 Line *l;
4262 char *equals;
4263
4264 equals = strchr(definition, '=');
H. Peter Anvin734b1882002-04-30 21:01:08 +00004265 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4266 def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004267 if (equals)
4268 *equals = ' ';
H. Peter Anvineba20a72002-04-30 20:53:55 +00004269 space->next = tokenise(definition);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004270 if (equals)
4271 *equals = '=';
4272
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004273 l = nasm_malloc(sizeof(Line));
4274 l->next = predef;
4275 l->first = def;
4276 l->finishes = FALSE;
4277 predef = l;
4278}
4279
H. Peter Anvin734b1882002-04-30 21:01:08 +00004280void
4281pp_pre_undefine(char *definition)
H. Peter Anvin620515a2002-04-30 20:57:38 +00004282{
4283 Token *def, *space;
4284 Line *l;
4285
H. Peter Anvin734b1882002-04-30 21:01:08 +00004286 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4287 def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
H. Peter Anvin620515a2002-04-30 20:57:38 +00004288
4289 l = nasm_malloc(sizeof(Line));
4290 l->next = predef;
4291 l->first = def;
4292 l->finishes = FALSE;
4293 predef = l;
4294}
4295
H. Peter Anvin734b1882002-04-30 21:01:08 +00004296void
4297pp_extra_stdmac(char **macros)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004298{
H. Peter Anvin76690a12002-04-30 20:52:49 +00004299 extrastdmac = macros;
4300}
4301
H. Peter Anvin734b1882002-04-30 21:01:08 +00004302static void
4303make_tok_num(Token * tok, long val)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004304{
4305 char numbuf[20];
4306 sprintf(numbuf, "%ld", val);
4307 tok->text = nasm_strdup(numbuf);
4308 tok->type = TOK_NUMBER;
4309}
4310
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004311Preproc nasmpp = {
4312 pp_reset,
4313 pp_getline,
4314 pp_cleanup
4315};