145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* -*- mode: c; c-file-style: "bsd" -*- */ 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* preproc.c macro preprocessor for the Netwide Assembler 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The Netwide Assembler is copyright (C) 1996 Simon Tatham and 545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Julian Hall. All rights reserved. The software is 645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * redistributable under the licence given in the file "Licence" 745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * distributed in the NASM archive. 845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * initial version 18/iii/97 by Simon Tatham 1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Typical flow of text through preproc 1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * pp_getline gets tokenised lines, either 1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * from a macro expansion 1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * or 1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * { 2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * read_line gets raw text from stdmacpos, or predef, or current input file 2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * tokenise converts to tokens 2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * } 2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * expand_mmac_params is used to expand %1 etc., unless a macro is being 2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * defined or a false conditional is being processed 2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * (%0, %1, %+1, %-1, %%foo 2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * do_directive checks for directives 2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * expand_smacro is used to expand single line macros 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * expand_mmacro is used to expand multi-line macros 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * detoken is used to convert the line back to text 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <util.h> 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm-stdint.h> 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm/coretype.h> 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm/intnum.h> 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm/expr.h> 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm/file.h> 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <stdarg.h> 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <ctype.h> 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <limits.h> 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "nasm.h" 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "nasmlib.h" 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "nasm-pp.h" 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct SMacro SMacro; 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct MMacro MMacro; 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct Context Context; 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct Token Token; 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct Blocks Blocks; 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct Line Line; 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct Include Include; 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct Cond Cond; 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Store the definition of a single-line macro. 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct SMacro 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *next; 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *name; 66a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org int level; 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int casesense; 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int nparam; 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int in_progress; 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *expansion; 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Store the definition of a multi-line macro. This is also used to 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * store the interiors of `%rep...%endrep' blocks, which are 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * effectively self-re-invoking multi-line macros which simply 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * don't have a name or bother to appear in the hash tables. %rep 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * blocks are signified by having a NULL `name' field. 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * In a MMacro describing a `%rep' block, the `in_progress' field 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * isn't merely boolean, but gives the number of repeats left to 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * run. 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The `next' field is used for storing MMacros in hash tables; the 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * `next_active' field is for stacking them on istk entries. 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * When a MMacro is being expanded, `params', `iline', `nparam', 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * `paramlen', `rotate' and `unique' are local to the invocation. 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct MMacro 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *next; 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *name; 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int casesense; 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long nparam_min, nparam_max; 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int plus; /* is the last parameter greedy? */ 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int nolist; /* is this macro listing-inhibited? */ 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int in_progress; 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *dlist; /* All defaults as one list */ 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token **defaults; /* Parameter default pointers */ 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int ndefs; /* number of default parameters */ 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *expansion; 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *next_active; 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *rep_nest; /* used for nesting %rep */ 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token **params; /* actual parameters */ 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *iline; /* invocation line */ 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long nparam, rotate, *paramlen; 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long unique; 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int lineno; /* Current line number on expansion */ 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The context stack is composed of a linked list of these. 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct Context 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Context *next; 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *localmac; 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *name; 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long number; 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This is the internal form which we break input lines up into. 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Typically stored in linked lists. 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * necessarily used as-is, but is intended to denote the number of 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the substituted parameter. So in the definition 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %define a(x,y) ( (x) & ~(y) ) 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the token representing `x' will have its type changed to 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * TOK_SMAC_PARAM, but the one representing `y' will be 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * TOK_SMAC_PARAM+1. 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * TOK_INTERNAL_STRING is a dirty hack: it's a single string token 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * which doesn't need quotes around it. Used in the pre-include 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * mechanism as an alternative to trying to find a sensible type of 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * quote to use on the filename we were passed. 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct Token 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *next; 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *text; 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *mac; /* associated macro for TOK_SMAC_END */ 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int type; 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgenum 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING, 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM, 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TOK_INTERNAL_STRING 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Multi-line macro definitions are stored as a linked list of 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * these, which is essentially a container to allow several linked 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * lists of Tokens. 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Note that in this module, linked lists are treated as stacks 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * wherever possible. For this reason, Lines are _pushed_ on to the 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * `expansion' field in MMacro structures, so that the linked list, 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * if walked, would give the macro lines in reverse order; this 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * means that we can walk the list when expanding a macro, and thus 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * push the lines on to the `expansion' field in _istk_ in reverse 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * order (so that when popped back off they are in the right 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * order). It may seem cockeyed, and it relies on my design having 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * an even number of steps in, but it works... 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Some of these structures, rather than being actual lines, are 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * markers delimiting the end of the expansion of a given macro. 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This is for use in the cycle-tracking and %rep-handling code. 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Such structures have `finishes' non-NULL, and `first' NULL. All 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * others have `finishes' NULL, but `first' may still be NULL if 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the line is blank. 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct Line 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *next; 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *finishes; 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *first; 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * To handle an arbitrary level of file inclusion, we maintain a 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * stack (ie linked list) of these things. 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct Include 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Include *next; 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org FILE *fp; 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Cond *conds; 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *expansion; 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *fname; 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int lineno, lineinc; 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *mstk; /* stack of active macros/reps */ 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Conditional assembly: we maintain a separate stack of these for 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * each level of file inclusion. (The only reason we keep the 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * stacks separate is to ensure that a stray `%endif' in a file 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * included from within the true branch of a `%if' won't terminate 20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * it and cause confusion: instead, rightly, it'll cause an error.) 20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct Cond 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Cond *next; 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int state; 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgenum 21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * These states are for use just after %if or %elif: IF_TRUE 21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * means the condition has evaluated to truth so we are 21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * currently emitting, whereas IF_FALSE means we are not 21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * currently emitting but will start doing so if a %else comes 22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * up. In these states, all directives are admissible: %elif, 22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %else and %endif. (And of course %if.) 22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org COND_IF_TRUE, COND_IF_FALSE, 22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * These states come up after a %else: ELSE_TRUE means we're 22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * emitting, and ELSE_FALSE means we're not. In ELSE_* states, 22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * any %elif or %else will cause an error. 22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org COND_ELSE_TRUE, COND_ELSE_FALSE, 23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This state means that we're not emitting now, and also that 23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * nothing until %endif will be emitted at all. It's for use in 23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * two circumstances: (i) when we've had our moment of emission 23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and have now started seeing %elifs, and (ii) when the 23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * condition construct in question is contained within a 23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * non-emitting branch of a larger condition construct. 23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org COND_NEVER 23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE ) 24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * These defines are used as the possible return values for do_directive 24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define NO_DIRECTIVE_FOUND 0 24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define DIRECTIVE_FOUND 1 24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Condition codes. Note that we use c_ prefix not C_ because C_ is 25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * used in nasm.h for the "real" condition codes. At _this_ level, 25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * we treat CXZ and ECXZ as condition codes, albeit non-invertible 25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ones, so we need a different enum... 25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *conditions[] = { 25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le", 25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no", 25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "np", "ns", "nz", "o", "p", "pe", "po", "s", "z" 25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgenum 26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE, 26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO, 26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_S, c_Z 26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int inverse_ccs[] = { 26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE, 26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 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, 26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c_Z, c_NO, c_NP, c_PO, c_PE, c_NS, c_NZ 26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Directive names. 27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *directives[] = { 27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%arg", 27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef", 27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%elifid", "%elifidn", "%elifidni", "%elifmacro", "%elifnctx", "%elifndef", 27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%elifnid", "%elifnidn", "%elifnidni", "%elifnmacro", "%elifnnum", "%elifnstr", 27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro", 280a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org "%endrep", "%endscope", "%error", "%exitrep", "%iassign", "%idefine", "%if", 28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifmacro", "%ifnctx", 28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnmacro", "%ifnnum", 28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include", 28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%ixdefine", "%line", 28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%local", 28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%macro", "%pop", "%push", "%rep", "%repl", "%rotate", 287a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org "%scope", "%stacksize", 28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%strlen", "%substr", "%undef", "%xdefine" 28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgenum 29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_ARG, 29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_ASSIGN, PP_CLEAR, PP_DEFINE, PP_ELIF, PP_ELIFCTX, PP_ELIFDEF, 29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_ELIFID, PP_ELIFIDN, PP_ELIFIDNI, PP_ELIFMACRO, PP_ELIFNCTX, PP_ELIFNDEF, 29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_ELIFNID, PP_ELIFNIDN, PP_ELIFNIDNI, PP_ELIFNMACRO, PP_ELIFNNUM, PP_ELIFNSTR, 29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_ELIFNUM, PP_ELIFSTR, PP_ELSE, PP_ENDIF, PP_ENDM, PP_ENDMACRO, 297a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org PP_ENDREP, PP_ENDSCOPE, PP_ERROR, PP_EXITREP, PP_IASSIGN, PP_IDEFINE, PP_IF, 29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_IFCTX, PP_IFDEF, PP_IFID, PP_IFIDN, PP_IFIDNI, PP_IFMACRO, PP_IFNCTX, 29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_IFNDEF, PP_IFNID, PP_IFNIDN, PP_IFNIDNI, PP_IFNMACRO, PP_IFNNUM, 30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE, 30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_IXDEFINE, PP_LINE, 30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_LOCAL, 30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_MACRO, PP_POP, PP_PUSH, PP_REP, PP_REPL, PP_ROTATE, 304a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org PP_SCOPE, PP_STACKSIZE, 30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE 30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* If this is a an IF, ELIF, ELSE or ENDIF keyword */ 30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int is_condition(int arg) 31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ((arg >= PP_ELIF) && (arg <= PP_ENDIF)) || 31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ((arg >= PP_IF) && (arg <= PP_IFSTR)); 31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* For TASM compatibility we need to be able to recognise TASM compatible 31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * conditional compilation directives. Using the NASM pre-processor does 31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * not work, so we look for them specifically from the following list and 31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * then jam in the equivalent NASM directive into the input stream. 31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef MAX 32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org# define MAX(a,b) ( ((a) > (b)) ? (a) : (b)) 32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgenum 32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI, 32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TM_IFNDEF, TM_INCLUDE, TM_LOCAL, 32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TM_REPT, TM_IRP, TM_MACRO, 33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TM_STRUC, TM_SEGMENT 33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *tasm_directives[] = { 33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi", 33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "ifndef", "include", "local" 33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int StackSize = 4; 33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *StackPointer = "ebp"; 34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int ArgOffset = 8; 34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int LocalOffset = 4; 342a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgstatic int Level = 0; 34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Context *cstk; 34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Include *istk; 34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic FILE *first_fp = NULL; 34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic efunc _error; /* Pointer to client-provided error reporting function */ 35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic evalfunc evaluate; 35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int pass; /* HACK: pass 0 = generate dependencies only */ 35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic unsigned long unique; /* unique identifier numbers */ 35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Line *builtindef = NULL; 35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Line *stddef = NULL; 35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Line *predef = NULL; 36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int first_line = 1; 36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic ListGen *list; 36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The number of hash values we use for the macro lookup tables. 36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * FIXME: We should *really* be able to configure this at run time, 36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * or even have the hash table automatically expanding when necessary. 36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define NHASH 31 37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The current set of multi-line macros we have defined. 37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic MMacro *mmacros[NHASH]; 37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The current set of single-line macros we have defined. 37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic SMacro *smacros[NHASH]; 38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The multi-line macro we are currently defining, or the %rep 38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * block we are currently reading, if any. 38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic MMacro *defining; 38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The number of macro parameters to allocate space for at a time. 38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define PARAM_DELTA 16 39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Macros to make NASM ignore some TASM directives before the first include 39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * directive. 39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *tasm_compat_macros[] = 39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine IDEAL", 39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine JUMPS", 40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine END", 40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P8086 CPU 8086", 40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P186 CPU 186", 40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P286 CPU 286", 40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P286N CPU 286", 40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P286P CPU 286 Priv", 40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P386 CPU 386", 40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P386N CPU 386", 40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P386P CPU 386 Priv", 40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P486 CPU 486", 41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine P586 CPU 586", 41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .8086 CPU 8086", 41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .186 CPU 186", 41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .286 CPU 286", 41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .286C CPU 286", 41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .286P CPU 286", 41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .386 CPU 386", 41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .386C CPU 386", 41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .386P CPU 386", 41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .486 CPU 486", 42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .486C CPU 486", 42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .486P CPU 486", 42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .586 CPU 586", 42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .586C CPU 586", 42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine .586P CPU 586", 42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "", 42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%imacro TITLE 1", 42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endm", 42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%imacro NAME 1", 42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endm", 43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "", 43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%imacro EXTRN 1-*.nolist", 43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%rep %0", 43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "[extern %1]", 43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%rotate 1", 43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endrep", 43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endmacro", 43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "", 43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%imacro PUBLIC 1-*.nolist", 43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%rep %0", 44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "[global %1]", 44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%rotate 1", 44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endrep", 44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endmacro", 44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "", 44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "; this is not needed", 44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%idefine PTR", 44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL 44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int nested_mac_count, nested_rep_count; 45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Tokens are allocated in blocks to improve speed 45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TOKEN_BLOCKSIZE 4096 45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token *freeTokens = NULL; 45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct Blocks { 45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Blocks *next; 45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *chunk; 46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Blocks blocks = { NULL, NULL }; 46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Forward declarations. 46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token *expand_mmac_params(Token * tline); 46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token *expand_smacro(Token * tline); 46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token *expand_id(Token * tline); 47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Context *get_ctx(char *name, int all_contexts); 47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void make_tok_num(Token * tok, yasm_intnum *val); 47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void error(int severity, const char *fmt, ...); 47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void *new_Block(size_t size); 47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void delete_Blocks(void); 47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token *new_Token(Token * next, int type, const char *text, 47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t txtlen); 47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token *delete_Token(Token * t); 47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token *tokenise(char *line); 47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Macros for safe checking of token pointers, avoid *(NULL) 48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define tok_type_(x,t) ((x) && (x)->type == (t)) 48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next 48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v))) 48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v)))) 48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Handle TASM specific directives, which do not contain a % in 48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * front of them. We do it here because I could not find any other 49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * place to do it for the moment, and it is a hack (ideally it would 49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * be nice to be able to use the NASM pre-processor to do it). 49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct TMEndItem { 49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int type; 49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *data; 49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TMEndItem *next; 49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} TMEndItem; 49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic TMEndItem *EndmStack = NULL, *EndsStack = NULL; 50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgchar **TMParameters; 50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct TStrucField { 50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *name; 50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *type; 50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TStrucField *next; 50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct TStruc { 51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *name; 51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TStrucField *fields, *lastField; 51245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TStruc *next; 51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic struct TStruc *TStrucs = NULL; 51545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int inTstruc = 0; 51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct TSegmentAssume { 51845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *segreg; 51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *segment; 52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct TSegmentAssume *TAssumes; 52245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgconst char *tasm_get_segment_register(const char *segment) 52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TSegmentAssume *assume; 52645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!TAssumes) 52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (assume = TAssumes; assume->segreg; assume++) { 52945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(assume->segment, segment)) 53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return assume->segreg; 53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 53545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic char * 53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcheck_tasm_directive(char *line) 53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i, j, k, m; 53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t len, len2; 54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *p, *oldline, oldchar, *q, oldchar2; 54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TMEndItem *end; 54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = line; 54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Skip whitespace */ 546a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org while (isspace(*p) && *p != 0 && *p != ';') 54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Ignore nasm directives */ 55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*p == '%') 55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Binary search for the directive name */ 55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 555a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org while (!isspace(p[len]) && p[len] != 0 && p[len] != ';') 55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len++; 55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!len) 55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldchar = p[len]; 56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p[len] = 0; 56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = -1; 56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = elements(tasm_directives); 56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (j - i > 1) 56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org k = (j + i) / 2; 56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = nasm_stricmp(p, tasm_directives[k]); 56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m == 0) 56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* We have found a directive, so jam a % in front of it 57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * so that NASM will then recognise it as one if it's own. 57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p[len] = oldchar; 57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = strlen(p); 57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (k == TM_IFDIFI) 57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* NASM does not recognise IFDIFI, so we convert it to 57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %ifdef BOGUS. This is not used in NASM comaptible 58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * code, but does need to parse for the TASM macro 58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * package. 58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(13); 58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcpy(line, "%ifdef BOGUS"); 58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (k == TM_INCLUDE) 58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* add double quotes around file name */ 58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p += 7 + 1; 59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (isspace(*p) && *p) 59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = strlen(p); 59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(1 + 7 + 1 + 1 + len + 1 + 1); 59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line, "%%include \"%s\"", p); 59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(len + 2); 59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line[0] = '%'; 60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memcpy(line + 1, p, len + 1); 60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 60345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 60445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 60545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (m < 0) 60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = k; 60845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = k; 61145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Not a simple directive */ 61445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!nasm_stricmp(p, "endm")) { 61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle end of endm directive */ 61745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char **parameter; 61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end = EndmStack; 61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* undef parameters */ 62045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!end) { 62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "ENDM: not in an endm context"); 62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 62345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org EndmStack = EndmStack->next; 62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(line); 62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (end->type) { 62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TM_MACRO: 62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (parameter = end->data; *parameter; parameter++) 63045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += 6 + 1 + strlen(*parameter) + 1; 63145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += 5 + 1; 63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(len); 63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = line; 63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (parameter = end->data; *parameter; parameter++) { 63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p += sprintf(p, "%%undef %s\n", *parameter); 63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(*parameter); 63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(end->data); 63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(end); 64045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(p, "%%endm"); 64145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 64245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TM_REPT: 64345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(end); 64445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return nasm_strdup("%endrep"); 64545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TM_IRP: { 64645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char **data; 64745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *irp_format = 64845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%%undef %s\n" 64945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%%rotate 1\n" 65045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%%endrep\n" 65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%%endm\n" 65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "irp %s\n" 65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%%undef irp"; 65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data = end->data; 65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(strlen(irp_format) - 4 + strlen(data[0]) 65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org + strlen(data[1])); 65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line, irp_format, data[0], data[1]); 65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(data[0]); 65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(data[1]); 66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(data); 66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "ENDM: bogus endm context type %d\n",end->type); 66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 66745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(p, "end")) { 66845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(line); 66945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return nasm_strdup(""); 67045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(p, "rept")) { 67145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle repeat directive */ 67245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end = nasm_malloc(sizeof(*end)); 67345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->type = TM_REPT; 67445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->next = EndmStack; 67545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org EndmStack = end; 67645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memcpy(p, "%rep", 4); 67745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p[len] = oldchar; 67845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 67945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(p, "locals")) { 68045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tasm_locals = 1; 68145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(line); 68245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return nasm_strdup(""); 68345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 68445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 68545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!oldchar) 68645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 68745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 68845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle two-words directives */ 68945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q = p + len + 1; 69045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Skip whitespaces */ 69145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (isspace(*q) && *q) 69245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q++; 69345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 69445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len2 = 0; 69545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (!isspace(q[len2]) && q[len2]!=',' && q[len2] != 0) 69645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len2++; 69745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldchar2 = q[len2]; 69845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q[len2] = '\0'; 69945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 70045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!nasm_stricmp(p, "irp")) { 70145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle indefinite repeat directive */ 70245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *irp_format = 70345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%%imacro irp 0-*\n" 70445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%%rep %%0\n" 70545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%%define %s %%1\n"; 70645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char **data; 70745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 70845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data = malloc(2*sizeof(char*)); 70945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 71045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(strlen(irp_format) - 2 + len2 + 1); 71145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line,irp_format,q); 71245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data[0] = nasm_strdup(q); 71345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 71445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!oldchar2) 71545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "%s: expected <values>", q + len2); 71645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = strchr(q + len2 + 1, '<'); 71745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!p) 71845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "%s: expected <values>", q + len2); 71945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 72045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q = strchr(p, '>'); 72145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data[1] = nasm_strndup(p, q - p); 72245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 72345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end = nasm_malloc(sizeof(*end)); 72445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->type = TM_IRP; 72545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->next = EndmStack; 72645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->data = data; 72745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org EndmStack = end; 72845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 72945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 73045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 73145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(q, "macro")) { 73245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *name = p; 73345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle MACRO */ 73445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* count parameters */ 73545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = 1; 73645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = 0; 73745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TMParameters = nasm_malloc(j*sizeof(*TMParameters)); 73845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 73945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = q + len2 + 1; 74045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Skip whitespaces */ 74145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (isspace(*p) && *p) 74245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 74345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p) { 74445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Get parameter name */ 74545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (q = p; !isspace(*q) && *q != ',' && *q; q++); 74645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len2 = q-p; 74745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (len2 == 0) 74845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "'%s': expected parameter name", p); 74945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TMParameters[i] = nasm_malloc(len2 + 1); 75045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memcpy(TMParameters[i], p, len2); 75145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TMParameters[i][len2] = '\0'; 75245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += len2; 75345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i++; 75445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i + 1 > j) { 75545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j *= 2; 75645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TMParameters = nasm_realloc(TMParameters, 75745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j*sizeof(*TMParameters)); 75845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 75945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == 1000) 76045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "too many parameters for macro %s", name); 76145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = q; 76245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (isspace(*p) && *p) 76345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 76445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!*p) 76545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 76645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*p != ',') 76745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "expected comma"); 76845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 76945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (isspace(*p) && *p) 77045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 77145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 77245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TMParameters[i] = NULL; 77345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TMParameters = nasm_realloc(TMParameters, 77445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (i+1)*sizeof(*TMParameters)); 77545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += 1 + 6 + 1 + strlen(name) + 1 + 3; /* macro definition */ 77645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += i * (1 + 9 + 1 + 1 + 1 + 3 + 2); /* macro parameter definition */ 77745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 77845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = line = nasm_malloc(len + 1); 77945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p += sprintf(p, "%%imacro %s 0-*", name); 78045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 78145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (j = 0; TMParameters[j]; j++) { 78245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p += sprintf(p, "\n%%idefine %s %%{%-u}", TMParameters[j], j + 1); 78345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 78445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end = nasm_malloc(sizeof(*end)); 78545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->type = TM_MACRO; 78645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->next = EndmStack; 78745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->data = TMParameters; 78845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org EndmStack = end; 78945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 79045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(q, "proc")) { 79145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle PROC */ 79245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 79345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(2 + len + 1); 79445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line, "..%s",p); 79545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 79645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 79745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(q, "struc")) { 79845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle struc */ 79945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TStruc *struc; 80045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (inTstruc) { 80145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "STRUC: already in a struc context"); 80245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 80345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 80445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 80545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(5 + 1 + len + 1); 80645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line, "struc %s", p); 80745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struc = malloc(sizeof(*struc)); 80845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struc->name = nasm_strdup(p); 80945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struc->fields = NULL; 81045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struc->lastField = NULL; 81145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struc->next = TStrucs; 81245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TStrucs = struc; 81345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inTstruc = 1; 81445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 81545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end = nasm_malloc(sizeof(*end)); 81645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->type = TM_STRUC; 81745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->next = EndsStack; 81845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org EndsStack = end; 81945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 82045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(q, "segment")) { 82145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle SEGMENT */ 82245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 82345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_strdup(oldchar2?q+len2+1:""); 82445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tasm_segment) { 82545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "SEGMENT: already in a segment context"); 82645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 82745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 82845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tasm_segment = nasm_strdup(p); 82945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 83045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end = nasm_malloc(sizeof(*end)); 83145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->type = TM_SEGMENT; 83245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end->next = EndsStack; 83345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org EndsStack = end; 83445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 83545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(p, "ends") || !nasm_stricmp(q, "ends")) { 83645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle end of ends directive */ 83745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org end = EndsStack; 83845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* undef parameters */ 83945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!end) { 84045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "ENDS: not in an ends context"); 84145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 84245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 84345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org EndsStack = EndsStack->next; 84445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(line); 84545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (end->type) { 84645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TM_STRUC: 84745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inTstruc = 0; 84845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return nasm_strdup("endstruc"); 84945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TM_SEGMENT: 85045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* XXX: yes, we leak memory here, but that permits labels 85145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * to avoid strduping... */ 85245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tasm_segment = NULL; 85345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return nasm_strdup(""); 85445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 85545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "ENDS: bogus ends context type %d",end->type); 85645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 85745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 85845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(p, "endp") || !nasm_stricmp(q, "endp")) { 85945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(line); 86045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return nasm_strdup(""); 86145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!nasm_stricmp(p, "assume")) { 86245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TSegmentAssume *assume; 86345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* handle ASSUME */ 86445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!TAssumes) { 86545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAssumes = nasm_malloc(sizeof(*TAssumes)); 86645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAssumes[0].segreg = NULL; 86745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 86845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = 0; 86945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q[len2] = oldchar2; 87045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Skip whitespaces */ 87145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (isspace(*q) && *q) 87245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q++; 873a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org while (*q && *q != ';') { 87445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = q; 875a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (; *q && *q != ';' && *q != ':' && !isspace(*q); q++); 876a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (!*q || *q == ';') 87745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 87845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* segment register name */ 87945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (assume = TAssumes; assume->segreg; assume++) 88045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (strlen(assume->segreg) == (size_t)(q-p) && 88145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org !yasm__strncasecmp(assume->segreg, p, q-p)) 88245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 88345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!assume->segreg) { 88445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = assume - TAssumes + 1; 88545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAssumes = nasm_realloc(TAssumes, (i+1)*sizeof(*TAssumes)); 88645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assume = TAssumes + i - 1; 88745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assume->segreg = nasm_strndup(p, q-p); 88845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assume[1].segreg = NULL; 88945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 890a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (; *q && *q != ';' && *q != ':' && isspace(*q); q++); 89145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*q != ':') 89245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "expected `:' instead of `%c'", *q); 89345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (q++; *q && isspace(*q); q++); 89445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 89545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* segment name */ 89645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = q; 897a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (; *q && *q != ';' && *q != ',' && !isspace(*q); q++); 89845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assume->segment = nasm_strndup(p, q-p); 89945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (; *q && isspace(*q); q++); 900a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (*q && *q != ';' && *q != ',') 90145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "expected `,' instead of `%c'", *q); 90245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 903a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (*q && *q != ';') 904a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org q++; 905a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (; *q && isspace(*q); q++); 90645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 90745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAssumes[i].segreg = NULL; 90845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAssumes = nasm_realloc(TAssumes, (i+1)*sizeof(*TAssumes)); 90945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(line); 91045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return nasm_strdup(""); 91145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (inTstruc) { 91245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TStrucField *field; 91345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* TODO: handle unnamed data */ 91445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org field = nasm_malloc(sizeof(*field)); 91545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org field->name = nasm_strdup(p); 91645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* TODO: type struc ! */ 91745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org field->type = nasm_strdup(q); 91845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org field->next = NULL; 91945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!TStrucs->fields) 92045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TStrucs->fields = field; 92145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (TStrucs->lastField) 92245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TStrucs->lastField->next = field; 92345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TStrucs->lastField = field; 92445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!oldchar2) { 92545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "Expected struc field initializer after %s %s", p, q); 92645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 92745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 92845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 92945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(1 + len + 1 + len2 + 1 + strlen(q+len2+1) + 1); 93045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line, ".%s %s %s", p, q, q+len2+1); 93145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 93245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 93345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 93445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 93545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TStruc *struc; 93645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (struc = TStrucs; struc; struc = struc->next) { 93745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!yasm__strcasecmp(q, struc->name)) { 93845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *r = q + len2 + 1, *s, *t, tasm_param[6]; 93945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct TStrucField *field = struc->fields; 94045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int size, n; 94145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!oldchar2) { 94245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "Expected struc field initializer after %s %s", p, q); 94345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 94445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 94545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org r = strchr(r, '<'); 94645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!r) { 94745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "Expected < for struc field initializer in %s %s %s", p, q, r); 94845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 94945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 95045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = strchr(r + 1, '>'); 95145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!t) { 95245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "Expected > for struc field initializer in %s %s %s", p, q, r); 95345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 95445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 95545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *t = 0; 95645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 95745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = len + len2 + 128; 95845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(size); 95945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defining) 96045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (n=0;TMParameters[n];n++) 96145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(TMParameters[n],p)) { 96245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(tasm_param,"%%{%d}",n+1); 96345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = tasm_param; 96445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 96545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 96645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org n = sprintf(line, "%s: istruc %s\n", p, q); 96745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* use initialisers */ 96845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while ((s = strchr(r + 1, ','))) { 96945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!field) { 97045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "Too many initializers in structure %s %s", p, q); 97145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return oldline; 97245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 97345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *s = 0; 97445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = strlen(p) + 1 + strlen(field->name)*2 + 8 + 97545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strlen(field->type) + 1 + strlen(r+1) + 2; 97645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size += m; 97745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_realloc(line, size); 97845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line + n, "%s.%s: at .%s, %s %s\n", 97945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p, field->name, field->name, field->type, r + 1); 98045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org n += m-1; 98145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org r = s; 98245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org field = field->next; 98345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 98445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* complete with last initializer and '?' */ 98545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while(field) { 98645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = strlen(p) + 1 + strlen(field->name)*2 + 8 + 98745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strlen(field->type) + 1 + (r ? strlen(r+1) : 1) + 2; 98845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size += m; 98945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_realloc(line, size); 99045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line + n, "%s.%s: at .%s, %s %s\n", p, field->name, 99145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org field->name, field->type, r ? r + 1: "?"); 99245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org n += m-1; 99345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org r = NULL; 99445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org field = field->next; 99545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 99645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_realloc(line, n + 5); 99745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line + n, "iend"); 99845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 99945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 100045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 100145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 100245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 100345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 100445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q[len2] = oldchar2; 100545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p[len] = oldchar; 100645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 100745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 100845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 100945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 101045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token * tasm_join_tokens(Token *tline) 101145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 101245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t, *prev, *next; 101345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (prev = NULL, t = tline; t; prev = t, t = next) { 101445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org next = t->next; 101545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type == TOK_OTHER && !strcmp(t->text,"&")) { 101645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!prev) 101745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "no token before &"); 101845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (!next) 101945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "no token after &"); 102045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (prev->type != next->type) 102145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "can't handle different types of token around &"); 102245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (!prev->text || !next->text) 102345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "can't handle empty token around &"); 102445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 102545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int lenp = strlen(prev->text); 102645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int lenn = strlen(next->text); 102745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org prev->text = nasm_realloc(prev->text, lenp + lenn + 1); 102845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strncpy(prev->text + lenp, next->text, lenn + 1); 102945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (void) delete_Token(t); 103045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org prev->next = delete_Token(next); 103145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = prev; 103245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org next = t->next; 103345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 103445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 103545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 103645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tline; 103745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 103845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 103945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 104045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The pre-preprocessing stage... This function translates line 104145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * number indications as they emerge from GNU cpp (`# lineno "file" 104245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * flags') into NASM preprocessor line number indications (`%line 104345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * lineno file'). 104445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 104545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic char * 104645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgprepreproc(char *line) 104745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 104845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int lineno; 104945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t fnlen; 105045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *fname, *oldline; 105145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *c, *d, *ret; 105245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l, **lp; 105345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 105445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (line[0] == '#' && line[1] == ' ') 105545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 105645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldline = line; 105745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fname = oldline + 2; 105845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lineno = atoi(fname); 105945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fname += strspn(fname, "0123456789 "); 106045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*fname == '"') 106145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fname++; 106245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fnlen = strcspn(fname, "\""); 106345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = nasm_malloc(20 + fnlen); 106445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(line, "%%line %d %.*s", lineno, (int)fnlen, fname); 106545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(oldline); 106645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 106745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tasm_compatible_mode) 106845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = check_tasm_directive(line); 106945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 107045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!(c = strchr(line, '\n'))) 107145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 107245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 107345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Turn multiline macros into several lines */ 107445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *c = '\0'; 107545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = nasm_strdup(line); 107645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 107745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lp = &istk->expansion; 107845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do { 107945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org d = strchr(c+1, '\n'); 108045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (d) 108145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *d = '\0'; 108245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = malloc(sizeof(*l)); 108345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l -> first = tokenise(c+1); 108445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l -> finishes = NULL; 108545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l -> next = *lp; 108645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *lp = l; 108745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = d; 108845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lp = &l -> next; 108945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } while (c); 109045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(line); 109145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ret; 109245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 109345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 109445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 109545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The hash function for macro lookups. Note that due to some 109645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * macros having case-insensitive names, the hash function must be 109745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * invariant under case changes. We implement this by applying a 109845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * perfectly normal hash function to the uppercase of the string. 109945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 110045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 110145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orghash(char *s) 110245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 110345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int h = 0; 110445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int i = 0; 110545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 110645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Powers of three, mod 31. 110745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 110845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org static const int multipliers[] = { 110945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 111045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21 111145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org }; 111245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 111345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 111445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*s) 111545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 111645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org h += multipliers[i] * (unsigned char) (toupper(*s)); 111745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s++; 111845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (++i >= elements(multipliers)) 111945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = 0; 112045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 112145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org h %= NHASH; 112245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return h; 112345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 112445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 112545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 112645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Free a linked list of tokens. 112745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 112845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 112945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfree_tlist(Token * list_) 113045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 113145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (list_) 113245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 113345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list_ = delete_Token(list_); 113445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 113545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 113645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 113745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 113845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Free a linked list of lines. 113945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 114045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 114145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfree_llist(Line * list_) 114245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 114345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l; 114445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (list_) 114545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 114645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = list_; 114745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list_ = list_->next; 114845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(l->first); 114945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(l); 115045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 115145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 115245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 115345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 115445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Free an MMacro 115545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 115645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 115745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfree_mmacro(MMacro * m) 115845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 115945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(m->name); 116045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(m->dlist); 116145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(m->defaults); 116245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_llist(m->expansion); 116345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(m); 116445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 116545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 116645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 116745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Pop the context stack. 116845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 116945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 117045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgctx_pop(void) 117145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 117245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Context *c = cstk; 117345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *smac, *s; 117445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 117545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cstk = cstk->next; 117645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac = c->localmac; 117745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (smac) 117845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 117945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = smac; 118045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac = smac->next; 118145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(s->name); 118245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(s->expansion); 118345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(s); 118445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 118545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(c->name); 118645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(c); 118745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 118845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 118945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define BUF_DELTA 512 119045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 119145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Read a line from the top file in istk, handling multiple CR/LFs 119245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * at the end of the line read, and handling spurious ^Zs. Will 119345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * return lines from the standard macro set if this has not already 119445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * been done. 119545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 119645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic char * 119745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgread_line(void) 119845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 119945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *buffer, *p, *q; 120045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int bufsize, continued_count; 120145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 120245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bufsize = BUF_DELTA; 120345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buffer = nasm_malloc(BUF_DELTA); 120445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = buffer; 120545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continued_count = 0; 120645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (1) 120745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 120845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q = fgets(p, bufsize - (int)(p - buffer), istk->fp); 120945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!q) 121045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 121145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p += strlen(p); 121245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (p > buffer && p[-1] == '\n') 121345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 121445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Convert backslash-CRLF line continuation sequences into 121545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nothing at all (for DOS and Windows) */ 121645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (((p - 2) > buffer) && (p[-3] == '\\') && (p[-2] == '\r')) { 121745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p -= 3; 121845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p = 0; 121945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continued_count++; 122045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 122145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Also convert backslash-LF line continuation sequences into 122245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nothing at all (for Unix) */ 122345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (((p - 1) > buffer) && (p[-2] == '\\')) { 122445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p -= 2; 122545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p = 0; 122645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continued_count++; 122745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 122845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 122945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 123045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 123145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 123245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (p - buffer > bufsize - 10) 123345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 123445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long offset = (long)(p - buffer); 123545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bufsize += BUF_DELTA; 123645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buffer = nasm_realloc(buffer, (size_t)bufsize); 123745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = buffer + offset; /* prevent stale-pointer problems */ 123845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 123945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 124045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 124145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!q && p == buffer) 124245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 124345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(buffer); 124445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 124545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 124645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 124745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_src_set_linnum(nasm_src_get_linnum() + istk->lineinc + (continued_count * istk->lineinc)); 124845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 124945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 125045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Play safe: remove CRs as well as LFs, if any of either are 125145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * present at the end of the line. 125245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 125345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (--p >= buffer && (*p == '\n' || *p == '\r')) 125445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p = '\0'; 125545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 125645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 125745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Handle spurious ^Z, which may be inserted into source files 125845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * by some file transfer utilities. 125945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 126045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buffer[strcspn(buffer, "\032")] = '\0'; 126145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 126245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list->line(LIST_READ, buffer); 126345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 126445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return buffer; 126545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 126645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 126745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 126845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Tokenise a line of text. This is a very simple process since we 126945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * don't need to parse the value out of e.g. numeric tokens: we 127045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * simply split one string into many. 127145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 127245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token * 127345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtokenise(char *line) 127445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 127545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *p = line; 127645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int type; 127745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *list_ = NULL; 127845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t, **tail = &list_; 127945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 128045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*line) 128145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 128245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = line; 128345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*p == '%') 128445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 128545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 128645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ( isdigit(*p) || 128745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ((*p == '-' || *p == '+') && isdigit(p[1])) || 128845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ((*p == '+') && (isspace(p[1]) || !p[1]))) 128945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 129045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do 129145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 129245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 129345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 129445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (isdigit(*p)); 129545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_PREPROC_ID; 129645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 129745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (*p == '{') 129845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 129945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 130045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p && *p != '}') 130145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 130245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p[-1] = *p; 130345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 130445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 130545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p[-1] = '\0'; 130645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*p) 130745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 130845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_PREPROC_ID; 130945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 131045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (isidchar(*p) || 131145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ((*p == '!' || *p == '%' || *p == '$') && 131245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org isidchar(p[1]))) 131345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 131445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do 131545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 131645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 131745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 131845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (isidchar(*p)); 131945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_PREPROC_ID; 132045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 132145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 132245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 132345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_OTHER; 132445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*p == '%') 132545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 132645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 132745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 132845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (isidstart(*p) || (*p == '$' && isidstart(p[1]))) 132945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 133045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_ID; 133145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 133245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p && isidchar(*p)) 133345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 133445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 133545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (*p == '\'' || *p == '"') 133645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 133745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 133845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * A string token. 133945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 134045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char c = *p; 134145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 134245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_STRING; 134345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p && *p != c) 134445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 134545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 134645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*p) 134745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 134845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 134945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 135045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 135145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 135245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, "unterminated string"); 135345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = -1; 135445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 135545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 135645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (isnumstart(*p)) 135745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 135845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 135945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * A number token. 136045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 136145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_NUMBER; 136245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 136345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p && isnumchar(*p)) 136445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 136545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 136645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (isspace(*p)) 136745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 136845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_WHITESPACE; 136945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 137045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p && isspace(*p)) 137145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 137245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 137345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Whitespace just before end-of-line is discarded by 137445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * pretending it's a comment; whitespace just before a 137545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * comment gets lumped into the comment. 137645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 137745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!*p || *p == ';') 137845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 137945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_COMMENT; 138045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p) 138145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 138245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 138345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 138445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (*p == ';') 138545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 138645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_COMMENT; 138745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p) 138845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 138945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 139045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 139145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 139245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 139345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Anything else is an operator of some kind. We check 139445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * for all the double-character operators (>>, <<, //, 139545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything 139645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * else is a single-character operator. 139745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 139845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org type = TOK_OTHER; 139945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((p[0] == '>' && p[1] == '>') || 140045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '<' && p[1] == '<') || 140145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '/' && p[1] == '/') || 140245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '<' && p[1] == '=') || 140345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '>' && p[1] == '=') || 140445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '=' && p[1] == '=') || 140545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '!' && p[1] == '=') || 140645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '<' && p[1] == '>') || 140745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '&' && p[1] == '&') || 140845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '|' && p[1] == '|') || 140945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (p[0] == '^' && p[1] == '^')) 141045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 141145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 141245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 141345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 141445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 141545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 141645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Handle unterminated string */ 141745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (type == -1) 141845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 141945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = t = new_Token(NULL, TOK_STRING, line, (size_t)(p-line)+1); 142045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text[p-line] = *line; 142145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &t->next; 142245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 142345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (type != TOK_COMMENT) 142445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 142545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = t = new_Token(NULL, type, line, (size_t)(p - line)); 142645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &t->next; 142745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 142845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = p; 142945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 143045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return list_; 143145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 143245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 143345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 143445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * this function allocates a new managed block of memory and 143545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * returns a pointer to the block. The managed blocks are 143645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * deleted only all at once by the delete_Blocks function. 143745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 143845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void * 143945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnew_Block(size_t size) 144045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 144145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Blocks *b = &blocks; 144245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 144345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* first, get to the end of the linked list */ 144445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (b->next) 144545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org b = b->next; 144645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* now allocate the requested chunk */ 144745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org b->chunk = nasm_malloc(size); 144845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 144945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* now allocate a new block for the next request */ 145045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org b->next = nasm_malloc(sizeof(Blocks)); 145145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* and initialize the contents of the new block */ 145245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org b->next->next = NULL; 145345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org b->next->chunk = NULL; 145445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return b->chunk; 145545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 145645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 145745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 145845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * this function deletes all managed blocks of memory 145945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 146045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 146145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdelete_Blocks(void) 146245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 146345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Blocks *a,*b = &blocks; 146445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 146545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 146645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * keep in mind that the first block, pointed to by blocks 146745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * is a static and not dynamically allocated, so we don't 146845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * free it. 146945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 147045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (b) 147145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 147245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (b->chunk) 147345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(b->chunk); 147445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org a = b; 147545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org b = b->next; 147645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (a != &blocks) 147745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(a); 147845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 147945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 148045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 148145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 148245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * this function creates a new Token and passes a pointer to it 148345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * back to the caller. It sets the type and text elements, and 148445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * also the mac and next elements to NULL. 148545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 148645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token * 148745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnew_Token(Token * next, int type, const char *text, size_t txtlen) 148845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 148945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t; 149045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i; 149145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 149245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (freeTokens == NULL) 149345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 149445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org freeTokens = (Token *)new_Block(TOKEN_BLOCKSIZE * sizeof(Token)); 149545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++) 149645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org freeTokens[i].next = &freeTokens[i + 1]; 149745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org freeTokens[i].next = NULL; 149845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 149945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = freeTokens; 150045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org freeTokens = t->next; 150145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = next; 150245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->mac = NULL; 150345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->type = type; 150445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (type == TOK_WHITESPACE || text == NULL) 150545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 150645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = NULL; 150745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 150845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 150945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 151045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (txtlen == 0) 151145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org txtlen = strlen(text); 151245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = nasm_malloc(1 + txtlen); 151345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strncpy(t->text, text, txtlen); 151445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text[txtlen] = '\0'; 151545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 151645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return t; 151745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 151845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 151945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token * 152045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdelete_Token(Token * t) 152145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 152245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *next = t->next; 152345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(t->text); 152445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = freeTokens; 152545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org freeTokens = t; 152645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return next; 152745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 152845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 152945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 153045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Convert a line of tokens back into text. 153145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If expand_locals is not zero, identifiers of the form "%$*xxx" 153245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * will be transformed into ..@ctxnum.xxx 153345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 153445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic char * 153545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdetoken(Token * tlist, int expand_locals) 153645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 153745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t; 153845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t len; 153945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *line, *p; 154045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 154145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = 0; 154245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (t = tlist; t; t = t->next) 154345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 154445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type == TOK_PREPROC_ID && t->text[1] == '!') 154545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 154645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *p2 = getenv(t->text + 2); 154745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(t->text); 154845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (p2) 154945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = nasm_strdup(p2); 155045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 155145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = NULL; 155245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 155345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Expand local macros here and not during preprocessing */ 155445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (expand_locals && 155545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->type == TOK_PREPROC_ID && t->text && 155645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text[0] == '%' && t->text[1] == '$') 155745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 155845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Context *ctx = get_ctx(t->text, FALSE); 155945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ctx) 156045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 156145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char buffer[40]; 156245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *p2, *q = t->text + 2; 156345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 156445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q += strspn(q, "$"); 156545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(buffer, "..@%lu.", ctx->number); 156645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p2 = nasm_strcat(buffer, q); 156745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(t->text); 156845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = p2; 156945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 157045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 157145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type == TOK_WHITESPACE) 157245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 157345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len++; 157445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 157545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (t->text) 157645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 157745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len += strlen(t->text); 157845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 157945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 158045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = line = nasm_malloc(len + 1); 158145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (t = tlist; t; t = t->next) 158245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 158345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type == TOK_WHITESPACE) 158445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 158545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p = ' '; 158645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p++; 158745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p = '\0'; 158845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 158945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (t->text) 159045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 159145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcpy(p, t->text); 159245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p += strlen(p); 159345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 159445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 159545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p = '\0'; 159645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 159745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 159845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 159945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 160045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * A scanner, suitable for use by the expression evaluator, which 160145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * operates on a line of Tokens. Expects a pointer to a pointer to 160245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the first token in the line to be passed in as its private_data 160345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * field. 160445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 160545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 160645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgppscan(void *private_data, struct tokenval *tokval) 160745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 160845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token **tlineptr = private_data; 160945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *tline; 161045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 161145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do 161245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 161345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = *tlineptr; 161445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tlineptr = tline ? tline->next : NULL; 161545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 161645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tline && (tline->type == TOK_WHITESPACE || 161745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->type == TOK_COMMENT)); 161845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 161945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline) 162045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_EOS; 162145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 162245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->text[0] == '$' && !tline->text[1]) 162345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_HERE; 162445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[2]) 162545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_BASE; 162645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 162745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_ID) 162845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 162945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval->t_charptr = tline->text; 163045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->text[0] == '$') 163145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 163245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval->t_charptr++; 163345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_ID; 163445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 163545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 163645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 163745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This is the only special case we actually need to worry 163845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * about in this restricted context. 163945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 164045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!nasm_stricmp(tline->text, "seg")) 164145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_SEG; 164245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 164345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_ID; 164445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 164545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 164645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_NUMBER) 164745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 164845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int rn_error; 164945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 165045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval->t_integer = nasm_readnum(tline->text, &rn_error); 165145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (rn_error) 165245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_ERRNUM; 165345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval->t_charptr = NULL; 165445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_NUM; 165545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 165645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 165745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_STRING) 165845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 165945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int rn_warn; 166045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char q, *r; 166145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t l; 166245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 166345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org r = tline->text; 166445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org q = *r++; 166545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = strlen(r); 166645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 166745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (l == 0 || r[l - 1] != q) 166845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_ERRNUM; 166945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval->t_integer = nasm_readstrnum(r, l - 1, &rn_warn); 167045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (rn_warn) 167145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING | ERR_PASS1, "character constant too long"); 167245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval->t_charptr = NULL; 167345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_NUM; 167445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 167545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 167645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_OTHER) 167745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 167845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "<<")) 167945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_SHL; 168045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, ">>")) 168145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_SHR; 168245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "//")) 168345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_SDIV; 168445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "%%")) 168545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_SMOD; 168645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "==")) 168745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_EQ; 168845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "<>")) 168945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_NE; 169045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "!=")) 169145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_NE; 169245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "<=")) 169345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_LE; 169445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, ">=")) 169545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_GE; 169645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "&&")) 169745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_DBL_AND; 169845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "^^")) 169945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_DBL_XOR; 170045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(tline->text, "||")) 170145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = TOKEN_DBL_OR; 170245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 170345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 170445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 170545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We have no other options: just return the first character of 170645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the token text. 170745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 170845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tokval->t_type = tline->text[0]; 170945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 171045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 171145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 171245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Compare a string to the name of an existing macro; this is a 171345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * simple wrapper which calls either strcmp or nasm_stricmp 171445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * depending on the value of the `casesense' parameter. 171545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 171645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 171745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmstrcmp(char *p, char *q, int casesense) 171845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 171945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return casesense ? strcmp(p, q) : nasm_stricmp(p, q); 172045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 172145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 172245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 172345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Return the Context structure associated with a %$ token. Return 172445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * NULL, having _already_ reported an error condition, if the 172545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * context stack isn't deep enough for the supplied number of $ 172645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * signs. 172745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If all_contexts == TRUE, contexts that enclose current are 172845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * also scanned for such smacro, until it is found; if not - 172945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * only the context that directly results from the number of $'s 173045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * in variable's name. 173145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 173245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Context * 173345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgget_ctx(char *name, int all_contexts) 173445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 173545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Context *ctx; 173645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *m; 173745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t i; 173845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 173945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!name || name[0] != '%' || name[1] != '$') 174045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 174145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 174245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!cstk) 174345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 174445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%s': context stack is empty", name); 174545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 174645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 174745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 174845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--) 174945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 175045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = ctx->next; 175145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* i--; Lino - 02/25/02 */ 175245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 175345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!ctx) 175445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 175545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%s': context stack is only" 175645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org " %d level%s deep", name, i - 1, (i == 2 ? "" : "s")); 175745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 175845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 175945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!all_contexts) 176045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ctx; 176145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 176245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do 176345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 176445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Search for this smacro in found context */ 176545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = ctx->localmac; 176645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (m) 176745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 176845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!mstrcmp(m->name, name, m->casesense)) 176945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ctx; 177045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = m->next; 177145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 177245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = ctx->next; 177345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 177445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (ctx); 177545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 177645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 177745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 177845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 177945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Open an include file. This routine must always return a valid 178045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * file pointer if it returns - it's responsible for throwing an 178145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ERR_FATAL and bombing out completely if not. It should also try 178245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the include path one by one until it finds the file or reaches 178345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the end of the path. 178445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 178545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic FILE * 178645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orginc_fopen(char *file, char **newname) 178745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 178845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org FILE *fp; 178945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *combine = NULL, *c; 179045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *pb, *p1, *p2, *file2 = NULL; 179145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 179245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Try to expand all %ENVVAR% in filename. Warn, and leave %string% 179345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * intact, if ENVVAR is not set in the environment. 179445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 179545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pb = file; 179645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p1 = pb; 179745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (;;) { 179845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *env; 179945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p1 != '\0' && *p1 != '%') 180045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p1++; 180145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*p1 == '\0') 180245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 180345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p2 = p1+1; 180445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*p2 != '\0' && *p2 != '%') 180545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p2++; 180645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*p2 == '\0') 180745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 180845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Okay, we have a %...%, with p1 pointing to the first %, and p2 180945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * pointing to the second %. 181045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 181145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p2 = '\0'; 181245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org env = getenv(p1+1); 181345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!env) { 181445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* warn, restore %, and continue looking */ 181545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, "environment variable `%s' does not exist", 181645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p1+1); 181745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p2 = '%'; 181845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p1 = p2+1; 181945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 182045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 182145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* need to expand */ 182245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!file2) { 182345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org file2 = nasm_malloc(strlen(file)+strlen(env)+1); 182445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org file2[0] = '\0'; 182545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 182645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org file2 = nasm_realloc(file2, strlen(file2)+strlen(env)+1); 182745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p1 = '\0'; 182845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcat(file2, pb); 182945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcat(file2, env); 183045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pb = p2+1; 183145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p1 = pb; 183245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 183345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* add tail end; string is long enough that we don't need to realloc */ 183445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (file2) 183545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcat(file2, pb); 183645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 183745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fp = yasm_fopen_include(file2 ? file2 : file, nasm_src_get_fname(), "r", 183845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &combine); 183945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!fp && tasm_compatible_mode) 184045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 184145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *thefile = file2 ? file2 : file; 184245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* try a few case combinations */ 184345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do { 184445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (c = thefile; *c; c++) 184545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *c = toupper(*c); 184645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fp = yasm_fopen_include(thefile, nasm_src_get_fname(), "r", &combine); 184745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fp) break; 184845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *thefile = tolower(*thefile); 184945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fp = yasm_fopen_include(thefile, nasm_src_get_fname(), "r", &combine); 185045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fp) break; 185145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (c = thefile; *c; c++) 185245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *c = tolower(*c); 185345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fp = yasm_fopen_include(thefile, nasm_src_get_fname(), "r", &combine); 185445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fp) break; 185545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *thefile = toupper(*thefile); 185645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fp = yasm_fopen_include(thefile, nasm_src_get_fname(), "r", &combine); 185745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fp) break; 185845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } while (0); 185945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 186045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!fp) 186145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "unable to open include file `%s'", 186245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org file2 ? file2 : file); 186345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_preproc_add_dep(combine); 186445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 186545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (file2) 186645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(file2); 186745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 186845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *newname = combine; 186945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return fp; 187045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 187145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 187245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 187345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Determine if we should warn on defining a single-line macro of 187445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * name `name', with `nparam' parameters. If nparam is 0 or -1, will 187545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * return TRUE if _any_ single-line macro of that name is defined. 187645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Otherwise, will return TRUE if a single-line macro with either 187745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * `nparam' or no parameters is defined. 187845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 187945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If a macro with precisely the right number of parameters is 188045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * defined, or nparam is -1, the address of the definition structure 188145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * will be returned in `defn'; otherwise NULL will be returned. If `defn' 188245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * is NULL, no action will be taken regarding its contents, and no 188345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * error will occur. 188445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 188545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Note that this is also called with nparam zero to resolve 188645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * `ifdef'. 188745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 188845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If you already know which context macro belongs to, you can pass 188945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the context pointer as first parameter; if you won't but name begins 189045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * with %$ the context will be automatically computed. If all_contexts 189145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * is true, macro will be searched in outer contexts as well. 189245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 189345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 189445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsmacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn, 189545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int nocase) 189645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 189745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *m; 1898a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org int highest_level = -1; 189945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 190045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ctx) 190145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = ctx->localmac; 190245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (name[0] == '%' && name[1] == '$') 190345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 190445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (cstk) 190545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = get_ctx(name, FALSE); 190645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!ctx) 190745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return FALSE; /* got to return _something_ */ 190845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = ctx->localmac; 190945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 191045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 191145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = smacros[hash(name)]; 191245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 191345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (m) 191445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 191545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!mstrcmp(m->name, name, m->casesense && nocase) && 1916a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org (nparam <= 0 || m->nparam == 0 || nparam == m->nparam) && (highest_level < 0 || m->level > highest_level)) 191745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 1918a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org highest_level = m->level; 191945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defn) 192045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 192145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (nparam == m->nparam || nparam == -1) 192245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *defn = m; 192345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 192445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *defn = NULL; 192545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 192645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 192745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = m->next; 192845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 192945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1930a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org return highest_level >= 0; 193145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 193245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 193345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 193445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Count and mark off the parameters in a multi-line macro call. 193545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This is called both from within the multi-line macro expansion 193645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * code, and also to mark off the default parameters when provided 193745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * in a %macro definition line. 193845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 193945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 194045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcount_mmac_params(Token * t, int *nparam, Token *** params) 194145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 194245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int paramsize, brace; 194345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 194445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *nparam = paramsize = 0; 194545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *params = NULL; 194645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (t) 194745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 194845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*nparam+1 >= paramsize) 194945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 195045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramsize += PARAM_DELTA; 195145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *params = nasm_realloc(*params, sizeof(**params) * paramsize); 195245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 195345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(t); 195445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org brace = FALSE; 195545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_is_(t, "{")) 195645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org brace = TRUE; 195745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (*params)[(*nparam)++] = t; 195845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tok_isnt_(t, brace ? "}" : ",")) 195945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 196045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t) 196145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { /* got a comma/brace */ 196245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 196345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (brace) 196445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 196545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 196645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Now we've found the closing brace, look further 196745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * for the comma. 196845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 196945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(t); 197045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_isnt_(t, ",")) 197145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 197245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 197345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "braces do not enclose all of macro parameter"); 197445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tok_isnt_(t, ",")) 197545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 197645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 197745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t) 197845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; /* eat the comma */ 197945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 198045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 198145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 198245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 198345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 198445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 198545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Determine whether one of the various `if' conditions is true or 198645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * not. 198745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 198845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We must free the tline we get passed. 198945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 199045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 199145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgif_condition(Token * tline, int i) 199245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 199345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int j, casesense; 199445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t, *tt, **tptr, *origline; 199545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct tokenval tokval; 199645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr *evalresult; 199745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn; 199845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 199945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org origline = tline; 200045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 200145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (i) 200245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 200345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFCTX: 200445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFCTX: 200545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNCTX: 200645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNCTX: 200745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = FALSE; /* have we matched yet? */ 200845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (cstk && tline) 200945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 201045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 201145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || tline->type != TOK_ID) 201245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 201345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 201445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%s' expects context identifiers", 201545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 201645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 201745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 201845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 201945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!nasm_stricmp(tline->text, cstk->name)) 202045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = TRUE; 202145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 202245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 202345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_IFNCTX || i == PP_ELIFNCTX) 202445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = !j; 202545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 202645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return j; 202745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 202845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFDEF: 202945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFDEF: 203045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNDEF: 203145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNDEF: 203245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = FALSE; /* have we matched yet? */ 203345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tline) 203445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 203545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 203645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || (tline->type != TOK_ID && 203745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (tline->type != TOK_PREPROC_ID || 203845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text[1] != '$'))) 203945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 204045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 204145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%s' expects macro identifiers", 204245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 204345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 204445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 204545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 204645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (smacro_defined(NULL, tline->text, 0, NULL, 1)) 204745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = TRUE; 204845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 204945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 205045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_IFNDEF || i == PP_ELIFNDEF) 205145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = !j; 205245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 205345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return j; 205445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 205545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFIDN: 205645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFIDN: 205745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNIDN: 205845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNIDN: 205945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFIDNI: 206045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFIDNI: 206145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNIDNI: 206245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNIDNI: 206345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline); 206445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tt = tline; 206545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tok_isnt_(tt, ",")) 206645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = tt->next; 206745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tt) 206845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 206945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 207045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%s' expects two comma-separated arguments", 207145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 207245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 207345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 207445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 207545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = tt->next; 207645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org casesense = (i == PP_IFIDN || i == PP_ELIFIDN || 207745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i == PP_IFNIDN || i == PP_ELIFNIDN); 207845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = TRUE; /* assume equality unless proved not */ 207945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt) 208045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 208145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tt->type == TOK_OTHER && !strcmp(tt->text, ",")) 208245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 208345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%s': more than one comma on line", 208445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 208545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 208645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 208745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 208845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type == TOK_WHITESPACE) 208945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 209045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 209145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 209245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 209345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tt->type == TOK_WHITESPACE) 209445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 209545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = tt->next; 209645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 209745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 209845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tt->type != t->type) 209945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 210045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = FALSE; /* found mismatching tokens */ 210145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 210245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 210345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Unify surrounding quotes for strings */ 210445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type == TOK_STRING) 210545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 210645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt->text[0] = t->text[0]; 210745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt->text[strlen(tt->text) - 1] = t->text[0]; 210845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 210945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (mstrcmp(tt->text, t->text, casesense) != 0) 211045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 211145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = FALSE; /* found mismatching tokens */ 211245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 211345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 211445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 211545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 211645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = tt->next; 211745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 211845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt) 211945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = FALSE; /* trailing gunk on one end or other */ 212045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_IFNIDN || i == PP_ELIFNIDN || 212145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i == PP_IFNIDNI || i == PP_ELIFNIDNI) 212245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = !j; 212345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 212445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return j; 212545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 212645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFMACRO: 212745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFMACRO: 212845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNMACRO: 212945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNMACRO: 213045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 213145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int found = 0; 213245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro searching, *mmac; 213345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 213445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 213545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 213645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 213745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(tline, TOK_ID)) 213845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 213945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 214045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%s' expects a macro name", 214145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 214245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 214345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 214445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.name = nasm_strdup(tline->text); 214545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.casesense = (i == PP_MACRO); 214645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.plus = FALSE; 214745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.nolist = FALSE; 214845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.in_progress = FALSE; 214945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.rep_nest = NULL; 215045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.nparam_min = 0; 215145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.nparam_max = INT_MAX; 215245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline->next); 215345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 215445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline) 215545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 215645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!tok_type_(tline, TOK_NUMBER)) 215745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 215845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 215945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%s' expects a parameter count or nothing", 216045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 216145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 216245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 216345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 216445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = nasm_readnum(tline->text, &j); 216545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.nparam_min = searching.nparam_max = 216645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_int(intn); 216745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 216845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (j) 216945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 217045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "unable to parse parameter count `%s'", 217145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text); 217245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 217345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tok_is_(tline->next, "-")) 217445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 217545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next->next; 217645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_is_(tline, "*")) 217745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.nparam_max = INT_MAX; 217845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (!tok_type_(tline, TOK_NUMBER)) 217945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 218045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%s' expects a parameter count after `-'", 218145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 218245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 218345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 218445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = nasm_readnum(tline->text, &j); 218545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.nparam_max = yasm_intnum_get_int(intn); 218645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 218745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (j) 218845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 218945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "unable to parse parameter count `%s'", 219045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text); 219145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (searching.nparam_min > searching.nparam_max) 219245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 219345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "minimum parameter count exceeds maximum"); 219445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 219545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 219645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tok_is_(tline->next, "+")) 219745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 219845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 219945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org searching.plus = TRUE; 220045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 220145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac = mmacros[hash(searching.name)]; 220245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (mmac) 220345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 220445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(mmac->name, searching.name) && 220545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (mmac->nparam_min <= searching.nparam_max 220645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || searching.plus) 220745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && (searching.nparam_min <= mmac->nparam_max 220845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || mmac->plus)) 220945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 221045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found = TRUE; 221145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 221245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 221345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac = mmac->next; 221445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 221545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(searching.name); 221645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 221745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_IFNMACRO || i == PP_ELIFNMACRO) 221845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found = !found; 221945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return found; 222045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 222145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 222245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFID: 222345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFID: 222445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNID: 222545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNID: 222645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNUM: 222745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNUM: 222845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNNUM: 222945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNNUM: 223045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFSTR: 223145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFSTR: 223245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNSTR: 223345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNSTR: 223445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline); 223545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline; 223645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tok_type_(t, TOK_WHITESPACE)) 223745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 223845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = FALSE; /* placate optimiser */ 223945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t) 224045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (i) 224145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 224245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFID: 224345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFID: 224445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNID: 224545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNID: 224645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = (t->type == TOK_ID); 224745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 224845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNUM: 224945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNUM: 225045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNNUM: 225145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNNUM: 225245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = (t->type == TOK_NUMBER); 225345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 225445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFSTR: 225545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFSTR: 225645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNSTR: 225745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNSTR: 225845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = (t->type == TOK_STRING); 225945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 226045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 226145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_IFNID || i == PP_ELIFNID || 226245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i == PP_IFNNUM || i == PP_ELIFNNUM || 226345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i == PP_IFNSTR || i == PP_ELIFNSTR) 226445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = !j; 226545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 226645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return j; 226745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 226845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IF: 226945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIF: 227045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline = expand_smacro(tline); 227145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tptr = &t; 227245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval.t_type = TOKEN_INVALID; 227345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org evalresult = evaluate(ppscan, tptr, &tokval, pass | CRITICAL, 227445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error); 227545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 227645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!evalresult) 227745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 227845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tokval.t_type) 227945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 228045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "trailing garbage after expression ignored"); 228145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&evalresult, 0); 228245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn) 228345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 228445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 228545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "non-constant value given to `%s'", directives[i]); 228645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 228745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 228845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 228945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = !yasm_intnum_is_zero(intn); 229045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 229145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return j; 229245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 229345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 229445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, 229545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "preprocessor directive `%s' not yet implemented", 229645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 229745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 229845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; /* yeah, right */ 229945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 230045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 230145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 230245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 230345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Expand macros in a string. Used in %error and %include directives. 230445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * First tokenise the string, apply "expand_smacro" and then de-tokenise back. 230545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The returned variable should ALWAYS be freed after usage. 230645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 230745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 230845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgexpand_macros_in_string(char **p) 230945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 231045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *line = tokenise(*p); 231145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = expand_smacro(line); 231245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *p = detoken(line, FALSE); 231345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 231445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 231545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** 231645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * find and process preprocessor directive in passed line 231745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Find out if a line contains a preprocessor directive, and deal 231845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * with it if so. 231945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 232045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If a directive _is_ found, it is the responsibility of this routine 232145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * (and not the caller) to free_tlist() the line. 232245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 232345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * @param tline a pointer to the current tokeninzed line linked list 232445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND 232545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 232645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 232745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 232845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdo_directive(Token * tline) 232945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 233045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i, j, k, m, nparam, nolist; 233145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int offset; 233245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *p, *mname, *newname; 233345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Include *inc; 233445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Context *ctx; 233545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Cond *cond; 233645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *smac, **smhead; 233745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *mmac; 233845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline; 233945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l; 234045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct tokenval tokval; 234145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr *evalresult; 234245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *tmp_defining; /* Used when manipulating rep_nest */ 234345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn; 234445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 234545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org origline = tline; 234645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 234745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 234845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(tline, TOK_PREPROC_ID) || 234945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (tline->text[1] == '%' || tline->text[1] == '$' 235045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || tline->text[1] == '!')) 235145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NO_DIRECTIVE_FOUND; 235245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 235345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = -1; 235445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = elements(directives); 235545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (j - i > 1) 235645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 235745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org k = (j + i) / 2; 235845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = nasm_stricmp(tline->text, directives[k]); 235945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m == 0) { 236045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tasm_compatible_mode) { 236145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = k; 236245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = -2; 236345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) { 236445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = k; 236545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = -2; 236645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 236745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 236845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 236945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (m < 0) { 237045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = k; 237145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 237245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 237345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = k; 237445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 237545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 237645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 237745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If we're in a non-emitting branch of a condition construct, 237845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * or walking to the end of an already terminated %rep block, 237945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * we should ignore all directives except for condition 238045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * directives. 238145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 238245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (((istk->conds && !emitting(istk->conds->state)) || 238345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (istk->mstk && !istk->mstk->in_progress)) && 238445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org !is_condition(i)) 238545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 238645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NO_DIRECTIVE_FOUND; 238745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 238845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 238945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 239045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If we're defining a macro or reading a %rep block, we should 239145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ignore all directives except for %macro/%imacro (which 239245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * generate an error), %endm/%endmacro, and (only if we're in a 239345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %rep block) %endrep. If we're in a %rep block, another %rep 239445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * causes an error, so should be let through. 239545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 239645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defining && i != PP_MACRO && i != PP_IMACRO && 239745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i != PP_ENDMACRO && i != PP_ENDM && 239845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (defining->name || (i != PP_ENDREP && i != PP_REP))) 239945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 240045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NO_DIRECTIVE_FOUND; 240145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 240245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 240345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defining) { 240445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_MACRO || i == PP_IMACRO) { 240545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nested_mac_count++; 240645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NO_DIRECTIVE_FOUND; 240745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (nested_mac_count > 0) { 240845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_ENDMACRO) { 240945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nested_mac_count--; 241045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NO_DIRECTIVE_FOUND; 241145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 241245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 241345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!defining->name) { 241445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_REP) { 241545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nested_rep_count++; 241645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NO_DIRECTIVE_FOUND; 241745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (nested_rep_count > 0) { 241845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i == PP_ENDREP) { 241945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nested_rep_count--; 242045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NO_DIRECTIVE_FOUND; 242145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 242245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 242345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 242445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 242545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 242645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (j != -2) 242745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 242845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "unknown preprocessor directive `%s'", 242945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text); 243045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NO_DIRECTIVE_FOUND; /* didn't get it */ 243145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 243245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 243345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (i) 243445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 243545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_STACKSIZE: 243645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Directive to tell NASM what the default stack size is. The 243745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * default is for a 16-bit stack, and this can be overriden with 243845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %stacksize large. 243945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the following form: 244045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 244145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARG arg1:WORD, arg2:DWORD, arg4:QWORD 244245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 244345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 244445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tline->type == TOK_WHITESPACE) 244545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 244645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || tline->type != TOK_ID) 244745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 244845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%stacksize' missing size parameter"); 244945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 245045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 245145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 245245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (nasm_stricmp(tline->text, "flat") == 0) 245345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 245445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* All subsequent ARG directives are for a 32-bit stack */ 245545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org StackSize = 4; 245645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org StackPointer = "ebp"; 245745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ArgOffset = 8; 245845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org LocalOffset = 4; 245945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 246045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tline->text, "large") == 0) 246145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 246245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* All subsequent ARG directives are for a 16-bit stack, 246345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * far function call. 246445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 246545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org StackSize = 2; 246645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org StackPointer = "bp"; 246745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ArgOffset = 4; 246845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org LocalOffset = 2; 246945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 247045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tline->text, "small") == 0) 247145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 247245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* All subsequent ARG directives are for a 16-bit stack, 247345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * far function call. We don't support near functions. 247445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 247545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org StackSize = 2; 247645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org StackPointer = "bp"; 247745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ArgOffset = 6; 247845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org LocalOffset = 2; 247945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 248045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 248145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 248245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%stacksize' invalid size type"); 248345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 248445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 248545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 248645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 248745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 248845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 248945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ARG: 249045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* TASM like ARG directive to define arguments to functions, in 249145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the following form: 249245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 249345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARG arg1:WORD, arg2:DWORD, arg4:QWORD 249445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 249545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offset = ArgOffset; 249645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do 249745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 249845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *arg, directive[256]; 249945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int size = StackSize; 250045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 250145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Find the argument name */ 250245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 250345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tline->type == TOK_WHITESPACE) 250445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 250545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || tline->type != TOK_ID) 250645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 250745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%arg' missing argument parameter"); 250845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 250945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 251045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 251145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org arg = tline->text; 251245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 251345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Find the argument size type */ 251445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 251545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || tline->type != TOK_OTHER 251645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || tline->text[0] != ':') 251745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 251845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 251945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "Syntax error processing `%%arg' directive"); 252045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 252145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 252245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 252345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 252445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || tline->type != TOK_ID) 252545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 252645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 252745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%arg' missing size type parameter"); 252845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 252945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 253045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 253145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 253245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Allow macro expansion of type parameter */ 253345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = tokenise(tline->text); 253445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = expand_smacro(tt); 253545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (nasm_stricmp(tt->text, "byte") == 0) 253645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 253745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 1); 253845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 253945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tt->text, "word") == 0) 254045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 254145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 2); 254245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 254345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tt->text, "dword") == 0) 254445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 254545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 4); 254645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 254745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tt->text, "qword") == 0) 254845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 254945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 8); 255045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 255145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tt->text, "tword") == 0) 255245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 255345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 10); 255445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 255545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 255645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 255745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 255845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "Invalid size type for `%%arg' missing directive"); 255945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tt); 256045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 256145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 256245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 256345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tt); 256445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 256545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Now define the macro for the argument */ 256645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer, 256745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offset); 256845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do_directive(tokenise(directive)); 256945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offset += size; 257045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 257145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Move to the next argument in the list */ 257245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 257345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tline->type == TOK_WHITESPACE) 257445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 257545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 257645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tline && tline->type == TOK_OTHER 257745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && tline->text[0] == ','); 257845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 257945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 258045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 258145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_LOCAL: 258245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* TASM like LOCAL directive to define local variables for a 258345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * function, in the following form: 258445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 258545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize 258645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 258745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The '= LocalSize' at the end is ignored by NASM, but is 258845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * required by TASM to define the local parameter size (and used 258945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * by the TASM macro package). 259045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 259145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offset = LocalOffset; 259245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do 259345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 259445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *local, directive[256]; 259545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int size = StackSize; 259645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 259745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Find the argument name */ 259845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 259945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tline->type == TOK_WHITESPACE) 260045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 260145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || tline->type != TOK_ID) 260245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 260345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 260445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%local' missing argument parameter"); 260545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 260645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 260745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 260845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org local = tline->text; 260945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 261045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Find the argument size type */ 261145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 261245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || tline->type != TOK_OTHER 261345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || tline->text[0] != ':') 261445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 261545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 261645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "Syntax error processing `%%local' directive"); 261745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 261845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 261945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 262045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 262145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || tline->type != TOK_ID) 262245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 262345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 262445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%local' missing size type parameter"); 262545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 262645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 262745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 262845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 262945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Allow macro expansion of type parameter */ 263045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = tokenise(tline->text); 263145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = expand_smacro(tt); 263245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (nasm_stricmp(tt->text, "byte") == 0) 263345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 263445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 1); 263545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 263645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tt->text, "word") == 0) 263745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 263845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 2); 263945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 264045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tt->text, "dword") == 0) 264145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 264245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 4); 264345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 264445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tt->text, "qword") == 0) 264545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 264645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 8); 264745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 264845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (nasm_stricmp(tt->text, "tword") == 0) 264945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 265045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = MAX(StackSize, 10); 265145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 265245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 265345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 265445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 265545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "Invalid size type for `%%local' missing directive"); 265645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tt); 265745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 265845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 265945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 266045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tt); 266145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 266245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Now define the macro for the argument */ 266345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(directive, "%%define %s (%s-%d)", local, StackPointer, 266445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offset); 266545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do_directive(tokenise(directive)); 266645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offset += size; 266745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 266845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Now define the assign to setup the enter_c macro correctly */ 266945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sprintf(directive, "%%assign %%$localsize %%$localsize+%d", 267045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size); 267145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do_directive(tokenise(directive)); 267245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 267345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Move to the next argument in the list */ 267445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 267545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tline->type == TOK_WHITESPACE) 267645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 267745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 267845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tline && tline->type == TOK_OTHER 267945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && tline->text[0] == ','); 268045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 268145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 268245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 268345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_CLEAR: 268445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next) 268545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 268645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "trailing garbage after `%%clear' ignored"); 268745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (j = 0; j < NHASH; j++) 268845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 268945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (mmacros[j]) 269045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 269145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *m2 = mmacros[j]; 269245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmacros[j] = m2->next; 269345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_mmacro(m2); 269445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 269545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (smacros[j]) 269645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 269745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *s = smacros[j]; 269845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smacros[j] = smacros[j]->next; 269945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(s->name); 270045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(s->expansion); 270145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(s); 270245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 270345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 270445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 270545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 270645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 270745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_INCLUDE: 270845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 270945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 271045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || (tline->type != TOK_STRING && 271145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->type != TOK_INTERNAL_STRING)) 271245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 271345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%include' expects a file name"); 271445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 271545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; /* but we did _something_ */ 271645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 271745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next) 271845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 271945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "trailing garbage after `%%include' ignored"); 272045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type != TOK_INTERNAL_STRING) 272145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 272245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = tline->text + 1; /* point past the quote to the name */ 272345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p[strlen(p) - 1] = '\0'; /* remove the trailing quote */ 272445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 272545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 272645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = tline->text; /* internal_string is easier */ 272745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org expand_macros_in_string(&p); 272845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc = nasm_malloc(sizeof(Include)); 272945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc->next = istk; 273045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc->conds = NULL; 273145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc->fp = inc_fopen(p, &newname); 273245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc->fname = nasm_src_set_fname(newname); 273345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc->lineno = nasm_src_set_linnum(0); 273445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc->lineinc = 1; 273545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc->expansion = NULL; 273645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc->mstk = NULL; 273745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk = inc; 273845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list->uplevel(LIST_INCLUDE); 273945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 274045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 274145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 274245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_PUSH: 274345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 274445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 274545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 274645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(tline, TOK_ID)) 274745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 274845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%push' expects a context identifier"); 274945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 275045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; /* but we did _something_ */ 275145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 275245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next) 275345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, "trailing garbage after `%%push' ignored"); 275445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = nasm_malloc(sizeof(Context)); 275545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx->next = cstk; 275645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx->localmac = NULL; 275745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx->name = nasm_strdup(tline->text); 275845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx->number = unique++; 275945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cstk = ctx; 276045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 276145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 276245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 276345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_REPL: 276445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 276545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 276645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 276745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(tline, TOK_ID)) 276845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 276945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%repl' expects a context identifier"); 277045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 277145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; /* but we did _something_ */ 277245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 277345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next) 277445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, "trailing garbage after `%%repl' ignored"); 277545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!cstk) 277645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%repl': context stack is empty"); 277745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 277845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 277945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(cstk->name); 278045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cstk->name = nasm_strdup(tline->text); 278145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 278245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 278345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 278445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 278545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_POP: 278645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next) 278745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, "trailing garbage after `%%pop' ignored"); 278845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!cstk) 278945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 279045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%pop': context stack is already empty"); 279145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 279245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx_pop(); 279345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 279445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 279545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 2796a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org case PP_SCOPE: 2797a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (tline->next) 2798a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org error(ERR_WARNING, "trailing garbage after `%%scope' ignored"); 2799a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org Level++; 2800a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org free_tlist(origline); 2801a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 2802a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 2803a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org case PP_ENDSCOPE: 2804a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (tline->next) 2805a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org error(ERR_WARNING, "trailing garbage after `%%endscope' ignored"); 2806a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (!Level) 2807a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org error(ERR_NONFATAL, 2808a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org "`%%endscope': already popped all levels"); 2809a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 2810a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2811a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (k = 0; k < NHASH; k++) 2812a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2813a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org SMacro **smlast = &smacros[k]; 2814a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac = smacros[k]; 2815a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org while (smac) 2816a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2817a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (smac->level < Level) 2818a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2819a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smlast = &smac->next; 2820a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac = smac->next; 2821a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2822a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 2823a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2824a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org *smlast = smac->next; 2825a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org nasm_free(smac->name); 2826a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org free_tlist(smac->expansion); 2827a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org nasm_free(smac); 2828a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac = *smlast; 2829a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2830a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2831a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2832a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (ctx = cstk; ctx; ctx = ctx->next) 2833a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2834a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org SMacro **smlast = &ctx->localmac; 2835a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac = ctx->localmac; 2836a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org while (smac) 2837a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2838a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (smac->level < Level) 2839a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2840a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smlast = &smac->next; 2841a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac = smac->next; 2842a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2843a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 2844a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 2845a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org *smlast = smac->next; 2846a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org nasm_free(smac->name); 2847a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org free_tlist(smac->expansion); 2848a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org nasm_free(smac); 2849a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac = *smlast; 2850a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2851a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2852a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2853a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org Level--; 2854a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 2855a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org free_tlist(origline); 2856a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 2857a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 285845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ERROR: 285945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->next = expand_smacro(tline->next); 286045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 286145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 286245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_type_(tline, TOK_STRING)) 286345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 286445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = tline->text + 1; /* point past the quote to the name */ 286545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p[strlen(p) - 1] = '\0'; /* remove the trailing quote */ 286645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org expand_macros_in_string(&p); 286745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "%s", p); 286845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(p); 286945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 287045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 287145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 287245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = detoken(tline, FALSE); 287345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, "%s", p); 287445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(p); 287545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 287645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 287745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 287845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 287945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IF: 288045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFCTX: 288145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFDEF: 288245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFID: 288345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFIDN: 288445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFIDNI: 288545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFMACRO: 288645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNCTX: 288745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNDEF: 288845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNID: 288945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNIDN: 289045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNIDNI: 289145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNMACRO: 289245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNNUM: 289345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNSTR: 289445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFNUM: 289545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IFSTR: 289645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (istk->conds && !emitting(istk->conds->state)) 289745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = COND_NEVER; 289845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 289945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 290045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = if_condition(tline->next, i); 290145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->next = NULL; /* it got freed */ 290245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE; 290345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 290445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 290545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cond = nasm_malloc(sizeof(Cond)); 290645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cond->next = istk->conds; 290745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cond->state = j; 290845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->conds = cond; 290945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 291045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 291145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIF: 291245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFCTX: 291345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFDEF: 291445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFID: 291545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFIDN: 291645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFIDNI: 291745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFMACRO: 291845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNCTX: 291945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNDEF: 292045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNID: 292145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNIDN: 292245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNIDNI: 292345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNMACRO: 292445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNNUM: 292545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNSTR: 292645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFNUM: 292745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELIFSTR: 292845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!istk->conds) 292945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "`%s': no matching `%%if'", directives[i]); 293045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (emitting(istk->conds->state) 293145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || istk->conds->state == COND_NEVER) 293245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->conds->state = COND_NEVER; 293345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 293445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 293545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 293645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPORTANT: In the case of %if, we will already have 293745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * called expand_mmac_params(); however, if we're 293845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * processing an %elif we must have been in a 293945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * non-emitting mode, which would have inhibited 294045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the normal invocation of expand_mmac_params(). Therefore, 294145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * we have to do it explicitly here. 294245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 294345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = if_condition(expand_mmac_params(tline->next), i); 294445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->next = NULL; /* it got freed */ 294545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->conds->state = 294645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE; 294745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 294845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 294945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 295045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 295145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ELSE: 295245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next) 295345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, "trailing garbage after `%%else' ignored"); 295445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!istk->conds) 295545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "`%%else': no matching `%%if'"); 295645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (emitting(istk->conds->state) 295745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || istk->conds->state == COND_NEVER) 295845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->conds->state = COND_ELSE_FALSE; 295945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 296045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->conds->state = COND_ELSE_TRUE; 296145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 296245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 296345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 296445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ENDIF: 296545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next) 296645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 296745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "trailing garbage after `%%endif' ignored"); 296845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!istk->conds) 296945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "`%%endif': no matching `%%if'"); 297045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cond = istk->conds; 297145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->conds = cond->next; 297245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(cond); 297345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 297445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 297545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 297645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_MACRO: 297745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IMACRO: 297845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defining) 297945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, 298045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%%smacro': already defining a macro", 298145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (i == PP_IMACRO ? "i" : "")); 298245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 298345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 298445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 298545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(tline, TOK_ID)) 298645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 298745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 298845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%%smacro' expects a macro name", 298945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (i == PP_IMACRO ? "i" : "")); 299045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 299145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 299245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining = nasm_malloc(sizeof(MMacro)); 299345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->name = nasm_strdup(tline->text); 299445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->casesense = (i == PP_MACRO); 299545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->plus = FALSE; 299645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->nolist = FALSE; 299745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->in_progress = FALSE; 299845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->rep_nest = NULL; 299945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline->next); 300045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 300145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(tline, TOK_NUMBER)) 300245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 300345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 300445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%%smacro' expects a parameter count", 300545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (i == PP_IMACRO ? "i" : "")); 300645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->nparam_min = defining->nparam_max = 0; 300745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 300845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 300945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 301045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = nasm_readnum(tline->text, &j); 301145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->nparam_min = defining->nparam_max = 301245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_int(intn); 301345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 301445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (j) 301545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 301645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "unable to parse parameter count `%s'", 301745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text); 301845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 301945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tok_is_(tline->next, "-")) 302045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 302145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next->next; 302245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_is_(tline, "*")) 302345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->nparam_max = INT_MAX; 302445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (!tok_type_(tline, TOK_NUMBER)) 302545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 302645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%%smacro' expects a parameter count after `-'", 302745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (i == PP_IMACRO ? "i" : "")); 302845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 302945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 303045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = nasm_readnum(tline->text, &j); 303145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->nparam_max = yasm_intnum_get_int(intn); 303245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 303345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (j) 303445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 303545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "unable to parse parameter count `%s'", 303645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text); 303745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defining->nparam_min > defining->nparam_max) 303845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 303945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "minimum parameter count exceeds maximum"); 304045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 304145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 304245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tok_is_(tline->next, "+")) 304345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 304445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 304545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->plus = TRUE; 304645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 304745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tok_type_(tline->next, TOK_ID) && 304845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org !nasm_stricmp(tline->next->text, ".nolist")) 304945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 305045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 305145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->nolist = TRUE; 305245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 305345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac = mmacros[hash(defining->name)]; 305445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (mmac) 305545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 305645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp(mmac->name, defining->name) && 305745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (mmac->nparam_min <= defining->nparam_max 305845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || defining->plus) 305945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && (defining->nparam_min <= mmac->nparam_max 306045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || mmac->plus)) 306145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 306245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 306345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "redefining multi-line macro `%s'", 306445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->name); 306545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 306645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 306745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac = mmac->next; 306845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 306945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 307045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Handle default parameters. 307145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 307245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline && tline->next) 307345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 307445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->dlist = tline->next; 307545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->next = NULL; 307645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org count_mmac_params(defining->dlist, &defining->ndefs, 307745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &defining->defaults); 307845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 307945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 308045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 308145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->dlist = NULL; 308245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->defaults = NULL; 308345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 308445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->expansion = NULL; 308545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 308645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 308745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 308845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ENDM: 308945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ENDMACRO: 309045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!defining) 309145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 309245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%s': not defining a macro", 309345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text); 309445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 309545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 309645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org k = hash(defining->name); 309745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->next = mmacros[k]; 309845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmacros[k] = defining; 309945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining = NULL; 310045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 310145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 310245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 310345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ROTATE: 310445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next && tline->next->type == TOK_WHITESPACE) 310545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 310645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next == NULL) 310745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 310845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 310945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%rotate' missing rotate count"); 311045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 311145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 311245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = expand_smacro(tline->next); 311345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->next = NULL; 311445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 311545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = t; 311645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tptr = &t; 311745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval.t_type = TOKEN_INVALID; 311845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org evalresult = evaluate(ppscan, tptr, &tokval, pass, error); 311945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 312045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!evalresult) 312145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 312245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tokval.t_type) 312345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 312445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "trailing garbage after expression ignored"); 312545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&evalresult, 0); 312645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn) 312745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 312845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "non-constant value given to `%%rotate'"); 312945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 313045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 313145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 313245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac = istk->mstk; 313345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (mmac && !mmac->name) /* avoid mistaking %reps for macros */ 313445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac = mmac->next_active; 313545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!mmac) 313645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 313745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 313845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%rotate' invoked outside a macro call"); 313945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 314045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (mmac->nparam == 0) 314145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 314245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 314345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%rotate' invoked within macro without parameters"); 314445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 314545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 314645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 314745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac->rotate = mmac->rotate + yasm_intnum_get_int(intn); 314845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 314945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (mmac->rotate < 0) 315045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac->rotate = 315145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac->nparam - (-mmac->rotate) % mmac->nparam; 315245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmac->rotate %= mmac->nparam; 315345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 315445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 315545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 315645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 315745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_REP: 315845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nolist = FALSE; 315945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do { 316045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 316145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } while (tok_type_(tline, TOK_WHITESPACE)); 316245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 316345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_type_(tline, TOK_ID) && 316445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_stricmp(tline->text, ".nolist") == 0) 316545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 316645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nolist = TRUE; 316745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do { 316845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 316945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } while (tok_type_(tline, TOK_WHITESPACE)); 317045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 317145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 317245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline) 317345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 317445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = expand_smacro(tline); 317545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tptr = &t; 317645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval.t_type = TOKEN_INVALID; 317745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org evalresult = evaluate(ppscan, tptr, &tokval, pass, error); 317845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!evalresult) 317945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 318045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 318145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 318245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 318345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tokval.t_type) 318445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 318545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "trailing garbage after expression ignored"); 318645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&evalresult, 0); 318745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn) 318845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 318945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "non-constant value given to `%%rep'"); 319045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 319145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 319245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 319345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = (int)yasm_intnum_get_int(intn) + 1; 319445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 319545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 319645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 319745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 319845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%rep' expects a repeat count"); 319945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = 0; 320045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 320145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 320245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 320345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tmp_defining = defining; 320445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining = nasm_malloc(sizeof(MMacro)); 320545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->name = NULL; /* flags this macro as a %rep block */ 320645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->casesense = 0; 320745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->plus = FALSE; 320845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->nolist = nolist; 320945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->in_progress = i; 321045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->nparam_min = defining->nparam_max = 0; 321145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->defaults = NULL; 321245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->dlist = NULL; 321345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->expansion = NULL; 321445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->next_active = istk->mstk; 321545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->rep_nest = tmp_defining; 321645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 321745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 321845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ENDREP: 321945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!defining || defining->name) 322045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 322145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'"); 322245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 322345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 322445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 322545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 322645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Now we have a "macro" defined - although it has no name 322745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and we won't be entering it in the hash tables - we must 322845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * push a macro-end marker for it on to istk->expansion. 322945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * After that, it will take care of propagating itself (a 323045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * macro-end marker line for a macro which is really a %rep 323145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * block will cause the macro to be re-expanded, complete 323245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * with another macro-end marker to ensure the process 323345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * continues) until the whole expansion is forcibly removed 323445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * from istk->expansion by a %exitrep. 323545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 323645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = nasm_malloc(sizeof(Line)); 323745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->next = istk->expansion; 323845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes = defining; 323945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->first = NULL; 324045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = l; 324145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 324245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->mstk = defining; 324345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 324445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO); 324545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tmp_defining = defining; 324645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining = defining->rep_nest; 324745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 324845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 324945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 325045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_EXITREP: 325145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 325245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We must search along istk->expansion until we hit a 325345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * macro-end marker for a macro with no name. Then we set 325445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * its `in_progress' flag to 0. 325545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 325645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (l = istk->expansion; l; l = l->next) 325745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (l->finishes && !l->finishes->name) 325845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 325945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 326045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (l) 326145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes->in_progress = 0; 326245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 326345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block"); 326445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 326545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 326645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 326745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_XDEFINE: 326845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IXDEFINE: 326945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_DEFINE: 327045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IDEFINE: 327145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 327245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 327345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 327445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || (tline->type != TOK_ID && 327545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (tline->type != TOK_PREPROC_ID || 327645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text[1] != '$'))) 327745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 327845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 327945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%%s%sdefine' expects a macro identifier", 328045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""), 328145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : "")); 328245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 328345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 328445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 328545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 328645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = get_ctx(tline->text, FALSE); 328745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!ctx) 328845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &smacros[hash(tline->text)]; 328945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 329045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &ctx->localmac; 329145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mname = tline->text; 329245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = tline; 329345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org param_start = tline = tline->next; 329445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nparam = 0; 329545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 329645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Expand the macro definition now for %xdefine and %ixdefine */ 329745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((i == PP_XDEFINE) || (i == PP_IXDEFINE)) 329845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline); 329945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 330045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_is_(tline, "(")) 330145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 330245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 330345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This macro has parameters. 330445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 330545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 330645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 330745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (1) 330845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 330945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 331045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline) 331145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 331245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "parameter identifier expected"); 331345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 331445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 331545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 331645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type != TOK_ID) 331745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 331845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 331945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%s': parameter identifier expected", 332045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text); 332145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 332245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 332345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 332445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->type = TOK_SMAC_PARAM + nparam++; 332545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 332645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 332745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_is_(tline, ",")) 332845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 332945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 333045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 333145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 333245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_is_(tline, ")")) 333345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 333445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 333545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`)' expected to terminate macro template"); 333645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 333745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 333845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 333945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 334045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 334145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = tline; 334245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 334345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 334445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_type_(tline, TOK_WHITESPACE)) 334545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = tline, tline = tline->next; 334645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start = NULL; 334745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last->next = NULL; 334845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline; 334945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (t) 335045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 335145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type == TOK_ID) 335245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 335345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (tt = param_start; tt; tt = tt->next) 335445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tt->type >= TOK_SMAC_PARAM && 335545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org !strcmp(tt->text, t->text)) 335645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->type = tt->type; 335745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 335845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = t->next; 335945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = macro_start; 336045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start = t; 336145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tt; 336245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 336345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 336445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Good. We now have a macro name, a parameter count, and a 336545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * token list (in reverse order) for an expansion. We ought 336645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * to be OK just to create an SMacro, store it, and let 336745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * free_tlist have the rest of the line (which we have 336845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * carefully re-terminated after chopping off the expansion 336945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * from the end). 337045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 337145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE)) 337245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 337345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!smac) 337445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 337545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 337645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "single-line macro `%s' defined both with and" 337745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org " without parameters", mname); 337845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 337945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(macro_start); 338045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 338145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 3382a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else if (smac->level == Level) 338345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 338445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 3385a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org * We're redefining in the same level, so we have to 3386a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org * take over an existing SMacro structure. This means 3387a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org * freeing what was already in it. 338845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 338945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(smac->name); 339045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(smac->expansion); 339145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 3392a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 3393a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3394a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac = nasm_malloc(sizeof(SMacro)); 3395a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac->next = *smhead; 3396a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org *smhead = smac; 3397a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 339845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 339945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 340045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 340145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac = nasm_malloc(sizeof(SMacro)); 340245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->next = *smhead; 340345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *smhead = smac; 340445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 340545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->name = nasm_strdup(mname); 340645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE)); 340745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->nparam = nparam; 3408a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac->level = Level; 340945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->expansion = macro_start; 341045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->in_progress = FALSE; 341145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 341245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 341345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 341445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_UNDEF: 341545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 341645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 341745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 341845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || (tline->type != TOK_ID && 341945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (tline->type != TOK_PREPROC_ID || 342045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text[1] != '$'))) 342145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 342245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%undef' expects a macro identifier"); 342345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 342445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 342545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 342645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->next) 342745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 342845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 342945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "trailing garbage after macro name ignored"); 343045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 343145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 343245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Find the context that symbol belongs to */ 343345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = get_ctx(tline->text, FALSE); 343445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!ctx) 343545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &smacros[hash(tline->text)]; 343645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 343745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &ctx->localmac; 343845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 343945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mname = tline->text; 344045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 344145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 344245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We now have a macro name... go hunt for it. 344345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 344445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (smacro_defined(ctx, mname, -1, &smac, 1)) 344545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 344645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Defined, so we need to find its predecessor and nuke it */ 344745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro **s; 344845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (s = smhead; *s && *s != smac; s = &(*s)->next); 344945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*s) 345045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 345145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *s = smac->next; 345245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(smac->name); 345345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(smac->expansion); 345445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(smac); 345545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 345645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 345745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 345845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 345945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 346045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_STRLEN: 346145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 346245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 346345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 346445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || (tline->type != TOK_ID && 346545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (tline->type != TOK_PREPROC_ID || 346645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text[1] != '$'))) 346745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 346845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 346945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%strlen' expects a macro identifier as first parameter"); 347045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 347145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 347245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 347345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = get_ctx(tline->text, FALSE); 347445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!ctx) 347545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &smacros[hash(tline->text)]; 347645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 347745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &ctx->localmac; 347845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mname = tline->text; 347945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = tline; 348045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline->next); 348145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last->next = NULL; 348245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 348345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline; 348445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tok_type_(t, TOK_WHITESPACE)) 348545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 348645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* t should now point to the string */ 348745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type != TOK_STRING) 348845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 348945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 349045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%strlen` requires string as second parameter"); 349145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 349245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 349345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 349445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 349545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 349645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start = nasm_malloc(sizeof(*macro_start)); 349745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->next = NULL; 349845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org make_tok_num(macro_start, 349945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_create_uint((unsigned long)(strlen(t->text) - 2))); 350045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->mac = NULL; 350145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 350245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 350345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We now have a macro name, an implicit parameter count of 350445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * zero, and a numeric token to use as an expansion. Create 350545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and store an SMacro. 350645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 350745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN)) 350845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 350945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!smac) 351045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 351145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "single-line macro `%s' defined both with and" 351245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org " without parameters", mname); 351345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 351445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 351545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 351645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We're redefining, so we have to take over an 351745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * existing SMacro structure. This means freeing 351845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * what was already in it. 351945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 352045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(smac->name); 352145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(smac->expansion); 352245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 352345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 352445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 352545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 352645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac = nasm_malloc(sizeof(SMacro)); 352745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->next = *smhead; 352845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *smhead = smac; 352945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 353045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->name = nasm_strdup(mname); 353145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->casesense = (i == PP_STRLEN); 353245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->nparam = 0; 3533a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac->level = 0; 353445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->expansion = macro_start; 353545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->in_progress = FALSE; 353645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 353745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 353845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 353945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 354045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_SUBSTR: 354145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 354245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 354345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 354445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || (tline->type != TOK_ID && 354545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (tline->type != TOK_PREPROC_ID || 354645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text[1] != '$'))) 354745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 354845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 354945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%substr' expects a macro identifier as first parameter"); 355045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 355145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 355245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 355345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = get_ctx(tline->text, FALSE); 355445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!ctx) 355545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &smacros[hash(tline->text)]; 355645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 355745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &ctx->localmac; 355845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mname = tline->text; 355945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = tline; 356045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline->next); 356145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last->next = NULL; 356245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 356345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline->next; 356445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tok_type_(t, TOK_WHITESPACE)) 356545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 356645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 356745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* t should now point to the string */ 356845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type != TOK_STRING) 356945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 357045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 357145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%substr` requires string as second parameter"); 357245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 357345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 357445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 357545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 357645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 357745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = t->next; 357845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tptr = &tt; 357945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval.t_type = TOKEN_INVALID; 358045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org evalresult = evaluate(ppscan, tptr, &tokval, pass, error); 358145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!evalresult) 358245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 358345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 358445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 358545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 358645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 358745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&evalresult, 0); 358845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn) 358945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 359045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "non-constant value given to `%%substr`"); 359145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 359245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 359345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 359445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 359545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 359645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 359745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start = nasm_malloc(sizeof(*macro_start)); 359845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->next = NULL; 359945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->text = nasm_strdup("'''"); 360045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_sign(intn) == 1 360145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && yasm_intnum_get_uint(intn) < strlen(t->text) - 1) 360245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 360345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->text[1] = t->text[yasm_intnum_get_uint(intn)]; 360445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 360545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 360645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 360745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->text[2] = '\0'; 360845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 360945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 361045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->type = TOK_STRING; 361145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->mac = NULL; 361245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 361345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 361445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We now have a macro name, an implicit parameter count of 361545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * zero, and a numeric token to use as an expansion. Create 361645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and store an SMacro. 361745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 361845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR)) 361945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 362045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!smac) 362145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 362245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "single-line macro `%s' defined both with and" 362345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org " without parameters", mname); 362445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 362545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 362645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 362745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We're redefining, so we have to take over an 362845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * existing SMacro structure. This means freeing 362945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * what was already in it. 363045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 363145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(smac->name); 363245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(smac->expansion); 363345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 363445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 363545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 363645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 363745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac = nasm_malloc(sizeof(SMacro)); 363845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->next = *smhead; 363945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *smhead = smac; 364045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 364145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->name = nasm_strdup(mname); 364245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->casesense = (i == PP_SUBSTR); 364345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->nparam = 0; 3644a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac->level = 0; 364545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->expansion = macro_start; 364645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->in_progress = FALSE; 364745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 364845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 364945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 365045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 365145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 365245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_ASSIGN: 365345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_IASSIGN: 365445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 365545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 365645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_id(tline); 365745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || (tline->type != TOK_ID && 365845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (tline->type != TOK_PREPROC_ID || 365945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text[1] != '$'))) 366045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 366145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 366245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "`%%%sassign' expects a macro identifier", 366345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (i == PP_IASSIGN ? "i" : "")); 366445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 366545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 366645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 366745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = get_ctx(tline->text, FALSE); 366845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!ctx) 366945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &smacros[hash(tline->text)]; 367045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 367145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smhead = &ctx->localmac; 367245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mname = tline->text; 367345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = tline; 367445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline->next); 367545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last->next = NULL; 367645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 367745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline; 367845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tptr = &t; 367945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tokval.t_type = TOKEN_INVALID; 368045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org evalresult = evaluate(ppscan, tptr, &tokval, pass, error); 368145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 368245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!evalresult) 368345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 368445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 368545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 368645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 368745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 368845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tokval.t_type) 368945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 369045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "trailing garbage after expression ignored"); 369145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 369245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_expr_get_intnum(&evalresult, 0); 369345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn) 369445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 369545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 369645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "non-constant value given to `%%%sassign'", 369745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (i == PP_IASSIGN ? "i" : "")); 369845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 369945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 370045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 370145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 370245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 370345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start = nasm_malloc(sizeof(*macro_start)); 370445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->next = NULL; 370545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org make_tok_num(macro_start, yasm_intnum_copy(intn)); 370645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(evalresult); 370745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro_start->mac = NULL; 370845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 370945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 371045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We now have a macro name, an implicit parameter count of 371145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * zero, and a numeric token to use as an expansion. Create 371245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and store an SMacro. 371345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 371445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN)) 371545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 371645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!smac) 371745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING, 371845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "single-line macro `%s' defined both with and" 371945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org " without parameters", mname); 372045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 372145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 372245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 372345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We're redefining, so we have to take over an 372445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * existing SMacro structure. This means freeing 372545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * what was already in it. 372645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 372745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(smac->name); 372845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(smac->expansion); 372945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 373045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 373145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 373245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 373345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac = nasm_malloc(sizeof(SMacro)); 373445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->next = *smhead; 373545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *smhead = smac; 373645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 373745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->name = nasm_strdup(mname); 373845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->casesense = (i == PP_ASSIGN); 373945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->nparam = 0; 3740a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org smac->level = 0; 374145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->expansion = macro_start; 374245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smac->in_progress = FALSE; 374345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 374445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 374545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 374645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case PP_LINE: 374745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 374845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Syntax is `%line nnn[+mmm] [filename]' 374945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 375045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 375145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 375245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(tline, TOK_NUMBER)) 375345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 375445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%line' expects line number"); 375545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 375645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 375745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 375845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = nasm_readnum(tline->text, &j); 375945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org k = yasm_intnum_get_int(intn); 376045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 376145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = 1; 376245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 376345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_is_(tline, "+")) 376445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 376545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 376645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(tline, TOK_NUMBER)) 376745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 376845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%%line' expects line increment"); 376945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 377045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 377145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 377245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = nasm_readnum(tline->text, &j); 377345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = yasm_intnum_get_int(intn); 377445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 377545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 377645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 377745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline); 377845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_src_set_linnum(k); 377945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->lineinc = m; 378045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline) 378145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 378245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(nasm_src_set_fname(detoken(tline, FALSE))); 378345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 378445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(origline); 378545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 378645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 378745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 378845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, 378945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "preprocessor directive `%s' not yet implemented", 379045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org directives[i]); 379145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 379245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 379345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return DIRECTIVE_FOUND; 379445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 379545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 379645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 379745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Ensure that a macro parameter contains a condition code and 379845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * nothing else. Return the condition code index if so, or -1 379945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * otherwise. 380045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 380145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 380245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfind_cc(Token * t) 380345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 380445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *tt; 380545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i, j, k, m; 380645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 380745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(t); 380845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type != TOK_ID) 380945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 381045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = t->next; 381145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tt); 381245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ","))) 381345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 381445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 381545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = -1; 381645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = elements(conditions); 381745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (j - i > 1) 381845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 381945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org k = (j + i) / 2; 382045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = nasm_stricmp(t->text, conditions[k]); 382145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m == 0) 382245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 382345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = k; 382445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = -2; 382545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 382645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 382745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (m < 0) 382845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 382945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org j = k; 383045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 383145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 383245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org i = k; 383345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 383445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (j != -2) 383545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 383645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return i; 383745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 383845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 383945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 384045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Expand MMacro-local things: parameter references (%0, %n, %+n, 384145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %-n) and MMacro-local identifiers (%%foo). 384245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 384345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token * 384445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgexpand_mmac_params(Token * tline) 384545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 384645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t, *tt, **tail, *thead; 384745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 384845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &thead; 384945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org thead = NULL; 385045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 385145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tline) 385245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 385345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_PREPROC_ID && 385445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (((tline->text[1] == '+' || tline->text[1] == '-') 385545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && tline->text[2]) || tline->text[1] == '%' 385645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || (tline->text[1] >= '0' && tline->text[1] <= '9'))) 385745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 385845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *text = NULL; 385945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int type = 0, cc; /* type = 0 to placate optimisers */ 386045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char tmpbuf[30]; 3861a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org char *second_text = NULL; 386245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int n, i; 386345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *mac; 386445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 386545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline; 386645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 386745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3868a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org second_text = strchr(t->text, ':'); 3869a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 387045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mac = istk->mstk; 387145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (mac && !mac->name) /* avoid mistaking %reps for macros */ 387245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mac = mac->next_active; 387345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!mac) 387445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "`%s': not in a macro call", t->text); 387545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 3876a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3877a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (second_text) 387845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 3879a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org int end = atoi(second_text+1)-1; 3880a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org int is_fst = 1; 3881a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org int k; 3882a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n = atoi(t->text + 1)-1; 3883a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (end < 0) 3884a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org end += mac->nparam; 3885a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 3886a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (k = n; k <= end; k++) 3887a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3888a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (k >= mac->nparam) 388945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = NULL; 389045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 389145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 389245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (mac->nparam > 1) 3893a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org k = (k + mac->rotate) % mac->nparam; 3894a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tt = mac->params[k]; 389545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 3896a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (tt) 389745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 3898a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (!is_fst && mac->paramlen[k]) 389945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 3900a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org *tail = new_Token(NULL, TOK_OTHER, ",", 0); 3901a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tail = &(*tail)->next; 390245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 3903a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (mac->paramlen[k]) 3904a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org is_fst = 0; 3905a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (i = 0; i < mac->paramlen[k]; i++) 390645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 390745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = 390845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org new_Token(NULL, tt->type, tt->text, 390945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0); 391045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &(*tail)->next; 391145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = tt->next; 391245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 391345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 391445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org text = NULL; /* we've done it here */ 3915a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 391645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 3917a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 3918a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3919a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org switch (t->text[1]) 3920a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3921a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org /* 3922a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org * We have to make a substitution of one of the 3923a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org * forms %1, %-1, %+1, %%foo, %0. 3924a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org */ 3925a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org case '0': 3926a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org type = TOK_NUMBER; 3927a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org sprintf(tmpbuf, "%ld", mac->nparam); 3928a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org text = nasm_strdup(tmpbuf); 3929a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 3930a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org case '%': 3931a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org type = TOK_ID; 3932a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org sprintf(tmpbuf, "..@%lu.", mac->unique); 3933a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org text = nasm_strcat(tmpbuf, t->text + 2); 3934a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 3935a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org case '-': 3936a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n = atoi(t->text + 2) - 1; 3937a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (n >= mac->nparam) 3938a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tt = NULL; 3939a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 3940a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3941a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (mac->nparam > 1) 3942a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n = (n + mac->rotate) % mac->nparam; 3943a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tt = mac->params[n]; 3944a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 3945a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org cc = find_cc(tt); 3946a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (cc == -1) 3947a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3948a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org error(ERR_NONFATAL, 3949a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org "macro parameter %d is not a condition code", 3950a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n + 1); 3951a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org text = NULL; 3952a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 3953a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 3954a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3955a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org type = TOK_ID; 3956a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (inverse_ccs[cc] == -1) 3957a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3958a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org error(ERR_NONFATAL, 3959a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org "condition code `%s' is not invertible", 3960a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org conditions[cc]); 3961a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org text = NULL; 3962a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 3963a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 3964a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org text = 3965a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org nasm_strdup(conditions[inverse_ccs 3966a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org [cc]]); 3967a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 3968a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 3969a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org case '+': 3970a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n = atoi(t->text + 2) - 1; 3971a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (n >= mac->nparam) 3972a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tt = NULL; 3973a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 3974a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3975a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (mac->nparam > 1) 3976a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n = (n + mac->rotate) % mac->nparam; 3977a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tt = mac->params[n]; 3978a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 3979a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org cc = find_cc(tt); 3980a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (cc == -1) 3981a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3982a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org error(ERR_NONFATAL, 3983a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org "macro parameter %d is not a condition code", 3984a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n + 1); 3985a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org text = NULL; 3986a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 3987a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 3988a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3989a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org type = TOK_ID; 3990a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org text = nasm_strdup(conditions[cc]); 3991a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 3992a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 3993a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org default: 3994a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n = atoi(t->text + 1) - 1; 3995a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (n >= mac->nparam) 3996a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tt = NULL; 3997a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org else 3998a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 3999a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (mac->nparam > 1) 4000a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org n = (n + mac->rotate) % mac->nparam; 4001a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tt = mac->params[n]; 4002a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 4003a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (tt) 4004a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 4005a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org for (i = 0; i < mac->paramlen[n]; i++) 4006a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 4007a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org *tail = 4008a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org new_Token(NULL, tt->type, tt->text, 4009a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 0); 4010a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tail = &(*tail)->next; 4011a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org tt = tt->next; 4012a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 4013a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 4014a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org text = NULL; /* we've done it here */ 4015a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 4016a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 4017a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 4018a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 4019a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 402045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!text) 402145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 402245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org delete_Token(t); 402345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 402445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 402545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 402645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = t; 402745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &t->next; 402845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->type = type; 402945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(t->text); 403045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = text; 403145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->mac = NULL; 403245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 403345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 403445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 403545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 403645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 403745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = *tail = tline; 403845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 403945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->mac = NULL; 404045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &t->next; 404145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 404245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 404345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = NULL; 404445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = thead; 404545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (; t && (tt = t->next) != NULL; t = t->next) 404645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (t->type) 404745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 404845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TOK_WHITESPACE: 404945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tt->type == TOK_WHITESPACE) 405045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 405145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = delete_Token(tt); 405245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 405345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 405445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TOK_ID: 405545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tt->type == TOK_ID || tt->type == TOK_NUMBER) 405645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 405745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *tmp = nasm_strcat(t->text, tt->text); 405845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(t->text); 405945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = tmp; 406045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = delete_Token(tt); 406145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 406245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 406345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TOK_NUMBER: 406445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tt->type == TOK_NUMBER) 406545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 406645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *tmp = nasm_strcat(t->text, tt->text); 406745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(t->text); 406845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = tmp; 406945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = delete_Token(tt); 407045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 407145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 407245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 407345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 407445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return thead; 407545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 407645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 407745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 407845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Expand all single-line macro calls made in the given line. 407945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Return the expanded version of the line. The original is deemed 408045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * to be destroyed in the process. (In reality we'll just move 408145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Tokens from input to output a lot of the time, rather than 408245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * actually bothering to destroy and replicate.) 408345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 408445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token * 408545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgexpand_smacro(Token * tline) 408645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 408745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t, *tt, *mstart, **tail, *thead; 408845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *head = NULL, *m; 408945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token **params; 409045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int *paramsize; 409145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int nparam, sparam, brackets, rescan; 409245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *org_tline = tline; 409345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Context *ctx; 409445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *mname; 409545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 409645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 409745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Trick: we should avoid changing the start token pointer since it can 409845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * be contained in "next" field of other token. Because of this 409945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * we allocate a copy of first token and work with it; at the end of 410045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * routine we copy it back 410145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 410245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (org_tline) 410345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 410445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = 410545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org new_Token(org_tline->next, org_tline->type, org_tline->text, 410645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0); 410745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->mac = org_tline->mac; 410845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(org_tline->text); 410945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org org_tline->text = NULL; 411045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 411145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 411245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org again: 411345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &thead; 411445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org thead = NULL; 411545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 411645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tline) 411745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { /* main token loop */ 411845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((mname = tline->text)) 411945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 412045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* if this token is a local macro, look in local context */ 412145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID) 412245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = get_ctx(mname, TRUE); 412345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 412445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx = NULL; 412545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!ctx) 412645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org head = smacros[hash(mname)]; 412745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 412845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org head = ctx->localmac; 412945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 413045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We've hit an identifier. As in is_mmacro below, we first 413145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * check whether the identifier is a single-line macro at 413245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * all, then think about checking for parameters if 413345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * necessary. 413445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 413545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (m = head; m; m = m->next) 413645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!mstrcmp(m->name, mname, m->casesense)) 413745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 413845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m) 413945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 414045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mstart = tline; 414145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params = NULL; 414245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramsize = NULL; 414345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m->nparam == 0) 414445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 414545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 414645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Simple case: the macro is parameterless. Discard the 414745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * one token that the macro call took, and push the 414845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * expansion back on the to-do stack. 414945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 415045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!m->expansion) 415145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 415245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp("__FILE__", m->name)) 415345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 415445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long num = 0; 415545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_src_get(&num, &(tline->text)); 415645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_quote(&(tline->text)); 415745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->type = TOK_STRING; 415845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 415945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 416045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!strcmp("__LINE__", m->name)) 416145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 416245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(tline->text); 416345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org make_tok_num(tline, yasm_intnum_create_int(nasm_src_get_linnum())); 416445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 416545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 416645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = delete_Token(tline); 416745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 416845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 416945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 417045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 417145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 417245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 417345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Complicated case: at least one macro with this name 417445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * exists and takes parameters. We must find the 417545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * parameters in the call, count them, find the SMacro 417645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * that corresponds to that form of the macro call, and 417745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * substitute for the parameters when we expand. What a 417845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * pain. 417945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 418045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*tline = tline->next; 418145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(tline);*/ 418245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do { 418345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline->next; 418445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tok_type_(t, TOK_SMAC_END)) 418545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 418645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->mac->in_progress = FALSE; 418745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = NULL; 418845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline->next = delete_Token(t); 418945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 419045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = t; 419145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } while (tok_type_(tline, TOK_WHITESPACE)); 419245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_is_(tline, "(")) 419345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 419445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 419545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This macro wasn't called with parameters: ignore 419645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the call. (Behaviour borrowed from gnu cpp.) 419745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 419845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = mstart; 419945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = NULL; 420045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 420145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 420245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 420345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int paren = 0; 420445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int white = 0; 420545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org brackets = 0; 420645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nparam = 0; 420745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sparam = PARAM_DELTA; 420845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params = nasm_malloc(sparam * sizeof(Token *)); 420945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params[0] = tline->next; 421045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramsize = nasm_malloc(sparam * sizeof(int)); 421145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramsize[0] = 0; 421245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (TRUE) 421345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { /* parameter loop */ 421445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 421545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * For some unusual expansions 421645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * which concatenates function call 421745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 421845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline->next; 421945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (tok_type_(t, TOK_SMAC_END)) 422045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 422145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->mac->in_progress = FALSE; 422245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = NULL; 422345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline->next = delete_Token(t); 422445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 422545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = t; 422645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 422745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline) 422845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 422945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 423045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "macro call expects terminating `)'"); 423145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 423245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 423345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_WHITESPACE 423445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && brackets <= 0) 423545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 423645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (paramsize[nparam]) 423745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org white++; 423845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 423945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params[nparam] = tline->next; 424045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; /* parameter loop */ 424145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 424245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_OTHER 424345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && tline->text[1] == 0) 424445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 424545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char ch = tline->text[0]; 424645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ch == ',' && !paren && brackets <= 0) 424745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 424845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (++nparam >= sparam) 424945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 425045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sparam += PARAM_DELTA; 425145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params = nasm_realloc(params, 425245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sparam * sizeof(Token *)); 425345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramsize = nasm_realloc(paramsize, 425445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sparam * sizeof(int)); 425545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 425645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params[nparam] = tline->next; 425745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramsize[nparam] = 0; 425845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org white = 0; 425945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; /* parameter loop */ 426045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 426145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ch == '{' && 426245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (brackets > 0 || (brackets == 0 && 426345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org !paramsize[nparam]))) 426445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 426545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!(brackets++)) 426645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 426745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params[nparam] = tline->next; 426845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; /* parameter loop */ 426945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 427045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 427145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ch == '}' && brackets > 0) 427245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (--brackets == 0) 427345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 427445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org brackets = -1; 427545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; /* parameter loop */ 427645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 427745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ch == '(' && !brackets) 427845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paren++; 427945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ch == ')' && brackets <= 0) 428045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (--paren < 0) 428145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 428245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 428345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (brackets < 0) 428445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 428545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org brackets = 0; 428645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "braces do not " 428745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "enclose all of macro parameter"); 428845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 428945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramsize[nparam] += white + 1; 429045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org white = 0; 429145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } /* parameter loop */ 429245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nparam++; 429345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (m && (m->nparam != nparam || 429445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mstrcmp(m->name, mname, 429545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->casesense))) 429645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = m->next; 429745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!m) 429845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING | ERR_WARN_MNP, 429945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "macro `%s' exists, " 430045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "but not taking %d parameters", 430145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mstart->text, nparam); 430245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 430345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 430445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m && m->in_progress) 430545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = NULL; 430645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!m) /* in progess or didn't find '(' or wrong nparam */ 430745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 430845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 430945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Design question: should we handle !tline, which 431045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * indicates missing ')' here, or expand those 431145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * macros anyway, which requires the (t) test a few 431245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * lines down? 431345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 431445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(params); 431545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(paramsize); 431645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = mstart; 431745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 431845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 431945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 432045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 432145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Expand the macro: we are placed on the last token of the 432245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * call, so that we can easily split the call from the 432345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * following tokens. We also start by pushing an SMAC_END 432445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * token for the cycle removal. 432545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 432645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline; 432745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t) 432845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 432945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = t->next; 433045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = NULL; 433145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 433245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = new_Token(tline, TOK_SMAC_END, NULL, 0); 433345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt->mac = m; 433445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->in_progress = TRUE; 433545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tt; 433645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (t = m->expansion; t; t = t->next) 433745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 433845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type >= TOK_SMAC_PARAM) 433945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 434045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *pcopy = tline, **ptail = &pcopy; 434145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *ttt, *pt; 434245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i; 434345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 434445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ttt = params[t->type - TOK_SMAC_PARAM]; 434545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i = paramsize[t->type - TOK_SMAC_PARAM]; 434645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org --i >= 0;) 434745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 434845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pt = *ptail = 434945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org new_Token(tline, ttt->type, ttt->text, 435045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0); 435145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ptail = &pt->next; 435245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ttt = ttt->next; 435345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 435445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = pcopy; 435545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 435645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 435745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 435845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = new_Token(tline, t->type, t->text, 0); 435945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tt; 436045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 436145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 436245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 436345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 436445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Having done that, get rid of the macro call, and clean 436545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * up the parameters. 436645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 436745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(params); 436845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(paramsize); 436945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(mstart); 437045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; /* main token loop */ 437145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 437245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 437345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 437445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 437545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tline->type == TOK_SMAC_END) 437645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 437745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->mac->in_progress = FALSE; 437845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = delete_Token(tline); 437945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 438045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 438145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 438245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = *tail = tline; 438345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tline->next; 438445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->mac = NULL; 438545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = NULL; 438645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &t->next; 438745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 438845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 438945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 439045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 439145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Now scan the entire line and look for successive TOK_IDs that resulted 439245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * after expansion (they can't be produced by tokenise()). The successive 439345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * TOK_IDs should be concatenated. 439445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Also we look for %+ tokens and concatenate the tokens before and after 439545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * them (without white spaces in between). 439645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 439745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = thead; 439845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org rescan = 0; 439945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (t) 440045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 440145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID) 440245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 440345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!t || !t->next) 440445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 440545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->next->type == TOK_ID || 440645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next->type == TOK_PREPROC_ID || 440745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next->type == TOK_NUMBER) 440845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 440945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *p = nasm_strcat(t->text, t->next->text); 441045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(t->text); 441145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = delete_Token(t->next); 441245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text = p; 441345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org rescan = 1; 441445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 441545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (t->next->type == TOK_WHITESPACE && t->next->next && 441645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next->next->type == TOK_PREPROC_ID && 441745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcmp(t->next->next->text, "%+") == 0) 441845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 441945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* free the next whitespace, the %+ token and next whitespace */ 442045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i; 442145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i = 1; i <= 3; i++) 442245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 442345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!t->next || (i != 2 && t->next->type != TOK_WHITESPACE)) 442445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 442545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->next = delete_Token(t->next); 442645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } /* endfor */ 442745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 442845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 442945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 443045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 443145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* If we concatenaded something, re-scan the line for macros */ 443245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (rescan) 443345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 443445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = thead; 443545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org goto again; 443645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 443745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 443845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (org_tline) 443945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 444045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (thead) 444145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 444245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *org_tline = *thead; 444345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* since we just gave text to org_line, don't free it */ 444445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org thead->text = NULL; 444545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org delete_Token(thead); 444645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 444745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 444845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 444945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* the expression expanded to empty line; 445045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org we can't return NULL for some reasons 445145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org we just set the line to a single WHITESPACE token. */ 445245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memset(org_tline, 0, sizeof(*org_tline)); 445345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org org_tline->text = NULL; 445445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org org_tline->type = TOK_WHITESPACE; 445545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 445645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org thead = org_tline; 445745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 445845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 445945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return thead; 446045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 446145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 446245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 446345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Similar to expand_smacro but used exclusively with macro identifiers 446445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * right before they are fetched in. The reason is that there can be 446545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * identifiers consisting of several subparts. We consider that if there 446645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are more than one element forming the name, user wants a expansion, 446745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * otherwise it will be left as-is. Example: 446845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 446945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %define %$abc cde 447045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 447145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the identifier %$abc will be left as-is so that the handler for %define 447245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * will suck it and define the corresponding value. Other case: 447345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 447445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * %define _%$abc cde 447545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 447645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * In this case user wants name to be expanded *before* %define starts 447745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * working, so we'll expand %$abc into something (if it has a value; 447845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * otherwise it will be left as-is) then concatenate all successive 447945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * PP_IDs into one. 448045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 448145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Token * 448245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgexpand_id(Token * tline) 448345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 448445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *cur, *oldnext = NULL; 448545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 448645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tline || !tline->next) 448745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tline; 448845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 448945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur = tline; 449045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (cur->next && 449145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (cur->next->type == TOK_ID || 449245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur->next->type == TOK_PREPROC_ID || cur->next->type == TOK_NUMBER)) 449345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur = cur->next; 449445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 449545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* If identifier consists of just one token, don't expand */ 449645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (cur == tline) 449745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tline; 449845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 449945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (cur) 450045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 450145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org oldnext = cur->next; /* Detach the tail past identifier */ 450245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur->next = NULL; /* so that expand_smacro stops here */ 450345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 450445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 450545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline); 450645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 450745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (cur) 450845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 450945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* expand_smacro possibly changhed tline; re-scan for EOL */ 451045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur = tline; 451145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (cur && cur->next) 451245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur = cur->next; 451345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (cur) 451445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cur->next = oldnext; 451545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 451645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 451745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return tline; 451845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 451945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 452045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 452145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Determine whether the given line constitutes a multi-line macro 452245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * call, and return the MMacro structure called if so. Doesn't have 452345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * to check for an initial label - that's taken care of in 452445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * expand_mmacro - but must check numbers of parameters. Guaranteed 452545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * to be called with tline->type == TOK_ID, so the putative macro 452645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * name is easy to find. 452745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 452845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic MMacro * 452945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgis_mmacro(Token * tline, Token *** params_array) 453045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 453145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *head, *m; 453245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token **params; 453345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int nparam; 453445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 453545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org head = mmacros[hash(tline->text)]; 453645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 453745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 453845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Efficiency: first we see if any macro exists with the given 453945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * name. If not, we can return NULL immediately. _Then_ we 454045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * count the parameters, and then we look further along the 454145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * list if necessary to find the proper MMacro. 454245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 454345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (m = head; m; m = m->next) 454445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!mstrcmp(m->name, tline->text, m->casesense)) 454545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 454645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!m) 454745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 454845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 454945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 455045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * OK, we have a potential macro. Count and demarcate the 455145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * parameters. 455245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 455345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org count_mmac_params(tline->next, &nparam, ¶ms); 455445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 455545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 455645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * So we know how many parameters we've got. Find the MMacro 455745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * structure that handles this number. 455845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 455945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (m) 456045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 456145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m->nparam_min <= nparam && (m->plus || nparam <= m->nparam_max)) 456245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 456345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 456445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This one is right. Just check if cycle removal 456545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * prohibits us using it before we actually celebrate... 456645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 456745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m->in_progress) 456845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 456945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#if 0 457045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, 457145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "self-reference in multi-line macro `%s'", m->name); 457245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 457345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(params); 457445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 457545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 457645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 457745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * It's right, and we can use it. Add its default 457845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * parameters to the end of our list if necessary. 457945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 458045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m->defaults && nparam < m->nparam_min + m->ndefs) 458145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 458245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params = 458345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_realloc(params, 458445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ((m->nparam_min + m->ndefs + 1) * sizeof(*params))); 458545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (nparam < m->nparam_min + m->ndefs) 458645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 458745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params[nparam] = m->defaults[nparam - m->nparam_min]; 458845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nparam++; 458945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 459045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 459145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 459245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If we've gone over the maximum parameter count (and 459345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * we're in Plus mode), ignore parameters beyond 459445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * nparam_max. 459545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 459645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m->plus && nparam > m->nparam_max) 459745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nparam = m->nparam_max; 459845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 459945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Then terminate the parameter list, and leave. 460045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 460145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!params) 460245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { /* need this special case */ 460345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params = nasm_malloc(sizeof(*params)); 460445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nparam = 0; 460545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 460645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params[nparam] = NULL; 460745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *params_array = params; 460845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return m; 460945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 461045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 461145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This one wasn't right: look for the next one with the 461245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * same name. 461345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 461445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (m = m->next; m; m = m->next) 461545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!mstrcmp(m->name, tline->text, m->casesense)) 461645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 461745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 461845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 461945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 462045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * After all that, we didn't find one with the right number of 462145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * parameters. Issue a warning, and fail to expand the macro. 462245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 462345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_WARNING | ERR_WARN_MNP, 462445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "macro `%s' exists, but not taking %d parameters", 462545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline->text, nparam); 462645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(params); 462745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 462845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 462945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 463045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 463145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Expand the multi-line macro call made by the given line, if 463245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * there is one to be expanded. If there is, push the expansion on 463345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * istk->expansion and return 1. Otherwise return 0. 463445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 463545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 463645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgexpand_mmacro(Token * tline) 463745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 463845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *startline = tline; 463945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *label = NULL; 464045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int dont_prepend = 0; 464145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token **params, *t, *tt; 464245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *m; 464345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l, *ll; 464445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i, nparam; 464545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long *paramlen; 464645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 464745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tline; 464845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(t); 464945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* if (!tok_type_(t, TOK_ID)) Lino 02/25/02 */ 465045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID)) 465145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 465245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m = is_mmacro(t, ¶ms); 465345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!m) 465445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 465545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *last; 465645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 465745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We have an id which isn't a macro call. We'll assume 465845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * it might be a label; we'll also check to see if a 465945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * colon follows it. Then, if there's another id after 466045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * that lot, we'll check it again for macro-hood. 466145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 466245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org label = last = t; 466345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 466445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_type_(t, TOK_WHITESPACE)) 466545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = t, t = t->next; 466645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_is_(t, ":")) 466745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 466845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dont_prepend = 1; 466945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = t, t = t->next; 467045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_type_(t, TOK_WHITESPACE)) 467145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = t, t = t->next; 467245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 467345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, ¶ms)) == NULL) 467445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 467545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last->next = NULL; 467645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = t; 467745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 467845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 467945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 468045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Fix up the parameters: this involves stripping leading and 468145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * trailing whitespace, then stripping braces if they are 468245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * present. 468345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 468445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (nparam = 0; params[nparam]; nparam++) 468545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ; 468645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL; 468745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 468845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i = 0; params[i]; i++) 468945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 469045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int brace = FALSE; 469145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int comma = (!m->plus || i < nparam - 1); 469245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 469345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = params[i]; 469445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org skip_white_(t); 469545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tok_is_(t, "{")) 469645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next, brace = TRUE, comma = FALSE; 469745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org params[i] = t; 469845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramlen[i] = 0; 469945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (t) 470045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 470145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (comma && t->type == TOK_OTHER && !strcmp(t->text, ",")) 470245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; /* ... because we have hit a comma */ 470345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (comma && t->type == TOK_WHITESPACE && tok_is_(t->next, ",")) 470445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; /* ... or a space then a comma */ 470545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}")) 470645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; /* ... or a brace */ 470745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = t->next; 470845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org paramlen[i]++; 470945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 471045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 471145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 471245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 471345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * OK, we have a MMacro structure together with a set of 471445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * parameters. We must now go through the expansion and push 471545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * copies of each Line on to istk->expansion. Substitution of 471645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * parameter tokens and macro-local tokens doesn't get done 471745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * until the single-line macro substitution process; this is 471845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * because delaying them allows us to change the semantics 471945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * later through %rotate. 472045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 472145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * First, push an end marker on to istk->expansion, mark this 472245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * macro as in progress, and set up its invocation-specific 472345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * variables. 472445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 472545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll = nasm_malloc(sizeof(Line)); 472645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->next = istk->expansion; 472745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->finishes = m; 472845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->first = NULL; 472945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = ll; 473045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 473145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->in_progress = TRUE; 473245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->params = params; 473345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->iline = tline; 473445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->nparam = nparam; 473545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->rotate = 0; 473645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->paramlen = paramlen; 473745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->unique = unique++; 473845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->lineno = 0; 473945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 474045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org m->next_active = istk->mstk; 474145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->mstk = m; 474245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 474345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (l = m->expansion; l; l = l->next) 474445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 474545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token **tail; 474645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 474745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll = nasm_malloc(sizeof(Line)); 474845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->finishes = NULL; 474945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->next = istk->expansion; 475045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = ll; 475145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &ll->first; 475245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 475345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (t = l->first; t; t = t->next) 475445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 475545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *x = t; 475645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->type == TOK_PREPROC_ID && 475745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t->text[1] == '0' && t->text[2] == '0') 475845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 475945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dont_prepend = -1; 476045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org x = label; 476145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!x) 476245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 476345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 476445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = *tail = new_Token(NULL, x->type, x->text, 0); 476545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &tt->next; 476645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 476745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = NULL; 476845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 476945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 477045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 477145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If we had a label, push it on as the first line of 477245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the macro expansion. 477345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 477445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (label) 477545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 477645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (dont_prepend < 0) 477745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(startline); 477845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 477945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 478045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll = nasm_malloc(sizeof(Line)); 478145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->finishes = NULL; 478245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->next = istk->expansion; 478345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = ll; 478445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->first = startline; 478545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!dont_prepend) 478645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 478745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (label->next) 478845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org label = label->next; 478945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0); 479045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 479145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 479245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 479345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 479445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO); 479545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 479645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 479745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 479845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 479945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 4800a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org * Since preprocessor always operates only on the line that didn't 4801a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org * arrive yet, we should always use ERR_OFFBY1. Also since user 480245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * won't want to see same error twice (preprocessing is done once 480345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * per pass) we will want to show errors only during pass one. 480445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 480545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 480645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgerror(int severity, const char *fmt, ...) 480745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 480845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org va_list arg; 480945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char buff[1024]; 481045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 481145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* If we're in a dead branch of IF or something like it, ignore the error */ 481245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (istk && istk->conds && !emitting(istk->conds->state)) 481345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 481445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 481545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org va_start(arg, fmt); 4816a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#ifdef HAVE_VSNPRINTF 4817a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org vsnprintf(buff, sizeof(buff), fmt, arg); 4818a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#else 481945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vsprintf(buff, fmt, arg); 4820a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#endif 482145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org va_end(arg); 482245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 482345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (istk && istk->mstk && istk->mstk->name) 482445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org _error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name, 482545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->mstk->lineno, buff); 482645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 482745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org _error(severity | ERR_PASS1, "%s", buff); 482845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 482945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 483045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 483145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpp_reset(FILE *f, const char *file, int apass, efunc errfunc, evalfunc eval, 483245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ListGen * listgen) 483345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 483445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int h; 483545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 483645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org first_fp = f; 483745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org _error = errfunc; 483845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cstk = NULL; 483945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk = nasm_malloc(sizeof(Include)); 484045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->next = NULL; 484145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->conds = NULL; 484245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = NULL; 484345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->mstk = NULL; 484445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->fp = f; 484545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->fname = NULL; 484645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(nasm_src_set_fname(nasm_strdup(file))); 484745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_src_set_linnum(0); 484845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->lineinc = 1; 484945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining = NULL; 485045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nested_mac_count = 0; 485145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nested_rep_count = 0; 485245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (h = 0; h < NHASH; h++) 485345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 485445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmacros[h] = NULL; 485545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smacros[h] = NULL; 485645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 485745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unique = 0; 485845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tasm_compatible_mode) { 485945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pp_extra_stdmac(tasm_compat_macros); 486045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 486145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list = listgen; 486245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org evaluate = eval; 486345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pass = apass; 486445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org first_line = 1; 486545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 486645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 486745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 486845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Nasty hack: here we push the contents of `predef' on 486945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * to the top-level expansion stack, since this is the 487045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * most convenient way to implement the pre-include and 487145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * pre-define features. 487245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 487345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 487445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpoke_predef(Line *predef_lines) 487545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 487645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *pd, *l; 487745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *head, **tail, *t; 487845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 487945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (pd = predef_lines; pd; pd = pd->next) 488045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 488145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org head = NULL; 488245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &head; 488345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (t = pd->first; t; t = t->next) 488445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 488545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = new_Token(NULL, t->type, t->text, 0); 488645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &(*tail)->next; 488745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 488845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = nasm_malloc(sizeof(Line)); 488945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->next = istk->expansion; 489045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->first = head; 489145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes = FALSE; 489245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = l; 489345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 489445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 489545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 489645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic char * 489745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpp_getline(void) 489845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 489945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *line; 490045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *tline; 490145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 490245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (1) 490345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 490445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 490545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Fetch a tokenised line, either from the macro-expansion 490645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * buffer or from the input file. 490745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 490845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = NULL; 490945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 491045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (first_line) 491145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 491245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Reverse order */ 491345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org poke_predef(predef); 491445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org poke_predef(stddef); 491545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org poke_predef(builtindef); 491645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org first_line = 0; 491745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 491845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 491945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!istk) 492045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 492145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (istk->expansion && istk->expansion->finishes) 492245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 492345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l = istk->expansion; 492445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!l->finishes->name && l->finishes->in_progress > 1) 492545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 492645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *ll; 492745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 492845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 492945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This is a macro-end marker for a macro with no 493045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * name, which means it's not really a macro at all 493145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * but a %rep block, and the `in_progress' field is 493245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * more than 1, meaning that we still need to 493345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * repeat. (1 means the natural last repetition; 0 493445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * means termination by %exitrep.) We have 493545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * therefore expanded up to the %endrep, and must 493645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * push the whole block on to the expansion buffer 493745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * again. We don't bother to remove the macro-end 493845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * marker: we'd only have to generate another one 493945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * if we did. 494045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 494145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes->in_progress--; 494245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (l = l->finishes->expansion; l; l = l->next) 494345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 494445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t, *tt, **tail; 494545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 494645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll = nasm_malloc(sizeof(Line)); 494745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->next = istk->expansion; 494845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->finishes = NULL; 494945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ll->first = NULL; 495045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &ll->first; 495145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 495245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (t = l->first; t; t = t->next) 495345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 495445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (t->text || t->type == TOK_WHITESPACE) 495545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 495645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tt = *tail = new_Token(NULL, t->type, t->text, 0); 495745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tail = &tt->next; 495845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 495945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 496045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 496145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = ll; 496245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 496345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 496445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 496545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 496645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 496745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Check whether a `%rep' was started and not ended 496845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * within this macro expansion. This can happen and 496945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * should be detected. It's a fatal error because 497045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * I'm too confused to work out how to recover 497145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * sensibly from it. 497245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 497345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defining) 497445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 497545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defining->name) 497645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_PANIC, "defining with name in expansion"); 497745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (istk->mstk->name) 497845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "`%%rep' without `%%endrep' within" 497945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org " expansion of macro `%s'", istk->mstk->name); 498045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 498145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 498245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 498345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * FIXME: investigate the relationship at this point between 498445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * istk->mstk and l->finishes 498545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 498645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 498745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *m = istk->mstk; 498845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->mstk = m->next_active; 498945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (m->name) 499045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 499145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 499245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This was a real macro call, not a %rep, and 499345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * therefore the parameter information needs to 499445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * be freed. 499545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 499645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(m->params); 499745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(m->iline); 499845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(m->paramlen); 499945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes->in_progress = FALSE; 500045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 500145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 500245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_mmacro(m); 500345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 500445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = l->next; 500545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(l); 500645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list->downlevel(LIST_MACRO); 500745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 500845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 500945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (1) 501045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { /* until we get a line we can use */ 501145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 501245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (istk->expansion) 501345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { /* from a macro expansion */ 501445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *p; 501545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l = istk->expansion; 501645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (istk->mstk) 501745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->mstk->lineno++; 501845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = l->first; 501945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk->expansion = l->next; 502045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(l); 502145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = detoken(tline, FALSE); 502245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list->line(LIST_MACRO, p); 502345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(p); 502445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 502545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 502645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = read_line(); 502745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (line) 502845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { /* from the current input file */ 502945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = prepreproc(line); 503045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tokenise(line); 503145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(line); 503245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 503345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 503445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 503545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The current file has ended; work down the istk 503645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 503745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 503845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Include *i = istk; 503945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i->fp != first_fp) 504045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fclose(i->fp); 504145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i->conds) 504245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_FATAL, "expected `%%endif' before end of file"); 504345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* only set line and file name if there's a next node */ 504445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i->next) 504545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 504645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_src_set_linnum(i->lineno); 504745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(nasm_src_set_fname(nasm_strdup(i->fname))); 504845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 504945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk = i->next; 505045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org list->downlevel(LIST_INCLUDE); 505145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(i); 505245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!istk) 505345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 505445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (istk->expansion && istk->expansion->finishes) 505545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 505645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 505745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 505845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 505945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 506045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We must expand MMacro parameters and MMacro-local labels 506145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * _before_ we plunge into directive processing, to cope 506245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * with things like `%define something %1' such as STRUC 506345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * uses. Unless we're _defining_ a MMacro, in which case 506445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * those tokens should be left alone to go into the 506545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * definition; and unless we're in a non-emitting 506645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * condition, in which case we don't want to meddle with 506745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * anything. 506845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 506945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!defining && !(istk->conds && !emitting(istk->conds->state))) 507045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_mmac_params(tline); 507145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 507245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 507345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Check the line to see if it's a preprocessor directive. 507445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 507545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (do_directive(tline) == DIRECTIVE_FOUND) 507645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 507745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 507845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 507945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (defining) 508045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 508145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 508245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We're defining a multi-line macro. We emit nothing 508345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * at all, and just 508445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * shove the tokenised line on to the macro definition. 508545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 508645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l = nasm_malloc(sizeof(Line)); 508745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->next = defining->expansion; 508845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->first = tline; 508945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes = FALSE; 509045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->expansion = l; 509145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 509245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 509345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (istk->conds && !emitting(istk->conds->state)) 509445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 509545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 509645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We're in a non-emitting branch of a condition block. 509745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Emit nothing at all, not even a blank line: when we 509845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * emerge from the condition we'll give a line-number 509945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * directive so we keep our place correctly. 510045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 510145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 510245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 510345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 510445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (istk->mstk && !istk->mstk->in_progress) 510545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 510645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 510745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We're in a %rep block which has been terminated, so 510845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * we're walking through to the %endrep without 510945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * emitting anything. Emit nothing at all, not even a 511045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * blank line: when we emerge from the %rep block we'll 511145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * give a line-number directive so we keep our place 511245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * correctly. 511345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 511445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 511545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 511645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 511745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 511845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 511945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = expand_smacro(tline); 512045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!expand_mmacro(tline)) 512145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 512245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 512345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * De-tokenise the line again, and emit it. 512445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 512545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (tasm_compatible_mode) 512645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tline = tasm_join_tokens(tline); 512745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 512845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = detoken(tline, TRUE); 512945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(tline); 513045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 513145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 513245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 513345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 513445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; /* expand_mmacro calls free_tlist */ 513545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 513645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 513745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 513845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 513945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return line; 514045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 514145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 514245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 514345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpp_cleanup(int pass_) 514445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 514545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int h; 514645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 514745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pass_ == 1) 514845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 514945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (defining) 515045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 515145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org error(ERR_NONFATAL, "end of file while still defining macro `%s'", 515245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org defining->name); 515345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_mmacro(defining); 515445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 515545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 515645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 515745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (cstk) 515845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx_pop(); 515945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (h = 0; h < NHASH; h++) 516045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 516145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (mmacros[h]) 516245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 516345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MMacro *m = mmacros[h]; 516445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mmacros[h] = mmacros[h]->next; 516545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_mmacro(m); 516645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 516745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (smacros[h]) 516845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 516945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SMacro *s = smacros[h]; 517045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org smacros[h] = smacros[h]->next; 517145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(s->name); 517245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_tlist(s->expansion); 517345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(s); 517445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 517545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 517645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (istk) 517745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 517845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Include *i = istk; 517945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org istk = istk->next; 518045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i->fp != first_fp) 518145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fclose(i->fp); 518245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(i->fname); 518345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(i); 518445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 518545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (cstk) 518645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ctx_pop(); 518745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pass_ == 0) 518845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 518945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_llist(builtindef); 519045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_llist(stddef); 519145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org free_llist(predef); 5192a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org builtindef = NULL; 5193a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org stddef = NULL; 5194a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org predef = NULL; 5195a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org freeTokens = NULL; 519645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org delete_Blocks(); 5197a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org blocks.next = NULL; 5198a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org blocks.chunk = NULL; 519945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 520045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 520145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 520245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 520345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpp_pre_include(const char *fname) 520445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 520545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *inc, *space, *name; 520645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l; 520745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 520845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0); 520945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org space = new_Token(name, TOK_WHITESPACE, NULL, 0); 521045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org inc = new_Token(space, TOK_PREPROC_ID, "%include", 0); 521145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 521245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = nasm_malloc(sizeof(Line)); 521345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->next = predef; 521445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->first = inc; 521545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes = FALSE; 521645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org predef = l; 521745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 521845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 521945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 522045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpp_pre_define(char *definition) 522145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 522245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *def, *space; 522345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l; 522445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *equals; 522545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 522645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org equals = strchr(definition, '='); 522745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org space = new_Token(NULL, TOK_WHITESPACE, NULL, 0); 522845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def = new_Token(space, TOK_PREPROC_ID, "%define", 0); 522945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (equals) 523045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *equals = ' '; 523145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org space->next = tokenise(definition); 523245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (equals) 523345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *equals = '='; 523445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 523545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = nasm_malloc(sizeof(Line)); 523645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->next = predef; 523745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->first = def; 523845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes = FALSE; 523945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org predef = l; 524045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 524145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 524245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 524345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpp_pre_undefine(char *definition) 524445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 524545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *def, *space; 524645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l; 524745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 524845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org space = new_Token(NULL, TOK_WHITESPACE, NULL, 0); 524945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def = new_Token(space, TOK_PREPROC_ID, "%undef", 0); 525045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org space->next = tokenise(definition); 525145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 525245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = nasm_malloc(sizeof(Line)); 525345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->next = predef; 525445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->first = def; 525545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes = FALSE; 525645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org predef = l; 525745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 525845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 525945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 526045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpp_builtin_define(char *definition) 526145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 526245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *def, *space; 526345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l; 526445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *equals; 526545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 526645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org equals = strchr(definition, '='); 526745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org space = new_Token(NULL, TOK_WHITESPACE, NULL, 0); 526845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def = new_Token(space, TOK_PREPROC_ID, "%define", 0); 526945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (equals) 527045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *equals = ' '; 527145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org space->next = tokenise(definition); 527245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (equals) 527345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *equals = '='; 527445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 527545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = nasm_malloc(sizeof(Line)); 527645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->next = builtindef; 527745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->first = def; 527845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes = FALSE; 527945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org builtindef = l; 528045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 528145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 528245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 528345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpp_extra_stdmac(const char **macros) 528445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 528545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char **lp; 528645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 528745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (lp=macros; *lp; lp++) 528845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 528945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *macro; 529045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Token *t; 529145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Line *l; 529245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 529345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro = nasm_strdup(*lp); 529445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t = tokenise(macro); 529545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nasm_free(macro); 529645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 529745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l = nasm_malloc(sizeof(Line)); 529845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->next = stddef; 529945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->first = t; 530045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org l->finishes = FALSE; 530145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org stddef = l; 530245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 530345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 530445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 530545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 530645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmake_tok_num(Token * tok, yasm_intnum *val) 530745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 530845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tok->text = yasm_intnum_get_str(val); 530945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tok->type = TOK_NUMBER; 5310d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org yasm_intnum_destroy(val); 531145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 531245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 531345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgPreproc nasmpp = { 531445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pp_reset, 531545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pp_getline, 531645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pp_cleanup 531745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 5318