aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2018-06-25 22:56:10 -0700
committerH. Peter Anvin (Intel) <hpa@zytor.com>2018-06-25 22:56:10 -0700
commit18535fd48c78a09e8f5db189ad9bd762bdfeb059 (patch)
tree1eb4914ba123bd8f0807dfacbf590456cfa79d61
parent8884fc60a204b8b6d0322c76f1ca294472a32498 (diff)
downloadnasm-extnames.tar.gz
nasm-extnames.tar.xz
nasm-extnames.zip
preproc: add %(i)defid, fix %(i)deftok code manglingextnames
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@zytor.com>
-rw-r--r--asm/pptok.dat2
-rw-r--r--asm/preproc.c83
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) {
@@ -522,6 +522,68 @@ static Token *reverse_tokens(Token *t, Token *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
* place to do it for the moment, and it is a hack (ideally it would
@@ -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:
{