[nasm:master] preproc: distinguish between directives and functions

nasm-bot for H. Peter Anvin hpa at zytor.com
Fri Nov 11 19:57:04 PST 2022


Commit-ID:  3fe5b3f5a1ad935c7845271e8660f0705eaa1837
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=3fe5b3f5a1ad935c7845271e8660f0705eaa1837
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Fri, 11 Nov 2022 19:51:22 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Fri, 11 Nov 2022 19:51:22 -0800

preproc: distinguish between directives and functions

Some preprocessor functions have the same name as directives. In those
cases, they should be expanded as functions if and only if they are
followed by a left parenthesis. Although it is not inherently true that
either preprocessor functions require a paren nor that directives
cannot start with one, but it is true and will remain true for all
cases where there is a namespace collision.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 asm/pptok.pl  | 13 +++++++------
 asm/preproc.c | 19 ++++++++++++++++++-
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/asm/pptok.pl b/asm/pptok.pl
index 0ba6bed6..0b8ef251 100755
--- a/asm/pptok.pl
+++ b/asm/pptok.pl
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 ## --------------------------------------------------------------------------
 ##
-##   Copyright 1996-2020 The NASM Authors - All Rights Reserved
+##   Copyright 1996-2022 The NASM Authors - All Rights Reserved
 ##   See the file AUTHORS included with the NASM distribution for
 ##   the specific copyright holders.
 ##
@@ -132,7 +132,8 @@ if ($what eq 'h') {
 	}
 	$n++;
     }
-    printf OUT "    %-24s = %3d\n", 'PP_INVALID', -1;
+    printf OUT "    %-24s = %3d,\n", 'PP_count', $n;
+    printf OUT "    %-24s = %3d\n", 'PP_invalid', -1;
     print OUT "};\n";
     print OUT "\n";
 
@@ -257,11 +258,11 @@ if ($what eq 'c') {
     print  OUT "\n";
     print  OUT "    ix = hashdata[k1] + hashdata[k2];\n";
     printf OUT "    if (ix >= %d)\n", scalar(@pptok);
-    print OUT  "        return PP_INVALID;\n";
+    print OUT  "        return PP_invalid;\n";
     print OUT  "\n";
 
     print OUT  "    if (!pp_directives[ix] || nasm_stricmp(pp_directives[ix], token))\n";
-    print OUT  "        return PP_INVALID;\n";
+    print OUT  "        return PP_invalid;\n";
     print OUT  "\n";
     print OUT  "    return ix;\n";
     print OUT  "}\n";
@@ -315,11 +316,11 @@ if ($what eq 'c') {
     # Comparing to pptok here is correct, because this hash produces
     # an enum preproc_token value directly.
     printf OUT "    if (ix >= %d)\n", scalar(@pptok);
-    print OUT  "        return PP_INVALID;\n";
+    print OUT  "        return PP_invalid;\n";
     print OUT  "\n";
 
     print OUT  "    if (!pp_directives[ix] || nasm_stricmp(pp_directives[ix]+1, token))\n";
-    print OUT  "        return PP_INVALID;\n";
+    print OUT  "        return PP_invalid;\n";
     print OUT  "\n";
     print OUT  "    return ix;\n";
     print OUT  "}\n";
diff --git a/asm/preproc.c b/asm/preproc.c
index 64ba4e71..691f1d97 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -111,6 +111,13 @@ typedef struct Line Line;
 typedef struct Include Include;
 typedef struct Cond Cond;
 
+/*
+ * Map of preprocessor directives that are also preprocessor functions;
+ * if they are at the beginning of a line they are a function if and
+ * only if they are followed by a (
+ */
+static bool pp_op_may_be_function[PP_count];
+
 /*
  * This is the internal form which we break input lines up into.
  * Typically stored in linked lists.
@@ -3757,7 +3764,7 @@ static int do_directive(Token *tline, Token **output)
     }
 
     switch (op) {
-    case PP_INVALID:
+    case PP_invalid:
         return NO_DIRECTIVE_FOUND;
 
     case PP_LINE:
@@ -3828,6 +3835,11 @@ static int do_directive(Token *tline, Token **output)
         }
     }
 
+    if (pp_op_may_be_function[op]) {
+        if (tok_is(skip_white(tline->next), '('))
+            return NO_DIRECTIVE_FOUND; /* Expand as a preprocessor function */
+    }
+
     switch (op) {
     default:
         nasm_nonfatal("unknown preprocessor directive `%s'", dname);
@@ -7001,6 +7013,11 @@ static void pp_add_magic_stdmac(void)
             }
         }
         define_smacro(m->name, m->casesense, NULL, &tmpl);
+        if (m->name[0] == '%') {
+            enum preproc_token op = pp_token_hash(m->name);
+            if (op != PP_invalid)
+                pp_op_may_be_function[op] = true;
+        }
     }
 
     /* %is...() macro functions */


More information about the Nasm-commits mailing list