mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-07-24 10:25:42 -04:00
preproc: implement %str() and %strcat() functions
Add function equivalents of the %defstr and %strcat directives. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
a5d0284634
commit
57fbd34d9f
@ -3567,6 +3567,47 @@ static void assign_smacro(const char *mname, bool casesense,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement string concatenation as used by the %strcat directive
|
||||||
|
* and function.
|
||||||
|
*/
|
||||||
|
static Token *pp_strcat(Token *tline, const char *dname)
|
||||||
|
{
|
||||||
|
|
||||||
|
size_t len;
|
||||||
|
Token *t;
|
||||||
|
char *q, *qbuf;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
list_for_each(t, tline) {
|
||||||
|
switch (t->type) {
|
||||||
|
case TOKEN_WHITESPACE:
|
||||||
|
case TOKEN_COMMA:
|
||||||
|
break;
|
||||||
|
case TOKEN_STR:
|
||||||
|
unquote_token(t);
|
||||||
|
len += t->len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nasm_nonfatal("non-string passed to `%s': %s", dname,
|
||||||
|
tok_text(t));
|
||||||
|
free_tlist(tline);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q = qbuf = nasm_malloc(len+1);
|
||||||
|
list_for_each(t, tline) {
|
||||||
|
if (t->type == TOKEN_INTERNAL_STR)
|
||||||
|
q = mempcpy(q, tok_text(t), t->len);
|
||||||
|
}
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
|
return make_tok_qstr_len(NULL, qbuf, len);
|
||||||
|
nasm_free(qbuf);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find and process preprocessor directive in passed line
|
* find and process preprocessor directive in passed line
|
||||||
* Find out if a line contains a preprocessor directive, and deal
|
* Find out if a line contains a preprocessor directive, and deal
|
||||||
@ -3588,7 +3629,7 @@ static int do_directive(Token *tline, Token **output)
|
|||||||
bool casesense;
|
bool casesense;
|
||||||
int offset;
|
int offset;
|
||||||
const char *p;
|
const char *p;
|
||||||
char *q, *qbuf;
|
char *q;
|
||||||
const char *found_path;
|
const char *found_path;
|
||||||
const char *mname;
|
const char *mname;
|
||||||
struct ppscan pps;
|
struct ppscan pps;
|
||||||
@ -3601,7 +3642,6 @@ static int do_directive(Token *tline, Token **output)
|
|||||||
struct tokenval tokval;
|
struct tokenval tokval;
|
||||||
expr *evalresult;
|
expr *evalresult;
|
||||||
int64_t count;
|
int64_t count;
|
||||||
size_t len;
|
|
||||||
errflags severity;
|
errflags severity;
|
||||||
const char *dname; /* Name of directive, for messages */
|
const char *dname; /* Name of directive, for messages */
|
||||||
|
|
||||||
@ -4717,38 +4757,12 @@ issue_error:
|
|||||||
tline = expand_smacro(tline->next);
|
tline = expand_smacro(tline->next);
|
||||||
last->next = NULL;
|
last->next = NULL;
|
||||||
|
|
||||||
len = 0;
|
macro_start = pp_strcat(tline, dname);
|
||||||
list_for_each(t, tline) {
|
|
||||||
switch (t->type) {
|
|
||||||
case TOKEN_WHITESPACE:
|
|
||||||
case TOKEN_COMMA:
|
|
||||||
break;
|
|
||||||
case TOKEN_STR:
|
|
||||||
unquote_token(t);
|
|
||||||
len += t->len;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
nasm_nonfatal("non-string passed to `%s': %s", dname,
|
|
||||||
tok_text(t));
|
|
||||||
free_tlist(tline);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
q = qbuf = nasm_malloc(len+1);
|
|
||||||
list_for_each(t, tline) {
|
|
||||||
if (t->type == TOKEN_INTERNAL_STR)
|
|
||||||
q = mempcpy(q, tok_text(t), t->len);
|
|
||||||
}
|
|
||||||
*q = '\0';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We now have a macro name, an implicit parameter count of
|
* We now have a macro name, an implicit parameter count of
|
||||||
* zero, and a numeric token to use as an expansion. Create
|
* zero, and a string token to use as an expansion. Create
|
||||||
* and store an SMacro.
|
* and store an SMacro.
|
||||||
*/
|
*/
|
||||||
macro_start = make_tok_qstr_len(NULL, qbuf, len);
|
|
||||||
nasm_free(qbuf);
|
|
||||||
define_smacro(mname, casesense, macro_start, NULL);
|
define_smacro(mname, casesense, macro_start, NULL);
|
||||||
free_tlist(tline);
|
free_tlist(tline);
|
||||||
break;
|
break;
|
||||||
@ -6838,6 +6852,9 @@ stdmac_is(const SMacro *s, Token **params, int nparams)
|
|||||||
/*
|
/*
|
||||||
* Join all expanded macro arguments with commas, e.g. %eval().
|
* Join all expanded macro arguments with commas, e.g. %eval().
|
||||||
* Remember that this needs to output the tokens in reverse order.
|
* Remember that this needs to output the tokens in reverse order.
|
||||||
|
*
|
||||||
|
* This can also be used when only single argument is already ready
|
||||||
|
* to be emitted, e.g. %str().
|
||||||
*/
|
*/
|
||||||
static Token *
|
static Token *
|
||||||
stdmac_join(const SMacro *s, Token **params, int nparams)
|
stdmac_join(const SMacro *s, Token **params, int nparams)
|
||||||
@ -6865,6 +6882,14 @@ stdmac_join(const SMacro *s, Token **params, int nparams)
|
|||||||
return tline;
|
return tline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* %strcat() function */
|
||||||
|
static Token *
|
||||||
|
stdmac_strcat(const SMacro *s, Token **params, int nparams)
|
||||||
|
{
|
||||||
|
nasm_assert(nparams == 1);
|
||||||
|
return pp_strcat(expand_smacro_noreset(params[0]), s->name);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add magic standard macros */
|
/* Add magic standard macros */
|
||||||
struct magic_macros {
|
struct magic_macros {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -6881,6 +6906,8 @@ static void pp_add_magic_stdmac(void)
|
|||||||
{ "__?BITS?__", true, 0, 0, stdmac_bits },
|
{ "__?BITS?__", true, 0, 0, stdmac_bits },
|
||||||
{ "__?PTR?__", true, 0, 0, stdmac_ptr },
|
{ "__?PTR?__", true, 0, 0, stdmac_ptr },
|
||||||
{ "%eval", false, 1, SPARM_EVAL|SPARM_VARADIC, stdmac_join },
|
{ "%eval", false, 1, SPARM_EVAL|SPARM_VARADIC, stdmac_join },
|
||||||
|
{ "%str", false, 1, SPARM_GREEDY|SPARM_STR, stdmac_join },
|
||||||
|
{ "%strcat", false, 1, SPARM_GREEDY, stdmac_strcat },
|
||||||
{ NULL, false, 0, 0, NULL }
|
{ NULL, false, 0, 0, NULL }
|
||||||
};
|
};
|
||||||
const struct magic_macros *m;
|
const struct magic_macros *m;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user