blob: 525cce45dbf0e25fbe65093b50dcd0428dd311cc [file] [log] [blame]
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001/* preproc.c macro preprocessor for the Netwide Assembler
2 *
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
Beroset095e6a22007-12-29 09:44:23 -05005 * redistributable under the license given in the file "LICENSE"
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00006 * distributed in the NASM archive.
7 *
8 * initial version 18/iii/97 by Simon Tatham
9 */
10
H. Peter Anvin4836e332002-04-30 20:56:43 +000011/* Typical flow of text through preproc
12 *
Keith Kaniosb7a89542007-04-12 02:40:54 +000013 * pp_getline gets tokenized lines, either
H. Peter Anvin4836e332002-04-30 20:56:43 +000014 *
15 * from a macro expansion
16 *
17 * or
18 * {
19 * read_line gets raw text from stdmacpos, or predef, or current input file
Keith Kaniosb7a89542007-04-12 02:40:54 +000020 * tokenize converts to tokens
H. Peter Anvin4836e332002-04-30 20:56:43 +000021 * }
22 *
23 * expand_mmac_params is used to expand %1 etc., unless a macro is being
24 * defined or a false conditional is being processed
25 * (%0, %1, %+1, %-1, %%foo
26 *
27 * do_directive checks for directives
28 *
29 * expand_smacro is used to expand single line macros
30 *
31 * expand_mmacro is used to expand multi-line macros
32 *
33 * detoken is used to convert the line back to text
34 */
H. Peter Anvineba20a72002-04-30 20:53:55 +000035
H. Peter Anvinfe501952007-10-02 21:53:51 -070036#include "compiler.h"
37
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000038#include <stdio.h>
H. Peter Anvinaf535c12002-04-30 20:59:21 +000039#include <stdarg.h>
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000040#include <stdlib.h>
41#include <stddef.h>
42#include <string.h>
43#include <ctype.h>
H. Peter Anvin76690a12002-04-30 20:52:49 +000044#include <limits.h>
Keith Kaniosb7a89542007-04-12 02:40:54 +000045#include <inttypes.h>
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000046
47#include "nasm.h"
48#include "nasmlib.h"
H. Peter Anvin4169a472007-09-12 01:29:43 +000049#include "preproc.h"
H. Peter Anvin97a23472007-09-16 17:57:25 -070050#include "hashtbl.h"
H. Peter Anvin8cad14b2008-06-01 17:23:51 -070051#include "quote.h"
H. Peter Anvinc2df2822007-10-24 15:29:28 -070052#include "stdscan.h"
53#include "tokens.h"
H. Peter Anvina4835d42008-05-20 14:21:29 -070054#include "tables.h"
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000055
56typedef struct SMacro SMacro;
57typedef struct MMacro MMacro;
58typedef struct Context Context;
59typedef struct Token Token;
H. Peter Anvince616072002-04-30 21:02:23 +000060typedef struct Blocks Blocks;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000061typedef struct Line Line;
62typedef struct Include Include;
63typedef struct Cond Cond;
H. Peter Anvin6768eb72002-04-30 20:52:26 +000064typedef struct IncPath IncPath;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000065
66/*
H. Peter Anvin97a23472007-09-16 17:57:25 -070067 * Note on the storage of both SMacro and MMacros: the hash table
68 * indexes them case-insensitively, and we then have to go through a
69 * linked list of potential case aliases (and, for MMacros, parameter
70 * ranges); this is to preserve the matching semantics of the earlier
71 * code. If the number of case aliases for a specific macro is a
72 * performance issue, you may want to reconsider your coding style.
73 */
74
75/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000076 * Store the definition of a single-line macro.
77 */
H. Peter Anvine2c80182005-01-15 22:15:51 +000078struct SMacro {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000079 SMacro *next;
Keith Kaniosa6dfa782007-04-13 16:47:53 +000080 char *name;
H. Peter Anvin70055962007-10-11 00:05:31 -070081 bool casesense;
H. Peter Anvin16ed4382007-10-11 10:06:19 -070082 bool in_progress;
H. Peter Anvin70055962007-10-11 00:05:31 -070083 unsigned int nparam;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +000084 Token *expansion;
85};
86
87/*
H. Peter Anvin76690a12002-04-30 20:52:49 +000088 * Store the definition of a multi-line macro. This is also used to
89 * store the interiors of `%rep...%endrep' blocks, which are
90 * effectively self-re-invoking multi-line macros which simply
91 * don't have a name or bother to appear in the hash tables. %rep
92 * blocks are signified by having a NULL `name' field.
93 *
94 * In a MMacro describing a `%rep' block, the `in_progress' field
95 * isn't merely boolean, but gives the number of repeats left to
96 * run.
97 *
98 * The `next' field is used for storing MMacros in hash tables; the
99 * `next_active' field is for stacking them on istk entries.
100 *
101 * When a MMacro is being expanded, `params', `iline', `nparam',
102 * `paramlen', `rotate' and `unique' are local to the invocation.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000103 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000104struct MMacro {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000105 MMacro *next;
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000106 char *name;
H. Peter Anvin8cfdb9d2007-09-14 18:36:01 -0700107 int nparam_min, nparam_max;
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700108 bool casesense;
109 bool plus; /* is the last parameter greedy? */
110 bool nolist; /* is this macro listing-inhibited? */
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -0700111 int64_t in_progress;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000112 Token *dlist; /* All defaults as one list */
113 Token **defaults; /* Parameter default pointers */
114 int ndefs; /* number of default parameters */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000115 Line *expansion;
H. Peter Anvin76690a12002-04-30 20:52:49 +0000116
117 MMacro *next_active;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000118 MMacro *rep_nest; /* used for nesting %rep */
119 Token **params; /* actual parameters */
120 Token *iline; /* invocation line */
H. Peter Anvin25a99342007-09-22 17:45:45 -0700121 unsigned int nparam, rotate;
122 int *paramlen;
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -0700123 uint64_t unique;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000124 int lineno; /* Current line number on expansion */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000125};
126
127/*
128 * The context stack is composed of a linked list of these.
129 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000130struct Context {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000131 Context *next;
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000132 char *name;
H. Peter Anvin166c2472008-05-28 12:28:58 -0700133 struct hash_table localmac;
Keith Kaniosb7a89542007-04-12 02:40:54 +0000134 uint32_t number;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000135};
136
137/*
138 * This is the internal form which we break input lines up into.
139 * Typically stored in linked lists.
140 *
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000141 * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
142 * necessarily used as-is, but is intended to denote the number of
143 * the substituted parameter. So in the definition
144 *
145 * %define a(x,y) ( (x) & ~(y) )
H. Peter Anvin70653092007-10-19 14:42:29 -0700146 *
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000147 * the token representing `x' will have its type changed to
148 * TOK_SMAC_PARAM, but the one representing `y' will be
149 * TOK_SMAC_PARAM+1.
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000150 *
151 * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
152 * which doesn't need quotes around it. Used in the pre-include
153 * mechanism as an alternative to trying to find a sensible type of
154 * quote to use on the filename we were passed.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000155 */
H. Peter Anvinda10e7b2007-09-12 04:18:37 +0000156enum pp_token_type {
157 TOK_NONE = 0, TOK_WHITESPACE, TOK_COMMENT, TOK_ID,
158 TOK_PREPROC_ID, TOK_STRING,
H. Peter Anvin6c81f0a2008-05-25 21:46:17 -0700159 TOK_NUMBER, TOK_FLOAT, TOK_SMAC_END, TOK_OTHER,
160 TOK_INTERNAL_STRING,
161 TOK_PREPROC_Q, TOK_PREPROC_QQ,
H. Peter Anvin5b76fa22008-05-26 11:14:38 -0700162 TOK_SMAC_PARAM, /* MUST BE LAST IN THE LIST!!! */
163 TOK_MAX = INT_MAX /* Keep compiler from reducing the range */
H. Peter Anvinda10e7b2007-09-12 04:18:37 +0000164};
165
H. Peter Anvine2c80182005-01-15 22:15:51 +0000166struct Token {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000167 Token *next;
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000168 char *text;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000169 SMacro *mac; /* associated macro for TOK_SMAC_END */
H. Peter Anvinda10e7b2007-09-12 04:18:37 +0000170 enum pp_token_type type;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000171};
172
173/*
174 * Multi-line macro definitions are stored as a linked list of
175 * these, which is essentially a container to allow several linked
176 * lists of Tokens.
H. Peter Anvin70653092007-10-19 14:42:29 -0700177 *
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000178 * Note that in this module, linked lists are treated as stacks
179 * wherever possible. For this reason, Lines are _pushed_ on to the
180 * `expansion' field in MMacro structures, so that the linked list,
181 * if walked, would give the macro lines in reverse order; this
182 * means that we can walk the list when expanding a macro, and thus
183 * push the lines on to the `expansion' field in _istk_ in reverse
184 * order (so that when popped back off they are in the right
185 * order). It may seem cockeyed, and it relies on my design having
186 * an even number of steps in, but it works...
187 *
188 * Some of these structures, rather than being actual lines, are
189 * markers delimiting the end of the expansion of a given macro.
H. Peter Anvin76690a12002-04-30 20:52:49 +0000190 * This is for use in the cycle-tracking and %rep-handling code.
191 * Such structures have `finishes' non-NULL, and `first' NULL. All
192 * others have `finishes' NULL, but `first' may still be NULL if
193 * the line is blank.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000194 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000195struct Line {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000196 Line *next;
197 MMacro *finishes;
198 Token *first;
199};
200
201/*
202 * To handle an arbitrary level of file inclusion, we maintain a
203 * stack (ie linked list) of these things.
204 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000205struct Include {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000206 Include *next;
207 FILE *fp;
208 Cond *conds;
209 Line *expansion;
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000210 char *fname;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000211 int lineno, lineinc;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000212 MMacro *mstk; /* stack of active macros/reps */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000213};
214
215/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000216 * Include search path. This is simply a list of strings which get
217 * prepended, in turn, to the name of an include file, in an
218 * attempt to find the file if it's not in the current directory.
219 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000220struct IncPath {
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000221 IncPath *next;
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000222 char *path;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000223};
224
225/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000226 * Conditional assembly: we maintain a separate stack of these for
227 * each level of file inclusion. (The only reason we keep the
228 * stacks separate is to ensure that a stray `%endif' in a file
229 * included from within the true branch of a `%if' won't terminate
230 * it and cause confusion: instead, rightly, it'll cause an error.)
231 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000232struct Cond {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000233 Cond *next;
234 int state;
235};
H. Peter Anvine2c80182005-01-15 22:15:51 +0000236enum {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000237 /*
238 * These states are for use just after %if or %elif: IF_TRUE
239 * means the condition has evaluated to truth so we are
240 * currently emitting, whereas IF_FALSE means we are not
241 * currently emitting but will start doing so if a %else comes
242 * up. In these states, all directives are admissible: %elif,
243 * %else and %endif. (And of course %if.)
244 */
245 COND_IF_TRUE, COND_IF_FALSE,
246 /*
247 * These states come up after a %else: ELSE_TRUE means we're
248 * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
249 * any %elif or %else will cause an error.
250 */
251 COND_ELSE_TRUE, COND_ELSE_FALSE,
252 /*
253 * This state means that we're not emitting now, and also that
254 * nothing until %endif will be emitted at all. It's for use in
255 * two circumstances: (i) when we've had our moment of emission
256 * and have now started seeing %elifs, and (ii) when the
257 * condition construct in question is contained within a
258 * non-emitting branch of a larger condition construct.
259 */
260 COND_NEVER
261};
262#define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
263
H. Peter Anvin70653092007-10-19 14:42:29 -0700264/*
Ed Beroset3ab3f412002-06-11 03:31:49 +0000265 * These defines are used as the possible return values for do_directive
266 */
267#define NO_DIRECTIVE_FOUND 0
268#define DIRECTIVE_FOUND 1
269
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000270/*
271 * Condition codes. Note that we use c_ prefix not C_ because C_ is
272 * used in nasm.h for the "real" condition codes. At _this_ level,
273 * we treat CXZ and ECXZ as condition codes, albeit non-invertible
274 * ones, so we need a different enum...
275 */
H. Peter Anvin476d2862007-10-02 22:04:15 -0700276static const char * const conditions[] = {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000277 "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
278 "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
H. Peter Anvince9be342007-09-12 00:22:29 +0000279 "np", "ns", "nz", "o", "p", "pe", "po", "rcxz", "s", "z"
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000280};
H. Peter Anvin476d2862007-10-02 22:04:15 -0700281enum pp_conds {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000282 c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE,
283 c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO,
H. Peter Anvin476d2862007-10-02 22:04:15 -0700284 c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_RCXZ, c_S, c_Z,
285 c_none = -1
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000286};
H. Peter Anvin476d2862007-10-02 22:04:15 -0700287static const enum pp_conds inverse_ccs[] = {
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000288 c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE,
289 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,
H. Peter Anvince9be342007-09-12 00:22:29 +0000290 c_Z, c_NO, c_NP, c_PO, c_PE, -1, c_NS, c_NZ
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000291};
292
H. Peter Anvin76690a12002-04-30 20:52:49 +0000293/*
294 * Directive names.
295 */
H. Peter Anvin65747262002-05-07 00:10:05 +0000296/* If this is a an IF, ELIF, ELSE or ENDIF keyword */
H. Peter Anvin9bf0aa72007-09-12 02:12:07 +0000297static int is_condition(enum preproc_token arg)
H. Peter Anvin65747262002-05-07 00:10:05 +0000298{
H. Peter Anvinda10e7b2007-09-12 04:18:37 +0000299 return PP_IS_COND(arg) || (arg == PP_ELSE) || (arg == PP_ENDIF);
H. Peter Anvin65747262002-05-07 00:10:05 +0000300}
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000301
302/* For TASM compatibility we need to be able to recognise TASM compatible
303 * conditional compilation directives. Using the NASM pre-processor does
304 * not work, so we look for them specifically from the following list and
305 * then jam in the equivalent NASM directive into the input stream.
306 */
307
H. Peter Anvine2c80182005-01-15 22:15:51 +0000308enum {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000309 TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
310 TM_IFNDEF, TM_INCLUDE, TM_LOCAL
311};
312
H. Peter Anvin476d2862007-10-02 22:04:15 -0700313static const char * const tasm_directives[] = {
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000314 "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
315 "ifndef", "include", "local"
316};
317
318static int StackSize = 4;
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000319static char *StackPointer = "ebp";
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000320static int ArgOffset = 8;
H. Peter Anvin8781cb02007-11-08 20:01:11 -0800321static int LocalOffset = 0;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000322
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000323static Context *cstk;
324static Include *istk;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000325static IncPath *ipath = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000326
H. Peter Anvine2c80182005-01-15 22:15:51 +0000327static efunc _error; /* Pointer to client-provided error reporting function */
H. Peter Anvin76690a12002-04-30 20:52:49 +0000328static evalfunc evaluate;
329
H. Peter Anvine2c80182005-01-15 22:15:51 +0000330static int pass; /* HACK: pass 0 = generate dependencies only */
H. Peter Anvin9e1f5282008-05-29 21:38:00 -0700331static StrList **dephead, **deptail; /* Dependency list */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000332
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -0700333static uint64_t unique; /* unique identifier numbers */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000334
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000335static Line *predef = NULL;
H. Peter Anvind2456592008-06-19 15:04:18 -0700336static bool do_predef;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000337
338static ListGen *list;
339
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000340/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000341 * The current set of multi-line macros we have defined.
342 */
H. Peter Anvin166c2472008-05-28 12:28:58 -0700343static struct hash_table mmacros;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000344
345/*
346 * The current set of single-line macros we have defined.
347 */
H. Peter Anvin166c2472008-05-28 12:28:58 -0700348static struct hash_table smacros;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000349
350/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000351 * The multi-line macro we are currently defining, or the %rep
352 * block we are currently reading, if any.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000353 */
354static MMacro *defining;
355
356/*
357 * The number of macro parameters to allocate space for at a time.
358 */
359#define PARAM_DELTA 16
360
361/*
H. Peter Anvina4835d42008-05-20 14:21:29 -0700362 * The standard macro set: defined in macros.c in the array nasm_stdmac.
363 * This gives our position in the macro set, when we're processing it.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000364 */
H. Peter Anvin188ce762008-02-16 13:58:45 -0800365static const char * const *stdmacpos;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000366
367/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000368 * The extra standard macros that come from the object format, if
369 * any.
370 */
H. Peter Anvin188ce762008-02-16 13:58:45 -0800371static const char * const *extrastdmac = NULL;
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700372bool any_extrastdmac;
H. Peter Anvin76690a12002-04-30 20:52:49 +0000373
374/*
H. Peter Anvin734b1882002-04-30 21:01:08 +0000375 * Tokens are allocated in blocks to improve speed
376 */
377#define TOKEN_BLOCKSIZE 4096
378static Token *freeTokens = NULL;
H. Peter Anvince616072002-04-30 21:02:23 +0000379struct Blocks {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000380 Blocks *next;
381 void *chunk;
H. Peter Anvince616072002-04-30 21:02:23 +0000382};
383
384static Blocks blocks = { NULL, NULL };
H. Peter Anvin734b1882002-04-30 21:01:08 +0000385
386/*
H. Peter Anvin76690a12002-04-30 20:52:49 +0000387 * Forward declarations.
388 */
H. Peter Anvin734b1882002-04-30 21:01:08 +0000389static Token *expand_mmac_params(Token * tline);
390static Token *expand_smacro(Token * tline);
391static Token *expand_id(Token * tline);
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700392static Context *get_ctx(char *name, bool all_contexts);
Keith Kaniosa5fc6462007-10-13 07:09:22 -0700393static void make_tok_num(Token * tok, int64_t val);
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000394static void error(int severity, const char *fmt, ...);
H. Peter Anvince616072002-04-30 21:02:23 +0000395static void *new_Block(size_t size);
396static void delete_Blocks(void);
H. Peter Anvinc751e862008-06-09 10:18:45 -0700397static Token *new_Token(Token * next, enum pp_token_type type,
398 const char *text, int txtlen);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000399static Token *delete_Token(Token * t);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000400
401/*
402 * Macros for safe checking of token pointers, avoid *(NULL)
403 */
404#define tok_type_(x,t) ((x) && (x)->type == (t))
405#define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
406#define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
407#define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
H. Peter Anvin76690a12002-04-30 20:52:49 +0000408
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000409/* Handle TASM specific directives, which do not contain a % in
410 * front of them. We do it here because I could not find any other
411 * place to do it for the moment, and it is a hack (ideally it would
412 * be nice to be able to use the NASM pre-processor to do it).
413 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000414static char *check_tasm_directive(char *line)
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000415{
Keith Kaniosb7a89542007-04-12 02:40:54 +0000416 int32_t i, j, k, m, len;
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000417 char *p = line, *oldline, oldchar;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000418
419 /* Skip whitespace */
420 while (isspace(*p) && *p != 0)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000421 p++;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000422
423 /* Binary search for the directive name */
424 i = -1;
Ed Beroset3ab3f412002-06-11 03:31:49 +0000425 j = elements(tasm_directives);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000426 len = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +0000427 while (!isspace(p[len]) && p[len] != 0)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000428 len++;
429 if (len) {
430 oldchar = p[len];
431 p[len] = 0;
432 while (j - i > 1) {
433 k = (j + i) / 2;
434 m = nasm_stricmp(p, tasm_directives[k]);
435 if (m == 0) {
436 /* We have found a directive, so jam a % in front of it
437 * so that NASM will then recognise it as one if it's own.
438 */
439 p[len] = oldchar;
440 len = strlen(p);
441 oldline = line;
442 line = nasm_malloc(len + 2);
443 line[0] = '%';
444 if (k == TM_IFDIFI) {
445 /* NASM does not recognise IFDIFI, so we convert it to
446 * %ifdef BOGUS. This is not used in NASM comaptible
447 * code, but does need to parse for the TASM macro
448 * package.
449 */
450 strcpy(line + 1, "ifdef BOGUS");
451 } else {
452 memcpy(line + 1, p, len + 1);
453 }
454 nasm_free(oldline);
455 return line;
456 } else if (m < 0) {
457 j = k;
458 } else
459 i = k;
460 }
461 p[len] = oldchar;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000462 }
463 return line;
464}
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000465
H. Peter Anvin76690a12002-04-30 20:52:49 +0000466/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000467 * The pre-preprocessing stage... This function translates line
468 * number indications as they emerge from GNU cpp (`# lineno "file"
469 * flags') into NASM preprocessor line number indications (`%line
470 * lineno file').
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000471 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000472static char *prepreproc(char *line)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000473{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000474 int lineno, fnlen;
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000475 char *fname, *oldline;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000476
H. Peter Anvine2c80182005-01-15 22:15:51 +0000477 if (line[0] == '#' && line[1] == ' ') {
478 oldline = line;
479 fname = oldline + 2;
480 lineno = atoi(fname);
481 fname += strspn(fname, "0123456789 ");
482 if (*fname == '"')
483 fname++;
484 fnlen = strcspn(fname, "\"");
485 line = nasm_malloc(20 + fnlen);
486 snprintf(line, 20 + fnlen, "%%line %d %.*s", lineno, fnlen, fname);
487 nasm_free(oldline);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000488 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +0000489 if (tasm_compatible_mode)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000490 return check_tasm_directive(line);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000491 return line;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000492}
493
494/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000495 * Free a linked list of tokens.
496 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000497static void free_tlist(Token * list)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000498{
H. Peter Anvine2c80182005-01-15 22:15:51 +0000499 while (list) {
500 list = delete_Token(list);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000501 }
502}
503
504/*
505 * Free a linked list of lines.
506 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000507static void free_llist(Line * list)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000508{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000509 Line *l;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000510 while (list) {
511 l = list;
512 list = list->next;
513 free_tlist(l->first);
514 nasm_free(l);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000515 }
516}
517
518/*
H. Peter Anvineba20a72002-04-30 20:53:55 +0000519 * Free an MMacro
520 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000521static void free_mmacro(MMacro * m)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000522{
H. Peter Anvin734b1882002-04-30 21:01:08 +0000523 nasm_free(m->name);
524 free_tlist(m->dlist);
525 nasm_free(m->defaults);
526 free_llist(m->expansion);
527 nasm_free(m);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000528}
529
530/*
H. Peter Anvin97a23472007-09-16 17:57:25 -0700531 * Free all currently defined macros, and free the hash tables
532 */
H. Peter Anvin072771e2008-05-22 13:17:51 -0700533static void free_smacro_table(struct hash_table *smt)
H. Peter Anvin97a23472007-09-16 17:57:25 -0700534{
H. Peter Anvin97a23472007-09-16 17:57:25 -0700535 SMacro *s;
H. Peter Anvin072771e2008-05-22 13:17:51 -0700536 const char *key;
537 struct hash_tbl_node *it = NULL;
H. Peter Anvin97a23472007-09-16 17:57:25 -0700538
H. Peter Anvin072771e2008-05-22 13:17:51 -0700539 while ((s = hash_iterate(smt, &it, &key)) != NULL) {
H. Peter Anvin97a23472007-09-16 17:57:25 -0700540 nasm_free((void *)key);
541 while (s) {
542 SMacro *ns = s->next;
543 nasm_free(s->name);
544 free_tlist(s->expansion);
545 nasm_free(s);
546 s = ns;
547 }
548 }
H. Peter Anvin072771e2008-05-22 13:17:51 -0700549 hash_free(smt);
550}
551
552static void free_mmacro_table(struct hash_table *mmt)
553{
554 MMacro *m;
555 const char *key;
556 struct hash_tbl_node *it = NULL;
H. Peter Anvin97a23472007-09-16 17:57:25 -0700557
558 it = NULL;
H. Peter Anvin072771e2008-05-22 13:17:51 -0700559 while ((m = hash_iterate(mmt, &it, &key)) != NULL) {
H. Peter Anvin97a23472007-09-16 17:57:25 -0700560 nasm_free((void *)key);
561 while (m) {
562 MMacro *nm = m->next;
563 free_mmacro(m);
564 m = nm;
565 }
566 }
H. Peter Anvin072771e2008-05-22 13:17:51 -0700567 hash_free(mmt);
568}
569
570static void free_macros(void)
571{
H. Peter Anvin166c2472008-05-28 12:28:58 -0700572 free_smacro_table(&smacros);
573 free_mmacro_table(&mmacros);
H. Peter Anvin97a23472007-09-16 17:57:25 -0700574}
575
576/*
577 * Initialize the hash tables
578 */
579static void init_macros(void)
580{
H. Peter Anvin166c2472008-05-28 12:28:58 -0700581 hash_init(&smacros, HASH_LARGE);
582 hash_init(&mmacros, HASH_LARGE);
H. Peter Anvin97a23472007-09-16 17:57:25 -0700583}
584
585/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000586 * Pop the context stack.
587 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000588static void ctx_pop(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000589{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000590 Context *c = cstk;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000591
592 cstk = cstk->next;
H. Peter Anvin166c2472008-05-28 12:28:58 -0700593 free_smacro_table(&c->localmac);
H. Peter Anvin734b1882002-04-30 21:01:08 +0000594 nasm_free(c->name);
595 nasm_free(c);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000596}
597
H. Peter Anvin072771e2008-05-22 13:17:51 -0700598/*
599 * Search for a key in the hash index; adding it if necessary
600 * (in which case we initialize the data pointer to NULL.)
601 */
602static void **
603hash_findi_add(struct hash_table *hash, const char *str)
604{
605 struct hash_insert hi;
606 void **r;
607 char *strx;
608
609 r = hash_findi(hash, str, &hi);
610 if (r)
611 return r;
612
613 strx = nasm_strdup(str); /* Use a more efficient allocator here? */
614 return hash_add(&hi, strx, NULL);
615}
616
617/*
618 * Like hash_findi, but returns the data element rather than a pointer
619 * to it. Used only when not adding a new element, hence no third
620 * argument.
621 */
622static void *
623hash_findix(struct hash_table *hash, const char *str)
624{
625 void **p;
626
627 p = hash_findi(hash, str, NULL);
628 return p ? *p : NULL;
629}
630
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000631#define BUF_DELTA 512
632/*
633 * Read a line from the top file in istk, handling multiple CR/LFs
634 * at the end of the line read, and handling spurious ^Zs. Will
635 * return lines from the standard macro set if this has not already
636 * been done.
637 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000638static char *read_line(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000639{
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000640 char *buffer, *p, *q;
H. Peter Anvin9f394642002-04-30 21:07:51 +0000641 int bufsize, continued_count;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000642
H. Peter Anvine2c80182005-01-15 22:15:51 +0000643 if (stdmacpos) {
H. Peter Anvind2456592008-06-19 15:04:18 -0700644 char *ret = nasm_strdup(*stdmacpos++);
645 if (!*stdmacpos) {
646 /* This was the last of the standard macro chain... */
647 stdmacpos = NULL;
648 if (any_extrastdmac) {
649 stdmacpos = extrastdmac;
650 any_extrastdmac = false;
651 } else if (do_predef) {
652 Line *pd, *l;
653 Token *head, **tail, *t;
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000654
H. Peter Anvind2456592008-06-19 15:04:18 -0700655 /*
656 * Nasty hack: here we push the contents of
657 * `predef' on to the top-level expansion stack,
658 * since this is the most convenient way to
659 * implement the pre-include and pre-define
660 * features.
661 */
662 for (pd = predef; pd; pd = pd->next) {
663 head = NULL;
664 tail = &head;
665 for (t = pd->first; t; t = t->next) {
666 *tail = new_Token(NULL, t->type, t->text, 0);
667 tail = &(*tail)->next;
668 }
669 l = nasm_malloc(sizeof(Line));
670 l->next = istk->expansion;
671 l->first = head;
672 l->finishes = false;
673 istk->expansion = l;
674 }
675 do_predef = false;
676 }
677 }
678 return ret;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000679 }
680
681 bufsize = BUF_DELTA;
682 buffer = nasm_malloc(BUF_DELTA);
683 p = buffer;
H. Peter Anvin9f394642002-04-30 21:07:51 +0000684 continued_count = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000685 while (1) {
686 q = fgets(p, bufsize - (p - buffer), istk->fp);
687 if (!q)
688 break;
689 p += strlen(p);
690 if (p > buffer && p[-1] == '\n') {
691 /* Convert backslash-CRLF line continuation sequences into
692 nothing at all (for DOS and Windows) */
693 if (((p - 2) > buffer) && (p[-3] == '\\') && (p[-2] == '\r')) {
694 p -= 3;
695 *p = 0;
696 continued_count++;
697 }
698 /* Also convert backslash-LF line continuation sequences into
699 nothing at all (for Unix) */
700 else if (((p - 1) > buffer) && (p[-2] == '\\')) {
701 p -= 2;
702 *p = 0;
703 continued_count++;
704 } else {
705 break;
706 }
707 }
708 if (p - buffer > bufsize - 10) {
Keith Kaniosb7a89542007-04-12 02:40:54 +0000709 int32_t offset = p - buffer;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000710 bufsize += BUF_DELTA;
711 buffer = nasm_realloc(buffer, bufsize);
712 p = buffer + offset; /* prevent stale-pointer problems */
713 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000714 }
715
H. Peter Anvine2c80182005-01-15 22:15:51 +0000716 if (!q && p == buffer) {
717 nasm_free(buffer);
718 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000719 }
720
H. Peter Anvine2c80182005-01-15 22:15:51 +0000721 src_set_linnum(src_get_linnum() + istk->lineinc +
722 (continued_count * istk->lineinc));
H. Peter Anvineba20a72002-04-30 20:53:55 +0000723
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000724 /*
725 * Play safe: remove CRs as well as LFs, if any of either are
726 * present at the end of the line.
727 */
H. Peter Anvineba20a72002-04-30 20:53:55 +0000728 while (--p >= buffer && (*p == '\n' || *p == '\r'))
H. Peter Anvine2c80182005-01-15 22:15:51 +0000729 *p = '\0';
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000730
731 /*
732 * Handle spurious ^Z, which may be inserted into source files
733 * by some file transfer utilities.
734 */
735 buffer[strcspn(buffer, "\032")] = '\0';
736
H. Peter Anvin734b1882002-04-30 21:01:08 +0000737 list->line(LIST_READ, buffer);
H. Peter Anvin6768eb72002-04-30 20:52:26 +0000738
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000739 return buffer;
740}
741
742/*
Keith Kaniosb7a89542007-04-12 02:40:54 +0000743 * Tokenize a line of text. This is a very simple process since we
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000744 * don't need to parse the value out of e.g. numeric tokens: we
745 * simply split one string into many.
746 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000747static Token *tokenize(char *line)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000748{
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000749 char *p = line;
H. Peter Anvinda10e7b2007-09-12 04:18:37 +0000750 enum pp_token_type type;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000751 Token *list = NULL;
752 Token *t, **tail = &list;
753
H. Peter Anvine2c80182005-01-15 22:15:51 +0000754 while (*line) {
755 p = line;
756 if (*p == '%') {
757 p++;
758 if (isdigit(*p) ||
759 ((*p == '-' || *p == '+') && isdigit(p[1])) ||
760 ((*p == '+') && (isspace(p[1]) || !p[1]))) {
761 do {
762 p++;
763 }
764 while (isdigit(*p));
765 type = TOK_PREPROC_ID;
766 } else if (*p == '{') {
767 p++;
768 while (*p && *p != '}') {
769 p[-1] = *p;
770 p++;
771 }
772 p[-1] = '\0';
773 if (*p)
774 p++;
775 type = TOK_PREPROC_ID;
H. Peter Anvin6c81f0a2008-05-25 21:46:17 -0700776 } else if (*p == '?') {
777 type = TOK_PREPROC_Q; /* %? */
778 p++;
779 if (*p == '?') {
780 type = TOK_PREPROC_QQ; /* %?? */
781 p++;
782 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000783 } else if (isidchar(*p) ||
784 ((*p == '!' || *p == '%' || *p == '$') &&
785 isidchar(p[1]))) {
786 do {
787 p++;
788 }
789 while (isidchar(*p));
790 type = TOK_PREPROC_ID;
791 } else {
792 type = TOK_OTHER;
793 if (*p == '%')
794 p++;
795 }
796 } else if (isidstart(*p) || (*p == '$' && isidstart(p[1]))) {
797 type = TOK_ID;
798 p++;
799 while (*p && isidchar(*p))
800 p++;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -0700801 } else if (*p == '\'' || *p == '"' || *p == '`') {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000802 /*
803 * A string token.
804 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000805 type = TOK_STRING;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -0700806 p = nasm_skip_string(p);
Nickolay Yurchenkof3b3ce22003-09-21 20:38:43 +0000807
H. Peter Anvine2c80182005-01-15 22:15:51 +0000808 if (*p) {
809 p++;
810 } else {
811 error(ERR_WARNING, "unterminated string");
812 /* Handling unterminated strings by UNV */
813 /* type = -1; */
814 }
815 } else if (isnumstart(*p)) {
H. Peter Anvinc2df2822007-10-24 15:29:28 -0700816 bool is_hex = false;
817 bool is_float = false;
818 bool has_e = false;
819 char c, *r;
820
H. Peter Anvine2c80182005-01-15 22:15:51 +0000821 /*
H. Peter Anvinc2df2822007-10-24 15:29:28 -0700822 * A numeric token.
H. Peter Anvine2c80182005-01-15 22:15:51 +0000823 */
H. Peter Anvinc2df2822007-10-24 15:29:28 -0700824
825 if (*p == '$') {
826 p++;
827 is_hex = true;
828 }
829
830 for (;;) {
831 c = *p++;
832
833 if (!is_hex && (c == 'e' || c == 'E')) {
834 has_e = true;
835 if (*p == '+' || *p == '-') {
836 /* e can only be followed by +/- if it is either a
837 prefixed hex number or a floating-point number */
838 p++;
839 is_float = true;
840 }
841 } else if (c == 'H' || c == 'h' || c == 'X' || c == 'x') {
842 is_hex = true;
843 } else if (c == 'P' || c == 'p') {
844 is_float = true;
845 if (*p == '+' || *p == '-')
846 p++;
847 } else if (isnumchar(c) || c == '_')
848 ; /* just advance */
849 else if (c == '.') {
850 /* we need to deal with consequences of the legacy
851 parser, like "1.nolist" being two tokens
852 (TOK_NUMBER, TOK_ID) here; at least give it
853 a shot for now. In the future, we probably need
854 a flex-based scanner with proper pattern matching
855 to do it as well as it can be done. Nothing in
856 the world is going to help the person who wants
857 0x123.p16 interpreted as two tokens, though. */
858 r = p;
859 while (*r == '_')
860 r++;
861
862 if (isdigit(*r) || (is_hex && isxdigit(*r)) ||
863 (!is_hex && (*r == 'e' || *r == 'E')) ||
864 (*r == 'p' || *r == 'P')) {
865 p = r;
866 is_float = true;
867 } else
868 break; /* Terminate the token */
869 } else
870 break;
871 }
872 p--; /* Point to first character beyond number */
873
874 if (has_e && !is_hex) {
875 /* 1e13 is floating-point, but 1e13h is not */
876 is_float = true;
877 }
878
879 type = is_float ? TOK_FLOAT : TOK_NUMBER;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000880 } else if (isspace(*p)) {
881 type = TOK_WHITESPACE;
882 p++;
883 while (*p && isspace(*p))
884 p++;
885 /*
886 * Whitespace just before end-of-line is discarded by
887 * pretending it's a comment; whitespace just before a
888 * comment gets lumped into the comment.
889 */
890 if (!*p || *p == ';') {
891 type = TOK_COMMENT;
892 while (*p)
893 p++;
894 }
895 } else if (*p == ';') {
896 type = TOK_COMMENT;
897 while (*p)
898 p++;
899 } else {
900 /*
901 * Anything else is an operator of some kind. We check
902 * for all the double-character operators (>>, <<, //,
903 * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000904 * else is a single-character operator.
H. Peter Anvine2c80182005-01-15 22:15:51 +0000905 */
906 type = TOK_OTHER;
907 if ((p[0] == '>' && p[1] == '>') ||
908 (p[0] == '<' && p[1] == '<') ||
909 (p[0] == '/' && p[1] == '/') ||
910 (p[0] == '<' && p[1] == '=') ||
911 (p[0] == '>' && p[1] == '=') ||
912 (p[0] == '=' && p[1] == '=') ||
913 (p[0] == '!' && p[1] == '=') ||
914 (p[0] == '<' && p[1] == '>') ||
915 (p[0] == '&' && p[1] == '&') ||
916 (p[0] == '|' && p[1] == '|') ||
917 (p[0] == '^' && p[1] == '^')) {
918 p++;
919 }
920 p++;
921 }
Nickolay Yurchenkof3b3ce22003-09-21 20:38:43 +0000922
H. Peter Anvine2c80182005-01-15 22:15:51 +0000923 /* Handling unterminated string by UNV */
924 /*if (type == -1)
925 {
926 *tail = t = new_Token(NULL, TOK_STRING, line, p-line+1);
927 t->text[p-line] = *line;
928 tail = &t->next;
929 }
930 else */
931 if (type != TOK_COMMENT) {
932 *tail = t = new_Token(NULL, type, line, p - line);
933 tail = &t->next;
934 }
935 line = p;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000936 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000937 return list;
938}
939
H. Peter Anvince616072002-04-30 21:02:23 +0000940/*
941 * this function allocates a new managed block of memory and
H. Peter Anvin70653092007-10-19 14:42:29 -0700942 * returns a pointer to the block. The managed blocks are
H. Peter Anvince616072002-04-30 21:02:23 +0000943 * deleted only all at once by the delete_Blocks function.
944 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000945static void *new_Block(size_t size)
H. Peter Anvince616072002-04-30 21:02:23 +0000946{
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000947 Blocks *b = &blocks;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000948
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000949 /* first, get to the end of the linked list */
950 while (b->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000951 b = b->next;
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000952 /* now allocate the requested chunk */
953 b->chunk = nasm_malloc(size);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000954
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000955 /* now allocate a new block for the next request */
956 b->next = nasm_malloc(sizeof(Blocks));
957 /* and initialize the contents of the new block */
958 b->next->next = NULL;
959 b->next->chunk = NULL;
960 return b->chunk;
H. Peter Anvince616072002-04-30 21:02:23 +0000961}
962
963/*
964 * this function deletes all managed blocks of memory
965 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000966static void delete_Blocks(void)
H. Peter Anvince616072002-04-30 21:02:23 +0000967{
H. Peter Anvine2c80182005-01-15 22:15:51 +0000968 Blocks *a, *b = &blocks;
H. Peter Anvince616072002-04-30 21:02:23 +0000969
H. Peter Anvin70653092007-10-19 14:42:29 -0700970 /*
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000971 * keep in mind that the first block, pointed to by blocks
H. Peter Anvin70653092007-10-19 14:42:29 -0700972 * is a static and not dynamically allocated, so we don't
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000973 * free it.
974 */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000975 while (b) {
976 if (b->chunk)
977 nasm_free(b->chunk);
978 a = b;
979 b = b->next;
980 if (a != &blocks)
981 nasm_free(a);
Nickolay Yurchenkof7956c42003-09-26 19:03:40 +0000982 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000983}
H. Peter Anvin734b1882002-04-30 21:01:08 +0000984
985/*
H. Peter Anvin70653092007-10-19 14:42:29 -0700986 * this function creates a new Token and passes a pointer to it
H. Peter Anvin734b1882002-04-30 21:01:08 +0000987 * back to the caller. It sets the type and text elements, and
988 * also the mac and next elements to NULL.
989 */
H. Peter Anvin6ecc1592008-06-01 21:34:49 -0700990static Token *new_Token(Token * next, enum pp_token_type type,
H. Peter Anvinc751e862008-06-09 10:18:45 -0700991 const char *text, int txtlen)
H. Peter Anvin734b1882002-04-30 21:01:08 +0000992{
993 Token *t;
994 int i;
995
H. Peter Anvine2c80182005-01-15 22:15:51 +0000996 if (freeTokens == NULL) {
997 freeTokens = (Token *) new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
998 for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
999 freeTokens[i].next = &freeTokens[i + 1];
1000 freeTokens[i].next = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001001 }
1002 t = freeTokens;
1003 freeTokens = t->next;
1004 t->next = next;
1005 t->mac = NULL;
1006 t->type = type;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001007 if (type == TOK_WHITESPACE || text == NULL) {
1008 t->text = NULL;
1009 } else {
1010 if (txtlen == 0)
1011 txtlen = strlen(text);
H. Peter Anvin6ecc1592008-06-01 21:34:49 -07001012 t->text = nasm_malloc(txtlen+1);
1013 memcpy(t->text, text, txtlen);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001014 t->text[txtlen] = '\0';
H. Peter Anvin734b1882002-04-30 21:01:08 +00001015 }
1016 return t;
1017}
1018
H. Peter Anvine2c80182005-01-15 22:15:51 +00001019static Token *delete_Token(Token * t)
H. Peter Anvin734b1882002-04-30 21:01:08 +00001020{
1021 Token *next = t->next;
1022 nasm_free(t->text);
H. Peter Anvin788e6c12002-04-30 21:02:01 +00001023 t->next = freeTokens;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001024 freeTokens = t;
1025 return next;
1026}
1027
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001028/*
1029 * Convert a line of tokens back into text.
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001030 * If expand_locals is not zero, identifiers of the form "%$*xxx"
1031 * will be transformed into ..@ctxnum.xxx
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001032 */
H. Peter Anvin9e200162008-06-04 17:23:14 -07001033static char *detoken(Token * tlist, bool expand_locals)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001034{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001035 Token *t;
1036 int len;
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001037 char *line, *p;
H. Peter Anvinb4daadc2008-01-21 16:31:57 -08001038 const char *q;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001039
1040 len = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001041 for (t = tlist; t; t = t->next) {
1042 if (t->type == TOK_PREPROC_ID && t->text[1] == '!') {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001043 char *p = getenv(t->text + 2);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001044 nasm_free(t->text);
1045 if (p)
1046 t->text = nasm_strdup(p);
1047 else
1048 t->text = NULL;
1049 }
1050 /* Expand local macros here and not during preprocessing */
1051 if (expand_locals &&
1052 t->type == TOK_PREPROC_ID && t->text &&
1053 t->text[0] == '%' && t->text[1] == '$') {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001054 Context *ctx = get_ctx(t->text, false);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001055 if (ctx) {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001056 char buffer[40];
1057 char *p, *q = t->text + 2;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001058
H. Peter Anvine2c80182005-01-15 22:15:51 +00001059 q += strspn(q, "$");
Keith Kanios93f2e9a2007-04-14 00:10:59 +00001060 snprintf(buffer, sizeof(buffer), "..@%"PRIu32".", ctx->number);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001061 p = nasm_strcat(buffer, q);
1062 nasm_free(t->text);
1063 t->text = p;
1064 }
1065 }
1066 if (t->type == TOK_WHITESPACE) {
1067 len++;
1068 } else if (t->text) {
1069 len += strlen(t->text);
1070 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001071 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00001072 p = line = nasm_malloc(len + 1);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001073 for (t = tlist; t; t = t->next) {
1074 if (t->type == TOK_WHITESPACE) {
H. Peter Anvinb4daadc2008-01-21 16:31:57 -08001075 *p++ = ' ';
H. Peter Anvine2c80182005-01-15 22:15:51 +00001076 } else if (t->text) {
H. Peter Anvinb4daadc2008-01-21 16:31:57 -08001077 q = t->text;
1078 while (*q)
1079 *p++ = *q++;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001080 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001081 }
1082 *p = '\0';
1083 return line;
1084}
1085
1086/*
H. Peter Anvin76690a12002-04-30 20:52:49 +00001087 * A scanner, suitable for use by the expression evaluator, which
1088 * operates on a line of Tokens. Expects a pointer to a pointer to
1089 * the first token in the line to be passed in as its private_data
1090 * field.
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001091 *
1092 * FIX: This really needs to be unified with stdscan.
H. Peter Anvin76690a12002-04-30 20:52:49 +00001093 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001094static int ppscan(void *private_data, struct tokenval *tokval)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001095{
H. Peter Anvin76690a12002-04-30 20:52:49 +00001096 Token **tlineptr = private_data;
1097 Token *tline;
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001098 char ourcopy[MAX_KEYWORD+1], *p, *r, *s;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001099
H. Peter Anvine2c80182005-01-15 22:15:51 +00001100 do {
1101 tline = *tlineptr;
1102 *tlineptr = tline ? tline->next : NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001103 }
1104 while (tline && (tline->type == TOK_WHITESPACE ||
H. Peter Anvine2c80182005-01-15 22:15:51 +00001105 tline->type == TOK_COMMENT));
H. Peter Anvin76690a12002-04-30 20:52:49 +00001106
1107 if (!tline)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001108 return tokval->t_type = TOKEN_EOS;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001109
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001110 tokval->t_charptr = tline->text;
1111
H. Peter Anvin76690a12002-04-30 20:52:49 +00001112 if (tline->text[0] == '$' && !tline->text[1])
H. Peter Anvine2c80182005-01-15 22:15:51 +00001113 return tokval->t_type = TOKEN_HERE;
H. Peter Anvin7cf897e2002-05-30 21:30:33 +00001114 if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[2])
H. Peter Anvine2c80182005-01-15 22:15:51 +00001115 return tokval->t_type = TOKEN_BASE;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001116
H. Peter Anvine2c80182005-01-15 22:15:51 +00001117 if (tline->type == TOK_ID) {
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001118 p = tokval->t_charptr = tline->text;
1119 if (p[0] == '$') {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001120 tokval->t_charptr++;
1121 return tokval->t_type = TOKEN_ID;
1122 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00001123
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001124 for (r = p, s = ourcopy; *r; r++) {
Philipp Thomas76ec8e72008-05-21 08:53:21 -07001125 if (r >= p+MAX_KEYWORD)
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001126 return tokval->t_type = TOKEN_ID; /* Not a keyword */
H. Peter Anvinac8f8fc2008-06-11 15:49:41 -07001127 *s++ = nasm_tolower(*r);
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001128 }
1129 *s = '\0';
1130 /* right, so we have an identifier sitting in temp storage. now,
1131 * is it actually a register or instruction name, or what? */
1132 return nasm_token_hash(ourcopy, tokval);
H. Peter Anvin76690a12002-04-30 20:52:49 +00001133 }
1134
H. Peter Anvine2c80182005-01-15 22:15:51 +00001135 if (tline->type == TOK_NUMBER) {
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001136 bool rn_error;
1137 tokval->t_integer = readnum(tline->text, &rn_error);
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001138 tokval->t_charptr = tline->text;
H. Peter Anvin11627042008-06-09 20:45:19 -07001139 if (rn_error)
1140 return tokval->t_type = TOKEN_ERRNUM;
1141 else
1142 return tokval->t_type = TOKEN_NUM;
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001143 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00001144
H. Peter Anvinc2df2822007-10-24 15:29:28 -07001145 if (tline->type == TOK_FLOAT) {
1146 return tokval->t_type = TOKEN_FLOAT;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001147 }
1148
H. Peter Anvine2c80182005-01-15 22:15:51 +00001149 if (tline->type == TOK_STRING) {
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07001150 char bq, *ep;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001151
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07001152 bq = tline->text[0];
H. Peter Anvin11627042008-06-09 20:45:19 -07001153 tokval->t_charptr = tline->text;
1154 tokval->t_inttwo = nasm_unquote(tline->text, &ep);
H. Peter Anvind2456592008-06-19 15:04:18 -07001155
H. Peter Anvin11627042008-06-09 20:45:19 -07001156 if (ep[0] != bq || ep[1] != '\0')
1157 return tokval->t_type = TOKEN_ERRSTR;
1158 else
1159 return tokval->t_type = TOKEN_STR;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001160 }
1161
H. Peter Anvine2c80182005-01-15 22:15:51 +00001162 if (tline->type == TOK_OTHER) {
1163 if (!strcmp(tline->text, "<<"))
1164 return tokval->t_type = TOKEN_SHL;
1165 if (!strcmp(tline->text, ">>"))
1166 return tokval->t_type = TOKEN_SHR;
1167 if (!strcmp(tline->text, "//"))
1168 return tokval->t_type = TOKEN_SDIV;
1169 if (!strcmp(tline->text, "%%"))
1170 return tokval->t_type = TOKEN_SMOD;
1171 if (!strcmp(tline->text, "=="))
1172 return tokval->t_type = TOKEN_EQ;
1173 if (!strcmp(tline->text, "<>"))
1174 return tokval->t_type = TOKEN_NE;
1175 if (!strcmp(tline->text, "!="))
1176 return tokval->t_type = TOKEN_NE;
1177 if (!strcmp(tline->text, "<="))
1178 return tokval->t_type = TOKEN_LE;
1179 if (!strcmp(tline->text, ">="))
1180 return tokval->t_type = TOKEN_GE;
1181 if (!strcmp(tline->text, "&&"))
1182 return tokval->t_type = TOKEN_DBL_AND;
1183 if (!strcmp(tline->text, "^^"))
1184 return tokval->t_type = TOKEN_DBL_XOR;
1185 if (!strcmp(tline->text, "||"))
1186 return tokval->t_type = TOKEN_DBL_OR;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001187 }
1188
1189 /*
1190 * We have no other options: just return the first character of
1191 * the token text.
1192 */
1193 return tokval->t_type = tline->text[0];
1194}
1195
1196/*
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001197 * Compare a string to the name of an existing macro; this is a
1198 * simple wrapper which calls either strcmp or nasm_stricmp
1199 * depending on the value of the `casesense' parameter.
1200 */
H. Peter Anvin4db5a162007-10-11 13:42:09 -07001201static int mstrcmp(const char *p, const char *q, bool casesense)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001202{
H. Peter Anvin734b1882002-04-30 21:01:08 +00001203 return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001204}
1205
1206/*
H. Peter Anvin6ecc1592008-06-01 21:34:49 -07001207 * Compare a string to the name of an existing macro; this is a
1208 * simple wrapper which calls either strcmp or nasm_stricmp
1209 * depending on the value of the `casesense' parameter.
1210 */
1211static int mmemcmp(const char *p, const char *q, size_t l, bool casesense)
1212{
1213 return casesense ? memcmp(p, q, l) : nasm_memicmp(p, q, l);
1214}
1215
1216/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001217 * Return the Context structure associated with a %$ token. Return
1218 * NULL, having _already_ reported an error condition, if the
1219 * context stack isn't deep enough for the supplied number of $
1220 * signs.
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001221 * If all_contexts == true, contexts that enclose current are
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001222 * also scanned for such smacro, until it is found; if not -
1223 * only the context that directly results from the number of $'s
1224 * in variable's name.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001225 */
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001226static Context *get_ctx(char *name, bool all_contexts)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001227{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001228 Context *ctx;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001229 SMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001230 int i;
1231
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001232 if (!name || name[0] != '%' || name[1] != '$')
H. Peter Anvine2c80182005-01-15 22:15:51 +00001233 return NULL;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001234
H. Peter Anvine2c80182005-01-15 22:15:51 +00001235 if (!cstk) {
1236 error(ERR_NONFATAL, "`%s': context stack is empty", name);
1237 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001238 }
1239
H. Peter Anvine2c80182005-01-15 22:15:51 +00001240 for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--) {
1241 ctx = ctx->next;
H. Peter Anvindce1e2f2002-04-30 21:06:37 +00001242/* i--; Lino - 02/25/02 */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001243 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001244 if (!ctx) {
1245 error(ERR_NONFATAL, "`%s': context stack is only"
1246 " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
1247 return NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001248 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001249 if (!all_contexts)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001250 return ctx;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001251
H. Peter Anvine2c80182005-01-15 22:15:51 +00001252 do {
1253 /* Search for this smacro in found context */
H. Peter Anvin166c2472008-05-28 12:28:58 -07001254 m = hash_findix(&ctx->localmac, name);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001255 while (m) {
1256 if (!mstrcmp(m->name, name, m->casesense))
1257 return ctx;
1258 m = m->next;
1259 }
1260 ctx = ctx->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001261 }
1262 while (ctx);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001263 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001264}
1265
1266/*
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001267 * Check to see if a file is already in a string list
1268 */
1269static bool in_list(const StrList *list, const char *str)
1270{
1271 while (list) {
1272 if (!strcmp(list->str, str))
1273 return true;
1274 list = list->next;
1275 }
1276 return false;
1277}
1278
1279/*
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001280 * Open an include file. This routine must always return a valid
1281 * file pointer if it returns - it's responsible for throwing an
1282 * ERR_FATAL and bombing out completely if not. It should also try
1283 * the include path one by one until it finds the file or reaches
1284 * the end of the path.
1285 */
H. Peter Anvin2b1c3b92008-06-06 10:38:46 -07001286static FILE *inc_fopen(const char *file, StrList **dhead, StrList ***dtail,
H. Peter Anvin418ca702008-05-30 10:42:30 -07001287 bool missing_ok)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001288{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001289 FILE *fp;
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001290 char *prefix = "";
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001291 IncPath *ip = ipath;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001292 int len = strlen(file);
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001293 size_t prefix_len = 0;
1294 StrList *sl;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001295
H. Peter Anvine2c80182005-01-15 22:15:51 +00001296 while (1) {
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001297 sl = nasm_malloc(prefix_len+len+1+sizeof sl->next);
1298 memcpy(sl->str, prefix, prefix_len);
1299 memcpy(sl->str+prefix_len, file, len+1);
1300 fp = fopen(sl->str, "r");
H. Peter Anvin418ca702008-05-30 10:42:30 -07001301 if (fp && dhead && !in_list(*dhead, sl->str)) {
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001302 sl->next = NULL;
H. Peter Anvin2b1c3b92008-06-06 10:38:46 -07001303 **dtail = sl;
1304 *dtail = &sl->next;
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001305 } else {
1306 nasm_free(sl);
1307 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001308 if (fp)
1309 return fp;
H. Peter Anvin418ca702008-05-30 10:42:30 -07001310 if (!ip) {
1311 if (!missing_ok)
1312 break;
1313 prefix = NULL;
1314 } else {
1315 prefix = ip->path;
1316 ip = ip->next;
1317 }
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001318 if (prefix) {
1319 prefix_len = strlen(prefix);
1320 } else {
1321 /* -MG given and file not found */
H. Peter Anvin418ca702008-05-30 10:42:30 -07001322 if (dhead && !in_list(*dhead, file)) {
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001323 sl = nasm_malloc(len+1+sizeof sl->next);
1324 sl->next = NULL;
1325 strcpy(sl->str, file);
H. Peter Anvin2b1c3b92008-06-06 10:38:46 -07001326 **dtail = sl;
1327 *dtail = &sl->next;
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07001328 }
H. Peter Anvin37a321f2007-09-24 13:41:58 -07001329 return NULL;
1330 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00001331 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001332
H. Peter Anvin734b1882002-04-30 21:01:08 +00001333 error(ERR_FATAL, "unable to open include file `%s'", file);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001334 return NULL; /* never reached - placate compilers */
H. Peter Anvin6768eb72002-04-30 20:52:26 +00001335}
1336
1337/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001338 * Determine if we should warn on defining a single-line macro of
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001339 * name `name', with `nparam' parameters. If nparam is 0 or -1, will
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001340 * return true if _any_ single-line macro of that name is defined.
1341 * Otherwise, will return true if a single-line macro with either
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001342 * `nparam' or no parameters is defined.
1343 *
1344 * If a macro with precisely the right number of parameters is
H. Peter Anvinef7468f2002-04-30 20:57:59 +00001345 * defined, or nparam is -1, the address of the definition structure
1346 * will be returned in `defn'; otherwise NULL will be returned. If `defn'
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001347 * is NULL, no action will be taken regarding its contents, and no
1348 * error will occur.
1349 *
1350 * Note that this is also called with nparam zero to resolve
1351 * `ifdef'.
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001352 *
1353 * If you already know which context macro belongs to, you can pass
1354 * the context pointer as first parameter; if you won't but name begins
1355 * with %$ the context will be automatically computed. If all_contexts
1356 * is true, macro will be searched in outer contexts as well.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001357 */
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07001358static bool
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001359smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07001360 bool nocase)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001361{
H. Peter Anvin166c2472008-05-28 12:28:58 -07001362 struct hash_table *smtbl;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001363 SMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001364
H. Peter Anvin97a23472007-09-16 17:57:25 -07001365 if (ctx) {
H. Peter Anvin166c2472008-05-28 12:28:58 -07001366 smtbl = &ctx->localmac;
H. Peter Anvin97a23472007-09-16 17:57:25 -07001367 } else if (name[0] == '%' && name[1] == '$') {
1368 if (cstk)
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001369 ctx = get_ctx(name, false);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001370 if (!ctx)
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001371 return false; /* got to return _something_ */
H. Peter Anvin166c2472008-05-28 12:28:58 -07001372 smtbl = &ctx->localmac;
H. Peter Anvin97a23472007-09-16 17:57:25 -07001373 } else {
H. Peter Anvin166c2472008-05-28 12:28:58 -07001374 smtbl = &smacros;
H. Peter Anvin97a23472007-09-16 17:57:25 -07001375 }
H. Peter Anvin166c2472008-05-28 12:28:58 -07001376 m = (SMacro *) hash_findix(smtbl, name);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001377
H. Peter Anvine2c80182005-01-15 22:15:51 +00001378 while (m) {
1379 if (!mstrcmp(m->name, name, m->casesense && nocase) &&
Charles Crayne192d5b52007-10-18 19:02:42 -07001380 (nparam <= 0 || m->nparam == 0 || nparam == (int) m->nparam)) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001381 if (defn) {
Charles Crayne192d5b52007-10-18 19:02:42 -07001382 if (nparam == (int) m->nparam || nparam == -1)
H. Peter Anvine2c80182005-01-15 22:15:51 +00001383 *defn = m;
1384 else
1385 *defn = NULL;
1386 }
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001387 return true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001388 }
1389 m = m->next;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001390 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00001391
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001392 return false;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001393}
1394
1395/*
1396 * Count and mark off the parameters in a multi-line macro call.
1397 * This is called both from within the multi-line macro expansion
1398 * code, and also to mark off the default parameters when provided
1399 * in a %macro definition line.
1400 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001401static void count_mmac_params(Token * t, int *nparam, Token *** params)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001402{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001403 int paramsize, brace;
1404
1405 *nparam = paramsize = 0;
1406 *params = NULL;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001407 while (t) {
1408 if (*nparam >= paramsize) {
1409 paramsize += PARAM_DELTA;
1410 *params = nasm_realloc(*params, sizeof(**params) * paramsize);
1411 }
1412 skip_white_(t);
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001413 brace = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001414 if (tok_is_(t, "{"))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001415 brace = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001416 (*params)[(*nparam)++] = t;
1417 while (tok_isnt_(t, brace ? "}" : ","))
1418 t = t->next;
1419 if (t) { /* got a comma/brace */
1420 t = t->next;
1421 if (brace) {
1422 /*
1423 * Now we've found the closing brace, look further
1424 * for the comma.
1425 */
1426 skip_white_(t);
1427 if (tok_isnt_(t, ",")) {
1428 error(ERR_NONFATAL,
1429 "braces do not enclose all of macro parameter");
1430 while (tok_isnt_(t, ","))
1431 t = t->next;
1432 }
1433 if (t)
1434 t = t->next; /* eat the comma */
1435 }
1436 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001437 }
1438}
1439
1440/*
H. Peter Anvin76690a12002-04-30 20:52:49 +00001441 * Determine whether one of the various `if' conditions is true or
1442 * not.
1443 *
1444 * We must free the tline we get passed.
1445 */
H. Peter Anvin70055962007-10-11 00:05:31 -07001446static bool if_condition(Token * tline, enum preproc_token ct)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001447{
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001448 enum pp_conditional i = PP_COND(ct);
H. Peter Anvin70055962007-10-11 00:05:31 -07001449 bool j;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001450 Token *t, *tt, **tptr, *origline;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001451 struct tokenval tokval;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001452 expr *evalresult;
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001453 enum pp_token_type needtype;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001454
1455 origline = tline;
1456
H. Peter Anvine2c80182005-01-15 22:15:51 +00001457 switch (i) {
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001458 case PPC_IFCTX:
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001459 j = false; /* have we matched yet? */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001460 while (cstk && tline) {
1461 skip_white_(tline);
1462 if (!tline || tline->type != TOK_ID) {
1463 error(ERR_NONFATAL,
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001464 "`%s' expects context identifiers", pp_directives[ct]);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001465 free_tlist(origline);
1466 return -1;
1467 }
1468 if (!nasm_stricmp(tline->text, cstk->name))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001469 j = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001470 tline = tline->next;
1471 }
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001472 break;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001473
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001474 case PPC_IFDEF:
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001475 j = false; /* have we matched yet? */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001476 while (tline) {
1477 skip_white_(tline);
1478 if (!tline || (tline->type != TOK_ID &&
1479 (tline->type != TOK_PREPROC_ID ||
1480 tline->text[1] != '$'))) {
1481 error(ERR_NONFATAL,
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001482 "`%s' expects macro identifiers", pp_directives[ct]);
1483 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001484 }
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07001485 if (smacro_defined(NULL, tline->text, 0, NULL, true))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001486 j = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001487 tline = tline->next;
1488 }
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001489 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001490
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001491 case PPC_IFIDN:
1492 case PPC_IFIDNI:
H. Peter Anvine2c80182005-01-15 22:15:51 +00001493 tline = expand_smacro(tline);
1494 t = tt = tline;
1495 while (tok_isnt_(tt, ","))
1496 tt = tt->next;
1497 if (!tt) {
1498 error(ERR_NONFATAL,
1499 "`%s' expects two comma-separated arguments",
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001500 pp_directives[ct]);
1501 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001502 }
1503 tt = tt->next;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001504 j = true; /* assume equality unless proved not */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001505 while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt) {
1506 if (tt->type == TOK_OTHER && !strcmp(tt->text, ",")) {
1507 error(ERR_NONFATAL, "`%s': more than one comma on line",
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001508 pp_directives[ct]);
1509 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001510 }
1511 if (t->type == TOK_WHITESPACE) {
1512 t = t->next;
1513 continue;
1514 }
1515 if (tt->type == TOK_WHITESPACE) {
1516 tt = tt->next;
1517 continue;
1518 }
1519 if (tt->type != t->type) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001520 j = false; /* found mismatching tokens */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001521 break;
1522 }
H. Peter Anvin6ecc1592008-06-01 21:34:49 -07001523 /* When comparing strings, need to unquote them first */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001524 if (t->type == TOK_STRING) {
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07001525 size_t l1 = nasm_unquote(t->text, NULL);
1526 size_t l2 = nasm_unquote(tt->text, NULL);
H. Peter Anvind2456592008-06-19 15:04:18 -07001527
H. Peter Anvin6ecc1592008-06-01 21:34:49 -07001528 if (l1 != l2) {
1529 j = false;
1530 break;
1531 }
1532 if (mmemcmp(t->text, tt->text, l1, i == PPC_IFIDN)) {
1533 j = false;
1534 break;
1535 }
1536 } else if (mstrcmp(tt->text, t->text, i == PPC_IFIDN) != 0) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001537 j = false; /* found mismatching tokens */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001538 break;
1539 }
Nickolay Yurchenkof3b3ce22003-09-21 20:38:43 +00001540
H. Peter Anvine2c80182005-01-15 22:15:51 +00001541 t = t->next;
1542 tt = tt->next;
1543 }
1544 if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001545 j = false; /* trailing gunk on one end or other */
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001546 break;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001547
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001548 case PPC_IFMACRO:
H. Peter Anvine2c80182005-01-15 22:15:51 +00001549 {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001550 bool found = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001551 MMacro searching, *mmac;
H. Peter Anvin65747262002-05-07 00:10:05 +00001552
H. Peter Anvine2c80182005-01-15 22:15:51 +00001553 tline = tline->next;
1554 skip_white_(tline);
1555 tline = expand_id(tline);
1556 if (!tok_type_(tline, TOK_ID)) {
1557 error(ERR_NONFATAL,
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001558 "`%s' expects a macro name", pp_directives[ct]);
1559 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001560 }
1561 searching.name = nasm_strdup(tline->text);
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07001562 searching.casesense = true;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001563 searching.plus = false;
1564 searching.nolist = false;
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -07001565 searching.in_progress = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001566 searching.rep_nest = NULL;
1567 searching.nparam_min = 0;
1568 searching.nparam_max = INT_MAX;
1569 tline = expand_smacro(tline->next);
1570 skip_white_(tline);
1571 if (!tline) {
1572 } else if (!tok_type_(tline, TOK_NUMBER)) {
1573 error(ERR_NONFATAL,
1574 "`%s' expects a parameter count or nothing",
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001575 pp_directives[ct]);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001576 } else {
1577 searching.nparam_min = searching.nparam_max =
1578 readnum(tline->text, &j);
1579 if (j)
1580 error(ERR_NONFATAL,
1581 "unable to parse parameter count `%s'",
1582 tline->text);
1583 }
1584 if (tline && tok_is_(tline->next, "-")) {
1585 tline = tline->next->next;
1586 if (tok_is_(tline, "*"))
1587 searching.nparam_max = INT_MAX;
1588 else if (!tok_type_(tline, TOK_NUMBER))
1589 error(ERR_NONFATAL,
1590 "`%s' expects a parameter count after `-'",
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001591 pp_directives[ct]);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001592 else {
1593 searching.nparam_max = readnum(tline->text, &j);
1594 if (j)
1595 error(ERR_NONFATAL,
1596 "unable to parse parameter count `%s'",
1597 tline->text);
1598 if (searching.nparam_min > searching.nparam_max)
1599 error(ERR_NONFATAL,
1600 "minimum parameter count exceeds maximum");
1601 }
1602 }
1603 if (tline && tok_is_(tline->next, "+")) {
1604 tline = tline->next;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001605 searching.plus = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001606 }
H. Peter Anvin166c2472008-05-28 12:28:58 -07001607 mmac = (MMacro *) hash_findix(&mmacros, searching.name);
H. Peter Anvin97a23472007-09-16 17:57:25 -07001608 while (mmac) {
1609 if (!strcmp(mmac->name, searching.name) &&
1610 (mmac->nparam_min <= searching.nparam_max
1611 || searching.plus)
1612 && (searching.nparam_min <= mmac->nparam_max
1613 || mmac->plus)) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07001614 found = true;
H. Peter Anvin97a23472007-09-16 17:57:25 -07001615 break;
1616 }
1617 mmac = mmac->next;
1618 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001619 nasm_free(searching.name);
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001620 j = found;
1621 break;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001622 }
H. Peter Anvin65747262002-05-07 00:10:05 +00001623
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001624 case PPC_IFID:
1625 needtype = TOK_ID;
1626 goto iftype;
1627 case PPC_IFNUM:
1628 needtype = TOK_NUMBER;
1629 goto iftype;
1630 case PPC_IFSTR:
1631 needtype = TOK_STRING;
1632 goto iftype;
1633
1634 iftype:
H. Peter Anvin134b9462008-02-16 17:01:40 -08001635 t = tline = expand_smacro(tline);
H. Peter Anvind85d2502008-05-04 17:53:31 -07001636
H. Peter Anvin927c92b2008-02-16 13:44:52 -08001637 while (tok_type_(t, TOK_WHITESPACE) ||
1638 (needtype == TOK_NUMBER &&
1639 tok_type_(t, TOK_OTHER) &&
1640 (t->text[0] == '-' || t->text[0] == '+') &&
1641 !t->text[1]))
1642 t = t->next;
H. Peter Anvind85d2502008-05-04 17:53:31 -07001643
H. Peter Anvincbf768d2008-02-16 16:41:25 -08001644 j = tok_type_(t, needtype);
1645 break;
1646
1647 case PPC_IFTOKEN:
1648 t = tline = expand_smacro(tline);
1649 while (tok_type_(t, TOK_WHITESPACE))
1650 t = t->next;
1651
1652 j = false;
1653 if (t) {
1654 t = t->next; /* Skip the actual token */
1655 while (tok_type_(t, TOK_WHITESPACE))
1656 t = t->next;
1657 j = !t; /* Should be nothing left */
1658 }
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001659 break;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001660
H. Peter Anvin134b9462008-02-16 17:01:40 -08001661 case PPC_IFEMPTY:
1662 t = tline = expand_smacro(tline);
1663 while (tok_type_(t, TOK_WHITESPACE))
1664 t = t->next;
1665
1666 j = !t; /* Should be empty */
1667 break;
1668
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001669 case PPC_IF:
H. Peter Anvine2c80182005-01-15 22:15:51 +00001670 t = tline = expand_smacro(tline);
1671 tptr = &t;
1672 tokval.t_type = TOKEN_INVALID;
1673 evalresult = evaluate(ppscan, tptr, &tokval,
1674 NULL, pass | CRITICAL, error, NULL);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001675 if (!evalresult)
1676 return -1;
1677 if (tokval.t_type)
1678 error(ERR_WARNING,
1679 "trailing garbage after expression ignored");
1680 if (!is_simple(evalresult)) {
1681 error(ERR_NONFATAL,
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001682 "non-constant value given to `%s'", pp_directives[ct]);
1683 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001684 }
Chuck Crayne60ae75d2007-05-02 01:59:16 +00001685 j = reloc_value(evalresult) != 0;
Chuck Crayne60ae75d2007-05-02 01:59:16 +00001686 return j;
H. Peter Anvin95e28822007-09-12 04:20:08 +00001687
H. Peter Anvine2c80182005-01-15 22:15:51 +00001688 default:
1689 error(ERR_FATAL,
1690 "preprocessor directive `%s' not yet implemented",
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001691 pp_directives[ct]);
1692 goto fail;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001693 }
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001694
1695 free_tlist(origline);
1696 return j ^ PP_NEGATIVE(ct);
H. Peter Anvin70653092007-10-19 14:42:29 -07001697
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00001698fail:
1699 free_tlist(origline);
1700 return -1;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001701}
1702
1703/*
H. Peter Anvin4db5a162007-10-11 13:42:09 -07001704 * Common code for defining an smacro
1705 */
1706static bool define_smacro(Context *ctx, char *mname, bool casesense,
1707 int nparam, Token *expansion)
1708{
1709 SMacro *smac, **smhead;
H. Peter Anvin166c2472008-05-28 12:28:58 -07001710 struct hash_table *smtbl;
H. Peter Anvin70653092007-10-19 14:42:29 -07001711
H. Peter Anvin4db5a162007-10-11 13:42:09 -07001712 if (smacro_defined(ctx, mname, nparam, &smac, casesense)) {
1713 if (!smac) {
1714 error(ERR_WARNING,
1715 "single-line macro `%s' defined both with and"
1716 " without parameters", mname);
1717
1718 /* Some instances of the old code considered this a failure,
1719 some others didn't. What is the right thing to do here? */
1720 free_tlist(expansion);
1721 return false; /* Failure */
1722 } else {
1723 /*
1724 * We're redefining, so we have to take over an
1725 * existing SMacro structure. This means freeing
1726 * what was already in it.
1727 */
1728 nasm_free(smac->name);
1729 free_tlist(smac->expansion);
1730 }
1731 } else {
H. Peter Anvin166c2472008-05-28 12:28:58 -07001732 smtbl = ctx ? &ctx->localmac : &smacros;
1733 smhead = (SMacro **) hash_findi_add(smtbl, mname);
H. Peter Anvin4db5a162007-10-11 13:42:09 -07001734 smac = nasm_malloc(sizeof(SMacro));
1735 smac->next = *smhead;
1736 *smhead = smac;
1737 }
1738 smac->name = nasm_strdup(mname);
1739 smac->casesense = casesense;
1740 smac->nparam = nparam;
1741 smac->expansion = expansion;
1742 smac->in_progress = false;
1743 return true; /* Success */
1744}
1745
1746/*
1747 * Undefine an smacro
1748 */
1749static void undef_smacro(Context *ctx, const char *mname)
1750{
1751 SMacro **smhead, *s, **sp;
H. Peter Anvin166c2472008-05-28 12:28:58 -07001752 struct hash_table *smtbl;
H. Peter Anvin4db5a162007-10-11 13:42:09 -07001753
H. Peter Anvin166c2472008-05-28 12:28:58 -07001754 smtbl = ctx ? &ctx->localmac : &smacros;
1755 smhead = (SMacro **)hash_findi(smtbl, mname, NULL);
H. Peter Anvin70653092007-10-19 14:42:29 -07001756
H. Peter Anvin4db5a162007-10-11 13:42:09 -07001757 if (smhead) {
1758 /*
1759 * We now have a macro name... go hunt for it.
1760 */
1761 sp = smhead;
1762 while ((s = *sp) != NULL) {
1763 if (!mstrcmp(s->name, mname, s->casesense)) {
1764 *sp = s->next;
1765 nasm_free(s->name);
1766 free_tlist(s->expansion);
1767 nasm_free(s);
1768 } else {
1769 sp = &s->next;
1770 }
1771 }
1772 }
1773}
1774
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001775/*
1776 * Decode a size directive
1777 */
1778static int parse_size(const char *str) {
1779 static const char *size_names[] =
H. Peter Anvindfb91802008-05-20 11:43:53 -07001780 { "byte", "dword", "oword", "qword", "tword", "word", "yword" };
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001781 static const int sizes[] =
H. Peter Anvindfb91802008-05-20 11:43:53 -07001782 { 0, 1, 4, 16, 8, 10, 2, 32 };
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001783
1784 return sizes[bsii(str, size_names, elements(size_names))+1];
1785}
1786
Ed Beroset3ab3f412002-06-11 03:31:49 +00001787/**
1788 * find and process preprocessor directive in passed line
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001789 * Find out if a line contains a preprocessor directive, and deal
1790 * with it if so.
H. Peter Anvin70653092007-10-19 14:42:29 -07001791 *
Ed Beroset3ab3f412002-06-11 03:31:49 +00001792 * If a directive _is_ found, it is the responsibility of this routine
1793 * (and not the caller) to free_tlist() the line.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001794 *
Ed Beroset3ab3f412002-06-11 03:31:49 +00001795 * @param tline a pointer to the current tokeninzed line linked list
1796 * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND
H. Peter Anvin70653092007-10-19 14:42:29 -07001797 *
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001798 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001799static int do_directive(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001800{
H. Peter Anvin4169a472007-09-12 01:29:43 +00001801 enum preproc_token i;
1802 int j;
H. Peter Anvin70055962007-10-11 00:05:31 -07001803 bool err;
1804 int nparam;
1805 bool nolist;
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07001806 bool casesense;
H. Peter Anvin8cfdb9d2007-09-14 18:36:01 -07001807 int k, m;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001808 int offset;
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001809 char *p, *mname;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001810 Include *inc;
1811 Context *ctx;
1812 Cond *cond;
H. Peter Anvin97a23472007-09-16 17:57:25 -07001813 MMacro *mmac, **mmhead;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001814 Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
1815 Line *l;
1816 struct tokenval tokval;
1817 expr *evalresult;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001818 MMacro *tmp_defining; /* Used when manipulating rep_nest */
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -07001819 int64_t count;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001820
1821 origline = tline;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001822
H. Peter Anvineba20a72002-04-30 20:53:55 +00001823 skip_white_(tline);
H. Peter Anvinf2936d72008-06-04 15:11:23 -07001824 if (!tline || !tok_type_(tline, TOK_PREPROC_ID) ||
H. Peter Anvine2c80182005-01-15 22:15:51 +00001825 (tline->text[1] == '%' || tline->text[1] == '$'
1826 || tline->text[1] == '!'))
1827 return NO_DIRECTIVE_FOUND;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001828
H. Peter Anvin4169a472007-09-12 01:29:43 +00001829 i = pp_token_hash(tline->text);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001830
1831 /*
1832 * If we're in a non-emitting branch of a condition construct,
H. Peter Anvin76690a12002-04-30 20:52:49 +00001833 * or walking to the end of an already terminated %rep block,
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001834 * we should ignore all directives except for condition
1835 * directives.
1836 */
H. Peter Anvin76690a12002-04-30 20:52:49 +00001837 if (((istk->conds && !emitting(istk->conds->state)) ||
H. Peter Anvine2c80182005-01-15 22:15:51 +00001838 (istk->mstk && !istk->mstk->in_progress)) && !is_condition(i)) {
1839 return NO_DIRECTIVE_FOUND;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001840 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001841
1842 /*
H. Peter Anvin76690a12002-04-30 20:52:49 +00001843 * If we're defining a macro or reading a %rep block, we should
1844 * ignore all directives except for %macro/%imacro (which
1845 * generate an error), %endm/%endmacro, and (only if we're in a
H. Peter Anvineba20a72002-04-30 20:53:55 +00001846 * %rep block) %endrep. If we're in a %rep block, another %rep
1847 * causes an error, so should be let through.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001848 */
1849 if (defining && i != PP_MACRO && i != PP_IMACRO &&
H. Peter Anvine2c80182005-01-15 22:15:51 +00001850 i != PP_ENDMACRO && i != PP_ENDM &&
1851 (defining->name || (i != PP_ENDREP && i != PP_REP))) {
1852 return NO_DIRECTIVE_FOUND;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001853 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001854
H. Peter Anvin4169a472007-09-12 01:29:43 +00001855 switch (i) {
1856 case PP_INVALID:
H. Peter Anvine2c80182005-01-15 22:15:51 +00001857 error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
1858 tline->text);
1859 return NO_DIRECTIVE_FOUND; /* didn't get it */
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00001860
H. Peter Anvine2c80182005-01-15 22:15:51 +00001861 case PP_STACKSIZE:
1862 /* Directive to tell NASM what the default stack size is. The
1863 * default is for a 16-bit stack, and this can be overriden with
1864 * %stacksize large.
1865 * the following form:
1866 *
1867 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1868 */
1869 tline = tline->next;
1870 if (tline && tline->type == TOK_WHITESPACE)
1871 tline = tline->next;
1872 if (!tline || tline->type != TOK_ID) {
1873 error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
1874 free_tlist(origline);
1875 return DIRECTIVE_FOUND;
1876 }
1877 if (nasm_stricmp(tline->text, "flat") == 0) {
1878 /* All subsequent ARG directives are for a 32-bit stack */
1879 StackSize = 4;
1880 StackPointer = "ebp";
1881 ArgOffset = 8;
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001882 LocalOffset = 0;
Charles Crayne7eaf9192007-11-08 22:11:14 -08001883 } else if (nasm_stricmp(tline->text, "flat64") == 0) {
1884 /* All subsequent ARG directives are for a 64-bit stack */
1885 StackSize = 8;
1886 StackPointer = "rbp";
1887 ArgOffset = 8;
1888 LocalOffset = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001889 } else if (nasm_stricmp(tline->text, "large") == 0) {
1890 /* All subsequent ARG directives are for a 16-bit stack,
1891 * far function call.
1892 */
1893 StackSize = 2;
1894 StackPointer = "bp";
1895 ArgOffset = 4;
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001896 LocalOffset = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001897 } else if (nasm_stricmp(tline->text, "small") == 0) {
1898 /* All subsequent ARG directives are for a 16-bit stack,
1899 * far function call. We don't support near functions.
1900 */
1901 StackSize = 2;
1902 StackPointer = "bp";
1903 ArgOffset = 6;
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001904 LocalOffset = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001905 } else {
1906 error(ERR_NONFATAL, "`%%stacksize' invalid size type");
1907 free_tlist(origline);
1908 return DIRECTIVE_FOUND;
1909 }
1910 free_tlist(origline);
1911 return DIRECTIVE_FOUND;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001912
H. Peter Anvine2c80182005-01-15 22:15:51 +00001913 case PP_ARG:
1914 /* TASM like ARG directive to define arguments to functions, in
1915 * the following form:
1916 *
1917 * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
1918 */
1919 offset = ArgOffset;
1920 do {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001921 char *arg, directive[256];
H. Peter Anvine2c80182005-01-15 22:15:51 +00001922 int size = StackSize;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001923
H. Peter Anvine2c80182005-01-15 22:15:51 +00001924 /* Find the argument name */
1925 tline = tline->next;
1926 if (tline && tline->type == TOK_WHITESPACE)
1927 tline = tline->next;
1928 if (!tline || tline->type != TOK_ID) {
1929 error(ERR_NONFATAL, "`%%arg' missing argument parameter");
1930 free_tlist(origline);
1931 return DIRECTIVE_FOUND;
1932 }
1933 arg = tline->text;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001934
H. Peter Anvine2c80182005-01-15 22:15:51 +00001935 /* Find the argument size type */
1936 tline = tline->next;
1937 if (!tline || tline->type != TOK_OTHER
1938 || tline->text[0] != ':') {
1939 error(ERR_NONFATAL,
1940 "Syntax error processing `%%arg' directive");
1941 free_tlist(origline);
1942 return DIRECTIVE_FOUND;
1943 }
1944 tline = tline->next;
1945 if (!tline || tline->type != TOK_ID) {
1946 error(ERR_NONFATAL, "`%%arg' missing size type parameter");
1947 free_tlist(origline);
1948 return DIRECTIVE_FOUND;
1949 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001950
H. Peter Anvine2c80182005-01-15 22:15:51 +00001951 /* Allow macro expansion of type parameter */
Keith Kaniosb7a89542007-04-12 02:40:54 +00001952 tt = tokenize(tline->text);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001953 tt = expand_smacro(tt);
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001954 size = parse_size(tt->text);
1955 if (!size) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001956 error(ERR_NONFATAL,
1957 "Invalid size type for `%%arg' missing directive");
1958 free_tlist(tt);
1959 free_tlist(origline);
1960 return DIRECTIVE_FOUND;
1961 }
1962 free_tlist(tt);
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001963
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001964 /* Round up to even stack slots */
1965 size = (size+StackSize-1) & ~(StackSize-1);
1966
H. Peter Anvine2c80182005-01-15 22:15:51 +00001967 /* Now define the macro for the argument */
1968 snprintf(directive, sizeof(directive), "%%define %s (%s+%d)",
1969 arg, StackPointer, offset);
Keith Kaniosb7a89542007-04-12 02:40:54 +00001970 do_directive(tokenize(directive));
H. Peter Anvine2c80182005-01-15 22:15:51 +00001971 offset += size;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00001972
H. Peter Anvine2c80182005-01-15 22:15:51 +00001973 /* Move to the next argument in the list */
1974 tline = tline->next;
1975 if (tline && tline->type == TOK_WHITESPACE)
1976 tline = tline->next;
H. Peter Anvin8781cb02007-11-08 20:01:11 -08001977 } while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
1978 ArgOffset = offset;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001979 free_tlist(origline);
1980 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001981
H. Peter Anvine2c80182005-01-15 22:15:51 +00001982 case PP_LOCAL:
1983 /* TASM like LOCAL directive to define local variables for a
1984 * function, in the following form:
1985 *
1986 * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
1987 *
1988 * The '= LocalSize' at the end is ignored by NASM, but is
1989 * required by TASM to define the local parameter size (and used
1990 * by the TASM macro package).
1991 */
1992 offset = LocalOffset;
1993 do {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001994 char *local, directive[256];
H. Peter Anvine2c80182005-01-15 22:15:51 +00001995 int size = StackSize;
H. Peter Anvin734b1882002-04-30 21:01:08 +00001996
H. Peter Anvine2c80182005-01-15 22:15:51 +00001997 /* Find the argument name */
1998 tline = tline->next;
1999 if (tline && tline->type == TOK_WHITESPACE)
2000 tline = tline->next;
2001 if (!tline || tline->type != TOK_ID) {
2002 error(ERR_NONFATAL,
2003 "`%%local' missing argument parameter");
2004 free_tlist(origline);
2005 return DIRECTIVE_FOUND;
2006 }
2007 local = tline->text;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002008
H. Peter Anvine2c80182005-01-15 22:15:51 +00002009 /* Find the argument size type */
2010 tline = tline->next;
2011 if (!tline || tline->type != TOK_OTHER
2012 || tline->text[0] != ':') {
2013 error(ERR_NONFATAL,
2014 "Syntax error processing `%%local' directive");
2015 free_tlist(origline);
2016 return DIRECTIVE_FOUND;
2017 }
2018 tline = tline->next;
2019 if (!tline || tline->type != TOK_ID) {
2020 error(ERR_NONFATAL,
2021 "`%%local' missing size type parameter");
2022 free_tlist(origline);
2023 return DIRECTIVE_FOUND;
2024 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002025
H. Peter Anvine2c80182005-01-15 22:15:51 +00002026 /* Allow macro expansion of type parameter */
Keith Kaniosb7a89542007-04-12 02:40:54 +00002027 tt = tokenize(tline->text);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002028 tt = expand_smacro(tt);
H. Peter Anvin8781cb02007-11-08 20:01:11 -08002029 size = parse_size(tt->text);
2030 if (!size) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00002031 error(ERR_NONFATAL,
2032 "Invalid size type for `%%local' missing directive");
2033 free_tlist(tt);
2034 free_tlist(origline);
2035 return DIRECTIVE_FOUND;
2036 }
2037 free_tlist(tt);
H. Peter Anvin734b1882002-04-30 21:01:08 +00002038
H. Peter Anvin8781cb02007-11-08 20:01:11 -08002039 /* Round up to even stack slots */
2040 size = (size+StackSize-1) & ~(StackSize-1);
2041
2042 offset += size; /* Negative offset, increment before */
2043
2044 /* Now define the macro for the argument */
H. Peter Anvine2c80182005-01-15 22:15:51 +00002045 snprintf(directive, sizeof(directive), "%%define %s (%s-%d)",
2046 local, StackPointer, offset);
Keith Kaniosb7a89542007-04-12 02:40:54 +00002047 do_directive(tokenize(directive));
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002048
H. Peter Anvine2c80182005-01-15 22:15:51 +00002049 /* Now define the assign to setup the enter_c macro correctly */
2050 snprintf(directive, sizeof(directive),
2051 "%%assign %%$localsize %%$localsize+%d", size);
Keith Kaniosb7a89542007-04-12 02:40:54 +00002052 do_directive(tokenize(directive));
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002053
H. Peter Anvine2c80182005-01-15 22:15:51 +00002054 /* Move to the next argument in the list */
2055 tline = tline->next;
2056 if (tline && tline->type == TOK_WHITESPACE)
2057 tline = tline->next;
H. Peter Anvin8781cb02007-11-08 20:01:11 -08002058 } while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
2059 LocalOffset = offset;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002060 free_tlist(origline);
2061 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002062
H. Peter Anvine2c80182005-01-15 22:15:51 +00002063 case PP_CLEAR:
2064 if (tline->next)
2065 error(ERR_WARNING, "trailing garbage after `%%clear' ignored");
H. Peter Anvin97a23472007-09-16 17:57:25 -07002066 free_macros();
2067 init_macros();
H. Peter Anvine2c80182005-01-15 22:15:51 +00002068 free_tlist(origline);
2069 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002070
H. Peter Anvin418ca702008-05-30 10:42:30 -07002071 case PP_DEPEND:
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002072 t = tline->next = expand_smacro(tline->next);
2073 skip_white_(t);
2074 if (!t || (t->type != TOK_STRING &&
2075 t->type != TOK_INTERNAL_STRING)) {
H. Peter Anvin418ca702008-05-30 10:42:30 -07002076 error(ERR_NONFATAL, "`%%depend' expects a file name");
2077 free_tlist(origline);
2078 return DIRECTIVE_FOUND; /* but we did _something_ */
2079 }
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002080 if (t->next)
H. Peter Anvin418ca702008-05-30 10:42:30 -07002081 error(ERR_WARNING,
2082 "trailing garbage after `%%depend' ignored");
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002083 p = t->text;
2084 if (t->type != TOK_INTERNAL_STRING)
2085 nasm_unquote(p, NULL);
H. Peter Anvin418ca702008-05-30 10:42:30 -07002086 if (dephead && !in_list(*dephead, p)) {
2087 StrList *sl = nasm_malloc(strlen(p)+1+sizeof sl->next);
2088 sl->next = NULL;
2089 strcpy(sl->str, p);
2090 *deptail = sl;
2091 deptail = &sl->next;
2092 }
2093 free_tlist(origline);
2094 return DIRECTIVE_FOUND;
2095
2096 case PP_INCLUDE:
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002097 t = tline->next = expand_smacro(tline->next);
2098 skip_white_(t);
H. Peter Anvind2456592008-06-19 15:04:18 -07002099
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002100 if (!t || (t->type != TOK_STRING &&
2101 t->type != TOK_INTERNAL_STRING)) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00002102 error(ERR_NONFATAL, "`%%include' expects a file name");
2103 free_tlist(origline);
2104 return DIRECTIVE_FOUND; /* but we did _something_ */
2105 }
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002106 if (t->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +00002107 error(ERR_WARNING,
2108 "trailing garbage after `%%include' ignored");
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002109 p = t->text;
2110 if (t->type != TOK_INTERNAL_STRING)
2111 nasm_unquote(p, NULL);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002112 inc = nasm_malloc(sizeof(Include));
2113 inc->next = istk;
2114 inc->conds = NULL;
H. Peter Anvin2b1c3b92008-06-06 10:38:46 -07002115 inc->fp = inc_fopen(p, dephead, &deptail, pass == 0);
H. Peter Anvin418ca702008-05-30 10:42:30 -07002116 if (!inc->fp) {
H. Peter Anvin37a321f2007-09-24 13:41:58 -07002117 /* -MG given but file not found */
2118 nasm_free(inc);
2119 } else {
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002120 inc->fname = src_set_fname(nasm_strdup(p));
H. Peter Anvin37a321f2007-09-24 13:41:58 -07002121 inc->lineno = src_set_linnum(0);
2122 inc->lineinc = 1;
2123 inc->expansion = NULL;
2124 inc->mstk = NULL;
2125 istk = inc;
2126 list->uplevel(LIST_INCLUDE);
2127 }
2128 free_tlist(origline);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002129 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002130
H. Peter Anvind2456592008-06-19 15:04:18 -07002131 case PP_USE:
2132 t = tline->next = expand_smacro(tline->next);
2133 skip_white_(t);
2134
2135 if (!t || (t->type != TOK_STRING &&
2136 t->type != TOK_INTERNAL_STRING &&
2137 t->type != TOK_ID)) {
2138 error(ERR_NONFATAL, "`%%use' expects a module name");
2139 free_tlist(origline);
2140 return DIRECTIVE_FOUND; /* but we did _something_ */
2141 }
2142 if (t->next)
2143 error(ERR_WARNING,
2144 "trailing garbage after `%%use' ignored");
2145 p = t->text;
2146 if (t->type == TOK_STRING)
2147 nasm_unquote(p, NULL);
2148 stdmacpos = nasm_stdmac_find_module(p);
2149 if (!stdmacpos)
2150 error(ERR_NONFATAL, "unknown `%%use' module: %s", p);
2151 free_tlist(origline);
2152 return DIRECTIVE_FOUND;
2153
H. Peter Anvine2c80182005-01-15 22:15:51 +00002154 case PP_PUSH:
2155 tline = tline->next;
2156 skip_white_(tline);
2157 tline = expand_id(tline);
2158 if (!tok_type_(tline, TOK_ID)) {
2159 error(ERR_NONFATAL, "`%%push' expects a context identifier");
2160 free_tlist(origline);
2161 return DIRECTIVE_FOUND; /* but we did _something_ */
2162 }
2163 if (tline->next)
2164 error(ERR_WARNING, "trailing garbage after `%%push' ignored");
2165 ctx = nasm_malloc(sizeof(Context));
2166 ctx->next = cstk;
H. Peter Anvin166c2472008-05-28 12:28:58 -07002167 hash_init(&ctx->localmac, HASH_SMALL);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002168 ctx->name = nasm_strdup(tline->text);
2169 ctx->number = unique++;
2170 cstk = ctx;
2171 free_tlist(origline);
2172 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002173
H. Peter Anvine2c80182005-01-15 22:15:51 +00002174 case PP_REPL:
2175 tline = tline->next;
2176 skip_white_(tline);
2177 tline = expand_id(tline);
2178 if (!tok_type_(tline, TOK_ID)) {
2179 error(ERR_NONFATAL, "`%%repl' expects a context identifier");
2180 free_tlist(origline);
2181 return DIRECTIVE_FOUND; /* but we did _something_ */
2182 }
2183 if (tline->next)
2184 error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
2185 if (!cstk)
2186 error(ERR_NONFATAL, "`%%repl': context stack is empty");
2187 else {
2188 nasm_free(cstk->name);
2189 cstk->name = nasm_strdup(tline->text);
2190 }
2191 free_tlist(origline);
2192 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002193
H. Peter Anvine2c80182005-01-15 22:15:51 +00002194 case PP_POP:
2195 if (tline->next)
2196 error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
2197 if (!cstk)
2198 error(ERR_NONFATAL, "`%%pop': context stack is already empty");
2199 else
2200 ctx_pop();
2201 free_tlist(origline);
2202 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002203
H. Peter Anvine2c80182005-01-15 22:15:51 +00002204 case PP_ERROR:
H. Peter Anvin7df04172008-06-10 18:27:38 -07002205 case PP_WARNING:
2206 {
2207 int severity = PP_ERROR ? ERR_NONFATAL|ERR_NO_SEVERITY :
2208 ERR_WARNING|ERR_NO_SEVERITY;
2209
H. Peter Anvine2c80182005-01-15 22:15:51 +00002210 tline->next = expand_smacro(tline->next);
2211 tline = tline->next;
2212 skip_white_(tline);
H. Peter Anvin7df04172008-06-10 18:27:38 -07002213 t = tline ? tline->next : NULL;
2214 skip_white_(t);
2215 if (tok_type_(tline, TOK_STRING) && !t) {
2216 /* The line contains only a quoted string */
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002217 p = tline->text;
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002218 nasm_unquote(p, NULL);
H. Peter Anvin7df04172008-06-10 18:27:38 -07002219 error(severity, "%s: %s", pp_directives[i], p);
2220 } else {
2221 /* Not a quoted string, or more than a quoted string */
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002222 p = detoken(tline, false);
H. Peter Anvin7df04172008-06-10 18:27:38 -07002223 error(severity, "%s: %s", pp_directives[i], p);
2224 nasm_free(p);
H. Peter Anvind2456592008-06-19 15:04:18 -07002225 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00002226 free_tlist(origline);
2227 break;
H. Peter Anvin7df04172008-06-10 18:27:38 -07002228 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002229
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00002230 CASE_PP_IF:
H. Peter Anvine2c80182005-01-15 22:15:51 +00002231 if (istk->conds && !emitting(istk->conds->state))
2232 j = COND_NEVER;
2233 else {
2234 j = if_condition(tline->next, i);
2235 tline->next = NULL; /* it got freed */
H. Peter Anvine2c80182005-01-15 22:15:51 +00002236 j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2237 }
2238 cond = nasm_malloc(sizeof(Cond));
2239 cond->next = istk->conds;
2240 cond->state = j;
2241 istk->conds = cond;
H. Peter Anvin7061ad72007-11-26 22:02:21 -08002242 free_tlist(origline);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002243 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002244
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00002245 CASE_PP_ELIF:
H. Peter Anvine2c80182005-01-15 22:15:51 +00002246 if (!istk->conds)
H. Peter Anvin4169a472007-09-12 01:29:43 +00002247 error(ERR_FATAL, "`%s': no matching `%%if'", pp_directives[i]);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002248 if (emitting(istk->conds->state)
2249 || istk->conds->state == COND_NEVER)
2250 istk->conds->state = COND_NEVER;
2251 else {
2252 /*
2253 * IMPORTANT: In the case of %if, we will already have
2254 * called expand_mmac_params(); however, if we're
2255 * processing an %elif we must have been in a
2256 * non-emitting mode, which would have inhibited
2257 * the normal invocation of expand_mmac_params(). Therefore,
2258 * we have to do it explicitly here.
2259 */
2260 j = if_condition(expand_mmac_params(tline->next), i);
2261 tline->next = NULL; /* it got freed */
H. Peter Anvine2c80182005-01-15 22:15:51 +00002262 istk->conds->state =
2263 j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
2264 }
H. Peter Anvin7061ad72007-11-26 22:02:21 -08002265 free_tlist(origline);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002266 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002267
H. Peter Anvine2c80182005-01-15 22:15:51 +00002268 case PP_ELSE:
2269 if (tline->next)
2270 error(ERR_WARNING, "trailing garbage after `%%else' ignored");
2271 if (!istk->conds)
2272 error(ERR_FATAL, "`%%else': no matching `%%if'");
2273 if (emitting(istk->conds->state)
2274 || istk->conds->state == COND_NEVER)
2275 istk->conds->state = COND_ELSE_FALSE;
2276 else
2277 istk->conds->state = COND_ELSE_TRUE;
2278 free_tlist(origline);
2279 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002280
H. Peter Anvine2c80182005-01-15 22:15:51 +00002281 case PP_ENDIF:
2282 if (tline->next)
2283 error(ERR_WARNING, "trailing garbage after `%%endif' ignored");
2284 if (!istk->conds)
2285 error(ERR_FATAL, "`%%endif': no matching `%%if'");
2286 cond = istk->conds;
2287 istk->conds = cond->next;
2288 nasm_free(cond);
2289 free_tlist(origline);
2290 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002291
H. Peter Anvine2c80182005-01-15 22:15:51 +00002292 case PP_MACRO:
2293 case PP_IMACRO:
2294 if (defining)
2295 error(ERR_FATAL,
2296 "`%%%smacro': already defining a macro",
2297 (i == PP_IMACRO ? "i" : ""));
2298 tline = tline->next;
2299 skip_white_(tline);
2300 tline = expand_id(tline);
2301 if (!tok_type_(tline, TOK_ID)) {
2302 error(ERR_NONFATAL,
2303 "`%%%smacro' expects a macro name",
2304 (i == PP_IMACRO ? "i" : ""));
2305 return DIRECTIVE_FOUND;
2306 }
2307 defining = nasm_malloc(sizeof(MMacro));
2308 defining->name = nasm_strdup(tline->text);
2309 defining->casesense = (i == PP_MACRO);
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002310 defining->plus = false;
2311 defining->nolist = false;
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -07002312 defining->in_progress = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002313 defining->rep_nest = NULL;
2314 tline = expand_smacro(tline->next);
2315 skip_white_(tline);
2316 if (!tok_type_(tline, TOK_NUMBER)) {
2317 error(ERR_NONFATAL,
2318 "`%%%smacro' expects a parameter count",
2319 (i == PP_IMACRO ? "i" : ""));
2320 defining->nparam_min = defining->nparam_max = 0;
2321 } else {
2322 defining->nparam_min = defining->nparam_max =
H. Peter Anvin70055962007-10-11 00:05:31 -07002323 readnum(tline->text, &err);
2324 if (err)
H. Peter Anvine2c80182005-01-15 22:15:51 +00002325 error(ERR_NONFATAL,
2326 "unable to parse parameter count `%s'", tline->text);
2327 }
2328 if (tline && tok_is_(tline->next, "-")) {
2329 tline = tline->next->next;
2330 if (tok_is_(tline, "*"))
2331 defining->nparam_max = INT_MAX;
2332 else if (!tok_type_(tline, TOK_NUMBER))
2333 error(ERR_NONFATAL,
2334 "`%%%smacro' expects a parameter count after `-'",
2335 (i == PP_IMACRO ? "i" : ""));
2336 else {
H. Peter Anvin70055962007-10-11 00:05:31 -07002337 defining->nparam_max = readnum(tline->text, &err);
2338 if (err)
H. Peter Anvine2c80182005-01-15 22:15:51 +00002339 error(ERR_NONFATAL,
2340 "unable to parse parameter count `%s'",
2341 tline->text);
2342 if (defining->nparam_min > defining->nparam_max)
2343 error(ERR_NONFATAL,
2344 "minimum parameter count exceeds maximum");
2345 }
2346 }
2347 if (tline && tok_is_(tline->next, "+")) {
2348 tline = tline->next;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002349 defining->plus = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002350 }
2351 if (tline && tok_type_(tline->next, TOK_ID) &&
2352 !nasm_stricmp(tline->next->text, ".nolist")) {
2353 tline = tline->next;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002354 defining->nolist = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002355 }
H. Peter Anvin166c2472008-05-28 12:28:58 -07002356 mmac = (MMacro *) hash_findix(&mmacros, defining->name);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002357 while (mmac) {
2358 if (!strcmp(mmac->name, defining->name) &&
2359 (mmac->nparam_min <= defining->nparam_max
2360 || defining->plus)
2361 && (defining->nparam_min <= mmac->nparam_max
2362 || mmac->plus)) {
2363 error(ERR_WARNING,
2364 "redefining multi-line macro `%s'", defining->name);
2365 break;
2366 }
2367 mmac = mmac->next;
2368 }
2369 /*
2370 * Handle default parameters.
2371 */
2372 if (tline && tline->next) {
2373 defining->dlist = tline->next;
2374 tline->next = NULL;
2375 count_mmac_params(defining->dlist, &defining->ndefs,
2376 &defining->defaults);
2377 } else {
2378 defining->dlist = NULL;
2379 defining->defaults = NULL;
2380 }
2381 defining->expansion = NULL;
2382 free_tlist(origline);
2383 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002384
H. Peter Anvine2c80182005-01-15 22:15:51 +00002385 case PP_ENDM:
2386 case PP_ENDMACRO:
2387 if (!defining) {
2388 error(ERR_NONFATAL, "`%s': not defining a macro", tline->text);
2389 return DIRECTIVE_FOUND;
2390 }
H. Peter Anvin166c2472008-05-28 12:28:58 -07002391 mmhead = (MMacro **) hash_findi_add(&mmacros, defining->name);
H. Peter Anvin97a23472007-09-16 17:57:25 -07002392 defining->next = *mmhead;
2393 *mmhead = defining;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002394 defining = NULL;
2395 free_tlist(origline);
2396 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002397
H. Peter Anvine2c80182005-01-15 22:15:51 +00002398 case PP_ROTATE:
2399 if (tline->next && tline->next->type == TOK_WHITESPACE)
2400 tline = tline->next;
2401 if (tline->next == NULL) {
2402 free_tlist(origline);
2403 error(ERR_NONFATAL, "`%%rotate' missing rotate count");
2404 return DIRECTIVE_FOUND;
2405 }
2406 t = expand_smacro(tline->next);
2407 tline->next = NULL;
2408 free_tlist(origline);
2409 tline = t;
2410 tptr = &t;
2411 tokval.t_type = TOKEN_INVALID;
2412 evalresult =
2413 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2414 free_tlist(tline);
2415 if (!evalresult)
2416 return DIRECTIVE_FOUND;
2417 if (tokval.t_type)
2418 error(ERR_WARNING,
2419 "trailing garbage after expression ignored");
2420 if (!is_simple(evalresult)) {
2421 error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
2422 return DIRECTIVE_FOUND;
2423 }
2424 mmac = istk->mstk;
2425 while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
2426 mmac = mmac->next_active;
2427 if (!mmac) {
2428 error(ERR_NONFATAL, "`%%rotate' invoked outside a macro call");
2429 } else if (mmac->nparam == 0) {
2430 error(ERR_NONFATAL,
2431 "`%%rotate' invoked within macro without parameters");
2432 } else {
H. Peter Anvin25a99342007-09-22 17:45:45 -07002433 int rotate = mmac->rotate + reloc_value(evalresult);
H. Peter Anvin734b1882002-04-30 21:01:08 +00002434
H. Peter Anvin25a99342007-09-22 17:45:45 -07002435 rotate %= (int)mmac->nparam;
2436 if (rotate < 0)
2437 rotate += mmac->nparam;
H. Peter Anvin70653092007-10-19 14:42:29 -07002438
H. Peter Anvin25a99342007-09-22 17:45:45 -07002439 mmac->rotate = rotate;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002440 }
2441 return DIRECTIVE_FOUND;
Nickolay Yurchenko9aea7152003-09-07 22:46:26 +00002442
H. Peter Anvine2c80182005-01-15 22:15:51 +00002443 case PP_REP:
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002444 nolist = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002445 do {
2446 tline = tline->next;
2447 } while (tok_type_(tline, TOK_WHITESPACE));
Nickolay Yurchenko9aea7152003-09-07 22:46:26 +00002448
H. Peter Anvine2c80182005-01-15 22:15:51 +00002449 if (tok_type_(tline, TOK_ID) &&
2450 nasm_stricmp(tline->text, ".nolist") == 0) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002451 nolist = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002452 do {
2453 tline = tline->next;
2454 } while (tok_type_(tline, TOK_WHITESPACE));
2455 }
Nickolay Yurchenko9aea7152003-09-07 22:46:26 +00002456
H. Peter Anvine2c80182005-01-15 22:15:51 +00002457 if (tline) {
2458 t = expand_smacro(tline);
2459 tptr = &t;
2460 tokval.t_type = TOKEN_INVALID;
2461 evalresult =
2462 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2463 if (!evalresult) {
2464 free_tlist(origline);
2465 return DIRECTIVE_FOUND;
2466 }
2467 if (tokval.t_type)
2468 error(ERR_WARNING,
2469 "trailing garbage after expression ignored");
2470 if (!is_simple(evalresult)) {
2471 error(ERR_NONFATAL, "non-constant value given to `%%rep'");
2472 return DIRECTIVE_FOUND;
2473 }
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -07002474 count = reloc_value(evalresult) + 1;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002475 } else {
2476 error(ERR_NONFATAL, "`%%rep' expects a repeat count");
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -07002477 count = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002478 }
2479 free_tlist(origline);
H. Peter Anvin734b1882002-04-30 21:01:08 +00002480
H. Peter Anvine2c80182005-01-15 22:15:51 +00002481 tmp_defining = defining;
2482 defining = nasm_malloc(sizeof(MMacro));
2483 defining->name = NULL; /* flags this macro as a %rep block */
H. Peter Anvin70055962007-10-11 00:05:31 -07002484 defining->casesense = false;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002485 defining->plus = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002486 defining->nolist = nolist;
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -07002487 defining->in_progress = count;
H. Peter Anvine2c80182005-01-15 22:15:51 +00002488 defining->nparam_min = defining->nparam_max = 0;
2489 defining->defaults = NULL;
2490 defining->dlist = NULL;
2491 defining->expansion = NULL;
2492 defining->next_active = istk->mstk;
2493 defining->rep_nest = tmp_defining;
2494 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002495
H. Peter Anvine2c80182005-01-15 22:15:51 +00002496 case PP_ENDREP:
2497 if (!defining || defining->name) {
2498 error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
2499 return DIRECTIVE_FOUND;
2500 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002501
H. Peter Anvine2c80182005-01-15 22:15:51 +00002502 /*
2503 * Now we have a "macro" defined - although it has no name
2504 * and we won't be entering it in the hash tables - we must
2505 * push a macro-end marker for it on to istk->expansion.
2506 * After that, it will take care of propagating itself (a
2507 * macro-end marker line for a macro which is really a %rep
2508 * block will cause the macro to be re-expanded, complete
2509 * with another macro-end marker to ensure the process
2510 * continues) until the whole expansion is forcibly removed
2511 * from istk->expansion by a %exitrep.
2512 */
2513 l = nasm_malloc(sizeof(Line));
2514 l->next = istk->expansion;
2515 l->finishes = defining;
2516 l->first = NULL;
2517 istk->expansion = l;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002518
H. Peter Anvine2c80182005-01-15 22:15:51 +00002519 istk->mstk = defining;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002520
H. Peter Anvine2c80182005-01-15 22:15:51 +00002521 list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
2522 tmp_defining = defining;
2523 defining = defining->rep_nest;
2524 free_tlist(origline);
2525 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002526
H. Peter Anvine2c80182005-01-15 22:15:51 +00002527 case PP_EXITREP:
2528 /*
2529 * We must search along istk->expansion until we hit a
2530 * macro-end marker for a macro with no name. Then we set
2531 * its `in_progress' flag to 0.
2532 */
2533 for (l = istk->expansion; l; l = l->next)
2534 if (l->finishes && !l->finishes->name)
2535 break;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002536
H. Peter Anvine2c80182005-01-15 22:15:51 +00002537 if (l)
2538 l->finishes->in_progress = 0;
2539 else
2540 error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
2541 free_tlist(origline);
2542 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002543
H. Peter Anvine2c80182005-01-15 22:15:51 +00002544 case PP_XDEFINE:
2545 case PP_IXDEFINE:
2546 case PP_DEFINE:
2547 case PP_IDEFINE:
H. Peter Anvin95e7f952007-10-11 13:38:38 -07002548 casesense = (i == PP_DEFINE || i == PP_XDEFINE);
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07002549
H. Peter Anvine2c80182005-01-15 22:15:51 +00002550 tline = tline->next;
2551 skip_white_(tline);
2552 tline = expand_id(tline);
2553 if (!tline || (tline->type != TOK_ID &&
2554 (tline->type != TOK_PREPROC_ID ||
2555 tline->text[1] != '$'))) {
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07002556 error(ERR_NONFATAL, "`%s' expects a macro identifier",
2557 pp_directives[i]);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002558 free_tlist(origline);
2559 return DIRECTIVE_FOUND;
2560 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002561
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002562 ctx = get_ctx(tline->text, false);
H. Peter Anvin97a23472007-09-16 17:57:25 -07002563
H. Peter Anvine2c80182005-01-15 22:15:51 +00002564 mname = tline->text;
2565 last = tline;
2566 param_start = tline = tline->next;
2567 nparam = 0;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002568
H. Peter Anvine2c80182005-01-15 22:15:51 +00002569 /* Expand the macro definition now for %xdefine and %ixdefine */
2570 if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
2571 tline = expand_smacro(tline);
H. Peter Anvin734b1882002-04-30 21:01:08 +00002572
H. Peter Anvine2c80182005-01-15 22:15:51 +00002573 if (tok_is_(tline, "(")) {
2574 /*
2575 * This macro has parameters.
2576 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00002577
H. Peter Anvine2c80182005-01-15 22:15:51 +00002578 tline = tline->next;
2579 while (1) {
2580 skip_white_(tline);
2581 if (!tline) {
2582 error(ERR_NONFATAL, "parameter identifier expected");
2583 free_tlist(origline);
2584 return DIRECTIVE_FOUND;
2585 }
2586 if (tline->type != TOK_ID) {
2587 error(ERR_NONFATAL,
2588 "`%s': parameter identifier expected",
2589 tline->text);
2590 free_tlist(origline);
2591 return DIRECTIVE_FOUND;
2592 }
2593 tline->type = TOK_SMAC_PARAM + nparam++;
2594 tline = tline->next;
2595 skip_white_(tline);
2596 if (tok_is_(tline, ",")) {
2597 tline = tline->next;
2598 continue;
2599 }
2600 if (!tok_is_(tline, ")")) {
2601 error(ERR_NONFATAL,
2602 "`)' expected to terminate macro template");
2603 free_tlist(origline);
2604 return DIRECTIVE_FOUND;
2605 }
2606 break;
2607 }
2608 last = tline;
2609 tline = tline->next;
2610 }
2611 if (tok_type_(tline, TOK_WHITESPACE))
2612 last = tline, tline = tline->next;
2613 macro_start = NULL;
2614 last->next = NULL;
2615 t = tline;
2616 while (t) {
2617 if (t->type == TOK_ID) {
2618 for (tt = param_start; tt; tt = tt->next)
2619 if (tt->type >= TOK_SMAC_PARAM &&
2620 !strcmp(tt->text, t->text))
2621 t->type = tt->type;
2622 }
2623 tt = t->next;
2624 t->next = macro_start;
2625 macro_start = t;
2626 t = tt;
2627 }
2628 /*
2629 * Good. We now have a macro name, a parameter count, and a
2630 * token list (in reverse order) for an expansion. We ought
2631 * to be OK just to create an SMacro, store it, and let
2632 * free_tlist have the rest of the line (which we have
2633 * carefully re-terminated after chopping off the expansion
2634 * from the end).
2635 */
H. Peter Anvin4db5a162007-10-11 13:42:09 -07002636 define_smacro(ctx, mname, casesense, nparam, macro_start);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002637 free_tlist(origline);
2638 return DIRECTIVE_FOUND;
H. Peter Anvin76690a12002-04-30 20:52:49 +00002639
H. Peter Anvine2c80182005-01-15 22:15:51 +00002640 case PP_UNDEF:
2641 tline = tline->next;
2642 skip_white_(tline);
2643 tline = expand_id(tline);
2644 if (!tline || (tline->type != TOK_ID &&
2645 (tline->type != TOK_PREPROC_ID ||
2646 tline->text[1] != '$'))) {
2647 error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
2648 free_tlist(origline);
2649 return DIRECTIVE_FOUND;
2650 }
2651 if (tline->next) {
2652 error(ERR_WARNING,
2653 "trailing garbage after macro name ignored");
2654 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002655
H. Peter Anvine2c80182005-01-15 22:15:51 +00002656 /* Find the context that symbol belongs to */
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002657 ctx = get_ctx(tline->text, false);
H. Peter Anvin4db5a162007-10-11 13:42:09 -07002658 undef_smacro(ctx, tline->text);
2659 free_tlist(origline);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002660 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002661
H. Peter Anvin9e200162008-06-04 17:23:14 -07002662 case PP_DEFSTR:
2663 case PP_IDEFSTR:
2664 casesense = (i == PP_DEFSTR);
2665
2666 tline = tline->next;
2667 skip_white_(tline);
2668 tline = expand_id(tline);
2669 if (!tline || (tline->type != TOK_ID &&
2670 (tline->type != TOK_PREPROC_ID ||
2671 tline->text[1] != '$'))) {
2672 error(ERR_NONFATAL, "`%s' expects a macro identifier",
2673 pp_directives[i]);
2674 free_tlist(origline);
2675 return DIRECTIVE_FOUND;
2676 }
2677
2678 ctx = get_ctx(tline->text, false);
2679
2680 mname = tline->text;
2681 last = tline;
2682 tline = expand_smacro(tline->next);
2683 last->next = NULL;
2684
2685 while (tok_type_(tline, TOK_WHITESPACE))
2686 tline = delete_Token(tline);
2687
2688 p = detoken(tline, false);
2689 macro_start = nasm_malloc(sizeof(*macro_start));
2690 macro_start->next = NULL;
2691 macro_start->text = nasm_quote(p, strlen(p));
2692 macro_start->type = TOK_STRING;
2693 macro_start->mac = NULL;
2694 nasm_free(p);
2695
2696 /*
2697 * We now have a macro name, an implicit parameter count of
2698 * zero, and a string token to use as an expansion. Create
2699 * and store an SMacro.
2700 */
2701 define_smacro(ctx, mname, casesense, 0, macro_start);
2702 free_tlist(origline);
2703 return DIRECTIVE_FOUND;
2704
H. Peter Anvin418ca702008-05-30 10:42:30 -07002705 case PP_PATHSEARCH:
2706 {
2707 FILE *fp;
2708 StrList *xsl = NULL;
H. Peter Anvin2b1c3b92008-06-06 10:38:46 -07002709 StrList **xst = &xsl;
H. Peter Anvin418ca702008-05-30 10:42:30 -07002710
2711 casesense = true;
2712
2713 tline = tline->next;
2714 skip_white_(tline);
2715 tline = expand_id(tline);
2716 if (!tline || (tline->type != TOK_ID &&
2717 (tline->type != TOK_PREPROC_ID ||
2718 tline->text[1] != '$'))) {
2719 error(ERR_NONFATAL,
2720 "`%%pathsearch' expects a macro identifier as first parameter");
2721 free_tlist(origline);
2722 return DIRECTIVE_FOUND;
2723 }
2724 ctx = get_ctx(tline->text, false);
2725
2726 mname = tline->text;
2727 last = tline;
2728 tline = expand_smacro(tline->next);
2729 last->next = NULL;
2730
2731 t = tline;
2732 while (tok_type_(t, TOK_WHITESPACE))
2733 t = t->next;
2734
2735 if (!t || (t->type != TOK_STRING &&
2736 t->type != TOK_INTERNAL_STRING)) {
2737 error(ERR_NONFATAL, "`%%pathsearch' expects a file name");
2738 free_tlist(tline);
2739 free_tlist(origline);
2740 return DIRECTIVE_FOUND; /* but we did _something_ */
2741 }
2742 if (t->next)
2743 error(ERR_WARNING,
2744 "trailing garbage after `%%pathsearch' ignored");
H. Peter Anvin427cc912008-06-01 21:43:03 -07002745 p = t->text;
2746 if (t->type != TOK_INTERNAL_STRING)
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002747 nasm_unquote(p, NULL);
H. Peter Anvin418ca702008-05-30 10:42:30 -07002748
H. Peter Anvin2b1c3b92008-06-06 10:38:46 -07002749 fp = inc_fopen(p, &xsl, &xst, true);
H. Peter Anvin418ca702008-05-30 10:42:30 -07002750 if (fp) {
2751 p = xsl->str;
2752 fclose(fp); /* Don't actually care about the file */
2753 }
2754 macro_start = nasm_malloc(sizeof(*macro_start));
2755 macro_start->next = NULL;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002756 macro_start->text = nasm_quote(p, strlen(p));
H. Peter Anvin418ca702008-05-30 10:42:30 -07002757 macro_start->type = TOK_STRING;
2758 macro_start->mac = NULL;
2759 if (xsl)
2760 nasm_free(xsl);
2761
2762 /*
2763 * We now have a macro name, an implicit parameter count of
2764 * zero, and a string token to use as an expansion. Create
2765 * and store an SMacro.
2766 */
2767 define_smacro(ctx, mname, casesense, 0, macro_start);
2768 free_tlist(tline);
2769 free_tlist(origline);
2770 return DIRECTIVE_FOUND;
2771 }
2772
H. Peter Anvine2c80182005-01-15 22:15:51 +00002773 case PP_STRLEN:
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07002774 casesense = true;
H. Peter Anvin70653092007-10-19 14:42:29 -07002775
H. Peter Anvine2c80182005-01-15 22:15:51 +00002776 tline = tline->next;
2777 skip_white_(tline);
2778 tline = expand_id(tline);
2779 if (!tline || (tline->type != TOK_ID &&
2780 (tline->type != TOK_PREPROC_ID ||
2781 tline->text[1] != '$'))) {
2782 error(ERR_NONFATAL,
2783 "`%%strlen' expects a macro identifier as first parameter");
2784 free_tlist(origline);
2785 return DIRECTIVE_FOUND;
2786 }
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002787 ctx = get_ctx(tline->text, false);
H. Peter Anvin97a23472007-09-16 17:57:25 -07002788
H. Peter Anvine2c80182005-01-15 22:15:51 +00002789 mname = tline->text;
2790 last = tline;
2791 tline = expand_smacro(tline->next);
2792 last->next = NULL;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002793
H. Peter Anvine2c80182005-01-15 22:15:51 +00002794 t = tline;
2795 while (tok_type_(t, TOK_WHITESPACE))
2796 t = t->next;
2797 /* t should now point to the string */
2798 if (t->type != TOK_STRING) {
2799 error(ERR_NONFATAL,
2800 "`%%strlen` requires string as second parameter");
2801 free_tlist(tline);
2802 free_tlist(origline);
2803 return DIRECTIVE_FOUND;
2804 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002805
H. Peter Anvine2c80182005-01-15 22:15:51 +00002806 macro_start = nasm_malloc(sizeof(*macro_start));
2807 macro_start->next = NULL;
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002808 make_tok_num(macro_start, nasm_unquote(t->text, NULL));
H. Peter Anvine2c80182005-01-15 22:15:51 +00002809 macro_start->mac = NULL;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002810
H. Peter Anvine2c80182005-01-15 22:15:51 +00002811 /*
2812 * We now have a macro name, an implicit parameter count of
2813 * zero, and a numeric token to use as an expansion. Create
2814 * and store an SMacro.
2815 */
H. Peter Anvin4db5a162007-10-11 13:42:09 -07002816 define_smacro(ctx, mname, casesense, 0, macro_start);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002817 free_tlist(tline);
2818 free_tlist(origline);
2819 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002820
H. Peter Anvine2c80182005-01-15 22:15:51 +00002821 case PP_SUBSTR:
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002822 {
2823 int64_t a1, a2;
2824 size_t len;
H. Peter Anvind2456592008-06-19 15:04:18 -07002825
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07002826 casesense = true;
2827
H. Peter Anvine2c80182005-01-15 22:15:51 +00002828 tline = tline->next;
2829 skip_white_(tline);
2830 tline = expand_id(tline);
2831 if (!tline || (tline->type != TOK_ID &&
2832 (tline->type != TOK_PREPROC_ID ||
2833 tline->text[1] != '$'))) {
2834 error(ERR_NONFATAL,
2835 "`%%substr' expects a macro identifier as first parameter");
2836 free_tlist(origline);
2837 return DIRECTIVE_FOUND;
2838 }
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002839 ctx = get_ctx(tline->text, false);
H. Peter Anvin97a23472007-09-16 17:57:25 -07002840
H. Peter Anvine2c80182005-01-15 22:15:51 +00002841 mname = tline->text;
2842 last = tline;
2843 tline = expand_smacro(tline->next);
2844 last->next = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002845
H. Peter Anvine2c80182005-01-15 22:15:51 +00002846 t = tline->next;
2847 while (tok_type_(t, TOK_WHITESPACE))
2848 t = t->next;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002849
H. Peter Anvine2c80182005-01-15 22:15:51 +00002850 /* t should now point to the string */
2851 if (t->type != TOK_STRING) {
2852 error(ERR_NONFATAL,
2853 "`%%substr` requires string as second parameter");
2854 free_tlist(tline);
2855 free_tlist(origline);
2856 return DIRECTIVE_FOUND;
2857 }
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002858
H. Peter Anvine2c80182005-01-15 22:15:51 +00002859 tt = t->next;
2860 tptr = &tt;
2861 tokval.t_type = TOKEN_INVALID;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002862 evalresult = evaluate(ppscan, tptr, &tokval, NULL,
2863 pass, error, NULL);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002864 if (!evalresult) {
2865 free_tlist(tline);
2866 free_tlist(origline);
2867 return DIRECTIVE_FOUND;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002868 } else if (!is_simple(evalresult)) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00002869 error(ERR_NONFATAL, "non-constant value given to `%%substr`");
2870 free_tlist(tline);
2871 free_tlist(origline);
2872 return DIRECTIVE_FOUND;
2873 }
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002874 a1 = evalresult->value-1;
2875
2876 while (tok_type_(tt, TOK_WHITESPACE))
2877 tt = tt->next;
2878 if (!tt) {
2879 a2 = 1; /* Backwards compatibility: one character */
2880 } else {
2881 tokval.t_type = TOKEN_INVALID;
2882 evalresult = evaluate(ppscan, tptr, &tokval, NULL,
2883 pass, error, NULL);
2884 if (!evalresult) {
2885 free_tlist(tline);
2886 free_tlist(origline);
2887 return DIRECTIVE_FOUND;
2888 } else if (!is_simple(evalresult)) {
2889 error(ERR_NONFATAL, "non-constant value given to `%%substr`");
2890 free_tlist(tline);
2891 free_tlist(origline);
2892 return DIRECTIVE_FOUND;
2893 }
2894 a2 = evalresult->value;
2895 }
2896
H. Peter Anvin88c9e1f2008-06-04 11:26:59 -07002897 len = nasm_unquote(t->text, NULL);
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002898 if (a2 < 0)
2899 a2 = a2+1+len-a1;
2900 if (a1+a2 > (int64_t)len)
2901 a2 = len-a1;
H. Peter Anvin1cd0e2d2002-04-30 21:00:33 +00002902
H. Peter Anvine2c80182005-01-15 22:15:51 +00002903 macro_start = nasm_malloc(sizeof(*macro_start));
2904 macro_start->next = NULL;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002905 macro_start->text = nasm_quote((a1 < 0) ? "" : t->text+a1, a2);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002906 macro_start->type = TOK_STRING;
2907 macro_start->mac = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002908
H. Peter Anvine2c80182005-01-15 22:15:51 +00002909 /*
2910 * We now have a macro name, an implicit parameter count of
2911 * zero, and a numeric token to use as an expansion. Create
2912 * and store an SMacro.
2913 */
H. Peter Anvin4db5a162007-10-11 13:42:09 -07002914 define_smacro(ctx, mname, casesense, 0, macro_start);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002915 free_tlist(tline);
2916 free_tlist(origline);
2917 return DIRECTIVE_FOUND;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07002918 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002919
H. Peter Anvine2c80182005-01-15 22:15:51 +00002920 case PP_ASSIGN:
2921 case PP_IASSIGN:
H. Peter Anvin4bc9f1d2007-10-11 12:52:03 -07002922 casesense = (i == PP_ASSIGN);
2923
H. Peter Anvine2c80182005-01-15 22:15:51 +00002924 tline = tline->next;
2925 skip_white_(tline);
2926 tline = expand_id(tline);
2927 if (!tline || (tline->type != TOK_ID &&
2928 (tline->type != TOK_PREPROC_ID ||
2929 tline->text[1] != '$'))) {
2930 error(ERR_NONFATAL,
2931 "`%%%sassign' expects a macro identifier",
2932 (i == PP_IASSIGN ? "i" : ""));
2933 free_tlist(origline);
2934 return DIRECTIVE_FOUND;
2935 }
H. Peter Anvin6867acc2007-10-10 14:58:45 -07002936 ctx = get_ctx(tline->text, false);
H. Peter Anvin97a23472007-09-16 17:57:25 -07002937
H. Peter Anvine2c80182005-01-15 22:15:51 +00002938 mname = tline->text;
2939 last = tline;
2940 tline = expand_smacro(tline->next);
2941 last->next = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00002942
H. Peter Anvine2c80182005-01-15 22:15:51 +00002943 t = tline;
2944 tptr = &t;
2945 tokval.t_type = TOKEN_INVALID;
2946 evalresult =
2947 evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
2948 free_tlist(tline);
2949 if (!evalresult) {
2950 free_tlist(origline);
2951 return DIRECTIVE_FOUND;
2952 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002953
H. Peter Anvine2c80182005-01-15 22:15:51 +00002954 if (tokval.t_type)
2955 error(ERR_WARNING,
2956 "trailing garbage after expression ignored");
H. Peter Anvin734b1882002-04-30 21:01:08 +00002957
H. Peter Anvine2c80182005-01-15 22:15:51 +00002958 if (!is_simple(evalresult)) {
2959 error(ERR_NONFATAL,
2960 "non-constant value given to `%%%sassign'",
2961 (i == PP_IASSIGN ? "i" : ""));
2962 free_tlist(origline);
2963 return DIRECTIVE_FOUND;
2964 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00002965
H. Peter Anvine2c80182005-01-15 22:15:51 +00002966 macro_start = nasm_malloc(sizeof(*macro_start));
2967 macro_start->next = NULL;
2968 make_tok_num(macro_start, reloc_value(evalresult));
2969 macro_start->mac = NULL;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002970
H. Peter Anvine2c80182005-01-15 22:15:51 +00002971 /*
2972 * We now have a macro name, an implicit parameter count of
2973 * zero, and a numeric token to use as an expansion. Create
2974 * and store an SMacro.
2975 */
H. Peter Anvin4db5a162007-10-11 13:42:09 -07002976 define_smacro(ctx, mname, casesense, 0, macro_start);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002977 free_tlist(origline);
2978 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00002979
H. Peter Anvine2c80182005-01-15 22:15:51 +00002980 case PP_LINE:
2981 /*
2982 * Syntax is `%line nnn[+mmm] [filename]'
2983 */
2984 tline = tline->next;
2985 skip_white_(tline);
2986 if (!tok_type_(tline, TOK_NUMBER)) {
2987 error(ERR_NONFATAL, "`%%line' expects line number");
2988 free_tlist(origline);
2989 return DIRECTIVE_FOUND;
2990 }
H. Peter Anvin70055962007-10-11 00:05:31 -07002991 k = readnum(tline->text, &err);
H. Peter Anvine2c80182005-01-15 22:15:51 +00002992 m = 1;
2993 tline = tline->next;
2994 if (tok_is_(tline, "+")) {
2995 tline = tline->next;
2996 if (!tok_type_(tline, TOK_NUMBER)) {
2997 error(ERR_NONFATAL, "`%%line' expects line increment");
2998 free_tlist(origline);
2999 return DIRECTIVE_FOUND;
3000 }
H. Peter Anvin70055962007-10-11 00:05:31 -07003001 m = readnum(tline->text, &err);
H. Peter Anvine2c80182005-01-15 22:15:51 +00003002 tline = tline->next;
3003 }
3004 skip_white_(tline);
3005 src_set_linnum(k);
3006 istk->lineinc = m;
3007 if (tline) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003008 nasm_free(src_set_fname(detoken(tline, false)));
H. Peter Anvine2c80182005-01-15 22:15:51 +00003009 }
3010 free_tlist(origline);
3011 return DIRECTIVE_FOUND;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003012
H. Peter Anvine2c80182005-01-15 22:15:51 +00003013 default:
3014 error(ERR_FATAL,
3015 "preprocessor directive `%s' not yet implemented",
H. Peter Anvin4169a472007-09-12 01:29:43 +00003016 pp_directives[i]);
H. Peter Anvine2c80182005-01-15 22:15:51 +00003017 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003018 }
Ed Beroset3ab3f412002-06-11 03:31:49 +00003019 return DIRECTIVE_FOUND;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003020}
3021
3022/*
H. Peter Anvin76690a12002-04-30 20:52:49 +00003023 * Ensure that a macro parameter contains a condition code and
3024 * nothing else. Return the condition code index if so, or -1
3025 * otherwise.
3026 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003027static int find_cc(Token * t)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003028{
H. Peter Anvin76690a12002-04-30 20:52:49 +00003029 Token *tt;
3030 int i, j, k, m;
3031
H. Peter Anvin25a99342007-09-22 17:45:45 -07003032 if (!t)
3033 return -1; /* Probably a %+ without a space */
3034
H. Peter Anvineba20a72002-04-30 20:53:55 +00003035 skip_white_(t);
H. Peter Anvin76690a12002-04-30 20:52:49 +00003036 if (t->type != TOK_ID)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003037 return -1;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003038 tt = t->next;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003039 skip_white_(tt);
H. Peter Anvin76690a12002-04-30 20:52:49 +00003040 if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
H. Peter Anvine2c80182005-01-15 22:15:51 +00003041 return -1;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003042
3043 i = -1;
Ed Beroset3ab3f412002-06-11 03:31:49 +00003044 j = elements(conditions);
H. Peter Anvine2c80182005-01-15 22:15:51 +00003045 while (j - i > 1) {
3046 k = (j + i) / 2;
3047 m = nasm_stricmp(t->text, conditions[k]);
3048 if (m == 0) {
3049 i = k;
3050 j = -2;
3051 break;
3052 } else if (m < 0) {
3053 j = k;
3054 } else
3055 i = k;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003056 }
3057 if (j != -2)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003058 return -1;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003059 return i;
3060}
3061
3062/*
3063 * Expand MMacro-local things: parameter references (%0, %n, %+n,
3064 * %-n) and MMacro-local identifiers (%%foo).
3065 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003066static Token *expand_mmac_params(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003067{
H. Peter Anvin734b1882002-04-30 21:01:08 +00003068 Token *t, *tt, **tail, *thead;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003069
3070 tail = &thead;
3071 thead = NULL;
3072
H. Peter Anvine2c80182005-01-15 22:15:51 +00003073 while (tline) {
3074 if (tline->type == TOK_PREPROC_ID &&
3075 (((tline->text[1] == '+' || tline->text[1] == '-')
3076 && tline->text[2]) || tline->text[1] == '%'
3077 || (tline->text[1] >= '0' && tline->text[1] <= '9'))) {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003078 char *text = NULL;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003079 int type = 0, cc; /* type = 0 to placate optimisers */
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003080 char tmpbuf[30];
H. Peter Anvin25a99342007-09-22 17:45:45 -07003081 unsigned int n;
3082 int i;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003083 MMacro *mac;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003084
H. Peter Anvine2c80182005-01-15 22:15:51 +00003085 t = tline;
3086 tline = tline->next;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003087
H. Peter Anvine2c80182005-01-15 22:15:51 +00003088 mac = istk->mstk;
3089 while (mac && !mac->name) /* avoid mistaking %reps for macros */
3090 mac = mac->next_active;
3091 if (!mac)
3092 error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
3093 else
3094 switch (t->text[1]) {
3095 /*
3096 * We have to make a substitution of one of the
3097 * forms %1, %-1, %+1, %%foo, %0.
3098 */
3099 case '0':
3100 type = TOK_NUMBER;
3101 snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam);
3102 text = nasm_strdup(tmpbuf);
3103 break;
3104 case '%':
3105 type = TOK_ID;
H. Peter Anvinf8ba53e2007-10-11 10:11:57 -07003106 snprintf(tmpbuf, sizeof(tmpbuf), "..@%"PRIu64".",
H. Peter Anvine2c80182005-01-15 22:15:51 +00003107 mac->unique);
3108 text = nasm_strcat(tmpbuf, t->text + 2);
3109 break;
3110 case '-':
3111 n = atoi(t->text + 2) - 1;
3112 if (n >= mac->nparam)
3113 tt = NULL;
3114 else {
3115 if (mac->nparam > 1)
3116 n = (n + mac->rotate) % mac->nparam;
3117 tt = mac->params[n];
3118 }
3119 cc = find_cc(tt);
3120 if (cc == -1) {
3121 error(ERR_NONFATAL,
3122 "macro parameter %d is not a condition code",
3123 n + 1);
3124 text = NULL;
3125 } else {
3126 type = TOK_ID;
3127 if (inverse_ccs[cc] == -1) {
3128 error(ERR_NONFATAL,
3129 "condition code `%s' is not invertible",
3130 conditions[cc]);
3131 text = NULL;
3132 } else
3133 text =
3134 nasm_strdup(conditions[inverse_ccs[cc]]);
3135 }
3136 break;
3137 case '+':
3138 n = atoi(t->text + 2) - 1;
3139 if (n >= mac->nparam)
3140 tt = NULL;
3141 else {
3142 if (mac->nparam > 1)
3143 n = (n + mac->rotate) % mac->nparam;
3144 tt = mac->params[n];
3145 }
3146 cc = find_cc(tt);
3147 if (cc == -1) {
3148 error(ERR_NONFATAL,
3149 "macro parameter %d is not a condition code",
3150 n + 1);
3151 text = NULL;
3152 } else {
3153 type = TOK_ID;
3154 text = nasm_strdup(conditions[cc]);
3155 }
3156 break;
3157 default:
3158 n = atoi(t->text + 1) - 1;
3159 if (n >= mac->nparam)
3160 tt = NULL;
3161 else {
3162 if (mac->nparam > 1)
3163 n = (n + mac->rotate) % mac->nparam;
3164 tt = mac->params[n];
3165 }
3166 if (tt) {
3167 for (i = 0; i < mac->paramlen[n]; i++) {
3168 *tail = new_Token(NULL, tt->type, tt->text, 0);
3169 tail = &(*tail)->next;
3170 tt = tt->next;
3171 }
3172 }
3173 text = NULL; /* we've done it here */
3174 break;
3175 }
3176 if (!text) {
3177 delete_Token(t);
3178 } else {
3179 *tail = t;
3180 tail = &t->next;
3181 t->type = type;
3182 nasm_free(t->text);
3183 t->text = text;
3184 t->mac = NULL;
3185 }
3186 continue;
3187 } else {
3188 t = *tail = tline;
3189 tline = tline->next;
3190 t->mac = NULL;
3191 tail = &t->next;
3192 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00003193 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00003194 *tail = NULL;
3195 t = thead;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003196 for (; t && (tt = t->next) != NULL; t = t->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003197 switch (t->type) {
3198 case TOK_WHITESPACE:
3199 if (tt->type == TOK_WHITESPACE) {
3200 t->next = delete_Token(tt);
3201 }
3202 break;
3203 case TOK_ID:
3204 if (tt->type == TOK_ID || tt->type == TOK_NUMBER) {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003205 char *tmp = nasm_strcat(t->text, tt->text);
H. Peter Anvine2c80182005-01-15 22:15:51 +00003206 nasm_free(t->text);
3207 t->text = tmp;
3208 t->next = delete_Token(tt);
3209 }
3210 break;
3211 case TOK_NUMBER:
3212 if (tt->type == TOK_NUMBER) {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003213 char *tmp = nasm_strcat(t->text, tt->text);
H. Peter Anvine2c80182005-01-15 22:15:51 +00003214 nasm_free(t->text);
3215 t->text = tmp;
3216 t->next = delete_Token(tt);
3217 }
3218 break;
H. Peter Anvinda10e7b2007-09-12 04:18:37 +00003219 default:
3220 break;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003221 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003222
H. Peter Anvin76690a12002-04-30 20:52:49 +00003223 return thead;
3224}
3225
3226/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003227 * Expand all single-line macro calls made in the given line.
3228 * Return the expanded version of the line. The original is deemed
3229 * to be destroyed in the process. (In reality we'll just move
3230 * Tokens from input to output a lot of the time, rather than
3231 * actually bothering to destroy and replicate.)
3232 */
H. Peter Anvincb1cf592007-11-19 12:26:50 -08003233#define DEADMAN_LIMIT (1 << 20)
3234
H. Peter Anvine2c80182005-01-15 22:15:51 +00003235static Token *expand_smacro(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003236{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003237 Token *t, *tt, *mstart, **tail, *thead;
H. Peter Anvin166c2472008-05-28 12:28:58 -07003238 struct hash_table *smtbl;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003239 SMacro *head = NULL, *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003240 Token **params;
3241 int *paramsize;
H. Peter Anvin25a99342007-09-22 17:45:45 -07003242 unsigned int nparam, sparam;
3243 int brackets, rescan;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003244 Token *org_tline = tline;
3245 Context *ctx;
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003246 char *mname;
H. Peter Anvin2a15e692007-11-19 13:14:59 -08003247 int deadman = DEADMAN_LIMIT;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003248
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003249 /*
3250 * Trick: we should avoid changing the start token pointer since it can
3251 * be contained in "next" field of other token. Because of this
3252 * we allocate a copy of first token and work with it; at the end of
3253 * routine we copy it back
3254 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003255 if (org_tline) {
3256 tline =
3257 new_Token(org_tline->next, org_tline->type, org_tline->text,
3258 0);
3259 tline->mac = org_tline->mac;
3260 nasm_free(org_tline->text);
3261 org_tline->text = NULL;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003262 }
3263
H. Peter Anvincb1cf592007-11-19 12:26:50 -08003264again:
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003265 tail = &thead;
3266 thead = NULL;
3267
H. Peter Anvine2c80182005-01-15 22:15:51 +00003268 while (tline) { /* main token loop */
H. Peter Anvin2a15e692007-11-19 13:14:59 -08003269 if (!--deadman) {
H. Peter Anvincb1cf592007-11-19 12:26:50 -08003270 error(ERR_NONFATAL, "interminable macro recursion");
3271 break;
3272 }
3273
H. Peter Anvine2c80182005-01-15 22:15:51 +00003274 if ((mname = tline->text)) {
3275 /* if this token is a local macro, look in local context */
H. Peter Anvinb037a672008-05-29 19:08:08 -07003276 ctx = NULL;
3277 smtbl = &smacros;
H. Peter Anvin166c2472008-05-28 12:28:58 -07003278 if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003279 ctx = get_ctx(mname, true);
H. Peter Anvinb037a672008-05-29 19:08:08 -07003280 if (ctx)
3281 smtbl = &ctx->localmac;
H. Peter Anvin166c2472008-05-28 12:28:58 -07003282 }
H. Peter Anvin166c2472008-05-28 12:28:58 -07003283 head = (SMacro *) hash_findix(smtbl, mname);
H. Peter Anvin072771e2008-05-22 13:17:51 -07003284
H. Peter Anvine2c80182005-01-15 22:15:51 +00003285 /*
3286 * We've hit an identifier. As in is_mmacro below, we first
3287 * check whether the identifier is a single-line macro at
3288 * all, then think about checking for parameters if
3289 * necessary.
3290 */
H. Peter Anvin97a23472007-09-16 17:57:25 -07003291 for (m = head; m; m = m->next)
3292 if (!mstrcmp(m->name, mname, m->casesense))
3293 break;
3294 if (m) {
3295 mstart = tline;
3296 params = NULL;
3297 paramsize = NULL;
3298 if (m->nparam == 0) {
3299 /*
3300 * Simple case: the macro is parameterless. Discard the
3301 * one token that the macro call took, and push the
3302 * expansion back on the to-do stack.
3303 */
3304 if (!m->expansion) {
3305 if (!strcmp("__FILE__", m->name)) {
3306 int32_t num = 0;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07003307 char *file;
3308 src_get(&num, &file);
3309 tline->text = nasm_quote(file, strlen(file));
H. Peter Anvin97a23472007-09-16 17:57:25 -07003310 tline->type = TOK_STRING;
H. Peter Anvin8cad14b2008-06-01 17:23:51 -07003311 nasm_free(file);
H. Peter Anvin97a23472007-09-16 17:57:25 -07003312 continue;
3313 }
3314 if (!strcmp("__LINE__", m->name)) {
3315 nasm_free(tline->text);
3316 make_tok_num(tline, src_get_linnum());
3317 continue;
3318 }
3319 if (!strcmp("__BITS__", m->name)) {
3320 nasm_free(tline->text);
3321 make_tok_num(tline, globalbits);
H. Peter Anvine2c80182005-01-15 22:15:51 +00003322 continue;
H. Peter Anvin97a23472007-09-16 17:57:25 -07003323 }
3324 tline = delete_Token(tline);
3325 continue;
3326 }
3327 } else {
3328 /*
3329 * Complicated case: at least one macro with this name
H. Peter Anvine2c80182005-01-15 22:15:51 +00003330 * exists and takes parameters. We must find the
3331 * parameters in the call, count them, find the SMacro
3332 * that corresponds to that form of the macro call, and
3333 * substitute for the parameters when we expand. What a
3334 * pain.
3335 */
3336 /*tline = tline->next;
3337 skip_white_(tline); */
3338 do {
3339 t = tline->next;
3340 while (tok_type_(t, TOK_SMAC_END)) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003341 t->mac->in_progress = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003342 t->text = NULL;
3343 t = tline->next = delete_Token(t);
3344 }
3345 tline = t;
3346 } while (tok_type_(tline, TOK_WHITESPACE));
3347 if (!tok_is_(tline, "(")) {
3348 /*
3349 * This macro wasn't called with parameters: ignore
3350 * the call. (Behaviour borrowed from gnu cpp.)
3351 */
3352 tline = mstart;
3353 m = NULL;
3354 } else {
3355 int paren = 0;
3356 int white = 0;
3357 brackets = 0;
3358 nparam = 0;
3359 sparam = PARAM_DELTA;
3360 params = nasm_malloc(sparam * sizeof(Token *));
3361 params[0] = tline->next;
3362 paramsize = nasm_malloc(sparam * sizeof(int));
3363 paramsize[0] = 0;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003364 while (true) { /* parameter loop */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003365 /*
3366 * For some unusual expansions
3367 * which concatenates function call
3368 */
3369 t = tline->next;
3370 while (tok_type_(t, TOK_SMAC_END)) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003371 t->mac->in_progress = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003372 t->text = NULL;
3373 t = tline->next = delete_Token(t);
3374 }
3375 tline = t;
Nickolay Yurchenko9aea7152003-09-07 22:46:26 +00003376
H. Peter Anvine2c80182005-01-15 22:15:51 +00003377 if (!tline) {
3378 error(ERR_NONFATAL,
3379 "macro call expects terminating `)'");
3380 break;
3381 }
3382 if (tline->type == TOK_WHITESPACE
3383 && brackets <= 0) {
3384 if (paramsize[nparam])
3385 white++;
3386 else
3387 params[nparam] = tline->next;
3388 continue; /* parameter loop */
3389 }
3390 if (tline->type == TOK_OTHER
3391 && tline->text[1] == 0) {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003392 char ch = tline->text[0];
H. Peter Anvine2c80182005-01-15 22:15:51 +00003393 if (ch == ',' && !paren && brackets <= 0) {
3394 if (++nparam >= sparam) {
3395 sparam += PARAM_DELTA;
3396 params = nasm_realloc(params,
3397 sparam *
3398 sizeof(Token
3399 *));
3400 paramsize =
3401 nasm_realloc(paramsize,
3402 sparam *
3403 sizeof(int));
3404 }
3405 params[nparam] = tline->next;
3406 paramsize[nparam] = 0;
3407 white = 0;
3408 continue; /* parameter loop */
3409 }
3410 if (ch == '{' &&
3411 (brackets > 0 || (brackets == 0 &&
3412 !paramsize[nparam])))
3413 {
3414 if (!(brackets++)) {
3415 params[nparam] = tline->next;
3416 continue; /* parameter loop */
3417 }
3418 }
3419 if (ch == '}' && brackets > 0)
3420 if (--brackets == 0) {
3421 brackets = -1;
3422 continue; /* parameter loop */
3423 }
3424 if (ch == '(' && !brackets)
3425 paren++;
3426 if (ch == ')' && brackets <= 0)
3427 if (--paren < 0)
3428 break;
3429 }
3430 if (brackets < 0) {
3431 brackets = 0;
3432 error(ERR_NONFATAL, "braces do not "
3433 "enclose all of macro parameter");
3434 }
3435 paramsize[nparam] += white + 1;
3436 white = 0;
3437 } /* parameter loop */
3438 nparam++;
3439 while (m && (m->nparam != nparam ||
3440 mstrcmp(m->name, mname,
3441 m->casesense)))
3442 m = m->next;
3443 if (!m)
3444 error(ERR_WARNING | ERR_WARN_MNP,
3445 "macro `%s' exists, "
3446 "but not taking %d parameters",
3447 mstart->text, nparam);
3448 }
3449 }
3450 if (m && m->in_progress)
3451 m = NULL;
3452 if (!m) { /* in progess or didn't find '(' or wrong nparam */
H. Peter Anvin70653092007-10-19 14:42:29 -07003453 /*
H. Peter Anvine2c80182005-01-15 22:15:51 +00003454 * Design question: should we handle !tline, which
3455 * indicates missing ')' here, or expand those
3456 * macros anyway, which requires the (t) test a few
H. Peter Anvin70653092007-10-19 14:42:29 -07003457 * lines down?
H. Peter Anvine2c80182005-01-15 22:15:51 +00003458 */
3459 nasm_free(params);
3460 nasm_free(paramsize);
3461 tline = mstart;
3462 } else {
3463 /*
3464 * Expand the macro: we are placed on the last token of the
3465 * call, so that we can easily split the call from the
3466 * following tokens. We also start by pushing an SMAC_END
3467 * token for the cycle removal.
3468 */
3469 t = tline;
3470 if (t) {
3471 tline = t->next;
3472 t->next = NULL;
3473 }
3474 tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
3475 tt->mac = m;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003476 m->in_progress = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003477 tline = tt;
3478 for (t = m->expansion; t; t = t->next) {
3479 if (t->type >= TOK_SMAC_PARAM) {
3480 Token *pcopy = tline, **ptail = &pcopy;
3481 Token *ttt, *pt;
3482 int i;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003483
H. Peter Anvine2c80182005-01-15 22:15:51 +00003484 ttt = params[t->type - TOK_SMAC_PARAM];
3485 for (i = paramsize[t->type - TOK_SMAC_PARAM];
3486 --i >= 0;) {
3487 pt = *ptail =
3488 new_Token(tline, ttt->type, ttt->text,
3489 0);
3490 ptail = &pt->next;
3491 ttt = ttt->next;
3492 }
3493 tline = pcopy;
H. Peter Anvin6c81f0a2008-05-25 21:46:17 -07003494 } else if (t->type == TOK_PREPROC_Q) {
3495 tt = new_Token(tline, TOK_ID, mname, 0);
3496 tline = tt;
3497 } else if (t->type == TOK_PREPROC_QQ) {
3498 tt = new_Token(tline, TOK_ID, m->name, 0);
3499 tline = tt;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003500 } else {
3501 tt = new_Token(tline, t->type, t->text, 0);
3502 tline = tt;
3503 }
3504 }
H. Peter Anvin734b1882002-04-30 21:01:08 +00003505
H. Peter Anvine2c80182005-01-15 22:15:51 +00003506 /*
3507 * Having done that, get rid of the macro call, and clean
3508 * up the parameters.
3509 */
3510 nasm_free(params);
3511 nasm_free(paramsize);
3512 free_tlist(mstart);
3513 continue; /* main token loop */
3514 }
3515 }
3516 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003517
H. Peter Anvine2c80182005-01-15 22:15:51 +00003518 if (tline->type == TOK_SMAC_END) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003519 tline->mac->in_progress = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003520 tline = delete_Token(tline);
3521 } else {
3522 t = *tail = tline;
3523 tline = tline->next;
3524 t->mac = NULL;
3525 t->next = NULL;
3526 tail = &t->next;
3527 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003528 }
3529
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003530 /*
3531 * Now scan the entire line and look for successive TOK_IDs that resulted
Keith Kaniosb7a89542007-04-12 02:40:54 +00003532 * after expansion (they can't be produced by tokenize()). The successive
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003533 * TOK_IDs should be concatenated.
3534 * Also we look for %+ tokens and concatenate the tokens before and after
3535 * them (without white spaces in between).
3536 */
3537 t = thead;
3538 rescan = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003539 while (t) {
3540 while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
3541 t = t->next;
3542 if (!t || !t->next)
3543 break;
3544 if (t->next->type == TOK_ID ||
3545 t->next->type == TOK_PREPROC_ID ||
3546 t->next->type == TOK_NUMBER) {
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003547 char *p = nasm_strcat(t->text, t->next->text);
H. Peter Anvine2c80182005-01-15 22:15:51 +00003548 nasm_free(t->text);
3549 t->next = delete_Token(t->next);
3550 t->text = p;
3551 rescan = 1;
3552 } else if (t->next->type == TOK_WHITESPACE && t->next->next &&
3553 t->next->next->type == TOK_PREPROC_ID &&
3554 strcmp(t->next->next->text, "%+") == 0) {
3555 /* free the next whitespace, the %+ token and next whitespace */
3556 int i;
3557 for (i = 1; i <= 3; i++) {
3558 if (!t->next
3559 || (i != 2 && t->next->type != TOK_WHITESPACE))
3560 break;
3561 t->next = delete_Token(t->next);
3562 } /* endfor */
3563 } else
3564 t = t->next;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003565 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003566 /* If we concatenaded something, re-scan the line for macros */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003567 if (rescan) {
3568 tline = thead;
3569 goto again;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003570 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003571
H. Peter Anvine2c80182005-01-15 22:15:51 +00003572 if (org_tline) {
3573 if (thead) {
3574 *org_tline = *thead;
3575 /* since we just gave text to org_line, don't free it */
3576 thead->text = NULL;
3577 delete_Token(thead);
3578 } else {
3579 /* the expression expanded to empty line;
3580 we can't return NULL for some reasons
3581 we just set the line to a single WHITESPACE token. */
3582 memset(org_tline, 0, sizeof(*org_tline));
3583 org_tline->text = NULL;
3584 org_tline->type = TOK_WHITESPACE;
3585 }
3586 thead = org_tline;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003587 }
3588
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003589 return thead;
3590}
3591
3592/*
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003593 * Similar to expand_smacro but used exclusively with macro identifiers
3594 * right before they are fetched in. The reason is that there can be
3595 * identifiers consisting of several subparts. We consider that if there
3596 * are more than one element forming the name, user wants a expansion,
3597 * otherwise it will be left as-is. Example:
3598 *
3599 * %define %$abc cde
3600 *
3601 * the identifier %$abc will be left as-is so that the handler for %define
3602 * will suck it and define the corresponding value. Other case:
3603 *
3604 * %define _%$abc cde
3605 *
3606 * In this case user wants name to be expanded *before* %define starts
3607 * working, so we'll expand %$abc into something (if it has a value;
3608 * otherwise it will be left as-is) then concatenate all successive
3609 * PP_IDs into one.
3610 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003611static Token *expand_id(Token * tline)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003612{
3613 Token *cur, *oldnext = NULL;
3614
H. Peter Anvin734b1882002-04-30 21:01:08 +00003615 if (!tline || !tline->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003616 return tline;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003617
3618 cur = tline;
3619 while (cur->next &&
H. Peter Anvine2c80182005-01-15 22:15:51 +00003620 (cur->next->type == TOK_ID ||
3621 cur->next->type == TOK_PREPROC_ID
3622 || cur->next->type == TOK_NUMBER))
3623 cur = cur->next;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003624
3625 /* If identifier consists of just one token, don't expand */
3626 if (cur == tline)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003627 return tline;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003628
H. Peter Anvine2c80182005-01-15 22:15:51 +00003629 if (cur) {
3630 oldnext = cur->next; /* Detach the tail past identifier */
3631 cur->next = NULL; /* so that expand_smacro stops here */
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003632 }
3633
H. Peter Anvin734b1882002-04-30 21:01:08 +00003634 tline = expand_smacro(tline);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003635
H. Peter Anvine2c80182005-01-15 22:15:51 +00003636 if (cur) {
3637 /* expand_smacro possibly changhed tline; re-scan for EOL */
3638 cur = tline;
3639 while (cur && cur->next)
3640 cur = cur->next;
3641 if (cur)
3642 cur->next = oldnext;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003643 }
3644
3645 return tline;
3646}
3647
3648/*
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003649 * Determine whether the given line constitutes a multi-line macro
3650 * call, and return the MMacro structure called if so. Doesn't have
3651 * to check for an initial label - that's taken care of in
3652 * expand_mmacro - but must check numbers of parameters. Guaranteed
3653 * to be called with tline->type == TOK_ID, so the putative macro
3654 * name is easy to find.
3655 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003656static MMacro *is_mmacro(Token * tline, Token *** params_array)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003657{
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003658 MMacro *head, *m;
3659 Token **params;
3660 int nparam;
3661
H. Peter Anvin166c2472008-05-28 12:28:58 -07003662 head = (MMacro *) hash_findix(&mmacros, tline->text);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003663
3664 /*
3665 * Efficiency: first we see if any macro exists with the given
3666 * name. If not, we can return NULL immediately. _Then_ we
3667 * count the parameters, and then we look further along the
3668 * list if necessary to find the proper MMacro.
3669 */
3670 for (m = head; m; m = m->next)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003671 if (!mstrcmp(m->name, tline->text, m->casesense))
3672 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003673 if (!m)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003674 return NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003675
3676 /*
3677 * OK, we have a potential macro. Count and demarcate the
3678 * parameters.
3679 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003680 count_mmac_params(tline->next, &nparam, &params);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003681
3682 /*
3683 * So we know how many parameters we've got. Find the MMacro
3684 * structure that handles this number.
3685 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003686 while (m) {
3687 if (m->nparam_min <= nparam
3688 && (m->plus || nparam <= m->nparam_max)) {
3689 /*
3690 * This one is right. Just check if cycle removal
3691 * prohibits us using it before we actually celebrate...
3692 */
3693 if (m->in_progress) {
H. Peter Anvineba20a72002-04-30 20:53:55 +00003694#if 0
H. Peter Anvine2c80182005-01-15 22:15:51 +00003695 error(ERR_NONFATAL,
3696 "self-reference in multi-line macro `%s'", m->name);
H. Peter Anvineba20a72002-04-30 20:53:55 +00003697#endif
H. Peter Anvine2c80182005-01-15 22:15:51 +00003698 nasm_free(params);
3699 return NULL;
3700 }
3701 /*
3702 * It's right, and we can use it. Add its default
3703 * parameters to the end of our list if necessary.
3704 */
3705 if (m->defaults && nparam < m->nparam_min + m->ndefs) {
3706 params =
3707 nasm_realloc(params,
3708 ((m->nparam_min + m->ndefs +
3709 1) * sizeof(*params)));
3710 while (nparam < m->nparam_min + m->ndefs) {
3711 params[nparam] = m->defaults[nparam - m->nparam_min];
3712 nparam++;
3713 }
3714 }
3715 /*
3716 * If we've gone over the maximum parameter count (and
3717 * we're in Plus mode), ignore parameters beyond
3718 * nparam_max.
3719 */
3720 if (m->plus && nparam > m->nparam_max)
3721 nparam = m->nparam_max;
3722 /*
3723 * Then terminate the parameter list, and leave.
3724 */
3725 if (!params) { /* need this special case */
3726 params = nasm_malloc(sizeof(*params));
3727 nparam = 0;
3728 }
3729 params[nparam] = NULL;
3730 *params_array = params;
3731 return m;
3732 }
3733 /*
3734 * This one wasn't right: look for the next one with the
3735 * same name.
3736 */
3737 for (m = m->next; m; m = m->next)
3738 if (!mstrcmp(m->name, tline->text, m->casesense))
3739 break;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003740 }
3741
3742 /*
3743 * After all that, we didn't find one with the right number of
3744 * parameters. Issue a warning, and fail to expand the macro.
3745 */
H. Peter Anvin734b1882002-04-30 21:01:08 +00003746 error(ERR_WARNING | ERR_WARN_MNP,
H. Peter Anvine2c80182005-01-15 22:15:51 +00003747 "macro `%s' exists, but not taking %d parameters",
3748 tline->text, nparam);
H. Peter Anvin734b1882002-04-30 21:01:08 +00003749 nasm_free(params);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003750 return NULL;
3751}
3752
3753/*
3754 * Expand the multi-line macro call made by the given line, if
3755 * there is one to be expanded. If there is, push the expansion on
H. Peter Anvineba20a72002-04-30 20:53:55 +00003756 * istk->expansion and return 1. Otherwise return 0.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003757 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003758static int expand_mmacro(Token * tline)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003759{
3760 Token *startline = tline;
3761 Token *label = NULL;
3762 int dont_prepend = 0;
H. Peter Anvince2233b2008-05-25 21:57:00 -07003763 Token **params, *t, *mtok, *tt;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003764 MMacro *m;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003765 Line *l, *ll;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003766 int i, nparam, *paramlen;
H. Peter Anvinc751e862008-06-09 10:18:45 -07003767 const char *mname;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003768
3769 t = tline;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003770 skip_white_(t);
H. Peter Anvince2233b2008-05-25 21:57:00 -07003771 /* if (!tok_type_(t, TOK_ID)) Lino 02/25/02 */
H. Peter Anvindce1e2f2002-04-30 21:06:37 +00003772 if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID))
H. Peter Anvine2c80182005-01-15 22:15:51 +00003773 return 0;
H. Peter Anvince2233b2008-05-25 21:57:00 -07003774 mtok = t;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003775 m = is_mmacro(t, &params);
H. Peter Anvinc751e862008-06-09 10:18:45 -07003776 if (m) {
3777 mname = t->text;
3778 } else {
H. Peter Anvine2c80182005-01-15 22:15:51 +00003779 Token *last;
3780 /*
3781 * We have an id which isn't a macro call. We'll assume
3782 * it might be a label; we'll also check to see if a
3783 * colon follows it. Then, if there's another id after
3784 * that lot, we'll check it again for macro-hood.
3785 */
3786 label = last = t;
3787 t = t->next;
3788 if (tok_type_(t, TOK_WHITESPACE))
3789 last = t, t = t->next;
3790 if (tok_is_(t, ":")) {
3791 dont_prepend = 1;
3792 last = t, t = t->next;
3793 if (tok_type_(t, TOK_WHITESPACE))
3794 last = t, t = t->next;
3795 }
3796 if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, &params)) == NULL)
3797 return 0;
3798 last->next = NULL;
H. Peter Anvinc751e862008-06-09 10:18:45 -07003799 mname = t->text;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003800 tline = t;
H. Peter Anvineba20a72002-04-30 20:53:55 +00003801 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003802
3803 /*
3804 * Fix up the parameters: this involves stripping leading and
3805 * trailing whitespace, then stripping braces if they are
3806 * present.
3807 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003808 for (nparam = 0; params[nparam]; nparam++) ;
H. Peter Anvin734b1882002-04-30 21:01:08 +00003809 paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003810
H. Peter Anvine2c80182005-01-15 22:15:51 +00003811 for (i = 0; params[i]; i++) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003812 int brace = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003813 int comma = (!m->plus || i < nparam - 1);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003814
H. Peter Anvine2c80182005-01-15 22:15:51 +00003815 t = params[i];
3816 skip_white_(t);
3817 if (tok_is_(t, "{"))
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003818 t = t->next, brace = true, comma = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003819 params[i] = t;
3820 paramlen[i] = 0;
3821 while (t) {
3822 if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
3823 break; /* ... because we have hit a comma */
3824 if (comma && t->type == TOK_WHITESPACE
3825 && tok_is_(t->next, ","))
3826 break; /* ... or a space then a comma */
3827 if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
3828 break; /* ... or a brace */
3829 t = t->next;
3830 paramlen[i]++;
3831 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003832 }
3833
3834 /*
3835 * OK, we have a MMacro structure together with a set of
3836 * parameters. We must now go through the expansion and push
H. Peter Anvin76690a12002-04-30 20:52:49 +00003837 * copies of each Line on to istk->expansion. Substitution of
3838 * parameter tokens and macro-local tokens doesn't get done
3839 * until the single-line macro substitution process; this is
3840 * because delaying them allows us to change the semantics
3841 * later through %rotate.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003842 *
H. Peter Anvin76690a12002-04-30 20:52:49 +00003843 * First, push an end marker on to istk->expansion, mark this
3844 * macro as in progress, and set up its invocation-specific
3845 * variables.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003846 */
3847 ll = nasm_malloc(sizeof(Line));
3848 ll->next = istk->expansion;
3849 ll->finishes = m;
3850 ll->first = NULL;
3851 istk->expansion = ll;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003852
H. Peter Anvin6867acc2007-10-10 14:58:45 -07003853 m->in_progress = true;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003854 m->params = params;
3855 m->iline = tline;
3856 m->nparam = nparam;
3857 m->rotate = 0;
3858 m->paramlen = paramlen;
3859 m->unique = unique++;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003860 m->lineno = 0;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003861
3862 m->next_active = istk->mstk;
3863 istk->mstk = m;
3864
H. Peter Anvine2c80182005-01-15 22:15:51 +00003865 for (l = m->expansion; l; l = l->next) {
3866 Token **tail;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003867
H. Peter Anvine2c80182005-01-15 22:15:51 +00003868 ll = nasm_malloc(sizeof(Line));
3869 ll->finishes = NULL;
3870 ll->next = istk->expansion;
3871 istk->expansion = ll;
3872 tail = &ll->first;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003873
H. Peter Anvine2c80182005-01-15 22:15:51 +00003874 for (t = l->first; t; t = t->next) {
3875 Token *x = t;
H. Peter Anvince2233b2008-05-25 21:57:00 -07003876 switch (t->type) {
3877 case TOK_PREPROC_Q:
H. Peter Anvinc751e862008-06-09 10:18:45 -07003878 tt = *tail = new_Token(NULL, TOK_ID, mname, 0);
H. Peter Anvince2233b2008-05-25 21:57:00 -07003879 break;
3880 case TOK_PREPROC_QQ:
3881 tt = *tail = new_Token(NULL, TOK_ID, m->name, 0);
3882 break;
3883 case TOK_PREPROC_ID:
3884 if (t->text[1] == '0' && t->text[2] == '0') {
3885 dont_prepend = -1;
3886 x = label;
3887 if (!x)
3888 continue;
3889 }
3890 /* fall through */
3891 default:
3892 tt = *tail = new_Token(NULL, x->type, x->text, 0);
3893 break;
H. Peter Anvin166c2472008-05-28 12:28:58 -07003894 }
H. Peter Anvince2233b2008-05-25 21:57:00 -07003895 tail = &tt->next;
3896 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00003897 *tail = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003898 }
3899
3900 /*
H. Peter Anvineba20a72002-04-30 20:53:55 +00003901 * If we had a label, push it on as the first line of
3902 * the macro expansion.
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003903 */
H. Peter Anvine2c80182005-01-15 22:15:51 +00003904 if (label) {
3905 if (dont_prepend < 0)
3906 free_tlist(startline);
3907 else {
3908 ll = nasm_malloc(sizeof(Line));
3909 ll->finishes = NULL;
3910 ll->next = istk->expansion;
3911 istk->expansion = ll;
3912 ll->first = startline;
3913 if (!dont_prepend) {
3914 while (label->next)
3915 label = label->next;
3916 label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
3917 }
3918 }
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003919 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003920
H. Peter Anvin734b1882002-04-30 21:01:08 +00003921 list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00003922
H. Peter Anvineba20a72002-04-30 20:53:55 +00003923 return 1;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003924}
3925
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003926/*
3927 * Since preprocessor always operate only on the line that didn't
3928 * arrived yet, we should always use ERR_OFFBY1. Also since user
3929 * won't want to see same error twice (preprocessing is done once
3930 * per pass) we will want to show errors only during pass one.
3931 */
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003932static void error(int severity, const char *fmt, ...)
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003933{
3934 va_list arg;
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003935 char buff[1024];
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003936
3937 /* If we're in a dead branch of IF or something like it, ignore the error */
H. Peter Anvin77ba0c62002-05-14 03:18:53 +00003938 if (istk && istk->conds && !emitting(istk->conds->state))
H. Peter Anvine2c80182005-01-15 22:15:51 +00003939 return;
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003940
H. Peter Anvin734b1882002-04-30 21:01:08 +00003941 va_start(arg, fmt);
Ed Beroset19f927a2004-12-15 17:07:03 +00003942 vsnprintf(buff, sizeof(buff), fmt, arg);
H. Peter Anvin734b1882002-04-30 21:01:08 +00003943 va_end(arg);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003944
H. Peter Anvin77ba0c62002-05-14 03:18:53 +00003945 if (istk && istk->mstk && istk->mstk->name)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003946 _error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
3947 istk->mstk->lineno, buff);
3948 else
3949 _error(severity | ERR_PASS1, "%s", buff);
H. Peter Anvinaf535c12002-04-30 20:59:21 +00003950}
3951
H. Peter Anvin734b1882002-04-30 21:01:08 +00003952static void
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003953pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07003954 ListGen * listgen, StrList **deplist)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003955{
H. Peter Anvin99941bf2002-05-14 17:44:03 +00003956 _error = errfunc;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003957 cstk = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003958 istk = nasm_malloc(sizeof(Include));
3959 istk->next = NULL;
3960 istk->conds = NULL;
3961 istk->expansion = NULL;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003962 istk->mstk = NULL;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003963 istk->fp = fopen(file, "r");
H. Peter Anvineba20a72002-04-30 20:53:55 +00003964 istk->fname = NULL;
3965 src_set_fname(nasm_strdup(file));
3966 src_set_linnum(0);
3967 istk->lineinc = 1;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003968 if (!istk->fp)
H. Peter Anvine2c80182005-01-15 22:15:51 +00003969 error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'",
3970 file);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003971 defining = NULL;
H. Peter Anvin97a23472007-09-16 17:57:25 -07003972 init_macros();
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003973 unique = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003974 if (tasm_compatible_mode) {
H. Peter Anvina4835d42008-05-20 14:21:29 -07003975 stdmacpos = nasm_stdmac;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003976 } else {
H. Peter Anvina4835d42008-05-20 14:21:29 -07003977 stdmacpos = nasm_stdmac_after_tasm;
H. Peter Anvine2c80182005-01-15 22:15:51 +00003978 }
H. Peter Anvind2456592008-06-19 15:04:18 -07003979 any_extrastdmac = extrastdmac && *extrastdmac;
3980 do_predef = true;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00003981 list = listgen;
H. Peter Anvin76690a12002-04-30 20:52:49 +00003982 evaluate = eval;
3983 pass = apass;
H. Peter Anvin9e1f5282008-05-29 21:38:00 -07003984 dephead = deptail = deplist;
3985 if (deplist) {
3986 StrList *sl = nasm_malloc(strlen(file)+1+sizeof sl->next);
3987 sl->next = NULL;
3988 strcpy(sl->str, file);
3989 *deptail = sl;
3990 deptail = &sl->next;
3991 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003992}
3993
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003994static char *pp_getline(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +00003995{
Keith Kaniosa6dfa782007-04-13 16:47:53 +00003996 char *line;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003997 Token *tline;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00003998
H. Peter Anvine2c80182005-01-15 22:15:51 +00003999 while (1) {
4000 /*
Keith Kaniosb7a89542007-04-12 02:40:54 +00004001 * Fetch a tokenized line, either from the macro-expansion
H. Peter Anvine2c80182005-01-15 22:15:51 +00004002 * buffer or from the input file.
4003 */
4004 tline = NULL;
4005 while (istk->expansion && istk->expansion->finishes) {
4006 Line *l = istk->expansion;
4007 if (!l->finishes->name && l->finishes->in_progress > 1) {
4008 Line *ll;
H. Peter Anvin76690a12002-04-30 20:52:49 +00004009
H. Peter Anvine2c80182005-01-15 22:15:51 +00004010 /*
4011 * This is a macro-end marker for a macro with no
4012 * name, which means it's not really a macro at all
4013 * but a %rep block, and the `in_progress' field is
4014 * more than 1, meaning that we still need to
4015 * repeat. (1 means the natural last repetition; 0
4016 * means termination by %exitrep.) We have
4017 * therefore expanded up to the %endrep, and must
4018 * push the whole block on to the expansion buffer
4019 * again. We don't bother to remove the macro-end
4020 * marker: we'd only have to generate another one
4021 * if we did.
4022 */
4023 l->finishes->in_progress--;
4024 for (l = l->finishes->expansion; l; l = l->next) {
4025 Token *t, *tt, **tail;
H. Peter Anvin76690a12002-04-30 20:52:49 +00004026
H. Peter Anvine2c80182005-01-15 22:15:51 +00004027 ll = nasm_malloc(sizeof(Line));
4028 ll->next = istk->expansion;
4029 ll->finishes = NULL;
4030 ll->first = NULL;
4031 tail = &ll->first;
H. Peter Anvin76690a12002-04-30 20:52:49 +00004032
H. Peter Anvine2c80182005-01-15 22:15:51 +00004033 for (t = l->first; t; t = t->next) {
4034 if (t->text || t->type == TOK_WHITESPACE) {
4035 tt = *tail =
4036 new_Token(NULL, t->type, t->text, 0);
4037 tail = &tt->next;
4038 }
4039 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00004040
H. Peter Anvine2c80182005-01-15 22:15:51 +00004041 istk->expansion = ll;
4042 }
4043 } else {
4044 /*
4045 * Check whether a `%rep' was started and not ended
4046 * within this macro expansion. This can happen and
4047 * should be detected. It's a fatal error because
4048 * I'm too confused to work out how to recover
4049 * sensibly from it.
4050 */
4051 if (defining) {
4052 if (defining->name)
4053 error(ERR_PANIC,
4054 "defining with name in expansion");
4055 else if (istk->mstk->name)
4056 error(ERR_FATAL,
4057 "`%%rep' without `%%endrep' within"
4058 " expansion of macro `%s'",
4059 istk->mstk->name);
4060 }
H. Peter Anvin87bc6192002-04-30 20:53:16 +00004061
H. Peter Anvine2c80182005-01-15 22:15:51 +00004062 /*
4063 * FIXME: investigate the relationship at this point between
4064 * istk->mstk and l->finishes
4065 */
4066 {
4067 MMacro *m = istk->mstk;
4068 istk->mstk = m->next_active;
4069 if (m->name) {
4070 /*
4071 * This was a real macro call, not a %rep, and
4072 * therefore the parameter information needs to
4073 * be freed.
4074 */
4075 nasm_free(m->params);
4076 free_tlist(m->iline);
4077 nasm_free(m->paramlen);
H. Peter Anvin6867acc2007-10-10 14:58:45 -07004078 l->finishes->in_progress = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00004079 } else
4080 free_mmacro(m);
4081 }
4082 istk->expansion = l->next;
4083 nasm_free(l);
4084 list->downlevel(LIST_MACRO);
4085 }
4086 }
4087 while (1) { /* until we get a line we can use */
H. Peter Anvineba20a72002-04-30 20:53:55 +00004088
H. Peter Anvine2c80182005-01-15 22:15:51 +00004089 if (istk->expansion) { /* from a macro expansion */
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004090 char *p;
H. Peter Anvine2c80182005-01-15 22:15:51 +00004091 Line *l = istk->expansion;
4092 if (istk->mstk)
4093 istk->mstk->lineno++;
4094 tline = l->first;
4095 istk->expansion = l->next;
4096 nasm_free(l);
H. Peter Anvin6867acc2007-10-10 14:58:45 -07004097 p = detoken(tline, false);
H. Peter Anvine2c80182005-01-15 22:15:51 +00004098 list->line(LIST_MACRO, p);
4099 nasm_free(p);
4100 break;
4101 }
4102 line = read_line();
4103 if (line) { /* from the current input file */
4104 line = prepreproc(line);
Keith Kaniosb7a89542007-04-12 02:40:54 +00004105 tline = tokenize(line);
H. Peter Anvine2c80182005-01-15 22:15:51 +00004106 nasm_free(line);
4107 break;
4108 }
4109 /*
4110 * The current file has ended; work down the istk
4111 */
4112 {
4113 Include *i = istk;
4114 fclose(i->fp);
4115 if (i->conds)
4116 error(ERR_FATAL,
4117 "expected `%%endif' before end of file");
4118 /* only set line and file name if there's a next node */
4119 if (i->next) {
4120 src_set_linnum(i->lineno);
4121 nasm_free(src_set_fname(i->fname));
4122 }
4123 istk = i->next;
4124 list->downlevel(LIST_INCLUDE);
4125 nasm_free(i);
4126 if (!istk)
4127 return NULL;
4128 }
4129 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004130
H. Peter Anvine2c80182005-01-15 22:15:51 +00004131 /*
4132 * We must expand MMacro parameters and MMacro-local labels
4133 * _before_ we plunge into directive processing, to cope
4134 * with things like `%define something %1' such as STRUC
4135 * uses. Unless we're _defining_ a MMacro, in which case
4136 * those tokens should be left alone to go into the
4137 * definition; and unless we're in a non-emitting
4138 * condition, in which case we don't want to meddle with
4139 * anything.
4140 */
4141 if (!defining && !(istk->conds && !emitting(istk->conds->state)))
4142 tline = expand_mmac_params(tline);
H. Peter Anvin76690a12002-04-30 20:52:49 +00004143
H. Peter Anvine2c80182005-01-15 22:15:51 +00004144 /*
4145 * Check the line to see if it's a preprocessor directive.
4146 */
4147 if (do_directive(tline) == DIRECTIVE_FOUND) {
4148 continue;
4149 } else if (defining) {
4150 /*
4151 * We're defining a multi-line macro. We emit nothing
4152 * at all, and just
Keith Kaniosb7a89542007-04-12 02:40:54 +00004153 * shove the tokenized line on to the macro definition.
H. Peter Anvine2c80182005-01-15 22:15:51 +00004154 */
4155 Line *l = nasm_malloc(sizeof(Line));
4156 l->next = defining->expansion;
4157 l->first = tline;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07004158 l->finishes = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +00004159 defining->expansion = l;
4160 continue;
4161 } else if (istk->conds && !emitting(istk->conds->state)) {
4162 /*
4163 * We're in a non-emitting branch of a condition block.
4164 * Emit nothing at all, not even a blank line: when we
4165 * emerge from the condition we'll give a line-number
4166 * directive so we keep our place correctly.
4167 */
4168 free_tlist(tline);
4169 continue;
4170 } else if (istk->mstk && !istk->mstk->in_progress) {
4171 /*
4172 * We're in a %rep block which has been terminated, so
4173 * we're walking through to the %endrep without
4174 * emitting anything. Emit nothing at all, not even a
4175 * blank line: when we emerge from the %rep block we'll
4176 * give a line-number directive so we keep our place
4177 * correctly.
4178 */
4179 free_tlist(tline);
4180 continue;
4181 } else {
4182 tline = expand_smacro(tline);
4183 if (!expand_mmacro(tline)) {
4184 /*
Keith Kaniosb7a89542007-04-12 02:40:54 +00004185 * De-tokenize the line again, and emit it.
H. Peter Anvine2c80182005-01-15 22:15:51 +00004186 */
H. Peter Anvin6867acc2007-10-10 14:58:45 -07004187 line = detoken(tline, true);
H. Peter Anvine2c80182005-01-15 22:15:51 +00004188 free_tlist(tline);
4189 break;
4190 } else {
4191 continue; /* expand_mmacro calls free_tlist */
4192 }
4193 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004194 }
4195
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004196 return line;
4197}
4198
H. Peter Anvine2c80182005-01-15 22:15:51 +00004199static void pp_cleanup(int pass)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004200{
H. Peter Anvine2c80182005-01-15 22:15:51 +00004201 if (defining) {
4202 error(ERR_NONFATAL, "end of file while still defining macro `%s'",
4203 defining->name);
4204 free_mmacro(defining);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004205 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004206 while (cstk)
H. Peter Anvine2c80182005-01-15 22:15:51 +00004207 ctx_pop();
H. Peter Anvin97a23472007-09-16 17:57:25 -07004208 free_macros();
H. Peter Anvine2c80182005-01-15 22:15:51 +00004209 while (istk) {
4210 Include *i = istk;
4211 istk = istk->next;
4212 fclose(i->fp);
4213 nasm_free(i->fname);
4214 nasm_free(i);
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004215 }
4216 while (cstk)
H. Peter Anvine2c80182005-01-15 22:15:51 +00004217 ctx_pop();
4218 if (pass == 0) {
4219 free_llist(predef);
4220 delete_Blocks();
4221 }
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004222}
4223
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004224void pp_include_path(char *path)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004225{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004226 IncPath *i;
H. Peter Anvin37a321f2007-09-24 13:41:58 -07004227
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004228 i = nasm_malloc(sizeof(IncPath));
H. Peter Anvin37a321f2007-09-24 13:41:58 -07004229 i->path = path ? nasm_strdup(path) : NULL;
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004230 i->next = NULL;
4231
H. Peter Anvine2c80182005-01-15 22:15:51 +00004232 if (ipath != NULL) {
4233 IncPath *j = ipath;
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004234 while (j->next != NULL)
H. Peter Anvine2c80182005-01-15 22:15:51 +00004235 j = j->next;
4236 j->next = i;
4237 } else {
4238 ipath = i;
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004239 }
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004240}
Frank Kotlerd0ed6fd2003-08-27 11:33:56 +00004241
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004242void pp_pre_include(char *fname)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004243{
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004244 Token *inc, *space, *name;
4245 Line *l;
4246
H. Peter Anvin734b1882002-04-30 21:01:08 +00004247 name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
4248 space = new_Token(name, TOK_WHITESPACE, NULL, 0);
4249 inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004250
4251 l = nasm_malloc(sizeof(Line));
4252 l->next = predef;
4253 l->first = inc;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07004254 l->finishes = false;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004255 predef = l;
4256}
4257
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004258void pp_pre_define(char *definition)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004259{
4260 Token *def, *space;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004261 Line *l;
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004262 char *equals;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004263
4264 equals = strchr(definition, '=');
H. Peter Anvin734b1882002-04-30 21:01:08 +00004265 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4266 def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004267 if (equals)
H. Peter Anvine2c80182005-01-15 22:15:51 +00004268 *equals = ' ';
Keith Kaniosb7a89542007-04-12 02:40:54 +00004269 space->next = tokenize(definition);
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004270 if (equals)
H. Peter Anvine2c80182005-01-15 22:15:51 +00004271 *equals = '=';
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004272
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004273 l = nasm_malloc(sizeof(Line));
4274 l->next = predef;
4275 l->first = def;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07004276 l->finishes = false;
H. Peter Anvin6768eb72002-04-30 20:52:26 +00004277 predef = l;
4278}
4279
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004280void pp_pre_undefine(char *definition)
H. Peter Anvin620515a2002-04-30 20:57:38 +00004281{
4282 Token *def, *space;
4283 Line *l;
4284
H. Peter Anvin734b1882002-04-30 21:01:08 +00004285 space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
4286 def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
Keith Kaniosb7a89542007-04-12 02:40:54 +00004287 space->next = tokenize(definition);
H. Peter Anvin620515a2002-04-30 20:57:38 +00004288
4289 l = nasm_malloc(sizeof(Line));
4290 l->next = predef;
4291 l->first = def;
H. Peter Anvin6867acc2007-10-10 14:58:45 -07004292 l->finishes = false;
H. Peter Anvin620515a2002-04-30 20:57:38 +00004293 predef = l;
4294}
4295
Keith Kaniosb7a89542007-04-12 02:40:54 +00004296/*
4297 * Added by Keith Kanios:
4298 *
4299 * This function is used to assist with "runtime" preprocessor
4300 * directives. (e.g. pp_runtime("%define __BITS__ 64");)
4301 *
4302 * ERRORS ARE IGNORED HERE, SO MAKE COMPLETELY SURE THAT YOU
4303 * PASS A VALID STRING TO THIS FUNCTION!!!!!
4304 */
4305
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004306void pp_runtime(char *definition)
Keith Kaniosb7a89542007-04-12 02:40:54 +00004307{
4308 Token *def;
H. Peter Anvin70653092007-10-19 14:42:29 -07004309
Keith Kaniosb7a89542007-04-12 02:40:54 +00004310 def = tokenize(definition);
4311 if(do_directive(def) == NO_DIRECTIVE_FOUND)
4312 free_tlist(def);
H. Peter Anvin70653092007-10-19 14:42:29 -07004313
Keith Kaniosb7a89542007-04-12 02:40:54 +00004314}
4315
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004316void pp_extra_stdmac(const char **macros)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004317{
H. Peter Anvin76690a12002-04-30 20:52:49 +00004318 extrastdmac = macros;
4319}
4320
Keith Kaniosa5fc6462007-10-13 07:09:22 -07004321static void make_tok_num(Token * tok, int64_t val)
H. Peter Anvineba20a72002-04-30 20:53:55 +00004322{
Keith Kaniosa6dfa782007-04-13 16:47:53 +00004323 char numbuf[20];
Keith Kaniosa5fc6462007-10-13 07:09:22 -07004324 snprintf(numbuf, sizeof(numbuf), "%"PRId64"", val);
H. Peter Anvineba20a72002-04-30 20:53:55 +00004325 tok->text = nasm_strdup(numbuf);
4326 tok->type = TOK_NUMBER;
4327}
4328
H. Peter Anvind7ed89e2002-04-30 20:52:08 +00004329Preproc nasmpp = {
4330 pp_reset,
4331 pp_getline,
4332 pp_cleanup
4333};