mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-09-22 10:43:39 -04:00
preproc: %strcat directive to concatenate quoted strings
I noticed there was no sane way to concatenate the contents of quoted strings, so add the %strcat directive. These really need to become preprocessor functions at some stage.
This commit is contained in:
@@ -44,6 +44,7 @@
|
|||||||
%repl
|
%repl
|
||||||
%rotate
|
%rotate
|
||||||
%stacksize
|
%stacksize
|
||||||
|
%strcat
|
||||||
%strlen
|
%strlen
|
||||||
%substr
|
%substr
|
||||||
%undef
|
%undef
|
||||||
|
98
preproc.c
98
preproc.c
@@ -166,7 +166,10 @@ enum pp_token_type {
|
|||||||
struct Token {
|
struct Token {
|
||||||
Token *next;
|
Token *next;
|
||||||
char *text;
|
char *text;
|
||||||
SMacro *mac; /* associated macro for TOK_SMAC_END */
|
union {
|
||||||
|
SMacro *mac; /* associated macro for TOK_SMAC_END */
|
||||||
|
size_t len; /* scratch length field */
|
||||||
|
} a; /* Auxiliary data */
|
||||||
enum pp_token_type type;
|
enum pp_token_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1008,7 +1011,7 @@ static void delete_Blocks(void)
|
|||||||
/*
|
/*
|
||||||
* this function creates a new Token and passes a pointer to it
|
* this function creates a new Token and passes a pointer to it
|
||||||
* back to the caller. It sets the type and text elements, and
|
* back to the caller. It sets the type and text elements, and
|
||||||
* also the mac and next elements to NULL.
|
* also the a.mac and next elements to NULL.
|
||||||
*/
|
*/
|
||||||
static Token *new_Token(Token * next, enum pp_token_type type,
|
static Token *new_Token(Token * next, enum pp_token_type type,
|
||||||
const char *text, int txtlen)
|
const char *text, int txtlen)
|
||||||
@@ -1025,7 +1028,7 @@ static Token *new_Token(Token * next, enum pp_token_type type,
|
|||||||
t = freeTokens;
|
t = freeTokens;
|
||||||
freeTokens = t->next;
|
freeTokens = t->next;
|
||||||
t->next = next;
|
t->next = next;
|
||||||
t->mac = NULL;
|
t->a.mac = NULL;
|
||||||
t->type = type;
|
t->type = type;
|
||||||
if (type == TOK_WHITESPACE || text == NULL) {
|
if (type == TOK_WHITESPACE || text == NULL) {
|
||||||
t->text = NULL;
|
t->text = NULL;
|
||||||
@@ -1829,7 +1832,7 @@ static int do_directive(Token * tline)
|
|||||||
bool casesense;
|
bool casesense;
|
||||||
int k, m;
|
int k, m;
|
||||||
int offset;
|
int offset;
|
||||||
char *p, *mname;
|
char *p, *pp, *mname;
|
||||||
Include *inc;
|
Include *inc;
|
||||||
Context *ctx;
|
Context *ctx;
|
||||||
Cond *cond;
|
Cond *cond;
|
||||||
@@ -1840,6 +1843,7 @@ static int do_directive(Token * tline)
|
|||||||
expr *evalresult;
|
expr *evalresult;
|
||||||
MMacro *tmp_defining; /* Used when manipulating rep_nest */
|
MMacro *tmp_defining; /* Used when manipulating rep_nest */
|
||||||
int64_t count;
|
int64_t count;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
origline = tline;
|
origline = tline;
|
||||||
|
|
||||||
@@ -2722,7 +2726,7 @@ static int do_directive(Token * tline)
|
|||||||
macro_start->next = NULL;
|
macro_start->next = NULL;
|
||||||
macro_start->text = nasm_quote(p, strlen(p));
|
macro_start->text = nasm_quote(p, strlen(p));
|
||||||
macro_start->type = TOK_STRING;
|
macro_start->type = TOK_STRING;
|
||||||
macro_start->mac = NULL;
|
macro_start->a.mac = NULL;
|
||||||
nasm_free(p);
|
nasm_free(p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2787,7 +2791,7 @@ static int do_directive(Token * tline)
|
|||||||
macro_start->next = NULL;
|
macro_start->next = NULL;
|
||||||
macro_start->text = nasm_quote(p, strlen(p));
|
macro_start->text = nasm_quote(p, strlen(p));
|
||||||
macro_start->type = TOK_STRING;
|
macro_start->type = TOK_STRING;
|
||||||
macro_start->mac = NULL;
|
macro_start->a.mac = NULL;
|
||||||
if (xsl)
|
if (xsl)
|
||||||
nasm_free(xsl);
|
nasm_free(xsl);
|
||||||
|
|
||||||
@@ -2838,7 +2842,7 @@ static int do_directive(Token * tline)
|
|||||||
macro_start = nasm_malloc(sizeof(*macro_start));
|
macro_start = nasm_malloc(sizeof(*macro_start));
|
||||||
macro_start->next = NULL;
|
macro_start->next = NULL;
|
||||||
make_tok_num(macro_start, nasm_unquote(t->text, NULL));
|
make_tok_num(macro_start, nasm_unquote(t->text, NULL));
|
||||||
macro_start->mac = NULL;
|
macro_start->a.mac = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We now have a macro name, an implicit parameter count of
|
* We now have a macro name, an implicit parameter count of
|
||||||
@@ -2850,6 +2854,66 @@ static int do_directive(Token * tline)
|
|||||||
free_tlist(origline);
|
free_tlist(origline);
|
||||||
return DIRECTIVE_FOUND;
|
return DIRECTIVE_FOUND;
|
||||||
|
|
||||||
|
case PP_STRCAT:
|
||||||
|
casesense = true;
|
||||||
|
|
||||||
|
tline = tline->next;
|
||||||
|
skip_white_(tline);
|
||||||
|
tline = expand_id(tline);
|
||||||
|
if (!tline || (tline->type != TOK_ID &&
|
||||||
|
(tline->type != TOK_PREPROC_ID ||
|
||||||
|
tline->text[1] != '$'))) {
|
||||||
|
error(ERR_NONFATAL,
|
||||||
|
"`%%strcat' expects a macro identifier as first parameter");
|
||||||
|
free_tlist(origline);
|
||||||
|
return DIRECTIVE_FOUND;
|
||||||
|
}
|
||||||
|
ctx = get_ctx(tline->text, false);
|
||||||
|
|
||||||
|
mname = tline->text;
|
||||||
|
last = tline;
|
||||||
|
tline = expand_smacro(tline->next);
|
||||||
|
last->next = NULL;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
for (t = tline; t; t = t->next) {
|
||||||
|
switch (t->type) {
|
||||||
|
case TOK_WHITESPACE:
|
||||||
|
break;
|
||||||
|
case TOK_STRING:
|
||||||
|
len += t->a.len = nasm_unquote(t->text, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error(ERR_NONFATAL,
|
||||||
|
"non-string passed to `%%strcat' (%d)", t->type);
|
||||||
|
free_tlist(tline);
|
||||||
|
free_tlist(origline);
|
||||||
|
return DIRECTIVE_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = pp = nasm_malloc(len);
|
||||||
|
t = tline;
|
||||||
|
for (t = tline; t; t = t->next) {
|
||||||
|
if (t->type == TOK_STRING) {
|
||||||
|
memcpy(p, t->text, t->a.len);
|
||||||
|
p += t->a.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We now have a macro name, an implicit parameter count of
|
||||||
|
* zero, and a numeric token to use as an expansion. Create
|
||||||
|
* and store an SMacro.
|
||||||
|
*/
|
||||||
|
macro_start = new_Token(NULL, TOK_STRING, NULL, 0);
|
||||||
|
macro_start->text = nasm_quote(pp, len);
|
||||||
|
nasm_free(pp);
|
||||||
|
define_smacro(ctx, mname, casesense, 0, macro_start);
|
||||||
|
free_tlist(tline);
|
||||||
|
free_tlist(origline);
|
||||||
|
return DIRECTIVE_FOUND;
|
||||||
|
|
||||||
case PP_SUBSTR:
|
case PP_SUBSTR:
|
||||||
{
|
{
|
||||||
int64_t a1, a2;
|
int64_t a1, a2;
|
||||||
@@ -2936,7 +3000,7 @@ static int do_directive(Token * tline)
|
|||||||
macro_start->next = NULL;
|
macro_start->next = NULL;
|
||||||
macro_start->text = nasm_quote((a1 < 0) ? "" : t->text+a1, a2);
|
macro_start->text = nasm_quote((a1 < 0) ? "" : t->text+a1, a2);
|
||||||
macro_start->type = TOK_STRING;
|
macro_start->type = TOK_STRING;
|
||||||
macro_start->mac = NULL;
|
macro_start->a.mac = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We now have a macro name, an implicit parameter count of
|
* We now have a macro name, an implicit parameter count of
|
||||||
@@ -2998,7 +3062,7 @@ static int do_directive(Token * tline)
|
|||||||
macro_start = nasm_malloc(sizeof(*macro_start));
|
macro_start = nasm_malloc(sizeof(*macro_start));
|
||||||
macro_start->next = NULL;
|
macro_start->next = NULL;
|
||||||
make_tok_num(macro_start, reloc_value(evalresult));
|
make_tok_num(macro_start, reloc_value(evalresult));
|
||||||
macro_start->mac = NULL;
|
macro_start->a.mac = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We now have a macro name, an implicit parameter count of
|
* We now have a macro name, an implicit parameter count of
|
||||||
@@ -3213,13 +3277,13 @@ static Token *expand_mmac_params(Token * tline)
|
|||||||
t->type = type;
|
t->type = type;
|
||||||
nasm_free(t->text);
|
nasm_free(t->text);
|
||||||
t->text = text;
|
t->text = text;
|
||||||
t->mac = NULL;
|
t->a.mac = NULL;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
t = *tail = tline;
|
t = *tail = tline;
|
||||||
tline = tline->next;
|
tline = tline->next;
|
||||||
t->mac = NULL;
|
t->a.mac = NULL;
|
||||||
tail = &t->next;
|
tail = &t->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3288,7 +3352,7 @@ static Token *expand_smacro(Token * tline)
|
|||||||
tline =
|
tline =
|
||||||
new_Token(org_tline->next, org_tline->type, org_tline->text,
|
new_Token(org_tline->next, org_tline->type, org_tline->text,
|
||||||
0);
|
0);
|
||||||
tline->mac = org_tline->mac;
|
tline->a.mac = org_tline->a.mac;
|
||||||
nasm_free(org_tline->text);
|
nasm_free(org_tline->text);
|
||||||
org_tline->text = NULL;
|
org_tline->text = NULL;
|
||||||
}
|
}
|
||||||
@@ -3370,7 +3434,7 @@ again:
|
|||||||
do {
|
do {
|
||||||
t = tline->next;
|
t = tline->next;
|
||||||
while (tok_type_(t, TOK_SMAC_END)) {
|
while (tok_type_(t, TOK_SMAC_END)) {
|
||||||
t->mac->in_progress = false;
|
t->a.mac->in_progress = false;
|
||||||
t->text = NULL;
|
t->text = NULL;
|
||||||
t = tline->next = delete_Token(t);
|
t = tline->next = delete_Token(t);
|
||||||
}
|
}
|
||||||
@@ -3400,7 +3464,7 @@ again:
|
|||||||
*/
|
*/
|
||||||
t = tline->next;
|
t = tline->next;
|
||||||
while (tok_type_(t, TOK_SMAC_END)) {
|
while (tok_type_(t, TOK_SMAC_END)) {
|
||||||
t->mac->in_progress = false;
|
t->a.mac->in_progress = false;
|
||||||
t->text = NULL;
|
t->text = NULL;
|
||||||
t = tline->next = delete_Token(t);
|
t = tline->next = delete_Token(t);
|
||||||
}
|
}
|
||||||
@@ -3504,7 +3568,7 @@ again:
|
|||||||
t->next = NULL;
|
t->next = NULL;
|
||||||
}
|
}
|
||||||
tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
|
tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
|
||||||
tt->mac = m;
|
tt->a.mac = m;
|
||||||
m->in_progress = true;
|
m->in_progress = true;
|
||||||
tline = tt;
|
tline = tt;
|
||||||
for (t = m->expansion; t; t = t->next) {
|
for (t = m->expansion; t; t = t->next) {
|
||||||
@@ -3548,12 +3612,12 @@ again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tline->type == TOK_SMAC_END) {
|
if (tline->type == TOK_SMAC_END) {
|
||||||
tline->mac->in_progress = false;
|
tline->a.mac->in_progress = false;
|
||||||
tline = delete_Token(tline);
|
tline = delete_Token(tline);
|
||||||
} else {
|
} else {
|
||||||
t = *tail = tline;
|
t = *tail = tline;
|
||||||
tline = tline->next;
|
tline = tline->next;
|
||||||
t->mac = NULL;
|
t->a.mac = NULL;
|
||||||
t->next = NULL;
|
t->next = NULL;
|
||||||
tail = &t->next;
|
tail = &t->next;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user