blob: 90c83e4c28a1a24074365ca2e000db414f244678 [file] [log] [blame]
H. Peter Anvin65747262002-05-07 00:10:05 +00001/* -*- mode: c; c-file-style: "bsd" -*- */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002/* preproc.c macro preprocessor for the Netwide Assembler
3 *
4 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
5 * Julian Hall. All rights reserved. The software is
6 * redistributable under the licence given in the file "Licence"
7 * distributed in the NASM archive.
8 *
9 * initial version 18/iii/97 by Simon Tatham
10 */
11
H. Peter Anvin4836e332002-04-30 20:56:43 +000012/* Typical flow of text through preproc
13 *
14 * pp_getline gets tokenised lines, either
15 *
16 * from a macro expansion
17 *
18 * or
19 * {
20 * read_line gets raw text from stdmacpos, or predef, or current input file
21 * tokenise converts to tokens
22 * }
23 *
24 * expand_mmac_params is used to expand %1 etc., unless a macro is being
25 * defined or a false conditional is being processed
26 * (%0, %1, %+1, %-1, %%foo
27 *
28 * do_directive checks for directives
29 *
30 * expand_smacro is used to expand single line macros
31 *
32 * expand_mmacro is used to expand multi-line macros
33 *
34 * detoken is used to convert the line back to text
35 */
H. Peter Anvineba20a72002-04-30 20:53:55 +000036
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000037#include <stdio.h>
H. Peter Anvinaf535c12002-04-30 20:59:21 +000038#include <stdarg.h>
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000039#include <stdlib.h>
40#include <stddef.h>
41#include <string.h>
42#include <ctype.h>
H. Peter Anvin76690a12002-04-30 20:52:49 +000043#include <limits.h>
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000044
45#include "nasm.h"
46#include "nasmlib.h"
47
48typedef struct SMacro SMacro;
49typedef struct MMacro MMacro;
50typedef struct Context Context;
51typedef struct Token Token;
H. Peter Anvince616072002-04-30 21:02:23 +000052typedef struct Blocks Blocks;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000053typedef struct Line Line;
54typedef struct Include Include;
55typedef struct Cond Cond;
H. Peter Anvin6768eb72002-04-30 20:52:26 +000056typedef struct IncPath IncPath;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000057
58/*
59 * Store the definition of a single-line macro.
60 */
H. Peter Anvine2c80182005-01-15 22:15:51 +000061struct SMacro {
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 Anvine2c80182005-01-15 22:15:51 +000087struct MMacro {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000088 MMacro *next;
89 char *name;
90 int casesense;
91 int nparam_min, nparam_max;
H. Peter Anvine2c80182005-01-15 22:15:51 +000092 int plus; /* is the last parameter greedy? */
93 int nolist; /* is this macro listing-inhibited? */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000094 int in_progress;
H. Peter Anvine2c80182005-01-15 22:15:51 +000095 Token *dlist; /* All defaults as one list */
96 Token **defaults; /* Parameter default pointers */
97 int ndefs; /* number of default parameters */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000098 Line *expansion;
H. Peter Anvin76690a12002-04-30 20:52:49 +000099
100 MMacro *next_active;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000101 MMacro *rep_nest; /* used for nesting %rep */
102 Token **params; /* actual parameters */
103 Token *iline; /* invocation line */
H. Peter Anvin76690a12002-04-30 20:52:49 +0000104 int nparam, rotate, *paramlen;
105 unsigned long unique;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000106 int lineno; /* Current line number on expansion */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000107};
108
109/*
110 * The context stack is composed of a linked list of these.
111 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000112struct Context {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000113 Context *next;
114 SMacro *localmac;
115 char *name;
116 unsigned long number;
117};
118
119/*
120 * This is the internal form which we break input lines up into.
121 * Typically stored in linked lists.
122 *
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000123 * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
124 * necessarily used as-is, but is intended to denote the number of
125 * the substituted parameter. So in the definition
126 *
127 * %define a(x,y) ( (x) & ~(y) )
128 *
129 * the token representing `x' will have its type changed to
130 * TOK_SMAC_PARAM, but the one representing `y' will be
131 * TOK_SMAC_PARAM+1.
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000132 *
133 * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
134 * which doesn't need quotes around it. Used in the pre-include
135 * mechanism as an alternative to trying to find a sensible type of
136 * quote to use on the filename we were passed.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000137 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000138struct Token {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000139 Token *next;
140 char *text;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000141 SMacro *mac; /* associated macro for TOK_SMAC_END */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000142 int type;
143};
H. Peter Anvine2c80182005-01-15 22:15:51 +0000144enum {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000145 TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING,
H. Peter Anvineba20a72002-04-30 20:53:55 +0000146 TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM,
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000147 TOK_INTERNAL_STRING
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000148};
149
150/*
151 * Multi-line macro definitions are stored as a linked list of
152 * these, which is essentially a container to allow several linked
153 * lists of Tokens.
154 *
155 * Note that in this module, linked lists are treated as stacks
156 * wherever possible. For this reason, Lines are _pushed_ on to the
157 * `expansion' field in MMacro structures, so that the linked list,
158 * if walked, would give the macro lines in reverse order; this
159 * means that we can walk the list when expanding a macro, and thus
160 * push the lines on to the `expansion' field in _istk_ in reverse
161 * order (so that when popped back off they are in the right
162 * order). It may seem cockeyed, and it relies on my design having
163 * an even number of steps in, but it works...
164 *
165 * Some of these structures, rather than being actual lines, are
166 * markers delimiting the end of the expansion of a given macro.
H. Peter Anvin76690a12002-04-30 20:52:49 +0000167 * This is for use in the cycle-tracking and %rep-handling code.
168 * Such structures have `finishes' non-NULL, and `first' NULL. All
169 * others have `finishes' NULL, but `first' may still be NULL if
170 * the line is blank.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000171 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000172struct Line {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000173 Line *next;
174 MMacro *finishes;
175 Token *first;
176};
177
178/*
179 * To handle an arbitrary level of file inclusion, we maintain a
180 * stack (ie linked list) of these things.
181 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000182struct Include {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000183 Include *next;
184 FILE *fp;
185 Cond *conds;
186 Line *expansion;
187 char *fname;
188 int lineno, lineinc;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000189 MMacro *mstk; /* stack of active macros/reps */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000190};
191
192/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000193 * Include search path. This is simply a list of strings which get
194 * prepended, in turn, to the name of an include file, in an
195 * attempt to find the file if it's not in the current directory.
196 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000197struct IncPath {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000198 IncPath *next;
199 char *path;
200};
201
202/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000203 * Conditional assembly: we maintain a separate stack of these for
204 * each level of file inclusion. (The only reason we keep the
205 * stacks separate is to ensure that a stray `%endif' in a file
206 * included from within the true branch of a `%if' won't terminate
207 * it and cause confusion: instead, rightly, it'll cause an error.)
208 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000209struct Cond {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000210 Cond *next;
211 int state;
212};
H. Peter Anvine2c80182005-01-15 22:15:51 +0000213enum {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000214 /*
215 * These states are for use just after %if or %elif: IF_TRUE
216 * means the condition has evaluated to truth so we are
217 * currently emitting, whereas IF_FALSE means we are not
218 * currently emitting but will start doing so if a %else comes
219 * up. In these states, all directives are admissible: %elif,
220 * %else and %endif. (And of course %if.)
221 */
222 COND_IF_TRUE, COND_IF_FALSE,
223 /*
224 * These states come up after a %else: ELSE_TRUE means we're
225 * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
226 * any %elif or %else will cause an error.
227 */
228 COND_ELSE_TRUE, COND_ELSE_FALSE,
229 /*
230 * This state means that we're not emitting now, and also that
231 * nothing until %endif will be emitted at all. It's for use in
232 * two circumstances: (i) when we've had our moment of emission
233 * and have now started seeing %elifs, and (ii) when the
234 * condition construct in question is contained within a
235 * non-emitting branch of a larger condition construct.
236 */
237 COND_NEVER
238};
239#define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
240
Ed Beroset3ab3f412002-06-11 03:31:49 +0000241/*
242 * These defines are used as the possible return values for do_directive
243 */
244#define NO_DIRECTIVE_FOUND 0
245#define DIRECTIVE_FOUND 1
246
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000247/*
248 * Condition codes. Note that we use c_ prefix not C_ because C_ is
249 * used in nasm.h for the "real" condition codes. At _this_ level,
250 * we treat CXZ and ECXZ as condition codes, albeit non-invertible
251 * ones, so we need a different enum...
252 */
H. Peter Anvin0a7a3b42002-05-14 23:54:46 +0000253static const char *conditions[] = {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000254 "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
255 "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
256 "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
257};
H. Peter Anvine2c80182005-01-15 22:15:51 +0000258enum {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000259 c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE,
260 c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO,
261 c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_S, c_Z
262};
263static int inverse_ccs[] = {
264 c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE,
265 c_A, c_AE, c_B, c_BE, c_C, c_E, c_G, c_GE, c_L, c_LE, c_O, c_P, c_S,
266 c_Z, c_NO, c_NP, c_PO, c_PE, c_NS, c_NZ
267};
268
H. Peter Anvin76690a12002-04-30 20:52:49 +0000269/*
270 * Directive names.
271 */
H. Peter Anvin0a7a3b42002-05-14 23:54:46 +0000272static const char *directives[] = {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000273 "%arg",
H. Peter Anvin76690a12002-04-30 20:52:49 +0000274 "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
H. Peter Anvine2c80182005-01-15 22:15:51 +0000275 "%elifid", "%elifidn", "%elifidni", "%elifmacro", "%elifnctx",
276 "%elifndef",
277 "%elifnid", "%elifnidn", "%elifnidni", "%elifnmacro", "%elifnnum",
278 "%elifnstr",
H. Peter Anvin76690a12002-04-30 20:52:49 +0000279 "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
280 "%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
H. Peter Anvine2c80182005-01-15 22:15:51 +0000281 "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifmacro",
282 "%ifnctx",
H. Peter Anvin65747262002-05-07 00:10:05 +0000283 "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnmacro", "%ifnnum",
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000284 "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
285 "%ixdefine", "%line",
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000286 "%local",
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000287 "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000288 "%stacksize",
H. Peter Anvin734b1882002-04-30 21:01:08 +0000289 "%strlen", "%substr", "%undef", "%xdefine"
H. Peter Anvin76690a12002-04-30 20:52:49 +0000290};
H. Peter Anvine2c80182005-01-15 22:15:51 +0000291enum {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000292 PP_ARG,
H. Peter Anvin76690a12002-04-30 20:52:49 +0000293 PP_ASSIGN, PP_CLEAR, PP_DEFINE, PP_ELIF, PP_ELIFCTX, PP_ELIFDEF,
H. Peter Anvine2c80182005-01-15 22:15:51 +0000294 PP_ELIFID, PP_ELIFIDN, PP_ELIFIDNI, PP_ELIFMACRO, PP_ELIFNCTX,
295 PP_ELIFNDEF,
296 PP_ELIFNID, PP_ELIFNIDN, PP_ELIFNIDNI, PP_ELIFNMACRO, PP_ELIFNNUM,
297 PP_ELIFNSTR,
H. Peter Anvin76690a12002-04-30 20:52:49 +0000298 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,
H. Peter Anvine2c80182005-01-15 22:15:51 +0000300 PP_IFCTX, PP_IFDEF, PP_IFID, PP_IFIDN, PP_IFIDNI, PP_IFMACRO,
301 PP_IFNCTX,
H. Peter Anvin65747262002-05-07 00:10:05 +0000302 PP_IFNDEF, PP_IFNID, PP_IFNIDN, PP_IFNIDNI, PP_IFNMACRO, PP_IFNNUM,
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000303 PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE,
304 PP_IXDEFINE, PP_LINE,
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000305 PP_LOCAL,
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000306 PP_MACRO, PP_POP, PP_PUSH, PP_REP, PP_REPL, PP_ROTATE,
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000307 PP_STACKSIZE,
H. Peter Anvin734b1882002-04-30 21:01:08 +0000308 PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
H. Peter Anvin76690a12002-04-30 20:52:49 +0000309};
310
H. Peter Anvin65747262002-05-07 00:10:05 +0000311/* If this is a an IF, ELIF, ELSE or ENDIF keyword */
312static int is_condition(int arg)
313{
314 return ((arg >= PP_ELIF) && (arg <= PP_ENDIF)) ||
H. Peter Anvine2c80182005-01-15 22:15:51 +0000315 ((arg >= PP_IF) && (arg <= PP_IFSTR));
H. Peter Anvin65747262002-05-07 00:10:05 +0000316}
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000317
318/* For TASM compatibility we need to be able to recognise TASM compatible
319 * conditional compilation directives. Using the NASM pre-processor does
320 * not work, so we look for them specifically from the following list and
321 * then jam in the equivalent NASM directive into the input stream.
322 */
323
324#ifndef MAX
325# define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
326#endif
327
H. Peter Anvine2c80182005-01-15 22:15:51 +0000328enum {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000329 TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
330 TM_IFNDEF, TM_INCLUDE, TM_LOCAL
331};
332
H. Peter Anvin0a7a3b42002-05-14 23:54:46 +0000333static const char *tasm_directives[] = {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000334 "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
335 "ifndef", "include", "local"
336};
337
338static int StackSize = 4;
339static char *StackPointer = "ebp";
340static int ArgOffset = 8;
341static int LocalOffset = 4;
342
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000343static Context *cstk;
344static Include *istk;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000345static IncPath *ipath = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000346
H. Peter Anvine2c80182005-01-15 22:15:51 +0000347static efunc _error; /* Pointer to client-provided error reporting function */
H. Peter Anvin76690a12002-04-30 20:52:49 +0000348static evalfunc evaluate;
349
H. Peter Anvine2c80182005-01-15 22:15:51 +0000350static int pass; /* HACK: pass 0 = generate dependencies only */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000351
H. Peter Anvine2c80182005-01-15 22:15:51 +0000352static unsigned long unique; /* unique identifier numbers */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000353
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000354static Line *predef = NULL;
355
356static ListGen *list;
357
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000358/*
359 * The number of hash values we use for the macro lookup tables.
H. Peter Anvineba20a72002-04-30 20:53:55 +0000360 * FIXME: We should *really* be able to configure this at run time,
361 * or even have the hash table automatically expanding when necessary.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000362 */
363#define NHASH 31
364
365/*
366 * The current set of multi-line macros we have defined.
367 */
368static MMacro *mmacros[NHASH];
369
370/*
371 * The current set of single-line macros we have defined.
372 */
373static SMacro *smacros[NHASH];
374
375/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000376 * The multi-line macro we are currently defining, or the %rep
377 * block we are currently reading, if any.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000378 */
379static MMacro *defining;
380
381/*
382 * The number of macro parameters to allocate space for at a time.
383 */
384#define PARAM_DELTA 16
385
386/*
387 * The standard macro set: defined as `static char *stdmac[]'. Also
388 * gives our position in the macro set, when we're processing it.
389 */
390#include "macros.c"
Ed Beroset168c9c02002-05-17 03:10:13 +0000391static const char **stdmacpos;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000392
393/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000394 * The extra standard macros that come from the object format, if
395 * any.
396 */
H. Peter Anvinbfebdb02002-09-12 02:23:54 +0000397static const char **extrastdmac = NULL;
H. Peter Anvin76690a12002-04-30 20:52:49 +0000398int any_extrastdmac;
399
400/*
H. Peter Anvin734b1882002-04-30 21:01:08 +0000401 * Tokens are allocated in blocks to improve speed
402 */
403#define TOKEN_BLOCKSIZE 4096
404static Token *freeTokens = NULL;
H. Peter Anvince616072002-04-30 21:02:23 +0000405struct Blocks {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000406 Blocks *next;
407 void *chunk;
H. Peter Anvince616072002-04-30 21:02:23 +0000408};
409
410static Blocks blocks = { NULL, NULL };
H. Peter Anvin734b1882002-04-30 21:01:08 +0000411
412/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000413 * Forward declarations.
414 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000415static Token *expand_mmac_params(Token * tline);
416static Token *expand_smacro(Token * tline);
417static Token *expand_id(Token * tline);
418static Context *get_ctx(char *name, int all_contexts);
419static void make_tok_num(Token * tok, long val);
Ed Beroset168c9c02002-05-17 03:10:13 +0000420static void error(int severity, const char *fmt, ...);
H. Peter Anvince616072002-04-30 21:02:23 +0000421static void *new_Block(size_t size);
422static void delete_Blocks(void);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000423static Token *new_Token(Token * next, int type, char *text, int txtlen);
424static Token *delete_Token(Token * t);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000425
426/*
427 * Macros for safe checking of token pointers, avoid *(NULL)
428 */
429#define tok_type_(x,t) ((x) && (x)->type == (t))
430#define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
431#define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
432#define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
H. Peter Anvin76690a12002-04-30 20:52:49 +0000433
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000434/* Handle TASM specific directives, which do not contain a % in
435 * front of them. We do it here because I could not find any other
436 * place to do it for the moment, and it is a hack (ideally it would
437 * be nice to be able to use the NASM pre-processor to do it).
438 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000439static char *check_tasm_directive(char *line)
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000440{
441 int i, j, k, m, len;
442 char *p = line, *oldline, oldchar;
443
444 /* Skip whitespace */
445 while (isspace(*p) && *p != 0)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000446 p++;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000447
448 /* Binary search for the directive name */
449 i = -1;
Ed Beroset3ab3f412002-06-11 03:31:49 +0000450 j = elements(tasm_directives);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000451 len = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000452 while (!isspace(p[len]) && p[len] != 0)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000453 len++;
454 if (len) {
455 oldchar = p[len];
456 p[len] = 0;
457 while (j - i > 1) {
458 k = (j + i) / 2;
459 m = nasm_stricmp(p, tasm_directives[k]);
460 if (m == 0) {
461 /* We have found a directive, so jam a % in front of it
462 * so that NASM will then recognise it as one if it's own.
463 */
464 p[len] = oldchar;
465 len = strlen(p);
466 oldline = line;
467 line = nasm_malloc(len + 2);
468 line[0] = '%';
469 if (k == TM_IFDIFI) {
470 /* NASM does not recognise IFDIFI, so we convert it to
471 * %ifdef BOGUS. This is not used in NASM comaptible
472 * code, but does need to parse for the TASM macro
473 * package.
474 */
475 strcpy(line + 1, "ifdef BOGUS");
476 } else {
477 memcpy(line + 1, p, len + 1);
478 }
479 nasm_free(oldline);
480 return line;
481 } else if (m < 0) {
482 j = k;
483 } else
484 i = k;
485 }
486 p[len] = oldchar;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000487 }
488 return line;
489}
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000490
H. Peter Anvin76690a12002-04-30 20:52:49 +0000491/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000492 * The pre-preprocessing stage... This function translates line
493 * number indications as they emerge from GNU cpp (`# lineno "file"
494 * flags') into NASM preprocessor line number indications (`%line
495 * lineno file').
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000496 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000497static char *prepreproc(char *line)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000498{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000499 int lineno, fnlen;
500 char *fname, *oldline;
501
H. Peter Anvine2c80182005-01-15 22:15:51 +0000502 if (line[0] == '#' && line[1] == ' ') {
503 oldline = line;
504 fname = oldline + 2;
505 lineno = atoi(fname);
506 fname += strspn(fname, "0123456789 ");
507 if (*fname == '"')
508 fname++;
509 fnlen = strcspn(fname, "\"");
510 line = nasm_malloc(20 + fnlen);
511 snprintf(line, 20 + fnlen, "%%line %d %.*s", lineno, fnlen, fname);
512 nasm_free(oldline);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000513 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000514 if (tasm_compatible_mode)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000515 return check_tasm_directive(line);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000516 return line;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000517}
518
519/*
520 * The hash function for macro lookups. Note that due to some
521 * macros having case-insensitive names, the hash function must be
522 * invariant under case changes. We implement this by applying a
523 * perfectly normal hash function to the uppercase of the string.
524 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000525static int hash(char *s)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000526{
527 unsigned int h = 0;
528 int i = 0;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000529 /*
530 * Powers of three, mod 31.
531 */
532 static const int multipliers[] = {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000533 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
534 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000535 };
H. Peter Anvineba20a72002-04-30 20:53:55 +0000536
H. Peter Anvine2c80182005-01-15 22:15:51 +0000537 while (*s) {
538 h += multipliers[i] * (unsigned char)(toupper(*s));
539 s++;
540 if (++i >= elements(multipliers))
541 i = 0;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000542 }
543 h %= NHASH;
544 return h;
545}
546
547/*
548 * Free a linked list of tokens.
549 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000550static void free_tlist(Token * list)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000551{
H. Peter Anvine2c80182005-01-15 22:15:51 +0000552 while (list) {
553 list = delete_Token(list);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000554 }
555}
556
557/*
558 * Free a linked list of lines.
559 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000560static void free_llist(Line * list)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000561{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000562 Line *l;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000563 while (list) {
564 l = list;
565 list = list->next;
566 free_tlist(l->first);
567 nasm_free(l);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000568 }
569}
570
571/*
H. Peter Anvineba20a72002-04-30 20:53:55 +0000572 * Free an MMacro
573 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000574static void free_mmacro(MMacro * m)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000575{
H. Peter Anvin734b1882002-04-30 21:01:08 +0000576 nasm_free(m->name);
577 free_tlist(m->dlist);
578 nasm_free(m->defaults);
579 free_llist(m->expansion);
580 nasm_free(m);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000581}
582
583/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000584 * Pop the context stack.
585 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000586static void ctx_pop(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000587{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000588 Context *c = cstk;
589 SMacro *smac, *s;
590
591 cstk = cstk->next;
592 smac = c->localmac;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000593 while (smac) {
594 s = smac;
595 smac = smac->next;
596 nasm_free(s->name);
597 free_tlist(s->expansion);
598 nasm_free(s);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000599 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000600 nasm_free(c->name);
601 nasm_free(c);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000602}
603
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000604#define BUF_DELTA 512
605/*
606 * Read a line from the top file in istk, handling multiple CR/LFs
607 * at the end of the line read, and handling spurious ^Zs. Will
608 * return lines from the standard macro set if this has not already
609 * been done.
610 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000611static char *read_line(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000612{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000613 char *buffer, *p, *q;
H. Peter Anvin9f394642002-04-30 21:07:51 +0000614 int bufsize, continued_count;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000615
H. Peter Anvine2c80182005-01-15 22:15:51 +0000616 if (stdmacpos) {
617 if (*stdmacpos) {
618 char *ret = nasm_strdup(*stdmacpos++);
619 if (!*stdmacpos && any_extrastdmac) {
620 stdmacpos = extrastdmac;
621 any_extrastdmac = FALSE;
622 return ret;
623 }
624 /*
625 * Nasty hack: here we push the contents of `predef' on
626 * to the top-level expansion stack, since this is the
627 * most convenient way to implement the pre-include and
628 * pre-define features.
629 */
630 if (!*stdmacpos) {
631 Line *pd, *l;
632 Token *head, **tail, *t;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000633
H. Peter Anvine2c80182005-01-15 22:15:51 +0000634 for (pd = predef; pd; pd = pd->next) {
635 head = NULL;
636 tail = &head;
637 for (t = pd->first; t; t = t->next) {
638 *tail = new_Token(NULL, t->type, t->text, 0);
639 tail = &(*tail)->next;
640 }
641 l = nasm_malloc(sizeof(Line));
642 l->next = istk->expansion;
643 l->first = head;
644 l->finishes = FALSE;
645 istk->expansion = l;
646 }
647 }
648 return ret;
649 } else {
650 stdmacpos = NULL;
651 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000652 }
653
654 bufsize = BUF_DELTA;
655 buffer = nasm_malloc(BUF_DELTA);
656 p = buffer;
H. Peter Anvin9f394642002-04-30 21:07:51 +0000657 continued_count = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000658 while (1) {
659 q = fgets(p, bufsize - (p - buffer), istk->fp);
660 if (!q)
661 break;
662 p += strlen(p);
663 if (p > buffer && p[-1] == '\n') {
664 /* Convert backslash-CRLF line continuation sequences into
665 nothing at all (for DOS and Windows) */
666 if (((p - 2) > buffer) && (p[-3] == '\\') && (p[-2] == '\r')) {
667 p -= 3;
668 *p = 0;
669 continued_count++;
670 }
671 /* Also convert backslash-LF line continuation sequences into
672 nothing at all (for Unix) */
673 else if (((p - 1) > buffer) && (p[-2] == '\\')) {
674 p -= 2;
675 *p = 0;
676 continued_count++;
677 } else {
678 break;
679 }
680 }
681 if (p - buffer > bufsize - 10) {
682 long offset = p - buffer;
683 bufsize += BUF_DELTA;
684 buffer = nasm_realloc(buffer, bufsize);
685 p = buffer + offset; /* prevent stale-pointer problems */
686 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000687 }
688
H. Peter Anvine2c80182005-01-15 22:15:51 +0000689 if (!q && p == buffer) {
690 nasm_free(buffer);
691 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000692 }
693
H. Peter Anvine2c80182005-01-15 22:15:51 +0000694 src_set_linnum(src_get_linnum() + istk->lineinc +
695 (continued_count * istk->lineinc));
H. Peter Anvineba20a72002-04-30 20:53:55 +0000696
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000697 /*
698 * Play safe: remove CRs as well as LFs, if any of either are
699 * present at the end of the line.
700 */
H. Peter Anvineba20a72002-04-30 20:53:55 +0000701 while (--p >= buffer && (*p == '\n' || *p == '\r'))
H. Peter Anvine2c80182005-01-15 22:15:51 +0000702 *p = '\0';
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000703
704 /*
705 * Handle spurious ^Z, which may be inserted into source files
706 * by some file transfer utilities.
707 */
708 buffer[strcspn(buffer, "\032")] = '\0';
709
H. Peter Anvin734b1882002-04-30 21:01:08 +0000710 list->line(LIST_READ, buffer);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000711
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000712 return buffer;
713}
714
715/*
716 * Tokenise a line of text. This is a very simple process since we
717 * don't need to parse the value out of e.g. numeric tokens: we
718 * simply split one string into many.
719 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000720static Token *tokenise(char *line)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000721{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000722 char *p = line;
723 int type;
724 Token *list = NULL;
725 Token *t, **tail = &list;
726
H. Peter Anvine2c80182005-01-15 22:15:51 +0000727 while (*line) {
728 p = line;
729 if (*p == '%') {
730 p++;
731 if (isdigit(*p) ||
732 ((*p == '-' || *p == '+') && isdigit(p[1])) ||
733 ((*p == '+') && (isspace(p[1]) || !p[1]))) {
734 do {
735 p++;
736 }
737 while (isdigit(*p));
738 type = TOK_PREPROC_ID;
739 } else if (*p == '{') {
740 p++;
741 while (*p && *p != '}') {
742 p[-1] = *p;
743 p++;
744 }
745 p[-1] = '\0';
746 if (*p)
747 p++;
748 type = TOK_PREPROC_ID;
749 } else if (isidchar(*p) ||
750 ((*p == '!' || *p == '%' || *p == '$') &&
751 isidchar(p[1]))) {
752 do {
753 p++;
754 }
755 while (isidchar(*p));
756 type = TOK_PREPROC_ID;
757 } else {
758 type = TOK_OTHER;
759 if (*p == '%')
760 p++;
761 }
762 } else if (isidstart(*p) || (*p == '$' && isidstart(p[1]))) {
763 type = TOK_ID;
764 p++;
765 while (*p && isidchar(*p))
766 p++;
767 } else if (*p == '\'' || *p == '"') {
768 /*
769 * A string token.
770 */
771 char c = *p;
772 p++;
773 type = TOK_STRING;
774 while (*p && *p != c)
775 p++;
Nickolay Yurchenkof3b3ce22003-09-21 20:38:43 +0000776
H. Peter Anvine2c80182005-01-15 22:15:51 +0000777 if (*p) {
778 p++;
779 } else {
780 error(ERR_WARNING, "unterminated string");
781 /* Handling unterminated strings by UNV */
782 /* type = -1; */
783 }
784 } else if (isnumstart(*p)) {
785 /*
786 * A number token.
787 */
788 type = TOK_NUMBER;
789 p++;
790 while (*p && isnumchar(*p))
791 p++;
792 } else if (isspace(*p)) {
793 type = TOK_WHITESPACE;
794 p++;
795 while (*p && isspace(*p))
796 p++;
797 /*
798 * Whitespace just before end-of-line is discarded by
799 * pretending it's a comment; whitespace just before a
800 * comment gets lumped into the comment.
801 */
802 if (!*p || *p == ';') {
803 type = TOK_COMMENT;
804 while (*p)
805 p++;
806 }
807 } else if (*p == ';') {
808 type = TOK_COMMENT;
809 while (*p)
810 p++;
811 } else {
812 /*
813 * Anything else is an operator of some kind. We check
814 * for all the double-character operators (>>, <<, //,
815 * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
816 * else is a single-character operator.
817 */
818 type = TOK_OTHER;
819 if ((p[0] == '>' && p[1] == '>') ||
820 (p[0] == '<' && p[1] == '<') ||
821 (p[0] == '/' && p[1] == '/') ||
822 (p[0] == '<' && p[1] == '=') ||
823 (p[0] == '>' && p[1] == '=') ||
824 (p[0] == '=' && p[1] == '=') ||
825 (p[0] == '!' && p[1] == '=') ||
826 (p[0] == '<' && p[1] == '>') ||
827 (p[0] == '&' && p[1] == '&') ||
828 (p[0] == '|' && p[1] == '|') ||
829 (p[0] == '^' && p[1] == '^')) {
830 p++;
831 }
832 p++;
833 }
Nickolay Yurchenkof3b3ce22003-09-21 20:38:43 +0000834
H. Peter Anvine2c80182005-01-15 22:15:51 +0000835 /* Handling unterminated string by UNV */
836 /*if (type == -1)
837 {
838 *tail = t = new_Token(NULL, TOK_STRING, line, p-line+1);
839 t->text[p-line] = *line;
840 tail = &t->next;
841 }
842 else */
843 if (type != TOK_COMMENT) {
844 *tail = t = new_Token(NULL, type, line, p - line);
845 tail = &t->next;
846 }
847 line = p;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000848 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000849 return list;
850}
851
H. Peter Anvince616072002-04-30 21:02:23 +0000852/*
853 * this function allocates a new managed block of memory and
854 * returns a pointer to the block. The managed blocks are
855 * deleted only all at once by the delete_Blocks function.
856 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000857static void *new_Block(size_t size)
H. Peter Anvince616072002-04-30 21:02:23 +0000858{
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000859 Blocks *b = &blocks;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000860
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000861 /* first, get to the end of the linked list */
862 while (b->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000863 b = b->next;
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000864 /* now allocate the requested chunk */
865 b->chunk = nasm_malloc(size);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000866
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000867 /* now allocate a new block for the next request */
868 b->next = nasm_malloc(sizeof(Blocks));
869 /* and initialize the contents of the new block */
870 b->next->next = NULL;
871 b->next->chunk = NULL;
872 return b->chunk;
H. Peter Anvince616072002-04-30 21:02:23 +0000873}
874
875/*
876 * this function deletes all managed blocks of memory
877 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000878static void delete_Blocks(void)
H. Peter Anvince616072002-04-30 21:02:23 +0000879{
H. Peter Anvine2c80182005-01-15 22:15:51 +0000880 Blocks *a, *b = &blocks;
H. Peter Anvince616072002-04-30 21:02:23 +0000881
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000882 /*
883 * keep in mind that the first block, pointed to by blocks
884 * is a static and not dynamically allocated, so we don't
885 * free it.
886 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000887 while (b) {
888 if (b->chunk)
889 nasm_free(b->chunk);
890 a = b;
891 b = b->next;
892 if (a != &blocks)
893 nasm_free(a);
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000894 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000895}
H. Peter Anvin734b1882002-04-30 21:01:08 +0000896
897/*
898 * this function creates a new Token and passes a pointer to it
899 * back to the caller. It sets the type and text elements, and
900 * also the mac and next elements to NULL.
901 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000902static Token *new_Token(Token * next, int type, char *text, int txtlen)
H. Peter Anvin734b1882002-04-30 21:01:08 +0000903{
904 Token *t;
905 int i;
906
H. Peter Anvine2c80182005-01-15 22:15:51 +0000907 if (freeTokens == NULL) {
908 freeTokens = (Token *) new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
909 for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
910 freeTokens[i].next = &freeTokens[i + 1];
911 freeTokens[i].next = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000912 }
913 t = freeTokens;
914 freeTokens = t->next;
915 t->next = next;
916 t->mac = NULL;
917 t->type = type;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000918 if (type == TOK_WHITESPACE || text == NULL) {
919 t->text = NULL;
920 } else {
921 if (txtlen == 0)
922 txtlen = strlen(text);
923 t->text = nasm_malloc(1 + txtlen);
924 strncpy(t->text, text, txtlen);
925 t->text[txtlen] = '\0';
H. Peter Anvin734b1882002-04-30 21:01:08 +0000926 }
927 return t;
928}
929
H. Peter Anvine2c80182005-01-15 22:15:51 +0000930static Token *delete_Token(Token * t)
H. Peter Anvin734b1882002-04-30 21:01:08 +0000931{
932 Token *next = t->next;
933 nasm_free(t->text);
H. Peter Anvin788e6c12002-04-30 21:02:01 +0000934 t->next = freeTokens;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000935 freeTokens = t;
936 return next;
937}
938
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000939/*
940 * Convert a line of tokens back into text.
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000941 * If expand_locals is not zero, identifiers of the form "%$*xxx"
942 * will be transformed into ..@ctxnum.xxx
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000943 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000944static char *detoken(Token * tlist, int expand_locals)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000945{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000946 Token *t;
947 int len;
948 char *line, *p;
949
950 len = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000951 for (t = tlist; t; t = t->next) {
952 if (t->type == TOK_PREPROC_ID && t->text[1] == '!') {
953 char *p = getenv(t->text + 2);
954 nasm_free(t->text);
955 if (p)
956 t->text = nasm_strdup(p);
957 else
958 t->text = NULL;
959 }
960 /* Expand local macros here and not during preprocessing */
961 if (expand_locals &&
962 t->type == TOK_PREPROC_ID && t->text &&
963 t->text[0] == '%' && t->text[1] == '$') {
964 Context *ctx = get_ctx(t->text, FALSE);
965 if (ctx) {
966 char buffer[40];
967 char *p, *q = t->text + 2;
H. Peter Anvinaf535c12002-04-30 20:59:21 +0000968
H. Peter Anvine2c80182005-01-15 22:15:51 +0000969 q += strspn(q, "$");
970 snprintf(buffer, sizeof(buffer), "..@%lu.", ctx->number);
971 p = nasm_strcat(buffer, q);
972 nasm_free(t->text);
973 t->text = p;
974 }
975 }
976 if (t->type == TOK_WHITESPACE) {
977 len++;
978 } else if (t->text) {
979 len += strlen(t->text);
980 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000981 }
H. Peter Anvin734b1882002-04-30 21:01:08 +0000982 p = line = nasm_malloc(len + 1);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000983 for (t = tlist; t; t = t->next) {
984 if (t->type == TOK_WHITESPACE) {
985 *p = ' ';
986 p++;
987 *p = '\0';
988 } else if (t->text) {
989 strcpy(p, t->text);
990 p += strlen(p);
991 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000992 }
993 *p = '\0';
994 return line;
995}
996
997/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000998 * A scanner, suitable for use by the expression evaluator, which
999 * operates on a line of Tokens. Expects a pointer to a pointer to
1000 * the first token in the line to be passed in as its private_data
1001 * field.
1002 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001003static int ppscan(void *private_data, struct tokenval *tokval)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001004{
H. Peter Anvin76690a12002-04-30 20:52:49 +00001005 Token **tlineptr = private_data;
1006 Token *tline;
1007
H. Peter Anvine2c80182005-01-15 22:15:51 +00001008 do {
1009 tline = *tlineptr;
1010 *tlineptr = tline ? tline->next : NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001011 }
1012 while (tline && (tline->type == TOK_WHITESPACE ||
H. Peter Anvine2c80182005-01-15 22:15:51 +00001013 tline->type == TOK_COMMENT));
H. Peter Anvin76690a12002-04-30 20:52:49 +00001014
1015 if (!tline)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001016 return tokval->t_type = TOKEN_EOS;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001017
1018 if (tline->text[0] == '$' && !tline->text[1])
H. Peter Anvine2c80182005-01-15 22:15:51 +00001019 return tokval->t_type = TOKEN_HERE;
H. Peter Anvin7cf897e2002-05-30 21:30:33 +00001020 if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[2])
H. Peter Anvine2c80182005-01-15 22:15:51 +00001021 return tokval->t_type = TOKEN_BASE;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001022
H. Peter Anvine2c80182005-01-15 22:15:51 +00001023 if (tline->type == TOK_ID) {
1024 tokval->t_charptr = tline->text;
1025 if (tline->text[0] == '$') {
1026 tokval->t_charptr++;
1027 return tokval->t_type = TOKEN_ID;
1028 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00001029
H. Peter Anvine2c80182005-01-15 22:15:51 +00001030 /*
1031 * This is the only special case we actually need to worry
1032 * about in this restricted context.
1033 */
1034 if (!nasm_stricmp(tline->text, "seg"))
1035 return tokval->t_type = TOKEN_SEG;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001036
H. Peter Anvine2c80182005-01-15 22:15:51 +00001037 return tokval->t_type = TOKEN_ID;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001038 }
1039
H. Peter Anvine2c80182005-01-15 22:15:51 +00001040 if (tline->type == TOK_NUMBER) {
1041 int rn_error;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001042
H. Peter Anvine2c80182005-01-15 22:15:51 +00001043 tokval->t_integer = readnum(tline->text, &rn_error);
1044 if (rn_error)
1045 return tokval->t_type = TOKEN_ERRNUM;
1046 tokval->t_charptr = NULL;
1047 return tokval->t_type = TOKEN_NUM;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001048 }
1049
H. Peter Anvine2c80182005-01-15 22:15:51 +00001050 if (tline->type == TOK_STRING) {
1051 int rn_warn;
1052 char q, *r;
1053 int l;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001054
H. Peter Anvine2c80182005-01-15 22:15:51 +00001055 r = tline->text;
1056 q = *r++;
1057 l = strlen(r);
H. Peter Anvineba20a72002-04-30 20:53:55 +00001058
H. Peter Anvine2c80182005-01-15 22:15:51 +00001059 if (l == 0 || r[l - 1] != q)
1060 return tokval->t_type = TOKEN_ERRNUM;
1061 tokval->t_integer = readstrnum(r, l - 1, &rn_warn);
1062 if (rn_warn)
1063 error(ERR_WARNING | ERR_PASS1, "character constant too long");
1064 tokval->t_charptr = NULL;
1065 return tokval->t_type = TOKEN_NUM;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001066 }
1067
H. Peter Anvine2c80182005-01-15 22:15:51 +00001068 if (tline->type == TOK_OTHER) {
1069 if (!strcmp(tline->text, "<<"))
1070 return tokval->t_type = TOKEN_SHL;
1071 if (!strcmp(tline->text, ">>"))
1072 return tokval->t_type = TOKEN_SHR;
1073 if (!strcmp(tline->text, "//"))
1074 return tokval->t_type = TOKEN_SDIV;
1075 if (!strcmp(tline->text, "%%"))
1076 return tokval->t_type = TOKEN_SMOD;
1077 if (!strcmp(tline->text, "=="))
1078 return tokval->t_type = TOKEN_EQ;
1079 if (!strcmp(tline->text, "<>"))
1080 return tokval->t_type = TOKEN_NE;
1081 if (!strcmp(tline->text, "!="))
1082 return tokval->t_type = TOKEN_NE;
1083 if (!strcmp(tline->text, "<="))
1084 return tokval->t_type = TOKEN_LE;
1085 if (!strcmp(tline->text, ">="))
1086 return tokval->t_type = TOKEN_GE;
1087 if (!strcmp(tline->text, "&&"))
1088 return tokval->t_type = TOKEN_DBL_AND;
1089 if (!strcmp(tline->text, "^^"))
1090 return tokval->t_type = TOKEN_DBL_XOR;
1091 if (!strcmp(tline->text, "||"))
1092 return tokval->t_type = TOKEN_DBL_OR;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001093 }
1094
1095 /*
1096 * We have no other options: just return the first character of
1097 * the token text.
1098 */
1099 return tokval->t_type = tline->text[0];
1100}
1101
1102/*
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001103 * Compare a string to the name of an existing macro; this is a
1104 * simple wrapper which calls either strcmp or nasm_stricmp
1105 * depending on the value of the `casesense' parameter.
1106 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001107static int mstrcmp(char *p, char *q, int casesense)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001108{
H. Peter Anvin734b1882002-04-30 21:01:08 +00001109 return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001110}
1111
1112/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001113 * Return the Context structure associated with a %$ token. Return
1114 * NULL, having _already_ reported an error condition, if the
1115 * context stack isn't deep enough for the supplied number of $
1116 * signs.
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001117 * If all_contexts == TRUE, contexts that enclose current are
1118 * also scanned for such smacro, until it is found; if not -
1119 * only the context that directly results from the number of $'s
1120 * in variable's name.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001121 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001122static Context *get_ctx(char *name, int all_contexts)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001123{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001124 Context *ctx;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001125 SMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001126 int i;
1127
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001128 if (!name || name[0] != '%' || name[1] != '$')
H. Peter Anvine2c80182005-01-15 22:15:51 +00001129 return NULL;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001130
H. Peter Anvine2c80182005-01-15 22:15:51 +00001131 if (!cstk) {
1132 error(ERR_NONFATAL, "`%s': context stack is empty", name);
1133 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001134 }
1135
H. Peter Anvine2c80182005-01-15 22:15:51 +00001136 for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--) {
1137 ctx = ctx->next;
H. Peter Anvindce1e2f2002-04-30 21:06:37 +00001138/* i--; Lino - 02/25/02 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001139 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001140 if (!ctx) {
1141 error(ERR_NONFATAL, "`%s': context stack is only"
1142 " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
1143 return NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001144 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001145 if (!all_contexts)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001146 return ctx;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001147
H. Peter Anvine2c80182005-01-15 22:15:51 +00001148 do {
1149 /* Search for this smacro in found context */
1150 m = ctx->localmac;
1151 while (m) {
1152 if (!mstrcmp(m->name, name, m->casesense))
1153 return ctx;
1154 m = m->next;
1155 }
1156 ctx = ctx->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001157 }
1158 while (ctx);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001159 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001160}
1161
1162/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001163 * Open an include file. This routine must always return a valid
1164 * file pointer if it returns - it's responsible for throwing an
1165 * ERR_FATAL and bombing out completely if not. It should also try
1166 * the include path one by one until it finds the file or reaches
1167 * the end of the path.
1168 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001169static FILE *inc_fopen(char *file)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001170{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001171 FILE *fp;
1172 char *prefix = "", *combine;
1173 IncPath *ip = ipath;
H. Peter Anvin620515a2002-04-30 20:57:38 +00001174 static int namelen = 0;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001175 int len = strlen(file);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001176
H. Peter Anvine2c80182005-01-15 22:15:51 +00001177 while (1) {
1178 combine = nasm_malloc(strlen(prefix) + len + 1);
1179 strcpy(combine, prefix);
1180 strcat(combine, file);
1181 fp = fopen(combine, "r");
1182 if (pass == 0 && fp) {
1183 namelen += strlen(combine) + 1;
1184 if (namelen > 62) {
1185 printf(" \\\n ");
1186 namelen = 2;
1187 }
1188 printf(" %s", combine);
1189 }
1190 nasm_free(combine);
1191 if (fp)
1192 return fp;
1193 if (!ip)
1194 break;
1195 prefix = ip->path;
1196 ip = ip->next;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001197 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001198
H. Peter Anvin734b1882002-04-30 21:01:08 +00001199 error(ERR_FATAL, "unable to open include file `%s'", file);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001200 return NULL; /* never reached - placate compilers */
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001201}
1202
1203/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001204 * Determine if we should warn on defining a single-line macro of
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001205 * name `name', with `nparam' parameters. If nparam is 0 or -1, will
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001206 * return TRUE if _any_ single-line macro of that name is defined.
1207 * Otherwise, will return TRUE if a single-line macro with either
1208 * `nparam' or no parameters is defined.
1209 *
1210 * If a macro with precisely the right number of parameters is
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001211 * defined, or nparam is -1, the address of the definition structure
1212 * will be returned in `defn'; otherwise NULL will be returned. If `defn'
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001213 * is NULL, no action will be taken regarding its contents, and no
1214 * error will occur.
1215 *
1216 * Note that this is also called with nparam zero to resolve
1217 * `ifdef'.
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001218 *
1219 * If you already know which context macro belongs to, you can pass
1220 * the context pointer as first parameter; if you won't but name begins
1221 * with %$ the context will be automatically computed. If all_contexts
1222 * is true, macro will be searched in outer contexts as well.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001223 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00001224static int
1225smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
H. Peter Anvine2c80182005-01-15 22:15:51 +00001226 int nocase)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001227{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001228 SMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001229
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001230 if (ctx)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001231 m = ctx->localmac;
1232 else if (name[0] == '%' && name[1] == '$') {
1233 if (cstk)
1234 ctx = get_ctx(name, FALSE);
1235 if (!ctx)
1236 return FALSE; /* got to return _something_ */
1237 m = ctx->localmac;
1238 } else
1239 m = smacros[hash(name)];
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001240
H. Peter Anvine2c80182005-01-15 22:15:51 +00001241 while (m) {
1242 if (!mstrcmp(m->name, name, m->casesense && nocase) &&
1243 (nparam <= 0 || m->nparam == 0 || nparam == m->nparam)) {
1244 if (defn) {
1245 if (nparam == m->nparam || nparam == -1)
1246 *defn = m;
1247 else
1248 *defn = NULL;
1249 }
1250 return TRUE;
1251 }
1252 m = m->next;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001253 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001254
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001255 return FALSE;
1256}
1257
1258/*
1259 * Count and mark off the parameters in a multi-line macro call.
1260 * This is called both from within the multi-line macro expansion
1261 * code, and also to mark off the default parameters when provided
1262 * in a %macro definition line.
1263 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001264static void count_mmac_params(Token * t, int *nparam, Token *** params)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001265{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001266 int paramsize, brace;
1267
1268 *nparam = paramsize = 0;
1269 *params = NULL;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001270 while (t) {
1271 if (*nparam >= paramsize) {
1272 paramsize += PARAM_DELTA;
1273 *params = nasm_realloc(*params, sizeof(**params) * paramsize);
1274 }
1275 skip_white_(t);
1276 brace = FALSE;
1277 if (tok_is_(t, "{"))
1278 brace = TRUE;
1279 (*params)[(*nparam)++] = t;
1280 while (tok_isnt_(t, brace ? "}" : ","))
1281 t = t->next;
1282 if (t) { /* got a comma/brace */
1283 t = t->next;
1284 if (brace) {
1285 /*
1286 * Now we've found the closing brace, look further
1287 * for the comma.
1288 */
1289 skip_white_(t);
1290 if (tok_isnt_(t, ",")) {
1291 error(ERR_NONFATAL,
1292 "braces do not enclose all of macro parameter");
1293 while (tok_isnt_(t, ","))
1294 t = t->next;
1295 }
1296 if (t)
1297 t = t->next; /* eat the comma */
1298 }
1299 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001300 }
1301}
1302
1303/*
H. Peter Anvin76690a12002-04-30 20:52:49 +00001304 * Determine whether one of the various `if' conditions is true or
1305 * not.
1306 *
1307 * We must free the tline we get passed.
1308 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001309static int if_condition(Token * tline, int i)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001310{
H. Peter Anvin734b1882002-04-30 21:01:08 +00001311 int j, casesense;
1312 Token *t, *tt, **tptr, *origline;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001313 struct tokenval tokval;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001314 expr *evalresult;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001315
1316 origline = tline;
1317
H. Peter Anvine2c80182005-01-15 22:15:51 +00001318 switch (i) {
1319 case PP_IFCTX:
1320 case PP_ELIFCTX:
1321 case PP_IFNCTX:
1322 case PP_ELIFNCTX:
1323 j = FALSE; /* have we matched yet? */
1324 while (cstk && tline) {
1325 skip_white_(tline);
1326 if (!tline || tline->type != TOK_ID) {
1327 error(ERR_NONFATAL,
1328 "`%s' expects context identifiers", directives[i]);
1329 free_tlist(origline);
1330 return -1;
1331 }
1332 if (!nasm_stricmp(tline->text, cstk->name))
1333 j = TRUE;
1334 tline = tline->next;
1335 }
1336 if (i == PP_IFNCTX || i == PP_ELIFNCTX)
1337 j = !j;
1338 free_tlist(origline);
1339 return j;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001340
H. Peter Anvine2c80182005-01-15 22:15:51 +00001341 case PP_IFDEF:
1342 case PP_ELIFDEF:
1343 case PP_IFNDEF:
1344 case PP_ELIFNDEF:
1345 j = FALSE; /* have we matched yet? */
1346 while (tline) {
1347 skip_white_(tline);
1348 if (!tline || (tline->type != TOK_ID &&
1349 (tline->type != TOK_PREPROC_ID ||
1350 tline->text[1] != '$'))) {
1351 error(ERR_NONFATAL,
1352 "`%s' expects macro identifiers", directives[i]);
1353 free_tlist(origline);
1354 return -1;
1355 }
1356 if (smacro_defined(NULL, tline->text, 0, NULL, 1))
1357 j = TRUE;
1358 tline = tline->next;
1359 }
1360 if (i == PP_IFNDEF || i == PP_ELIFNDEF)
1361 j = !j;
1362 free_tlist(origline);
1363 return j;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001364
H. Peter Anvine2c80182005-01-15 22:15:51 +00001365 case PP_IFIDN:
1366 case PP_ELIFIDN:
1367 case PP_IFNIDN:
1368 case PP_ELIFNIDN:
1369 case PP_IFIDNI:
1370 case PP_ELIFIDNI:
1371 case PP_IFNIDNI:
1372 case PP_ELIFNIDNI:
1373 tline = expand_smacro(tline);
1374 t = tt = tline;
1375 while (tok_isnt_(tt, ","))
1376 tt = tt->next;
1377 if (!tt) {
1378 error(ERR_NONFATAL,
1379 "`%s' expects two comma-separated arguments",
1380 directives[i]);
1381 free_tlist(tline);
1382 return -1;
1383 }
1384 tt = tt->next;
1385 casesense = (i == PP_IFIDN || i == PP_ELIFIDN ||
1386 i == PP_IFNIDN || i == PP_ELIFNIDN);
1387 j = TRUE; /* assume equality unless proved not */
1388 while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt) {
1389 if (tt->type == TOK_OTHER && !strcmp(tt->text, ",")) {
1390 error(ERR_NONFATAL, "`%s': more than one comma on line",
1391 directives[i]);
1392 free_tlist(tline);
1393 return -1;
1394 }
1395 if (t->type == TOK_WHITESPACE) {
1396 t = t->next;
1397 continue;
1398 }
1399 if (tt->type == TOK_WHITESPACE) {
1400 tt = tt->next;
1401 continue;
1402 }
1403 if (tt->type != t->type) {
1404 j = FALSE; /* found mismatching tokens */
1405 break;
1406 }
1407 /* Unify surrounding quotes for strings */
1408 if (t->type == TOK_STRING) {
1409 tt->text[0] = t->text[0];
1410 tt->text[strlen(tt->text) - 1] = t->text[0];
1411 }
1412 if (mstrcmp(tt->text, t->text, casesense) != 0) {
1413 j = FALSE; /* found mismatching tokens */
1414 break;
1415 }
Nickolay Yurchenkof3b3ce22003-09-21 20:38:43 +00001416
H. Peter Anvine2c80182005-01-15 22:15:51 +00001417 t = t->next;
1418 tt = tt->next;
1419 }
1420 if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
1421 j = FALSE; /* trailing gunk on one end or other */
1422 if (i == PP_IFNIDN || i == PP_ELIFNIDN ||
1423 i == PP_IFNIDNI || i == PP_ELIFNIDNI)
1424 j = !j;
1425 free_tlist(tline);
1426 return j;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001427
H. Peter Anvine2c80182005-01-15 22:15:51 +00001428 case PP_IFMACRO:
1429 case PP_ELIFMACRO:
1430 case PP_IFNMACRO:
1431 case PP_ELIFNMACRO:
1432 {
1433 int found = 0;
1434 MMacro searching, *mmac;
H. Peter Anvin65747262002-05-07 00:10:05 +00001435
H. Peter Anvine2c80182005-01-15 22:15:51 +00001436 tline = tline->next;
1437 skip_white_(tline);
1438 tline = expand_id(tline);
1439 if (!tok_type_(tline, TOK_ID)) {
1440 error(ERR_NONFATAL,
1441 "`%s' expects a macro name", directives[i]);
1442 return -1;
1443 }
1444 searching.name = nasm_strdup(tline->text);
1445 searching.casesense = (i == PP_MACRO);
1446 searching.plus = FALSE;
1447 searching.nolist = FALSE;
1448 searching.in_progress = FALSE;
1449 searching.rep_nest = NULL;
1450 searching.nparam_min = 0;
1451 searching.nparam_max = INT_MAX;
1452 tline = expand_smacro(tline->next);
1453 skip_white_(tline);
1454 if (!tline) {
1455 } else if (!tok_type_(tline, TOK_NUMBER)) {
1456 error(ERR_NONFATAL,
1457 "`%s' expects a parameter count or nothing",
1458 directives[i]);
1459 } else {
1460 searching.nparam_min = searching.nparam_max =
1461 readnum(tline->text, &j);
1462 if (j)
1463 error(ERR_NONFATAL,
1464 "unable to parse parameter count `%s'",
1465 tline->text);
1466 }
1467 if (tline && tok_is_(tline->next, "-")) {
1468 tline = tline->next->next;
1469 if (tok_is_(tline, "*"))
1470 searching.nparam_max = INT_MAX;
1471 else if (!tok_type_(tline, TOK_NUMBER))
1472 error(ERR_NONFATAL,
1473 "`%s' expects a parameter count after `-'",
1474 directives[i]);
1475 else {
1476 searching.nparam_max = readnum(tline->text, &j);
1477 if (j)
1478 error(ERR_NONFATAL,
1479 "unable to parse parameter count `%s'",
1480 tline->text);
1481 if (searching.nparam_min > searching.nparam_max)
1482 error(ERR_NONFATAL,
1483 "minimum parameter count exceeds maximum");
1484 }
1485 }
1486 if (tline && tok_is_(tline->next, "+")) {
1487 tline = tline->next;
1488 searching.plus = TRUE;
1489 }
1490 mmac = mmacros[hash(searching.name)];
1491 while (mmac) {
1492 if (!strcmp(mmac->name, searching.name) &&
1493 (mmac->nparam_min <= searching.nparam_max
1494 || searching.plus)
1495 && (searching.nparam_min <= mmac->nparam_max
1496 || mmac->plus)) {
1497 found = TRUE;
1498 break;
1499 }
1500 mmac = mmac->next;
1501 }
1502 nasm_free(searching.name);
1503 free_tlist(origline);
1504 if (i == PP_IFNMACRO || i == PP_ELIFNMACRO)
1505 found = !found;
1506 return found;
1507 }
H. Peter Anvin65747262002-05-07 00:10:05 +00001508
H. Peter Anvine2c80182005-01-15 22:15:51 +00001509 case PP_IFID:
1510 case PP_ELIFID:
1511 case PP_IFNID:
1512 case PP_ELIFNID:
1513 case PP_IFNUM:
1514 case PP_ELIFNUM:
1515 case PP_IFNNUM:
1516 case PP_ELIFNNUM:
1517 case PP_IFSTR:
1518 case PP_ELIFSTR:
1519 case PP_IFNSTR:
1520 case PP_ELIFNSTR:
1521 tline = expand_smacro(tline);
1522 t = tline;
1523 while (tok_type_(t, TOK_WHITESPACE))
1524 t = t->next;
1525 j = FALSE; /* placate optimiser */
1526 if (t)
1527 switch (i) {
1528 case PP_IFID:
1529 case PP_ELIFID:
1530 case PP_IFNID:
1531 case PP_ELIFNID:
1532 j = (t->type == TOK_ID);
1533 break;
1534 case PP_IFNUM:
1535 case PP_ELIFNUM:
1536 case PP_IFNNUM:
1537 case PP_ELIFNNUM:
1538 j = (t->type == TOK_NUMBER);
1539 break;
1540 case PP_IFSTR:
1541 case PP_ELIFSTR:
1542 case PP_IFNSTR:
1543 case PP_ELIFNSTR:
1544 j = (t->type == TOK_STRING);
1545 break;
1546 }
1547 if (i == PP_IFNID || i == PP_ELIFNID ||
1548 i == PP_IFNNUM || i == PP_ELIFNNUM ||
1549 i == PP_IFNSTR || i == PP_ELIFNSTR)
1550 j = !j;
1551 free_tlist(tline);
1552 return j;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001553
H. Peter Anvine2c80182005-01-15 22:15:51 +00001554 case PP_IF:
1555 case PP_ELIF:
1556 t = tline = expand_smacro(tline);
1557 tptr = &t;
1558 tokval.t_type = TOKEN_INVALID;
1559 evalresult = evaluate(ppscan, tptr, &tokval,
1560 NULL, pass | CRITICAL, error, NULL);
1561 free_tlist(tline);
1562 if (!evalresult)
1563 return -1;
1564 if (tokval.t_type)
1565 error(ERR_WARNING,
1566 "trailing garbage after expression ignored");
1567 if (!is_simple(evalresult)) {
1568 error(ERR_NONFATAL,
1569 "non-constant value given to `%s'", directives[i]);
1570 return -1;
1571 }
1572 return reloc_value(evalresult) != 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001573
H. Peter Anvine2c80182005-01-15 22:15:51 +00001574 default:
1575 error(ERR_FATAL,
1576 "preprocessor directive `%s' not yet implemented",
1577 directives[i]);
1578 free_tlist(origline);
1579 return -1; /* yeah, right */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001580 }
1581}
1582
1583/*
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001584 * Expand macros in a string. Used in %error and %include directives.
1585 * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
1586 * The returned variable should ALWAYS be freed after usage.
1587 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001588void expand_macros_in_string(char **p)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001589{
H. Peter Anvin734b1882002-04-30 21:01:08 +00001590 Token *line = tokenise(*p);
1591 line = expand_smacro(line);
1592 *p = detoken(line, FALSE);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001593}
1594
Ed Beroset3ab3f412002-06-11 03:31:49 +00001595/**
1596 * find and process preprocessor directive in passed line
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001597 * Find out if a line contains a preprocessor directive, and deal
1598 * with it if so.
1599 *
Ed Beroset3ab3f412002-06-11 03:31:49 +00001600 * If a directive _is_ found, it is the responsibility of this routine
1601 * (and not the caller) to free_tlist() the line.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001602 *
Ed Beroset3ab3f412002-06-11 03:31:49 +00001603 * @param tline a pointer to the current tokeninzed line linked list
1604 * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001605 *
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001606 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001607static int do_directive(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001608{
H. Peter Anvin76690a12002-04-30 20:52:49 +00001609 int i, j, k, m, nparam, nolist;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001610 int offset;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001611 char *p, *mname;
1612 Include *inc;
1613 Context *ctx;
1614 Cond *cond;
1615 SMacro *smac, **smhead;
1616 MMacro *mmac;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001617 Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
1618 Line *l;
1619 struct tokenval tokval;
1620 expr *evalresult;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001621 MMacro *tmp_defining; /* Used when manipulating rep_nest */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001622
1623 origline = tline;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001624
H. Peter Anvineba20a72002-04-30 20:53:55 +00001625 skip_white_(tline);
1626 if (!tok_type_(tline, TOK_PREPROC_ID) ||
H. Peter Anvine2c80182005-01-15 22:15:51 +00001627 (tline->text[1] == '%' || tline->text[1] == '$'
1628 || tline->text[1] == '!'))
1629 return NO_DIRECTIVE_FOUND;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001630
1631 i = -1;
Ed Beroset3ab3f412002-06-11 03:31:49 +00001632 j = elements(directives);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001633 while (j - i > 1) {
1634 k = (j + i) / 2;
1635 m = nasm_stricmp(tline->text, directives[k]);
1636 if (m == 0) {
1637 if (tasm_compatible_mode) {
1638 i = k;
1639 j = -2;
1640 } else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) {
1641 i = k;
1642 j = -2;
1643 }
1644 break;
1645 } else if (m < 0) {
1646 j = k;
1647 } else
1648 i = k;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001649 }
1650
1651 /*
1652 * If we're in a non-emitting branch of a condition construct,
H. Peter Anvin76690a12002-04-30 20:52:49 +00001653 * or walking to the end of an already terminated %rep block,
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001654 * we should ignore all directives except for condition
1655 * directives.
1656 */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001657 if (((istk->conds && !emitting(istk->conds->state)) ||
H. Peter Anvine2c80182005-01-15 22:15:51 +00001658 (istk->mstk && !istk->mstk->in_progress)) && !is_condition(i)) {
1659 return NO_DIRECTIVE_FOUND;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001660 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001661
1662 /*
H. Peter Anvin76690a12002-04-30 20:52:49 +00001663 * If we're defining a macro or reading a %rep block, we should
1664 * ignore all directives except for %macro/%imacro (which
1665 * generate an error), %endm/%endmacro, and (only if we're in a
H. Peter Anvineba20a72002-04-30 20:53:55 +00001666 * %rep block) %endrep. If we're in a %rep block, another %rep
1667 * causes an error, so should be let through.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001668 */
1669 if (defining && i != PP_MACRO && i != PP_IMACRO &&
H. Peter Anvine2c80182005-01-15 22:15:51 +00001670 i != PP_ENDMACRO && i != PP_ENDM &&
1671 (defining->name || (i != PP_ENDREP && i != PP_REP))) {
1672 return NO_DIRECTIVE_FOUND;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001673 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001674
H. Peter Anvine2c80182005-01-15 22:15:51 +00001675 if (j != -2) {
1676 error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
1677 tline->text);
1678 return NO_DIRECTIVE_FOUND; /* didn't get it */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001679 }
1680
H. Peter Anvine2c80182005-01-15 22:15:51 +00001681 switch (i) {
1682 case PP_STACKSIZE:
1683 /* Directive to tell NASM what the default stack size is. The
1684 * default is for a 16-bit stack, and this can be overriden with
1685 * %stacksize large.
1686 * the following form:
1687 *
1688 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1689 */
1690 tline = tline->next;
1691 if (tline && tline->type == TOK_WHITESPACE)
1692 tline = tline->next;
1693 if (!tline || tline->type != TOK_ID) {
1694 error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
1695 free_tlist(origline);
1696 return DIRECTIVE_FOUND;
1697 }
1698 if (nasm_stricmp(tline->text, "flat") == 0) {
1699 /* All subsequent ARG directives are for a 32-bit stack */
1700 StackSize = 4;
1701 StackPointer = "ebp";
1702 ArgOffset = 8;
1703 LocalOffset = 4;
1704 } else if (nasm_stricmp(tline->text, "large") == 0) {
1705 /* All subsequent ARG directives are for a 16-bit stack,
1706 * far function call.
1707 */
1708 StackSize = 2;
1709 StackPointer = "bp";
1710 ArgOffset = 4;
1711 LocalOffset = 2;
1712 } else if (nasm_stricmp(tline->text, "small") == 0) {
1713 /* All subsequent ARG directives are for a 16-bit stack,
1714 * far function call. We don't support near functions.
1715 */
1716 StackSize = 2;
1717 StackPointer = "bp";
1718 ArgOffset = 6;
1719 LocalOffset = 2;
1720 } else {
1721 error(ERR_NONFATAL, "`%%stacksize' invalid size type");
1722 free_tlist(origline);
1723 return DIRECTIVE_FOUND;
1724 }
1725 free_tlist(origline);
1726 return DIRECTIVE_FOUND;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001727
H. Peter Anvine2c80182005-01-15 22:15:51 +00001728 case PP_ARG:
1729 /* TASM like ARG directive to define arguments to functions, in
1730 * the following form:
1731 *
1732 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1733 */
1734 offset = ArgOffset;
1735 do {
1736 char *arg, directive[256];
1737 int size = StackSize;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001738
H. Peter Anvine2c80182005-01-15 22:15:51 +00001739 /* Find the argument name */
1740 tline = tline->next;
1741 if (tline && tline->type == TOK_WHITESPACE)
1742 tline = tline->next;
1743 if (!tline || tline->type != TOK_ID) {
1744 error(ERR_NONFATAL, "`%%arg' missing argument parameter");
1745 free_tlist(origline);
1746 return DIRECTIVE_FOUND;
1747 }
1748 arg = tline->text;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001749
H. Peter Anvine2c80182005-01-15 22:15:51 +00001750 /* Find the argument size type */
1751 tline = tline->next;
1752 if (!tline || tline->type != TOK_OTHER
1753 || tline->text[0] != ':') {
1754 error(ERR_NONFATAL,
1755 "Syntax error processing `%%arg' directive");
1756 free_tlist(origline);
1757 return DIRECTIVE_FOUND;
1758 }
1759 tline = tline->next;
1760 if (!tline || tline->type != TOK_ID) {
1761 error(ERR_NONFATAL, "`%%arg' missing size type parameter");
1762 free_tlist(origline);
1763 return DIRECTIVE_FOUND;
1764 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001765
H. Peter Anvine2c80182005-01-15 22:15:51 +00001766 /* Allow macro expansion of type parameter */
1767 tt = tokenise(tline->text);
1768 tt = expand_smacro(tt);
1769 if (nasm_stricmp(tt->text, "byte") == 0) {
1770 size = MAX(StackSize, 1);
1771 } else if (nasm_stricmp(tt->text, "word") == 0) {
1772 size = MAX(StackSize, 2);
1773 } else if (nasm_stricmp(tt->text, "dword") == 0) {
1774 size = MAX(StackSize, 4);
1775 } else if (nasm_stricmp(tt->text, "qword") == 0) {
1776 size = MAX(StackSize, 8);
1777 } else if (nasm_stricmp(tt->text, "tword") == 0) {
1778 size = MAX(StackSize, 10);
1779 } else {
1780 error(ERR_NONFATAL,
1781 "Invalid size type for `%%arg' missing directive");
1782 free_tlist(tt);
1783 free_tlist(origline);
1784 return DIRECTIVE_FOUND;
1785 }
1786 free_tlist(tt);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001787
H. Peter Anvine2c80182005-01-15 22:15:51 +00001788 /* Now define the macro for the argument */
1789 snprintf(directive, sizeof(directive), "%%define %s (%s+%d)",
1790 arg, StackPointer, offset);
1791 do_directive(tokenise(directive));
1792 offset += size;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001793
H. Peter Anvine2c80182005-01-15 22:15:51 +00001794 /* Move to the next argument in the list */
1795 tline = tline->next;
1796 if (tline && tline->type == TOK_WHITESPACE)
1797 tline = tline->next;
1798 }
1799 while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
1800 free_tlist(origline);
1801 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001802
H. Peter Anvine2c80182005-01-15 22:15:51 +00001803 case PP_LOCAL:
1804 /* TASM like LOCAL directive to define local variables for a
1805 * function, in the following form:
1806 *
1807 * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1808 *
1809 * The '= LocalSize' at the end is ignored by NASM, but is
1810 * required by TASM to define the local parameter size (and used
1811 * by the TASM macro package).
1812 */
1813 offset = LocalOffset;
1814 do {
1815 char *local, directive[256];
1816 int size = StackSize;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001817
H. Peter Anvine2c80182005-01-15 22:15:51 +00001818 /* Find the argument name */
1819 tline = tline->next;
1820 if (tline && tline->type == TOK_WHITESPACE)
1821 tline = tline->next;
1822 if (!tline || tline->type != TOK_ID) {
1823 error(ERR_NONFATAL,
1824 "`%%local' missing argument parameter");
1825 free_tlist(origline);
1826 return DIRECTIVE_FOUND;
1827 }
1828 local = tline->text;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001829
H. Peter Anvine2c80182005-01-15 22:15:51 +00001830 /* Find the argument size type */
1831 tline = tline->next;
1832 if (!tline || tline->type != TOK_OTHER
1833 || tline->text[0] != ':') {
1834 error(ERR_NONFATAL,
1835 "Syntax error processing `%%local' directive");
1836 free_tlist(origline);
1837 return DIRECTIVE_FOUND;
1838 }
1839 tline = tline->next;
1840 if (!tline || tline->type != TOK_ID) {
1841 error(ERR_NONFATAL,
1842 "`%%local' missing size type parameter");
1843 free_tlist(origline);
1844 return DIRECTIVE_FOUND;
1845 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001846
H. Peter Anvine2c80182005-01-15 22:15:51 +00001847 /* Allow macro expansion of type parameter */
1848 tt = tokenise(tline->text);
1849 tt = expand_smacro(tt);
1850 if (nasm_stricmp(tt->text, "byte") == 0) {
1851 size = MAX(StackSize, 1);
1852 } else if (nasm_stricmp(tt->text, "word") == 0) {
1853 size = MAX(StackSize, 2);
1854 } else if (nasm_stricmp(tt->text, "dword") == 0) {
1855 size = MAX(StackSize, 4);
1856 } else if (nasm_stricmp(tt->text, "qword") == 0) {
1857 size = MAX(StackSize, 8);
1858 } else if (nasm_stricmp(tt->text, "tword") == 0) {
1859 size = MAX(StackSize, 10);
1860 } else {
1861 error(ERR_NONFATAL,
1862 "Invalid size type for `%%local' missing directive");
1863 free_tlist(tt);
1864 free_tlist(origline);
1865 return DIRECTIVE_FOUND;
1866 }
1867 free_tlist(tt);
H. Peter Anvin734b1882002-04-30 21:01:08 +00001868
H. Peter Anvine2c80182005-01-15 22:15:51 +00001869 /* Now define the macro for the argument */
1870 snprintf(directive, sizeof(directive), "%%define %s (%s-%d)",
1871 local, StackPointer, offset);
1872 do_directive(tokenise(directive));
1873 offset += size;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001874
H. Peter Anvine2c80182005-01-15 22:15:51 +00001875 /* Now define the assign to setup the enter_c macro correctly */
1876 snprintf(directive, sizeof(directive),
1877 "%%assign %%$localsize %%$localsize+%d", size);
1878 do_directive(tokenise(directive));
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001879
H. Peter Anvine2c80182005-01-15 22:15:51 +00001880 /* Move to the next argument in the list */
1881 tline = tline->next;
1882 if (tline && tline->type == TOK_WHITESPACE)
1883 tline = tline->next;
1884 }
1885 while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
1886 free_tlist(origline);
1887 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001888
H. Peter Anvine2c80182005-01-15 22:15:51 +00001889 case PP_CLEAR:
1890 if (tline->next)
1891 error(ERR_WARNING, "trailing garbage after `%%clear' ignored");
1892 for (j = 0; j < NHASH; j++) {
1893 while (mmacros[j]) {
1894 MMacro *m = mmacros[j];
1895 mmacros[j] = m->next;
1896 free_mmacro(m);
1897 }
1898 while (smacros[j]) {
1899 SMacro *s = smacros[j];
1900 smacros[j] = smacros[j]->next;
1901 nasm_free(s->name);
1902 free_tlist(s->expansion);
1903 nasm_free(s);
1904 }
1905 }
1906 free_tlist(origline);
1907 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001908
H. Peter Anvine2c80182005-01-15 22:15:51 +00001909 case PP_INCLUDE:
1910 tline = tline->next;
1911 skip_white_(tline);
1912 if (!tline || (tline->type != TOK_STRING &&
1913 tline->type != TOK_INTERNAL_STRING)) {
1914 error(ERR_NONFATAL, "`%%include' expects a file name");
1915 free_tlist(origline);
1916 return DIRECTIVE_FOUND; /* but we did _something_ */
1917 }
1918 if (tline->next)
1919 error(ERR_WARNING,
1920 "trailing garbage after `%%include' ignored");
1921 if (tline->type != TOK_INTERNAL_STRING) {
1922 p = tline->text + 1; /* point past the quote to the name */
1923 p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
1924 } else
1925 p = tline->text; /* internal_string is easier */
1926 expand_macros_in_string(&p);
1927 inc = nasm_malloc(sizeof(Include));
1928 inc->next = istk;
1929 inc->conds = NULL;
1930 inc->fp = inc_fopen(p);
1931 inc->fname = src_set_fname(p);
1932 inc->lineno = src_set_linnum(0);
1933 inc->lineinc = 1;
1934 inc->expansion = NULL;
1935 inc->mstk = NULL;
1936 istk = inc;
1937 list->uplevel(LIST_INCLUDE);
1938 free_tlist(origline);
1939 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001940
H. Peter Anvine2c80182005-01-15 22:15:51 +00001941 case PP_PUSH:
1942 tline = tline->next;
1943 skip_white_(tline);
1944 tline = expand_id(tline);
1945 if (!tok_type_(tline, TOK_ID)) {
1946 error(ERR_NONFATAL, "`%%push' expects a context identifier");
1947 free_tlist(origline);
1948 return DIRECTIVE_FOUND; /* but we did _something_ */
1949 }
1950 if (tline->next)
1951 error(ERR_WARNING, "trailing garbage after `%%push' ignored");
1952 ctx = nasm_malloc(sizeof(Context));
1953 ctx->next = cstk;
1954 ctx->localmac = NULL;
1955 ctx->name = nasm_strdup(tline->text);
1956 ctx->number = unique++;
1957 cstk = ctx;
1958 free_tlist(origline);
1959 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001960
H. Peter Anvine2c80182005-01-15 22:15:51 +00001961 case PP_REPL:
1962 tline = tline->next;
1963 skip_white_(tline);
1964 tline = expand_id(tline);
1965 if (!tok_type_(tline, TOK_ID)) {
1966 error(ERR_NONFATAL, "`%%repl' expects a context identifier");
1967 free_tlist(origline);
1968 return DIRECTIVE_FOUND; /* but we did _something_ */
1969 }
1970 if (tline->next)
1971 error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
1972 if (!cstk)
1973 error(ERR_NONFATAL, "`%%repl': context stack is empty");
1974 else {
1975 nasm_free(cstk->name);
1976 cstk->name = nasm_strdup(tline->text);
1977 }
1978 free_tlist(origline);
1979 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001980
H. Peter Anvine2c80182005-01-15 22:15:51 +00001981 case PP_POP:
1982 if (tline->next)
1983 error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
1984 if (!cstk)
1985 error(ERR_NONFATAL, "`%%pop': context stack is already empty");
1986 else
1987 ctx_pop();
1988 free_tlist(origline);
1989 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001990
H. Peter Anvine2c80182005-01-15 22:15:51 +00001991 case PP_ERROR:
1992 tline->next = expand_smacro(tline->next);
1993 tline = tline->next;
1994 skip_white_(tline);
1995 if (tok_type_(tline, TOK_STRING)) {
1996 p = tline->text + 1; /* point past the quote to the name */
1997 p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
1998 expand_macros_in_string(&p);
1999 error(ERR_NONFATAL, "%s", p);
2000 nasm_free(p);
2001 } else {
2002 p = detoken(tline, FALSE);
2003 error(ERR_WARNING, "%s", p);
2004 nasm_free(p);
2005 }
2006 free_tlist(origline);
2007 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002008
H. Peter Anvine2c80182005-01-15 22:15:51 +00002009 case PP_IF:
2010 case PP_IFCTX:
2011 case PP_IFDEF:
2012 case PP_IFID:
2013 case PP_IFIDN:
2014 case PP_IFIDNI:
2015 case PP_IFMACRO:
2016 case PP_IFNCTX:
2017 case PP_IFNDEF:
2018 case PP_IFNID:
2019 case PP_IFNIDN:
2020 case PP_IFNIDNI:
2021 case PP_IFNMACRO:
2022 case PP_IFNNUM:
2023 case PP_IFNSTR:
2024 case PP_IFNUM:
2025 case PP_IFSTR:
2026 if (istk->conds && !emitting(istk->conds->state))
2027 j = COND_NEVER;
2028 else {
2029 j = if_condition(tline->next, i);
2030 tline->next = NULL; /* it got freed */
2031 free_tlist(origline);
2032 j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2033 }
2034 cond = nasm_malloc(sizeof(Cond));
2035 cond->next = istk->conds;
2036 cond->state = j;
2037 istk->conds = cond;
2038 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002039
H. Peter Anvine2c80182005-01-15 22:15:51 +00002040 case PP_ELIF:
2041 case PP_ELIFCTX:
2042 case PP_ELIFDEF:
2043 case PP_ELIFID:
2044 case PP_ELIFIDN:
2045 case PP_ELIFIDNI:
2046 case PP_ELIFMACRO:
2047 case PP_ELIFNCTX:
2048 case PP_ELIFNDEF:
2049 case PP_ELIFNID:
2050 case PP_ELIFNIDN:
2051 case PP_ELIFNIDNI:
2052 case PP_ELIFNMACRO:
2053 case PP_ELIFNNUM:
2054 case PP_ELIFNSTR:
2055 case PP_ELIFNUM:
2056 case PP_ELIFSTR:
2057 if (!istk->conds)
2058 error(ERR_FATAL, "`%s': no matching `%%if'", directives[i]);
2059 if (emitting(istk->conds->state)
2060 || istk->conds->state == COND_NEVER)
2061 istk->conds->state = COND_NEVER;
2062 else {
2063 /*
2064 * IMPORTANT: In the case of %if, we will already have
2065 * called expand_mmac_params(); however, if we're
2066 * processing an %elif we must have been in a
2067 * non-emitting mode, which would have inhibited
2068 * the normal invocation of expand_mmac_params(). Therefore,
2069 * we have to do it explicitly here.
2070 */
2071 j = if_condition(expand_mmac_params(tline->next), i);
2072 tline->next = NULL; /* it got freed */
2073 free_tlist(origline);
2074 istk->conds->state =
2075 j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2076 }
2077 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002078
H. Peter Anvine2c80182005-01-15 22:15:51 +00002079 case PP_ELSE:
2080 if (tline->next)
2081 error(ERR_WARNING, "trailing garbage after `%%else' ignored");
2082 if (!istk->conds)
2083 error(ERR_FATAL, "`%%else': no matching `%%if'");
2084 if (emitting(istk->conds->state)
2085 || istk->conds->state == COND_NEVER)
2086 istk->conds->state = COND_ELSE_FALSE;
2087 else
2088 istk->conds->state = COND_ELSE_TRUE;
2089 free_tlist(origline);
2090 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002091
H. Peter Anvine2c80182005-01-15 22:15:51 +00002092 case PP_ENDIF:
2093 if (tline->next)
2094 error(ERR_WARNING, "trailing garbage after `%%endif' ignored");
2095 if (!istk->conds)
2096 error(ERR_FATAL, "`%%endif': no matching `%%if'");
2097 cond = istk->conds;
2098 istk->conds = cond->next;
2099 nasm_free(cond);
2100 free_tlist(origline);
2101 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002102
H. Peter Anvine2c80182005-01-15 22:15:51 +00002103 case PP_MACRO:
2104 case PP_IMACRO:
2105 if (defining)
2106 error(ERR_FATAL,
2107 "`%%%smacro': already defining a macro",
2108 (i == PP_IMACRO ? "i" : ""));
2109 tline = tline->next;
2110 skip_white_(tline);
2111 tline = expand_id(tline);
2112 if (!tok_type_(tline, TOK_ID)) {
2113 error(ERR_NONFATAL,
2114 "`%%%smacro' expects a macro name",
2115 (i == PP_IMACRO ? "i" : ""));
2116 return DIRECTIVE_FOUND;
2117 }
2118 defining = nasm_malloc(sizeof(MMacro));
2119 defining->name = nasm_strdup(tline->text);
2120 defining->casesense = (i == PP_MACRO);
2121 defining->plus = FALSE;
2122 defining->nolist = FALSE;
2123 defining->in_progress = FALSE;
2124 defining->rep_nest = NULL;
2125 tline = expand_smacro(tline->next);
2126 skip_white_(tline);
2127 if (!tok_type_(tline, TOK_NUMBER)) {
2128 error(ERR_NONFATAL,
2129 "`%%%smacro' expects a parameter count",
2130 (i == PP_IMACRO ? "i" : ""));
2131 defining->nparam_min = defining->nparam_max = 0;
2132 } else {
2133 defining->nparam_min = defining->nparam_max =
2134 readnum(tline->text, &j);
2135 if (j)
2136 error(ERR_NONFATAL,
2137 "unable to parse parameter count `%s'", tline->text);
2138 }
2139 if (tline && tok_is_(tline->next, "-")) {
2140 tline = tline->next->next;
2141 if (tok_is_(tline, "*"))
2142 defining->nparam_max = INT_MAX;
2143 else if (!tok_type_(tline, TOK_NUMBER))
2144 error(ERR_NONFATAL,
2145 "`%%%smacro' expects a parameter count after `-'",
2146 (i == PP_IMACRO ? "i" : ""));
2147 else {
2148 defining->nparam_max = readnum(tline->text, &j);
2149 if (j)
2150 error(ERR_NONFATAL,
2151 "unable to parse parameter count `%s'",
2152 tline->text);
2153 if (defining->nparam_min > defining->nparam_max)
2154 error(ERR_NONFATAL,
2155 "minimum parameter count exceeds maximum");
2156 }
2157 }
2158 if (tline && tok_is_(tline->next, "+")) {
2159 tline = tline->next;
2160 defining->plus = TRUE;
2161 }
2162 if (tline && tok_type_(tline->next, TOK_ID) &&
2163 !nasm_stricmp(tline->next->text, ".nolist")) {
2164 tline = tline->next;
2165 defining->nolist = TRUE;
2166 }
2167 mmac = mmacros[hash(defining->name)];
2168 while (mmac) {
2169 if (!strcmp(mmac->name, defining->name) &&
2170 (mmac->nparam_min <= defining->nparam_max
2171 || defining->plus)
2172 && (defining->nparam_min <= mmac->nparam_max
2173 || mmac->plus)) {
2174 error(ERR_WARNING,
2175 "redefining multi-line macro `%s'", defining->name);
2176 break;
2177 }
2178 mmac = mmac->next;
2179 }
2180 /*
2181 * Handle default parameters.
2182 */
2183 if (tline && tline->next) {
2184 defining->dlist = tline->next;
2185 tline->next = NULL;
2186 count_mmac_params(defining->dlist, &defining->ndefs,
2187 &defining->defaults);
2188 } else {
2189 defining->dlist = NULL;
2190 defining->defaults = NULL;
2191 }
2192 defining->expansion = NULL;
2193 free_tlist(origline);
2194 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002195
H. Peter Anvine2c80182005-01-15 22:15:51 +00002196 case PP_ENDM:
2197 case PP_ENDMACRO:
2198 if (!defining) {
2199 error(ERR_NONFATAL, "`%s': not defining a macro", tline->text);
2200 return DIRECTIVE_FOUND;
2201 }
2202 k = hash(defining->name);
2203 defining->next = mmacros[k];
2204 mmacros[k] = defining;
2205 defining = NULL;
2206 free_tlist(origline);
2207 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002208
H. Peter Anvine2c80182005-01-15 22:15:51 +00002209 case PP_ROTATE:
2210 if (tline->next && tline->next->type == TOK_WHITESPACE)
2211 tline = tline->next;
2212 if (tline->next == NULL) {
2213 free_tlist(origline);
2214 error(ERR_NONFATAL, "`%%rotate' missing rotate count");
2215 return DIRECTIVE_FOUND;
2216 }
2217 t = expand_smacro(tline->next);
2218 tline->next = NULL;
2219 free_tlist(origline);
2220 tline = t;
2221 tptr = &t;
2222 tokval.t_type = TOKEN_INVALID;
2223 evalresult =
2224 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2225 free_tlist(tline);
2226 if (!evalresult)
2227 return DIRECTIVE_FOUND;
2228 if (tokval.t_type)
2229 error(ERR_WARNING,
2230 "trailing garbage after expression ignored");
2231 if (!is_simple(evalresult)) {
2232 error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
2233 return DIRECTIVE_FOUND;
2234 }
2235 mmac = istk->mstk;
2236 while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
2237 mmac = mmac->next_active;
2238 if (!mmac) {
2239 error(ERR_NONFATAL, "`%%rotate' invoked outside a macro call");
2240 } else if (mmac->nparam == 0) {
2241 error(ERR_NONFATAL,
2242 "`%%rotate' invoked within macro without parameters");
2243 } else {
2244 mmac->rotate = mmac->rotate + reloc_value(evalresult);
H. Peter Anvin734b1882002-04-30 21:01:08 +00002245
H. Peter Anvine2c80182005-01-15 22:15:51 +00002246 if (mmac->rotate < 0)
2247 mmac->rotate =
2248 mmac->nparam - (-mmac->rotate) % mmac->nparam;
2249 mmac->rotate %= mmac->nparam;
2250 }
2251 return DIRECTIVE_FOUND;
Nickolay Yurchenko9aea7152003-09-07 22:46:26 +00002252
H. Peter Anvine2c80182005-01-15 22:15:51 +00002253 case PP_REP:
2254 nolist = FALSE;
2255 do {
2256 tline = tline->next;
2257 } while (tok_type_(tline, TOK_WHITESPACE));
Nickolay Yurchenko9aea7152003-09-07 22:46:26 +00002258
H. Peter Anvine2c80182005-01-15 22:15:51 +00002259 if (tok_type_(tline, TOK_ID) &&
2260 nasm_stricmp(tline->text, ".nolist") == 0) {
2261 nolist = TRUE;
2262 do {
2263 tline = tline->next;
2264 } while (tok_type_(tline, TOK_WHITESPACE));
2265 }
Nickolay Yurchenko9aea7152003-09-07 22:46:26 +00002266
H. Peter Anvine2c80182005-01-15 22:15:51 +00002267 if (tline) {
2268 t = expand_smacro(tline);
2269 tptr = &t;
2270 tokval.t_type = TOKEN_INVALID;
2271 evalresult =
2272 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2273 if (!evalresult) {
2274 free_tlist(origline);
2275 return DIRECTIVE_FOUND;
2276 }
2277 if (tokval.t_type)
2278 error(ERR_WARNING,
2279 "trailing garbage after expression ignored");
2280 if (!is_simple(evalresult)) {
2281 error(ERR_NONFATAL, "non-constant value given to `%%rep'");
2282 return DIRECTIVE_FOUND;
2283 }
2284 i = (int)reloc_value(evalresult) + 1;
2285 } else {
2286 error(ERR_NONFATAL, "`%%rep' expects a repeat count");
2287 i = 0;
2288 }
2289 free_tlist(origline);
H. Peter Anvin734b1882002-04-30 21:01:08 +00002290
H. Peter Anvine2c80182005-01-15 22:15:51 +00002291 tmp_defining = defining;
2292 defining = nasm_malloc(sizeof(MMacro));
2293 defining->name = NULL; /* flags this macro as a %rep block */
2294 defining->casesense = 0;
2295 defining->plus = FALSE;
2296 defining->nolist = nolist;
2297 defining->in_progress = i;
2298 defining->nparam_min = defining->nparam_max = 0;
2299 defining->defaults = NULL;
2300 defining->dlist = NULL;
2301 defining->expansion = NULL;
2302 defining->next_active = istk->mstk;
2303 defining->rep_nest = tmp_defining;
2304 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002305
H. Peter Anvine2c80182005-01-15 22:15:51 +00002306 case PP_ENDREP:
2307 if (!defining || defining->name) {
2308 error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
2309 return DIRECTIVE_FOUND;
2310 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002311
H. Peter Anvine2c80182005-01-15 22:15:51 +00002312 /*
2313 * Now we have a "macro" defined - although it has no name
2314 * and we won't be entering it in the hash tables - we must
2315 * push a macro-end marker for it on to istk->expansion.
2316 * After that, it will take care of propagating itself (a
2317 * macro-end marker line for a macro which is really a %rep
2318 * block will cause the macro to be re-expanded, complete
2319 * with another macro-end marker to ensure the process
2320 * continues) until the whole expansion is forcibly removed
2321 * from istk->expansion by a %exitrep.
2322 */
2323 l = nasm_malloc(sizeof(Line));
2324 l->next = istk->expansion;
2325 l->finishes = defining;
2326 l->first = NULL;
2327 istk->expansion = l;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002328
H. Peter Anvine2c80182005-01-15 22:15:51 +00002329 istk->mstk = defining;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002330
H. Peter Anvine2c80182005-01-15 22:15:51 +00002331 list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
2332 tmp_defining = defining;
2333 defining = defining->rep_nest;
2334 free_tlist(origline);
2335 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002336
H. Peter Anvine2c80182005-01-15 22:15:51 +00002337 case PP_EXITREP:
2338 /*
2339 * We must search along istk->expansion until we hit a
2340 * macro-end marker for a macro with no name. Then we set
2341 * its `in_progress' flag to 0.
2342 */
2343 for (l = istk->expansion; l; l = l->next)
2344 if (l->finishes && !l->finishes->name)
2345 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002346
H. Peter Anvine2c80182005-01-15 22:15:51 +00002347 if (l)
2348 l->finishes->in_progress = 0;
2349 else
2350 error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
2351 free_tlist(origline);
2352 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002353
H. Peter Anvine2c80182005-01-15 22:15:51 +00002354 case PP_XDEFINE:
2355 case PP_IXDEFINE:
2356 case PP_DEFINE:
2357 case PP_IDEFINE:
2358 tline = tline->next;
2359 skip_white_(tline);
2360 tline = expand_id(tline);
2361 if (!tline || (tline->type != TOK_ID &&
2362 (tline->type != TOK_PREPROC_ID ||
2363 tline->text[1] != '$'))) {
2364 error(ERR_NONFATAL,
2365 "`%%%s%sdefine' expects a macro identifier",
2366 ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""),
2367 ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : ""));
2368 free_tlist(origline);
2369 return DIRECTIVE_FOUND;
2370 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002371
H. Peter Anvine2c80182005-01-15 22:15:51 +00002372 ctx = get_ctx(tline->text, FALSE);
2373 if (!ctx)
2374 smhead = &smacros[hash(tline->text)];
2375 else
2376 smhead = &ctx->localmac;
2377 mname = tline->text;
2378 last = tline;
2379 param_start = tline = tline->next;
2380 nparam = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002381
H. Peter Anvine2c80182005-01-15 22:15:51 +00002382 /* Expand the macro definition now for %xdefine and %ixdefine */
2383 if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
2384 tline = expand_smacro(tline);
H. Peter Anvin734b1882002-04-30 21:01:08 +00002385
H. Peter Anvine2c80182005-01-15 22:15:51 +00002386 if (tok_is_(tline, "(")) {
2387 /*
2388 * This macro has parameters.
2389 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00002390
H. Peter Anvine2c80182005-01-15 22:15:51 +00002391 tline = tline->next;
2392 while (1) {
2393 skip_white_(tline);
2394 if (!tline) {
2395 error(ERR_NONFATAL, "parameter identifier expected");
2396 free_tlist(origline);
2397 return DIRECTIVE_FOUND;
2398 }
2399 if (tline->type != TOK_ID) {
2400 error(ERR_NONFATAL,
2401 "`%s': parameter identifier expected",
2402 tline->text);
2403 free_tlist(origline);
2404 return DIRECTIVE_FOUND;
2405 }
2406 tline->type = TOK_SMAC_PARAM + nparam++;
2407 tline = tline->next;
2408 skip_white_(tline);
2409 if (tok_is_(tline, ",")) {
2410 tline = tline->next;
2411 continue;
2412 }
2413 if (!tok_is_(tline, ")")) {
2414 error(ERR_NONFATAL,
2415 "`)' expected to terminate macro template");
2416 free_tlist(origline);
2417 return DIRECTIVE_FOUND;
2418 }
2419 break;
2420 }
2421 last = tline;
2422 tline = tline->next;
2423 }
2424 if (tok_type_(tline, TOK_WHITESPACE))
2425 last = tline, tline = tline->next;
2426 macro_start = NULL;
2427 last->next = NULL;
2428 t = tline;
2429 while (t) {
2430 if (t->type == TOK_ID) {
2431 for (tt = param_start; tt; tt = tt->next)
2432 if (tt->type >= TOK_SMAC_PARAM &&
2433 !strcmp(tt->text, t->text))
2434 t->type = tt->type;
2435 }
2436 tt = t->next;
2437 t->next = macro_start;
2438 macro_start = t;
2439 t = tt;
2440 }
2441 /*
2442 * Good. We now have a macro name, a parameter count, and a
2443 * token list (in reverse order) for an expansion. We ought
2444 * to be OK just to create an SMacro, store it, and let
2445 * free_tlist have the rest of the line (which we have
2446 * carefully re-terminated after chopping off the expansion
2447 * from the end).
2448 */
2449 if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE)) {
2450 if (!smac) {
2451 error(ERR_WARNING,
2452 "single-line macro `%s' defined both with and"
2453 " without parameters", mname);
2454 free_tlist(origline);
2455 free_tlist(macro_start);
2456 return DIRECTIVE_FOUND;
2457 } else {
2458 /*
2459 * We're redefining, so we have to take over an
2460 * existing SMacro structure. This means freeing
2461 * what was already in it.
2462 */
2463 nasm_free(smac->name);
2464 free_tlist(smac->expansion);
2465 }
2466 } else {
2467 smac = nasm_malloc(sizeof(SMacro));
2468 smac->next = *smhead;
2469 *smhead = smac;
2470 }
2471 smac->name = nasm_strdup(mname);
2472 smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE));
2473 smac->nparam = nparam;
2474 smac->expansion = macro_start;
2475 smac->in_progress = FALSE;
2476 free_tlist(origline);
2477 return DIRECTIVE_FOUND;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002478
H. Peter Anvine2c80182005-01-15 22:15:51 +00002479 case PP_UNDEF:
2480 tline = tline->next;
2481 skip_white_(tline);
2482 tline = expand_id(tline);
2483 if (!tline || (tline->type != TOK_ID &&
2484 (tline->type != TOK_PREPROC_ID ||
2485 tline->text[1] != '$'))) {
2486 error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
2487 free_tlist(origline);
2488 return DIRECTIVE_FOUND;
2489 }
2490 if (tline->next) {
2491 error(ERR_WARNING,
2492 "trailing garbage after macro name ignored");
2493 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002494
H. Peter Anvine2c80182005-01-15 22:15:51 +00002495 /* Find the context that symbol belongs to */
2496 ctx = get_ctx(tline->text, FALSE);
2497 if (!ctx)
2498 smhead = &smacros[hash(tline->text)];
2499 else
2500 smhead = &ctx->localmac;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002501
H. Peter Anvine2c80182005-01-15 22:15:51 +00002502 mname = tline->text;
2503 last = tline;
2504 last->next = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002505
H. Peter Anvine2c80182005-01-15 22:15:51 +00002506 /*
2507 * We now have a macro name... go hunt for it.
2508 */
2509 while (smacro_defined(ctx, mname, -1, &smac, 1)) {
2510 /* Defined, so we need to find its predecessor and nuke it */
2511 SMacro **s;
2512 for (s = smhead; *s && *s != smac; s = &(*s)->next) ;
2513 if (*s) {
2514 *s = smac->next;
2515 nasm_free(smac->name);
2516 free_tlist(smac->expansion);
2517 nasm_free(smac);
2518 }
2519 }
2520 free_tlist(origline);
2521 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002522
H. Peter Anvine2c80182005-01-15 22:15:51 +00002523 case PP_STRLEN:
2524 tline = tline->next;
2525 skip_white_(tline);
2526 tline = expand_id(tline);
2527 if (!tline || (tline->type != TOK_ID &&
2528 (tline->type != TOK_PREPROC_ID ||
2529 tline->text[1] != '$'))) {
2530 error(ERR_NONFATAL,
2531 "`%%strlen' expects a macro identifier as first parameter");
2532 free_tlist(origline);
2533 return DIRECTIVE_FOUND;
2534 }
2535 ctx = get_ctx(tline->text, FALSE);
2536 if (!ctx)
2537 smhead = &smacros[hash(tline->text)];
2538 else
2539 smhead = &ctx->localmac;
2540 mname = tline->text;
2541 last = tline;
2542 tline = expand_smacro(tline->next);
2543 last->next = NULL;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002544
H. Peter Anvine2c80182005-01-15 22:15:51 +00002545 t = tline;
2546 while (tok_type_(t, TOK_WHITESPACE))
2547 t = t->next;
2548 /* t should now point to the string */
2549 if (t->type != TOK_STRING) {
2550 error(ERR_NONFATAL,
2551 "`%%strlen` requires string as second parameter");
2552 free_tlist(tline);
2553 free_tlist(origline);
2554 return DIRECTIVE_FOUND;
2555 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002556
H. Peter Anvine2c80182005-01-15 22:15:51 +00002557 macro_start = nasm_malloc(sizeof(*macro_start));
2558 macro_start->next = NULL;
2559 make_tok_num(macro_start, strlen(t->text) - 2);
2560 macro_start->mac = NULL;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002561
H. Peter Anvine2c80182005-01-15 22:15:51 +00002562 /*
2563 * We now have a macro name, an implicit parameter count of
2564 * zero, and a numeric token to use as an expansion. Create
2565 * and store an SMacro.
2566 */
2567 if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN)) {
2568 if (!smac)
2569 error(ERR_WARNING,
2570 "single-line macro `%s' defined both with and"
2571 " without parameters", mname);
2572 else {
2573 /*
2574 * We're redefining, so we have to take over an
2575 * existing SMacro structure. This means freeing
2576 * what was already in it.
2577 */
2578 nasm_free(smac->name);
2579 free_tlist(smac->expansion);
2580 }
2581 } else {
2582 smac = nasm_malloc(sizeof(SMacro));
2583 smac->next = *smhead;
2584 *smhead = smac;
2585 }
2586 smac->name = nasm_strdup(mname);
2587 smac->casesense = (i == PP_STRLEN);
2588 smac->nparam = 0;
2589 smac->expansion = macro_start;
2590 smac->in_progress = FALSE;
2591 free_tlist(tline);
2592 free_tlist(origline);
2593 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002594
H. Peter Anvine2c80182005-01-15 22:15:51 +00002595 case PP_SUBSTR:
2596 tline = tline->next;
2597 skip_white_(tline);
2598 tline = expand_id(tline);
2599 if (!tline || (tline->type != TOK_ID &&
2600 (tline->type != TOK_PREPROC_ID ||
2601 tline->text[1] != '$'))) {
2602 error(ERR_NONFATAL,
2603 "`%%substr' expects a macro identifier as first parameter");
2604 free_tlist(origline);
2605 return DIRECTIVE_FOUND;
2606 }
2607 ctx = get_ctx(tline->text, FALSE);
2608 if (!ctx)
2609 smhead = &smacros[hash(tline->text)];
2610 else
2611 smhead = &ctx->localmac;
2612 mname = tline->text;
2613 last = tline;
2614 tline = expand_smacro(tline->next);
2615 last->next = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002616
H. Peter Anvine2c80182005-01-15 22:15:51 +00002617 t = tline->next;
2618 while (tok_type_(t, TOK_WHITESPACE))
2619 t = t->next;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002620
H. Peter Anvine2c80182005-01-15 22:15:51 +00002621 /* t should now point to the string */
2622 if (t->type != TOK_STRING) {
2623 error(ERR_NONFATAL,
2624 "`%%substr` requires string as second parameter");
2625 free_tlist(tline);
2626 free_tlist(origline);
2627 return DIRECTIVE_FOUND;
2628 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002629
H. Peter Anvine2c80182005-01-15 22:15:51 +00002630 tt = t->next;
2631 tptr = &tt;
2632 tokval.t_type = TOKEN_INVALID;
2633 evalresult =
2634 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2635 if (!evalresult) {
2636 free_tlist(tline);
2637 free_tlist(origline);
2638 return DIRECTIVE_FOUND;
2639 }
2640 if (!is_simple(evalresult)) {
2641 error(ERR_NONFATAL, "non-constant value given to `%%substr`");
2642 free_tlist(tline);
2643 free_tlist(origline);
2644 return DIRECTIVE_FOUND;
2645 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002646
H. Peter Anvine2c80182005-01-15 22:15:51 +00002647 macro_start = nasm_malloc(sizeof(*macro_start));
2648 macro_start->next = NULL;
2649 macro_start->text = nasm_strdup("'''");
2650 if (evalresult->value > 0
2651 && evalresult->value < strlen(t->text) - 1) {
2652 macro_start->text[1] = t->text[evalresult->value];
2653 } else {
2654 macro_start->text[2] = '\0';
2655 }
2656 macro_start->type = TOK_STRING;
2657 macro_start->mac = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002658
H. Peter Anvine2c80182005-01-15 22:15:51 +00002659 /*
2660 * We now have a macro name, an implicit parameter count of
2661 * zero, and a numeric token to use as an expansion. Create
2662 * and store an SMacro.
2663 */
2664 if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR)) {
2665 if (!smac)
2666 error(ERR_WARNING,
2667 "single-line macro `%s' defined both with and"
2668 " without parameters", mname);
2669 else {
2670 /*
2671 * We're redefining, so we have to take over an
2672 * existing SMacro structure. This means freeing
2673 * what was already in it.
2674 */
2675 nasm_free(smac->name);
2676 free_tlist(smac->expansion);
2677 }
2678 } else {
2679 smac = nasm_malloc(sizeof(SMacro));
2680 smac->next = *smhead;
2681 *smhead = smac;
2682 }
2683 smac->name = nasm_strdup(mname);
2684 smac->casesense = (i == PP_SUBSTR);
2685 smac->nparam = 0;
2686 smac->expansion = macro_start;
2687 smac->in_progress = FALSE;
2688 free_tlist(tline);
2689 free_tlist(origline);
2690 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002691
H. Peter Anvine2c80182005-01-15 22:15:51 +00002692 case PP_ASSIGN:
2693 case PP_IASSIGN:
2694 tline = tline->next;
2695 skip_white_(tline);
2696 tline = expand_id(tline);
2697 if (!tline || (tline->type != TOK_ID &&
2698 (tline->type != TOK_PREPROC_ID ||
2699 tline->text[1] != '$'))) {
2700 error(ERR_NONFATAL,
2701 "`%%%sassign' expects a macro identifier",
2702 (i == PP_IASSIGN ? "i" : ""));
2703 free_tlist(origline);
2704 return DIRECTIVE_FOUND;
2705 }
2706 ctx = get_ctx(tline->text, FALSE);
2707 if (!ctx)
2708 smhead = &smacros[hash(tline->text)];
2709 else
2710 smhead = &ctx->localmac;
2711 mname = tline->text;
2712 last = tline;
2713 tline = expand_smacro(tline->next);
2714 last->next = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002715
H. Peter Anvine2c80182005-01-15 22:15:51 +00002716 t = tline;
2717 tptr = &t;
2718 tokval.t_type = TOKEN_INVALID;
2719 evalresult =
2720 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2721 free_tlist(tline);
2722 if (!evalresult) {
2723 free_tlist(origline);
2724 return DIRECTIVE_FOUND;
2725 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002726
H. Peter Anvine2c80182005-01-15 22:15:51 +00002727 if (tokval.t_type)
2728 error(ERR_WARNING,
2729 "trailing garbage after expression ignored");
H. Peter Anvin734b1882002-04-30 21:01:08 +00002730
H. Peter Anvine2c80182005-01-15 22:15:51 +00002731 if (!is_simple(evalresult)) {
2732 error(ERR_NONFATAL,
2733 "non-constant value given to `%%%sassign'",
2734 (i == PP_IASSIGN ? "i" : ""));
2735 free_tlist(origline);
2736 return DIRECTIVE_FOUND;
2737 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002738
H. Peter Anvine2c80182005-01-15 22:15:51 +00002739 macro_start = nasm_malloc(sizeof(*macro_start));
2740 macro_start->next = NULL;
2741 make_tok_num(macro_start, reloc_value(evalresult));
2742 macro_start->mac = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002743
H. Peter Anvine2c80182005-01-15 22:15:51 +00002744 /*
2745 * We now have a macro name, an implicit parameter count of
2746 * zero, and a numeric token to use as an expansion. Create
2747 * and store an SMacro.
2748 */
2749 if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN)) {
2750 if (!smac)
2751 error(ERR_WARNING,
2752 "single-line macro `%s' defined both with and"
2753 " without parameters", mname);
2754 else {
2755 /*
2756 * We're redefining, so we have to take over an
2757 * existing SMacro structure. This means freeing
2758 * what was already in it.
2759 */
2760 nasm_free(smac->name);
2761 free_tlist(smac->expansion);
2762 }
2763 } else {
2764 smac = nasm_malloc(sizeof(SMacro));
2765 smac->next = *smhead;
2766 *smhead = smac;
2767 }
2768 smac->name = nasm_strdup(mname);
2769 smac->casesense = (i == PP_ASSIGN);
2770 smac->nparam = 0;
2771 smac->expansion = macro_start;
2772 smac->in_progress = FALSE;
2773 free_tlist(origline);
2774 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002775
H. Peter Anvine2c80182005-01-15 22:15:51 +00002776 case PP_LINE:
2777 /*
2778 * Syntax is `%line nnn[+mmm] [filename]'
2779 */
2780 tline = tline->next;
2781 skip_white_(tline);
2782 if (!tok_type_(tline, TOK_NUMBER)) {
2783 error(ERR_NONFATAL, "`%%line' expects line number");
2784 free_tlist(origline);
2785 return DIRECTIVE_FOUND;
2786 }
2787 k = readnum(tline->text, &j);
2788 m = 1;
2789 tline = tline->next;
2790 if (tok_is_(tline, "+")) {
2791 tline = tline->next;
2792 if (!tok_type_(tline, TOK_NUMBER)) {
2793 error(ERR_NONFATAL, "`%%line' expects line increment");
2794 free_tlist(origline);
2795 return DIRECTIVE_FOUND;
2796 }
2797 m = readnum(tline->text, &j);
2798 tline = tline->next;
2799 }
2800 skip_white_(tline);
2801 src_set_linnum(k);
2802 istk->lineinc = m;
2803 if (tline) {
2804 nasm_free(src_set_fname(detoken(tline, FALSE)));
2805 }
2806 free_tlist(origline);
2807 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002808
H. Peter Anvine2c80182005-01-15 22:15:51 +00002809 default:
2810 error(ERR_FATAL,
2811 "preprocessor directive `%s' not yet implemented",
2812 directives[i]);
2813 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002814 }
Ed Beroset3ab3f412002-06-11 03:31:49 +00002815 return DIRECTIVE_FOUND;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002816}
2817
2818/*
H. Peter Anvin76690a12002-04-30 20:52:49 +00002819 * Ensure that a macro parameter contains a condition code and
2820 * nothing else. Return the condition code index if so, or -1
2821 * otherwise.
2822 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00002823static int find_cc(Token * t)
H. Peter Anvineba20a72002-04-30 20:53:55 +00002824{
H. Peter Anvin76690a12002-04-30 20:52:49 +00002825 Token *tt;
2826 int i, j, k, m;
2827
H. Peter Anvineba20a72002-04-30 20:53:55 +00002828 skip_white_(t);
H. Peter Anvin76690a12002-04-30 20:52:49 +00002829 if (t->type != TOK_ID)
H. Peter Anvine2c80182005-01-15 22:15:51 +00002830 return -1;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002831 tt = t->next;
H. Peter Anvineba20a72002-04-30 20:53:55 +00002832 skip_white_(tt);
H. Peter Anvin76690a12002-04-30 20:52:49 +00002833 if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
H. Peter Anvine2c80182005-01-15 22:15:51 +00002834 return -1;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002835
2836 i = -1;
Ed Beroset3ab3f412002-06-11 03:31:49 +00002837 j = elements(conditions);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002838 while (j - i > 1) {
2839 k = (j + i) / 2;
2840 m = nasm_stricmp(t->text, conditions[k]);
2841 if (m == 0) {
2842 i = k;
2843 j = -2;
2844 break;
2845 } else if (m < 0) {
2846 j = k;
2847 } else
2848 i = k;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002849 }
2850 if (j != -2)
H. Peter Anvine2c80182005-01-15 22:15:51 +00002851 return -1;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002852 return i;
2853}
2854
2855/*
2856 * Expand MMacro-local things: parameter references (%0, %n, %+n,
2857 * %-n) and MMacro-local identifiers (%%foo).
2858 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00002859static Token *expand_mmac_params(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00002860{
H. Peter Anvin734b1882002-04-30 21:01:08 +00002861 Token *t, *tt, **tail, *thead;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002862
2863 tail = &thead;
2864 thead = NULL;
2865
H. Peter Anvine2c80182005-01-15 22:15:51 +00002866 while (tline) {
2867 if (tline->type == TOK_PREPROC_ID &&
2868 (((tline->text[1] == '+' || tline->text[1] == '-')
2869 && tline->text[2]) || tline->text[1] == '%'
2870 || (tline->text[1] >= '0' && tline->text[1] <= '9'))) {
2871 char *text = NULL;
2872 int type = 0, cc; /* type = 0 to placate optimisers */
2873 char tmpbuf[30];
2874 int n, i;
2875 MMacro *mac;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002876
H. Peter Anvine2c80182005-01-15 22:15:51 +00002877 t = tline;
2878 tline = tline->next;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002879
H. Peter Anvine2c80182005-01-15 22:15:51 +00002880 mac = istk->mstk;
2881 while (mac && !mac->name) /* avoid mistaking %reps for macros */
2882 mac = mac->next_active;
2883 if (!mac)
2884 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
2885 else
2886 switch (t->text[1]) {
2887 /*
2888 * We have to make a substitution of one of the
2889 * forms %1, %-1, %+1, %%foo, %0.
2890 */
2891 case '0':
2892 type = TOK_NUMBER;
2893 snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam);
2894 text = nasm_strdup(tmpbuf);
2895 break;
2896 case '%':
2897 type = TOK_ID;
2898 snprintf(tmpbuf, sizeof(tmpbuf), "..@%lu.",
2899 mac->unique);
2900 text = nasm_strcat(tmpbuf, t->text + 2);
2901 break;
2902 case '-':
2903 n = atoi(t->text + 2) - 1;
2904 if (n >= mac->nparam)
2905 tt = NULL;
2906 else {
2907 if (mac->nparam > 1)
2908 n = (n + mac->rotate) % mac->nparam;
2909 tt = mac->params[n];
2910 }
2911 cc = find_cc(tt);
2912 if (cc == -1) {
2913 error(ERR_NONFATAL,
2914 "macro parameter %d is not a condition code",
2915 n + 1);
2916 text = NULL;
2917 } else {
2918 type = TOK_ID;
2919 if (inverse_ccs[cc] == -1) {
2920 error(ERR_NONFATAL,
2921 "condition code `%s' is not invertible",
2922 conditions[cc]);
2923 text = NULL;
2924 } else
2925 text =
2926 nasm_strdup(conditions[inverse_ccs[cc]]);
2927 }
2928 break;
2929 case '+':
2930 n = atoi(t->text + 2) - 1;
2931 if (n >= mac->nparam)
2932 tt = NULL;
2933 else {
2934 if (mac->nparam > 1)
2935 n = (n + mac->rotate) % mac->nparam;
2936 tt = mac->params[n];
2937 }
2938 cc = find_cc(tt);
2939 if (cc == -1) {
2940 error(ERR_NONFATAL,
2941 "macro parameter %d is not a condition code",
2942 n + 1);
2943 text = NULL;
2944 } else {
2945 type = TOK_ID;
2946 text = nasm_strdup(conditions[cc]);
2947 }
2948 break;
2949 default:
2950 n = atoi(t->text + 1) - 1;
2951 if (n >= mac->nparam)
2952 tt = NULL;
2953 else {
2954 if (mac->nparam > 1)
2955 n = (n + mac->rotate) % mac->nparam;
2956 tt = mac->params[n];
2957 }
2958 if (tt) {
2959 for (i = 0; i < mac->paramlen[n]; i++) {
2960 *tail = new_Token(NULL, tt->type, tt->text, 0);
2961 tail = &(*tail)->next;
2962 tt = tt->next;
2963 }
2964 }
2965 text = NULL; /* we've done it here */
2966 break;
2967 }
2968 if (!text) {
2969 delete_Token(t);
2970 } else {
2971 *tail = t;
2972 tail = &t->next;
2973 t->type = type;
2974 nasm_free(t->text);
2975 t->text = text;
2976 t->mac = NULL;
2977 }
2978 continue;
2979 } else {
2980 t = *tail = tline;
2981 tline = tline->next;
2982 t->mac = NULL;
2983 tail = &t->next;
2984 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00002985 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00002986 *tail = NULL;
2987 t = thead;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002988 for (; t && (tt = t->next) != NULL; t = t->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +00002989 switch (t->type) {
2990 case TOK_WHITESPACE:
2991 if (tt->type == TOK_WHITESPACE) {
2992 t->next = delete_Token(tt);
2993 }
2994 break;
2995 case TOK_ID:
2996 if (tt->type == TOK_ID || tt->type == TOK_NUMBER) {
2997 char *tmp = nasm_strcat(t->text, tt->text);
2998 nasm_free(t->text);
2999 t->text = tmp;
3000 t->next = delete_Token(tt);
3001 }
3002 break;
3003 case TOK_NUMBER:
3004 if (tt->type == TOK_NUMBER) {
3005 char *tmp = nasm_strcat(t->text, tt->text);
3006 nasm_free(t->text);
3007 t->text = tmp;
3008 t->next = delete_Token(tt);
3009 }
3010 break;
3011 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003012
H. Peter Anvin76690a12002-04-30 20:52:49 +00003013 return thead;
3014}
3015
3016/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003017 * Expand all single-line macro calls made in the given line.
3018 * Return the expanded version of the line. The original is deemed
3019 * to be destroyed in the process. (In reality we'll just move
3020 * Tokens from input to output a lot of the time, rather than
3021 * actually bothering to destroy and replicate.)
3022 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003023static Token *expand_smacro(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003024{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003025 Token *t, *tt, *mstart, **tail, *thead;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003026 SMacro *head = NULL, *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003027 Token **params;
3028 int *paramsize;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003029 int nparam, sparam, brackets, rescan;
3030 Token *org_tline = tline;
3031 Context *ctx;
3032 char *mname;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003033
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003034 /*
3035 * Trick: we should avoid changing the start token pointer since it can
3036 * be contained in "next" field of other token. Because of this
3037 * we allocate a copy of first token and work with it; at the end of
3038 * routine we copy it back
3039 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003040 if (org_tline) {
3041 tline =
3042 new_Token(org_tline->next, org_tline->type, org_tline->text,
3043 0);
3044 tline->mac = org_tline->mac;
3045 nasm_free(org_tline->text);
3046 org_tline->text = NULL;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003047 }
3048
H. Peter Anvin734b1882002-04-30 21:01:08 +00003049 again:
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003050 tail = &thead;
3051 thead = NULL;
3052
H. Peter Anvine2c80182005-01-15 22:15:51 +00003053 while (tline) { /* main token loop */
3054 if ((mname = tline->text)) {
3055 /* if this token is a local macro, look in local context */
3056 if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
3057 ctx = get_ctx(mname, TRUE);
3058 else
3059 ctx = NULL;
3060 if (!ctx)
3061 head = smacros[hash(mname)];
3062 else
3063 head = ctx->localmac;
3064 /*
3065 * We've hit an identifier. As in is_mmacro below, we first
3066 * check whether the identifier is a single-line macro at
3067 * all, then think about checking for parameters if
3068 * necessary.
3069 */
3070 for (m = head; m; m = m->next)
3071 if (!mstrcmp(m->name, mname, m->casesense))
3072 break;
3073 if (m) {
3074 mstart = tline;
3075 params = NULL;
3076 paramsize = NULL;
3077 if (m->nparam == 0) {
3078 /*
3079 * Simple case: the macro is parameterless. Discard the
3080 * one token that the macro call took, and push the
3081 * expansion back on the to-do stack.
3082 */
3083 if (!m->expansion) {
3084 if (!strcmp("__FILE__", m->name)) {
3085 long num = 0;
3086 src_get(&num, &(tline->text));
3087 nasm_quote(&(tline->text));
3088 tline->type = TOK_STRING;
3089 continue;
3090 }
3091 if (!strcmp("__LINE__", m->name)) {
3092 nasm_free(tline->text);
3093 make_tok_num(tline, src_get_linnum());
3094 continue;
3095 }
3096 tline = delete_Token(tline);
3097 continue;
3098 }
3099 } else {
3100 /*
3101 * Complicated case: at least one macro with this name
3102 * exists and takes parameters. We must find the
3103 * parameters in the call, count them, find the SMacro
3104 * that corresponds to that form of the macro call, and
3105 * substitute for the parameters when we expand. What a
3106 * pain.
3107 */
3108 /*tline = tline->next;
3109 skip_white_(tline); */
3110 do {
3111 t = tline->next;
3112 while (tok_type_(t, TOK_SMAC_END)) {
3113 t->mac->in_progress = FALSE;
3114 t->text = NULL;
3115 t = tline->next = delete_Token(t);
3116 }
3117 tline = t;
3118 } while (tok_type_(tline, TOK_WHITESPACE));
3119 if (!tok_is_(tline, "(")) {
3120 /*
3121 * This macro wasn't called with parameters: ignore
3122 * the call. (Behaviour borrowed from gnu cpp.)
3123 */
3124 tline = mstart;
3125 m = NULL;
3126 } else {
3127 int paren = 0;
3128 int white = 0;
3129 brackets = 0;
3130 nparam = 0;
3131 sparam = PARAM_DELTA;
3132 params = nasm_malloc(sparam * sizeof(Token *));
3133 params[0] = tline->next;
3134 paramsize = nasm_malloc(sparam * sizeof(int));
3135 paramsize[0] = 0;
3136 while (TRUE) { /* parameter loop */
3137 /*
3138 * For some unusual expansions
3139 * which concatenates function call
3140 */
3141 t = tline->next;
3142 while (tok_type_(t, TOK_SMAC_END)) {
3143 t->mac->in_progress = FALSE;
3144 t->text = NULL;
3145 t = tline->next = delete_Token(t);
3146 }
3147 tline = t;
Nickolay Yurchenko9aea7152003-09-07 22:46:26 +00003148
H. Peter Anvine2c80182005-01-15 22:15:51 +00003149 if (!tline) {
3150 error(ERR_NONFATAL,
3151 "macro call expects terminating `)'");
3152 break;
3153 }
3154 if (tline->type == TOK_WHITESPACE
3155 && brackets <= 0) {
3156 if (paramsize[nparam])
3157 white++;
3158 else
3159 params[nparam] = tline->next;
3160 continue; /* parameter loop */
3161 }
3162 if (tline->type == TOK_OTHER
3163 && tline->text[1] == 0) {
3164 char ch = tline->text[0];
3165 if (ch == ',' && !paren && brackets <= 0) {
3166 if (++nparam >= sparam) {
3167 sparam += PARAM_DELTA;
3168 params = nasm_realloc(params,
3169 sparam *
3170 sizeof(Token
3171 *));
3172 paramsize =
3173 nasm_realloc(paramsize,
3174 sparam *
3175 sizeof(int));
3176 }
3177 params[nparam] = tline->next;
3178 paramsize[nparam] = 0;
3179 white = 0;
3180 continue; /* parameter loop */
3181 }
3182 if (ch == '{' &&
3183 (brackets > 0 || (brackets == 0 &&
3184 !paramsize[nparam])))
3185 {
3186 if (!(brackets++)) {
3187 params[nparam] = tline->next;
3188 continue; /* parameter loop */
3189 }
3190 }
3191 if (ch == '}' && brackets > 0)
3192 if (--brackets == 0) {
3193 brackets = -1;
3194 continue; /* parameter loop */
3195 }
3196 if (ch == '(' && !brackets)
3197 paren++;
3198 if (ch == ')' && brackets <= 0)
3199 if (--paren < 0)
3200 break;
3201 }
3202 if (brackets < 0) {
3203 brackets = 0;
3204 error(ERR_NONFATAL, "braces do not "
3205 "enclose all of macro parameter");
3206 }
3207 paramsize[nparam] += white + 1;
3208 white = 0;
3209 } /* parameter loop */
3210 nparam++;
3211 while (m && (m->nparam != nparam ||
3212 mstrcmp(m->name, mname,
3213 m->casesense)))
3214 m = m->next;
3215 if (!m)
3216 error(ERR_WARNING | ERR_WARN_MNP,
3217 "macro `%s' exists, "
3218 "but not taking %d parameters",
3219 mstart->text, nparam);
3220 }
3221 }
3222 if (m && m->in_progress)
3223 m = NULL;
3224 if (!m) { /* in progess or didn't find '(' or wrong nparam */
3225 /*
3226 * Design question: should we handle !tline, which
3227 * indicates missing ')' here, or expand those
3228 * macros anyway, which requires the (t) test a few
3229 * lines down?
3230 */
3231 nasm_free(params);
3232 nasm_free(paramsize);
3233 tline = mstart;
3234 } else {
3235 /*
3236 * Expand the macro: we are placed on the last token of the
3237 * call, so that we can easily split the call from the
3238 * following tokens. We also start by pushing an SMAC_END
3239 * token for the cycle removal.
3240 */
3241 t = tline;
3242 if (t) {
3243 tline = t->next;
3244 t->next = NULL;
3245 }
3246 tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
3247 tt->mac = m;
3248 m->in_progress = TRUE;
3249 tline = tt;
3250 for (t = m->expansion; t; t = t->next) {
3251 if (t->type >= TOK_SMAC_PARAM) {
3252 Token *pcopy = tline, **ptail = &pcopy;
3253 Token *ttt, *pt;
3254 int i;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003255
H. Peter Anvine2c80182005-01-15 22:15:51 +00003256 ttt = params[t->type - TOK_SMAC_PARAM];
3257 for (i = paramsize[t->type - TOK_SMAC_PARAM];
3258 --i >= 0;) {
3259 pt = *ptail =
3260 new_Token(tline, ttt->type, ttt->text,
3261 0);
3262 ptail = &pt->next;
3263 ttt = ttt->next;
3264 }
3265 tline = pcopy;
3266 } else {
3267 tt = new_Token(tline, t->type, t->text, 0);
3268 tline = tt;
3269 }
3270 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003271
H. Peter Anvine2c80182005-01-15 22:15:51 +00003272 /*
3273 * Having done that, get rid of the macro call, and clean
3274 * up the parameters.
3275 */
3276 nasm_free(params);
3277 nasm_free(paramsize);
3278 free_tlist(mstart);
3279 continue; /* main token loop */
3280 }
3281 }
3282 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003283
H. Peter Anvine2c80182005-01-15 22:15:51 +00003284 if (tline->type == TOK_SMAC_END) {
3285 tline->mac->in_progress = FALSE;
3286 tline = delete_Token(tline);
3287 } else {
3288 t = *tail = tline;
3289 tline = tline->next;
3290 t->mac = NULL;
3291 t->next = NULL;
3292 tail = &t->next;
3293 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003294 }
3295
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003296 /*
3297 * Now scan the entire line and look for successive TOK_IDs that resulted
3298 * after expansion (they can't be produced by tokenise()). The successive
3299 * TOK_IDs should be concatenated.
3300 * Also we look for %+ tokens and concatenate the tokens before and after
3301 * them (without white spaces in between).
3302 */
3303 t = thead;
3304 rescan = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003305 while (t) {
3306 while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
3307 t = t->next;
3308 if (!t || !t->next)
3309 break;
3310 if (t->next->type == TOK_ID ||
3311 t->next->type == TOK_PREPROC_ID ||
3312 t->next->type == TOK_NUMBER) {
3313 char *p = nasm_strcat(t->text, t->next->text);
3314 nasm_free(t->text);
3315 t->next = delete_Token(t->next);
3316 t->text = p;
3317 rescan = 1;
3318 } else if (t->next->type == TOK_WHITESPACE && t->next->next &&
3319 t->next->next->type == TOK_PREPROC_ID &&
3320 strcmp(t->next->next->text, "%+") == 0) {
3321 /* free the next whitespace, the %+ token and next whitespace */
3322 int i;
3323 for (i = 1; i <= 3; i++) {
3324 if (!t->next
3325 || (i != 2 && t->next->type != TOK_WHITESPACE))
3326 break;
3327 t->next = delete_Token(t->next);
3328 } /* endfor */
3329 } else
3330 t = t->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003331 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003332 /* If we concatenaded something, re-scan the line for macros */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003333 if (rescan) {
3334 tline = thead;
3335 goto again;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003336 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003337
H. Peter Anvine2c80182005-01-15 22:15:51 +00003338 if (org_tline) {
3339 if (thead) {
3340 *org_tline = *thead;
3341 /* since we just gave text to org_line, don't free it */
3342 thead->text = NULL;
3343 delete_Token(thead);
3344 } else {
3345 /* the expression expanded to empty line;
3346 we can't return NULL for some reasons
3347 we just set the line to a single WHITESPACE token. */
3348 memset(org_tline, 0, sizeof(*org_tline));
3349 org_tline->text = NULL;
3350 org_tline->type = TOK_WHITESPACE;
3351 }
3352 thead = org_tline;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003353 }
3354
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003355 return thead;
3356}
3357
3358/*
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003359 * Similar to expand_smacro but used exclusively with macro identifiers
3360 * right before they are fetched in. The reason is that there can be
3361 * identifiers consisting of several subparts. We consider that if there
3362 * are more than one element forming the name, user wants a expansion,
3363 * otherwise it will be left as-is. Example:
3364 *
3365 * %define %$abc cde
3366 *
3367 * the identifier %$abc will be left as-is so that the handler for %define
3368 * will suck it and define the corresponding value. Other case:
3369 *
3370 * %define _%$abc cde
3371 *
3372 * In this case user wants name to be expanded *before* %define starts
3373 * working, so we'll expand %$abc into something (if it has a value;
3374 * otherwise it will be left as-is) then concatenate all successive
3375 * PP_IDs into one.
3376 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003377static Token *expand_id(Token * tline)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003378{
3379 Token *cur, *oldnext = NULL;
3380
H. Peter Anvin734b1882002-04-30 21:01:08 +00003381 if (!tline || !tline->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003382 return tline;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003383
3384 cur = tline;
3385 while (cur->next &&
H. Peter Anvine2c80182005-01-15 22:15:51 +00003386 (cur->next->type == TOK_ID ||
3387 cur->next->type == TOK_PREPROC_ID
3388 || cur->next->type == TOK_NUMBER))
3389 cur = cur->next;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003390
3391 /* If identifier consists of just one token, don't expand */
3392 if (cur == tline)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003393 return tline;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003394
H. Peter Anvine2c80182005-01-15 22:15:51 +00003395 if (cur) {
3396 oldnext = cur->next; /* Detach the tail past identifier */
3397 cur->next = NULL; /* so that expand_smacro stops here */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003398 }
3399
H. Peter Anvin734b1882002-04-30 21:01:08 +00003400 tline = expand_smacro(tline);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003401
H. Peter Anvine2c80182005-01-15 22:15:51 +00003402 if (cur) {
3403 /* expand_smacro possibly changhed tline; re-scan for EOL */
3404 cur = tline;
3405 while (cur && cur->next)
3406 cur = cur->next;
3407 if (cur)
3408 cur->next = oldnext;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003409 }
3410
3411 return tline;
3412}
3413
3414/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003415 * Determine whether the given line constitutes a multi-line macro
3416 * call, and return the MMacro structure called if so. Doesn't have
3417 * to check for an initial label - that's taken care of in
3418 * expand_mmacro - but must check numbers of parameters. Guaranteed
3419 * to be called with tline->type == TOK_ID, so the putative macro
3420 * name is easy to find.
3421 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003422static MMacro *is_mmacro(Token * tline, Token *** params_array)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003423{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003424 MMacro *head, *m;
3425 Token **params;
3426 int nparam;
3427
3428 head = mmacros[hash(tline->text)];
3429
3430 /*
3431 * Efficiency: first we see if any macro exists with the given
3432 * name. If not, we can return NULL immediately. _Then_ we
3433 * count the parameters, and then we look further along the
3434 * list if necessary to find the proper MMacro.
3435 */
3436 for (m = head; m; m = m->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003437 if (!mstrcmp(m->name, tline->text, m->casesense))
3438 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003439 if (!m)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003440 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003441
3442 /*
3443 * OK, we have a potential macro. Count and demarcate the
3444 * parameters.
3445 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003446 count_mmac_params(tline->next, &nparam, &params);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003447
3448 /*
3449 * So we know how many parameters we've got. Find the MMacro
3450 * structure that handles this number.
3451 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003452 while (m) {
3453 if (m->nparam_min <= nparam
3454 && (m->plus || nparam <= m->nparam_max)) {
3455 /*
3456 * This one is right. Just check if cycle removal
3457 * prohibits us using it before we actually celebrate...
3458 */
3459 if (m->in_progress) {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003460#if 0
H. Peter Anvine2c80182005-01-15 22:15:51 +00003461 error(ERR_NONFATAL,
3462 "self-reference in multi-line macro `%s'", m->name);
H. Peter Anvineba20a72002-04-30 20:53:55 +00003463#endif
H. Peter Anvine2c80182005-01-15 22:15:51 +00003464 nasm_free(params);
3465 return NULL;
3466 }
3467 /*
3468 * It's right, and we can use it. Add its default
3469 * parameters to the end of our list if necessary.
3470 */
3471 if (m->defaults && nparam < m->nparam_min + m->ndefs) {
3472 params =
3473 nasm_realloc(params,
3474 ((m->nparam_min + m->ndefs +
3475 1) * sizeof(*params)));
3476 while (nparam < m->nparam_min + m->ndefs) {
3477 params[nparam] = m->defaults[nparam - m->nparam_min];
3478 nparam++;
3479 }
3480 }
3481 /*
3482 * If we've gone over the maximum parameter count (and
3483 * we're in Plus mode), ignore parameters beyond
3484 * nparam_max.
3485 */
3486 if (m->plus && nparam > m->nparam_max)
3487 nparam = m->nparam_max;
3488 /*
3489 * Then terminate the parameter list, and leave.
3490 */
3491 if (!params) { /* need this special case */
3492 params = nasm_malloc(sizeof(*params));
3493 nparam = 0;
3494 }
3495 params[nparam] = NULL;
3496 *params_array = params;
3497 return m;
3498 }
3499 /*
3500 * This one wasn't right: look for the next one with the
3501 * same name.
3502 */
3503 for (m = m->next; m; m = m->next)
3504 if (!mstrcmp(m->name, tline->text, m->casesense))
3505 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003506 }
3507
3508 /*
3509 * After all that, we didn't find one with the right number of
3510 * parameters. Issue a warning, and fail to expand the macro.
3511 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003512 error(ERR_WARNING | ERR_WARN_MNP,
H. Peter Anvine2c80182005-01-15 22:15:51 +00003513 "macro `%s' exists, but not taking %d parameters",
3514 tline->text, nparam);
H. Peter Anvin734b1882002-04-30 21:01:08 +00003515 nasm_free(params);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003516 return NULL;
3517}
3518
3519/*
3520 * Expand the multi-line macro call made by the given line, if
3521 * there is one to be expanded. If there is, push the expansion on
H. Peter Anvineba20a72002-04-30 20:53:55 +00003522 * istk->expansion and return 1. Otherwise return 0.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003523 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003524static int expand_mmacro(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003525{
3526 Token *startline = tline;
3527 Token *label = NULL;
3528 int dont_prepend = 0;
3529 Token **params, *t, *tt;
3530 MMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003531 Line *l, *ll;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003532 int i, nparam, *paramlen;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003533
3534 t = tline;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003535 skip_white_(t);
H. Peter Anvindce1e2f2002-04-30 21:06:37 +00003536/* if (!tok_type_(t, TOK_ID)) Lino 02/25/02 */
3537 if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID))
H. Peter Anvine2c80182005-01-15 22:15:51 +00003538 return 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003539 m = is_mmacro(t, &params);
H. Peter Anvine2c80182005-01-15 22:15:51 +00003540 if (!m) {
3541 Token *last;
3542 /*
3543 * We have an id which isn't a macro call. We'll assume
3544 * it might be a label; we'll also check to see if a
3545 * colon follows it. Then, if there's another id after
3546 * that lot, we'll check it again for macro-hood.
3547 */
3548 label = last = t;
3549 t = t->next;
3550 if (tok_type_(t, TOK_WHITESPACE))
3551 last = t, t = t->next;
3552 if (tok_is_(t, ":")) {
3553 dont_prepend = 1;
3554 last = t, t = t->next;
3555 if (tok_type_(t, TOK_WHITESPACE))
3556 last = t, t = t->next;
3557 }
3558 if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, &params)) == NULL)
3559 return 0;
3560 last->next = NULL;
3561 tline = t;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003562 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003563
3564 /*
3565 * Fix up the parameters: this involves stripping leading and
3566 * trailing whitespace, then stripping braces if they are
3567 * present.
3568 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003569 for (nparam = 0; params[nparam]; nparam++) ;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003570 paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003571
H. Peter Anvine2c80182005-01-15 22:15:51 +00003572 for (i = 0; params[i]; i++) {
3573 int brace = FALSE;
3574 int comma = (!m->plus || i < nparam - 1);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003575
H. Peter Anvine2c80182005-01-15 22:15:51 +00003576 t = params[i];
3577 skip_white_(t);
3578 if (tok_is_(t, "{"))
3579 t = t->next, brace = TRUE, comma = FALSE;
3580 params[i] = t;
3581 paramlen[i] = 0;
3582 while (t) {
3583 if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
3584 break; /* ... because we have hit a comma */
3585 if (comma && t->type == TOK_WHITESPACE
3586 && tok_is_(t->next, ","))
3587 break; /* ... or a space then a comma */
3588 if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
3589 break; /* ... or a brace */
3590 t = t->next;
3591 paramlen[i]++;
3592 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003593 }
3594
3595 /*
3596 * OK, we have a MMacro structure together with a set of
3597 * parameters. We must now go through the expansion and push
H. Peter Anvin76690a12002-04-30 20:52:49 +00003598 * copies of each Line on to istk->expansion. Substitution of
3599 * parameter tokens and macro-local tokens doesn't get done
3600 * until the single-line macro substitution process; this is
3601 * because delaying them allows us to change the semantics
3602 * later through %rotate.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003603 *
H. Peter Anvin76690a12002-04-30 20:52:49 +00003604 * First, push an end marker on to istk->expansion, mark this
3605 * macro as in progress, and set up its invocation-specific
3606 * variables.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003607 */
3608 ll = nasm_malloc(sizeof(Line));
3609 ll->next = istk->expansion;
3610 ll->finishes = m;
3611 ll->first = NULL;
3612 istk->expansion = ll;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003613
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003614 m->in_progress = TRUE;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003615 m->params = params;
3616 m->iline = tline;
3617 m->nparam = nparam;
3618 m->rotate = 0;
3619 m->paramlen = paramlen;
3620 m->unique = unique++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003621 m->lineno = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003622
3623 m->next_active = istk->mstk;
3624 istk->mstk = m;
3625
H. Peter Anvine2c80182005-01-15 22:15:51 +00003626 for (l = m->expansion; l; l = l->next) {
3627 Token **tail;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003628
H. Peter Anvine2c80182005-01-15 22:15:51 +00003629 ll = nasm_malloc(sizeof(Line));
3630 ll->finishes = NULL;
3631 ll->next = istk->expansion;
3632 istk->expansion = ll;
3633 tail = &ll->first;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003634
H. Peter Anvine2c80182005-01-15 22:15:51 +00003635 for (t = l->first; t; t = t->next) {
3636 Token *x = t;
3637 if (t->type == TOK_PREPROC_ID &&
3638 t->text[1] == '0' && t->text[2] == '0') {
3639 dont_prepend = -1;
3640 x = label;
3641 if (!x)
3642 continue;
3643 }
3644 tt = *tail = new_Token(NULL, x->type, x->text, 0);
3645 tail = &tt->next;
3646 }
3647 *tail = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003648 }
3649
3650 /*
H. Peter Anvineba20a72002-04-30 20:53:55 +00003651 * If we had a label, push it on as the first line of
3652 * the macro expansion.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003653 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003654 if (label) {
3655 if (dont_prepend < 0)
3656 free_tlist(startline);
3657 else {
3658 ll = nasm_malloc(sizeof(Line));
3659 ll->finishes = NULL;
3660 ll->next = istk->expansion;
3661 istk->expansion = ll;
3662 ll->first = startline;
3663 if (!dont_prepend) {
3664 while (label->next)
3665 label = label->next;
3666 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
3667 }
3668 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003669 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003670
H. Peter Anvin734b1882002-04-30 21:01:08 +00003671 list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00003672
H. Peter Anvineba20a72002-04-30 20:53:55 +00003673 return 1;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003674}
3675
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003676/*
3677 * Since preprocessor always operate only on the line that didn't
3678 * arrived yet, we should always use ERR_OFFBY1. Also since user
3679 * won't want to see same error twice (preprocessing is done once
3680 * per pass) we will want to show errors only during pass one.
3681 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003682static void error(int severity, const char *fmt, ...)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003683{
3684 va_list arg;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003685 char buff[1024];
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003686
3687 /* If we're in a dead branch of IF or something like it, ignore the error */
H. Peter Anvin77ba0c62002-05-14 03:18:53 +00003688 if (istk && istk->conds && !emitting(istk->conds->state))
H. Peter Anvine2c80182005-01-15 22:15:51 +00003689 return;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003690
H. Peter Anvin734b1882002-04-30 21:01:08 +00003691 va_start(arg, fmt);
Ed Beroset19f927a2004-12-15 17:07:03 +00003692 vsnprintf(buff, sizeof(buff), fmt, arg);
H. Peter Anvin734b1882002-04-30 21:01:08 +00003693 va_end(arg);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003694
H. Peter Anvin77ba0c62002-05-14 03:18:53 +00003695 if (istk && istk->mstk && istk->mstk->name)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003696 _error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
3697 istk->mstk->lineno, buff);
3698 else
3699 _error(severity | ERR_PASS1, "%s", buff);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003700}
3701
H. Peter Anvin734b1882002-04-30 21:01:08 +00003702static void
3703pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
H. Peter Anvine2c80182005-01-15 22:15:51 +00003704 ListGen * listgen)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003705{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003706 int h;
3707
H. Peter Anvin99941bf2002-05-14 17:44:03 +00003708 _error = errfunc;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003709 cstk = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003710 istk = nasm_malloc(sizeof(Include));
3711 istk->next = NULL;
3712 istk->conds = NULL;
3713 istk->expansion = NULL;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003714 istk->mstk = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003715 istk->fp = fopen(file, "r");
H. Peter Anvineba20a72002-04-30 20:53:55 +00003716 istk->fname = NULL;
3717 src_set_fname(nasm_strdup(file));
3718 src_set_linnum(0);
3719 istk->lineinc = 1;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003720 if (!istk->fp)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003721 error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'",
3722 file);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003723 defining = NULL;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003724 for (h = 0; h < NHASH; h++) {
3725 mmacros[h] = NULL;
3726 smacros[h] = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003727 }
3728 unique = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003729 if (tasm_compatible_mode) {
3730 stdmacpos = stdmac;
3731 } else {
3732 stdmacpos = &stdmac[TASM_MACRO_COUNT];
3733 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00003734 any_extrastdmac = (extrastdmac != NULL);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00003735 list = listgen;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003736 evaluate = eval;
3737 pass = apass;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003738}
3739
H. Peter Anvine2c80182005-01-15 22:15:51 +00003740static char *pp_getline(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003741{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003742 char *line;
3743 Token *tline;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003744
H. Peter Anvine2c80182005-01-15 22:15:51 +00003745 while (1) {
3746 /*
3747 * Fetch a tokenised line, either from the macro-expansion
3748 * buffer or from the input file.
3749 */
3750 tline = NULL;
3751 while (istk->expansion && istk->expansion->finishes) {
3752 Line *l = istk->expansion;
3753 if (!l->finishes->name && l->finishes->in_progress > 1) {
3754 Line *ll;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003755
H. Peter Anvine2c80182005-01-15 22:15:51 +00003756 /*
3757 * This is a macro-end marker for a macro with no
3758 * name, which means it's not really a macro at all
3759 * but a %rep block, and the `in_progress' field is
3760 * more than 1, meaning that we still need to
3761 * repeat. (1 means the natural last repetition; 0
3762 * means termination by %exitrep.) We have
3763 * therefore expanded up to the %endrep, and must
3764 * push the whole block on to the expansion buffer
3765 * again. We don't bother to remove the macro-end
3766 * marker: we'd only have to generate another one
3767 * if we did.
3768 */
3769 l->finishes->in_progress--;
3770 for (l = l->finishes->expansion; l; l = l->next) {
3771 Token *t, *tt, **tail;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003772
H. Peter Anvine2c80182005-01-15 22:15:51 +00003773 ll = nasm_malloc(sizeof(Line));
3774 ll->next = istk->expansion;
3775 ll->finishes = NULL;
3776 ll->first = NULL;
3777 tail = &ll->first;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003778
H. Peter Anvine2c80182005-01-15 22:15:51 +00003779 for (t = l->first; t; t = t->next) {
3780 if (t->text || t->type == TOK_WHITESPACE) {
3781 tt = *tail =
3782 new_Token(NULL, t->type, t->text, 0);
3783 tail = &tt->next;
3784 }
3785 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00003786
H. Peter Anvine2c80182005-01-15 22:15:51 +00003787 istk->expansion = ll;
3788 }
3789 } else {
3790 /*
3791 * Check whether a `%rep' was started and not ended
3792 * within this macro expansion. This can happen and
3793 * should be detected. It's a fatal error because
3794 * I'm too confused to work out how to recover
3795 * sensibly from it.
3796 */
3797 if (defining) {
3798 if (defining->name)
3799 error(ERR_PANIC,
3800 "defining with name in expansion");
3801 else if (istk->mstk->name)
3802 error(ERR_FATAL,
3803 "`%%rep' without `%%endrep' within"
3804 " expansion of macro `%s'",
3805 istk->mstk->name);
3806 }
H. Peter Anvin87bc6192002-04-30 20:53:16 +00003807
H. Peter Anvine2c80182005-01-15 22:15:51 +00003808 /*
3809 * FIXME: investigate the relationship at this point between
3810 * istk->mstk and l->finishes
3811 */
3812 {
3813 MMacro *m = istk->mstk;
3814 istk->mstk = m->next_active;
3815 if (m->name) {
3816 /*
3817 * This was a real macro call, not a %rep, and
3818 * therefore the parameter information needs to
3819 * be freed.
3820 */
3821 nasm_free(m->params);
3822 free_tlist(m->iline);
3823 nasm_free(m->paramlen);
3824 l->finishes->in_progress = FALSE;
3825 } else
3826 free_mmacro(m);
3827 }
3828 istk->expansion = l->next;
3829 nasm_free(l);
3830 list->downlevel(LIST_MACRO);
3831 }
3832 }
3833 while (1) { /* until we get a line we can use */
H. Peter Anvineba20a72002-04-30 20:53:55 +00003834
H. Peter Anvine2c80182005-01-15 22:15:51 +00003835 if (istk->expansion) { /* from a macro expansion */
3836 char *p;
3837 Line *l = istk->expansion;
3838 if (istk->mstk)
3839 istk->mstk->lineno++;
3840 tline = l->first;
3841 istk->expansion = l->next;
3842 nasm_free(l);
3843 p = detoken(tline, FALSE);
3844 list->line(LIST_MACRO, p);
3845 nasm_free(p);
3846 break;
3847 }
3848 line = read_line();
3849 if (line) { /* from the current input file */
3850 line = prepreproc(line);
3851 tline = tokenise(line);
3852 nasm_free(line);
3853 break;
3854 }
3855 /*
3856 * The current file has ended; work down the istk
3857 */
3858 {
3859 Include *i = istk;
3860 fclose(i->fp);
3861 if (i->conds)
3862 error(ERR_FATAL,
3863 "expected `%%endif' before end of file");
3864 /* only set line and file name if there's a next node */
3865 if (i->next) {
3866 src_set_linnum(i->lineno);
3867 nasm_free(src_set_fname(i->fname));
3868 }
3869 istk = i->next;
3870 list->downlevel(LIST_INCLUDE);
3871 nasm_free(i);
3872 if (!istk)
3873 return NULL;
3874 }
3875 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003876
H. Peter Anvine2c80182005-01-15 22:15:51 +00003877 /*
3878 * We must expand MMacro parameters and MMacro-local labels
3879 * _before_ we plunge into directive processing, to cope
3880 * with things like `%define something %1' such as STRUC
3881 * uses. Unless we're _defining_ a MMacro, in which case
3882 * those tokens should be left alone to go into the
3883 * definition; and unless we're in a non-emitting
3884 * condition, in which case we don't want to meddle with
3885 * anything.
3886 */
3887 if (!defining && !(istk->conds && !emitting(istk->conds->state)))
3888 tline = expand_mmac_params(tline);
H. Peter Anvin76690a12002-04-30 20:52:49 +00003889
H. Peter Anvine2c80182005-01-15 22:15:51 +00003890 /*
3891 * Check the line to see if it's a preprocessor directive.
3892 */
3893 if (do_directive(tline) == DIRECTIVE_FOUND) {
3894 continue;
3895 } else if (defining) {
3896 /*
3897 * We're defining a multi-line macro. We emit nothing
3898 * at all, and just
3899 * shove the tokenised line on to the macro definition.
3900 */
3901 Line *l = nasm_malloc(sizeof(Line));
3902 l->next = defining->expansion;
3903 l->first = tline;
3904 l->finishes = FALSE;
3905 defining->expansion = l;
3906 continue;
3907 } else if (istk->conds && !emitting(istk->conds->state)) {
3908 /*
3909 * We're in a non-emitting branch of a condition block.
3910 * Emit nothing at all, not even a blank line: when we
3911 * emerge from the condition we'll give a line-number
3912 * directive so we keep our place correctly.
3913 */
3914 free_tlist(tline);
3915 continue;
3916 } else if (istk->mstk && !istk->mstk->in_progress) {
3917 /*
3918 * We're in a %rep block which has been terminated, so
3919 * we're walking through to the %endrep without
3920 * emitting anything. Emit nothing at all, not even a
3921 * blank line: when we emerge from the %rep block we'll
3922 * give a line-number directive so we keep our place
3923 * correctly.
3924 */
3925 free_tlist(tline);
3926 continue;
3927 } else {
3928 tline = expand_smacro(tline);
3929 if (!expand_mmacro(tline)) {
3930 /*
3931 * De-tokenise the line again, and emit it.
3932 */
3933 line = detoken(tline, TRUE);
3934 free_tlist(tline);
3935 break;
3936 } else {
3937 continue; /* expand_mmacro calls free_tlist */
3938 }
3939 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003940 }
3941
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003942 return line;
3943}
3944
H. Peter Anvine2c80182005-01-15 22:15:51 +00003945static void pp_cleanup(int pass)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003946{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003947 int h;
3948
H. Peter Anvine2c80182005-01-15 22:15:51 +00003949 if (defining) {
3950 error(ERR_NONFATAL, "end of file while still defining macro `%s'",
3951 defining->name);
3952 free_mmacro(defining);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003953 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003954 while (cstk)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003955 ctx_pop();
3956 for (h = 0; h < NHASH; h++) {
3957 while (mmacros[h]) {
3958 MMacro *m = mmacros[h];
3959 mmacros[h] = mmacros[h]->next;
3960 free_mmacro(m);
3961 }
3962 while (smacros[h]) {
3963 SMacro *s = smacros[h];
3964 smacros[h] = smacros[h]->next;
3965 nasm_free(s->name);
3966 free_tlist(s->expansion);
3967 nasm_free(s);
3968 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003969 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00003970 while (istk) {
3971 Include *i = istk;
3972 istk = istk->next;
3973 fclose(i->fp);
3974 nasm_free(i->fname);
3975 nasm_free(i);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003976 }
3977 while (cstk)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003978 ctx_pop();
3979 if (pass == 0) {
3980 free_llist(predef);
3981 delete_Blocks();
3982 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003983}
3984
H. Peter Anvine2c80182005-01-15 22:15:51 +00003985void pp_include_path(char *path)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003986{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00003987 IncPath *i;
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00003988/* by alexfru: order of path inclusion fixed (was reverse order) */
H. Peter Anvin6768eb72002-04-30 20:52:26 +00003989 i = nasm_malloc(sizeof(IncPath));
3990 i->path = nasm_strdup(path);
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00003991 i->next = NULL;
3992
H. Peter Anvine2c80182005-01-15 22:15:51 +00003993 if (ipath != NULL) {
3994 IncPath *j = ipath;
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00003995 while (j->next != NULL)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003996 j = j->next;
3997 j->next = i;
3998 } else {
3999 ipath = i;
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004000 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004001}
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004002
4003/*
4004 * added by alexfru:
4005 *
4006 * This function is used to "export" the include paths, e.g.
4007 * the paths specified in the '-I' command switch.
4008 * The need for such exporting is due to the 'incbin' directive,
4009 * which includes raw binary files (unlike '%include', which
4010 * includes text source files). It would be real nice to be
4011 * able to specify paths to search for incbin'ned files also.
4012 * So, this is a simple workaround.
4013 *
4014 * The function use is simple:
4015 *
4016 * The 1st call (with NULL argument) returns a pointer to the 1st path
4017 * (char** type) or NULL if none include paths available.
4018 *
4019 * All subsequent calls take as argument the value returned by this
4020 * function last. The return value is either the next path
4021 * (char** type) or NULL if the end of the paths list is reached.
4022 *
4023 * It is maybe not the best way to do things, but I didn't want
4024 * to export too much, just one or two functions and no types or
4025 * variables exported.
4026 *
4027 * Can't say I like the current situation with e.g. this path list either,
4028 * it seems to be never deallocated after creation...
4029 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00004030char **pp_get_include_path_ptr(char **pPrevPath)
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004031{
4032/* This macro returns offset of a member of a structure */
4033#define GetMemberOffset(StructType,MemberName)\
4034 ((size_t)&((StructType*)0)->MemberName)
4035 IncPath *i;
4036
H. Peter Anvine2c80182005-01-15 22:15:51 +00004037 if (pPrevPath == NULL) {
4038 if (ipath != NULL)
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004039 return &ipath->path;
4040 else
4041 return NULL;
4042 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00004043 i = (IncPath *) ((char *)pPrevPath - GetMemberOffset(IncPath, path));
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004044 i = i->next;
4045 if (i != NULL)
4046 return &i->path;
4047 else
4048 return NULL;
4049#undef GetMemberOffset
4050}
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004051
H. Peter Anvine2c80182005-01-15 22:15:51 +00004052void pp_pre_include(char *fname)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004053{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004054 Token *inc, *space, *name;
4055 Line *l;
4056
H. Peter Anvin734b1882002-04-30 21:01:08 +00004057 name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
4058 space = new_Token(name, TOK_WHITESPACE, NULL, 0);
4059 inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004060
4061 l = nasm_malloc(sizeof(Line));
4062 l->next = predef;
4063 l->first = inc;
4064 l->finishes = FALSE;
4065 predef = l;
4066}
4067
H. Peter Anvine2c80182005-01-15 22:15:51 +00004068void pp_pre_define(char *definition)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004069{
4070 Token *def, *space;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004071 Line *l;
4072 char *equals;
4073
4074 equals = strchr(definition, '=');
H. Peter Anvin734b1882002-04-30 21:01:08 +00004075 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4076 def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004077 if (equals)
H. Peter Anvine2c80182005-01-15 22:15:51 +00004078 *equals = ' ';
H. Peter Anvineba20a72002-04-30 20:53:55 +00004079 space->next = tokenise(definition);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004080 if (equals)
H. Peter Anvine2c80182005-01-15 22:15:51 +00004081 *equals = '=';
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004082
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004083 l = nasm_malloc(sizeof(Line));
4084 l->next = predef;
4085 l->first = def;
4086 l->finishes = FALSE;
4087 predef = l;
4088}
4089
H. Peter Anvine2c80182005-01-15 22:15:51 +00004090void pp_pre_undefine(char *definition)
H. Peter Anvin620515a2002-04-30 20:57:38 +00004091{
4092 Token *def, *space;
4093 Line *l;
4094
H. Peter Anvin734b1882002-04-30 21:01:08 +00004095 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4096 def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
Frank Kotlerd3523022003-06-14 12:12:26 +00004097 space->next = tokenise(definition);
H. Peter Anvin620515a2002-04-30 20:57:38 +00004098
4099 l = nasm_malloc(sizeof(Line));
4100 l->next = predef;
4101 l->first = def;
4102 l->finishes = FALSE;
4103 predef = l;
4104}
4105
H. Peter Anvine2c80182005-01-15 22:15:51 +00004106void pp_extra_stdmac(const char **macros)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004107{
H. Peter Anvin76690a12002-04-30 20:52:49 +00004108 extrastdmac = macros;
4109}
4110
H. Peter Anvine2c80182005-01-15 22:15:51 +00004111static void make_tok_num(Token * tok, long val)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004112{
4113 char numbuf[20];
Ed Beroset19f927a2004-12-15 17:07:03 +00004114 snprintf(numbuf, sizeof(numbuf), "%ld", val);
H. Peter Anvineba20a72002-04-30 20:53:55 +00004115 tok->text = nasm_strdup(numbuf);
4116 tok->type = TOK_NUMBER;
4117}
4118
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004119Preproc nasmpp = {
4120 pp_reset,
4121 pp_getline,
4122 pp_cleanup
4123};