[nasm:master] preproc: implement %str() and %strcat() functions
nasm-bot for H. Peter Anvin
hpa at zytor.com
Fri Nov 11 19:04:05 PST 2022
Commit-ID: 57fbd34d9ff35a9b34873e896b0983d63a13ee32
Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=57fbd34d9ff35a9b34873e896b0983d63a13ee32
Author: H. Peter Anvin <hpa at zytor.com>
AuthorDate: Fri, 11 Nov 2022 18:18:04 -0800
Committer: H. Peter Anvin <hpa at zytor.com>
CommitDate: Fri, 11 Nov 2022 18:18:04 -0800
preproc: implement %str() and %strcat() functions
Add function equivalents of the %defstr and %strcat directives.
Signed-off-by: H. Peter Anvin <hpa at zytor.com>
---
asm/preproc.c | 87 ++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 57 insertions(+), 30 deletions(-)
diff --git a/asm/preproc.c b/asm/preproc.c
index f3e4511f..ea18c270 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -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 out if a line contains a preprocessor directive, and deal
@@ -3588,7 +3629,7 @@ static int do_directive(Token *tline, Token **output)
bool casesense;
int offset;
const char *p;
- char *q, *qbuf;
+ char *q;
const char *found_path;
const char *mname;
struct ppscan pps;
@@ -3601,7 +3642,6 @@ static int do_directive(Token *tline, Token **output)
struct tokenval tokval;
expr *evalresult;
int64_t count;
- size_t len;
errflags severity;
const char *dname; /* Name of directive, for messages */
@@ -4717,38 +4757,12 @@ issue_error:
tline = expand_smacro(tline->next);
last->next = NULL;
- 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);
- 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';
-
+ macro_start = pp_strcat(tline, dname);
/*
* 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.
*/
- macro_start = make_tok_qstr_len(NULL, qbuf, len);
- nasm_free(qbuf);
define_smacro(mname, casesense, macro_start, NULL);
free_tlist(tline);
break;
@@ -6838,6 +6852,9 @@ stdmac_is(const SMacro *s, Token **params, int nparams)
/*
* Join all expanded macro arguments with commas, e.g. %eval().
* 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 *
stdmac_join(const SMacro *s, Token **params, int nparams)
@@ -6865,6 +6882,14 @@ stdmac_join(const SMacro *s, Token **params, int nparams)
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 */
struct magic_macros {
const char *name;
@@ -6881,6 +6906,8 @@ static void pp_add_magic_stdmac(void)
{ "__?BITS?__", true, 0, 0, stdmac_bits },
{ "__?PTR?__", true, 0, 0, stdmac_ptr },
{ "%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 }
};
const struct magic_macros *m;
More information about the Nasm-commits
mailing list