[Nasm-commits] [nasm:extnames] preproc: add %(i)defid, fix %(i)deftok code mangling
nasm-bot for H. Peter Anvin (Intel)
hpa at zytor.com
Thu Jun 4 19:56:47 PDT 2020
Commit-ID: 18535fd48c78a09e8f5db189ad9bd762bdfeb059
Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=18535fd48c78a09e8f5db189ad9bd762bdfeb059
Author: H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Mon, 25 Jun 2018 22:56:10 -0700
Committer: H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Mon, 25 Jun 2018 22:56:10 -0700
preproc: add %(i)defid, fix %(i)deftok code mangling
The previous checkin really got the code for %(i)deftok messed up;
this is fixed.
Add %(i)defid which works like %(i)deftok, except that the string
being input is mangled in such a way that it always results in a valid
NASM identifier.
Signed-off-by: H. Peter Anvin (Intel) <hpa at zytor.com>
---
asm/pptok.dat | 2 ++
asm/preproc.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 78 insertions(+), 7 deletions(-)
diff --git a/asm/pptok.dat b/asm/pptok.dat
index a2c64d0a..c274bc74 100644
--- a/asm/pptok.dat
+++ b/asm/pptok.dat
@@ -51,6 +51,7 @@
%assign
%clear
%define
+%defid
%defstr
%deftok
%depend
@@ -66,6 +67,7 @@
%fatal
%iassign
%idefine
+%idefid
%idefstr
%ideftok
%if*
diff --git a/asm/preproc.c b/asm/preproc.c
index 2244157f..57b88c4f 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -504,11 +504,11 @@ static void nasm_unquote_pp(char *qstr, enum preproc_token directive)
}
/*
- * In-place reverse a list of tokens; optionally link the last
- * (formerly first) element to a different token.
+ * In-place reverse a list of tokens.
*/
-static Token *reverse_tokens(Token *t, Token *prev)
+static Token *reverse_tokens(Token *t)
{
+ Token *prev = NULL;
Token *next;
while (t) {
@@ -521,6 +521,68 @@ static Token *reverse_tokens(Token *t, Token *prev)
return prev;
}
+/*
+ * Quote an arbitrary string into a valid identifier.
+ * 1. Prepend a $ to make sure we don't step on any other namespace;
+ * 2. Any character not valid in a NASM identifier is escaped as @xx;
+ * 3. A leading $ or . is escaped as @$ and @. respectively;
+ * 4. @ itself is escaped as @_.
+ */
+static Token *make_identifier(const char *str)
+{
+ Token *t;
+ const char *p;
+ char *q;
+ size_t n = 2; /* Leading $ + final NUL */
+
+ if (!str || !*str) /* Nothing there? */
+ return NULL;
+
+ n += (*str == '@' || *str == '$' || *str == '.') ? 2 :
+ isidstart(*str) ? 1 : 3;
+
+ for (p = str+1; *p; p++)
+ n += (*p == '@') ? 2 : isidchar(*p) ? 1 : 3;
+
+ t = new_Token(NULL, TOK_ID, NULL, 0);
+ t->text = q = nasm_malloc(n);
+
+ *q++ = '$';
+
+ switch (*str) {
+ case '$':
+ case '.':
+ *q++ = '@';
+ *q++ = *str;
+ break;
+
+ case '@':
+ *q++ = '@';
+ *q++ = '_';
+ break;
+
+ default:
+ if (isidstart(*str))
+ *q++ = *str;
+ else
+ q += snprintf(q, 4, "@%02x", (unsigned char)(*str));
+ }
+
+ for (p = str+1; *p; p++) {
+ if (*str == '@') {
+ *q++ = '@';
+ *q++ = '@';
+ } else if (isidchar(*p)) {
+ *q++ = *str;
+ } else {
+ q += snprintf(q, 4, "@%02x", (unsigned char)(*p));
+ }
+ }
+ *q = '\0';
+
+ return t;
+}
+
/*
* Handle TASM specific directives, which do not contain a % in
* front of them. We do it here because I could not find any other
@@ -1768,7 +1830,7 @@ static bool if_condition(Token * tline, enum preproc_token ct)
{
enum pp_conditional i = PP_COND(ct);
bool j;
- Token *t, *ttwhi, **tptr, *origline;
+ Token *t, *tt, **tptr, *origline;
struct tokenval tokval;
expr *evalresult;
enum pp_token_type needtype;
@@ -3295,10 +3357,12 @@ issue_error:
case PP_DEFTOK:
case PP_IDEFTOK:
+ case PP_DEFID:
+ case PP_IDEFID:
{
- char *xstr, *ystr;
+ char *xstr;
- casesense = (i == PP_DEFTOK);
+ casesense = (i == PP_DEFTOK) || (i == PP_DEFID);
tline = tline->next;
skip_white_(tline);
@@ -3337,7 +3401,11 @@ issue_error:
* are stored with the token stream reversed, so we have to
* reverse the output of tokenize().
*/
- macro_start = reverse_tokens(tokenize(xstr));
+ if (i == PP_DEFTOK || i == PP_IDEFTOK) {
+ macro_start = reverse_tokens(tokenize(xstr));
+ } else {
+ macro_start = make_identifier(xstr);
+ }
nasm_free(xstr);
/*
@@ -3349,6 +3417,7 @@ issue_error:
free_tlist(tline);
free_tlist(origline);
return DIRECTIVE_FOUND;
+ }
case PP_PATHSEARCH:
{
More information about the Nasm-commits
mailing list