[nasm:nasm-2.15.xx] preproc: saner handling of cpp-style line directives

nasm-bot for H. Peter Anvin (Intel) hpa at zytor.com
Fri Jul 10 18:48:03 PDT 2020


Commit-ID:  d9ea17fb47909ef27811c945b4c6e4b0742796d4
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=d9ea17fb47909ef27811c945b4c6e4b0742796d4
Author:     H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Fri, 10 Jul 2020 18:40:05 -0700
Committer:  H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Fri, 10 Jul 2020 18:44:15 -0700

preproc: saner handling of cpp-style line directives

NASM now supports a proper superset of cpp line number markers, so
there is no need to hack around them using the
"prepreprocessor". Instead, just put a quick test in do_directive()
treating it just like %line, except convert a "-quoted string into a
`-quoted string.

(This can break if there is a ` or \" sequence in the string... fix
that at some point. This is still much better than what there is now.)

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


---
 asm/preproc.c   | 45 ++++++++++++++++++++++++++-------------------
 doc/nasmdoc.src | 15 ++++++++++++++-
 2 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/asm/preproc.c b/asm/preproc.c
index 693cbcbb..8230f16f 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -945,26 +945,12 @@ static char *check_tasm_directive(char *line)
  * flags') into NASM preprocessor line number indications (`%line
  * lineno file').
  */
-static char *prepreproc(char *line)
-{
-    int lineno, fnlen;
-    char *fname, *oldline;
-
-    if (line[0] == '#' && line[1] == ' ') {
-        oldline = line;
-        fname = oldline + 2;
-        lineno = atoi(fname);
-        fname += strspn(fname, "0123456789 ");
-        if (*fname == '"')
-            fname++;
-        fnlen = strcspn(fname, "\"");
-        line = nasm_malloc(20 + fnlen);
-        snprintf(line, 20 + fnlen, "%%line %d %.*s", lineno, fnlen, fname);
-        nasm_free(oldline);
-    }
-    if (tasm_compatible_mode)
+static inline char *prepreproc(char *line)
+{
+    if (unlikely(tasm_compatible_mode))
         return check_tasm_directive(line);
-    return line;
+    else
+        return line;
 }
 
 /*
@@ -3426,6 +3412,14 @@ static int do_directive(Token *tline, Token **output)
     *output = NULL;             /* No output generated */
     origline = tline;
 
+    if (tok_is(tline, '#')) {
+        /* cpp-style line directive */
+        if (!tok_white(tline->next))
+            return NO_DIRECTIVE_FOUND;
+        dname = tok_text(tline);
+        goto pp_line;
+    }
+
     tline = skip_white(tline);
     if (!tline || !tok_type(tline, TOK_PREPROC_ID))
 	return NO_DIRECTIVE_FOUND;
@@ -3448,6 +3442,7 @@ static int do_directive(Token *tline, Token **output)
      * in externally preprocessed sources.
      */
     if (op == PP_LINE) {
+    pp_line:
         /*
          * Syntax is `%line nnn[+mmm] [filename]'
          */
@@ -3478,7 +3473,19 @@ static int do_directive(Token *tline, Token **output)
         tline = skip_white(tline);
         if (tline) {
             if (tline->type == TOK_STRING) {
+                if (dname[0] == '#') {
+                    /* cpp version: treat double quotes like NASM backquotes */
+                    char *txt = tok_text_buf(tline);
+                    if (txt[0] == '"') {
+                        txt[0] = '`';
+                        txt[tline->len - 1] = '`';
+                    }
+                }
                 src_set_fname(unquote_token(tline));
+                /*
+                 * Anything after the string is ignored by design (for cpp
+                 * compatibility and future extensions.)
+                 */
             } else {
                 char *fname = detoken(tline, false);
                 src_set_fname(fname);
diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src
index b52f854a..cfa92fd1 100644
--- a/doc/nasmdoc.src
+++ b/doc/nasmdoc.src
@@ -2753,6 +2753,11 @@ interfering with the local label mechanism, as described in
 (the \c{..@} prefix, then a number, then another period) in case
 they interfere with macro-local labels.
 
+These labels are really macro-local \e{tokens}, and can be used for
+other purposes where a token unique to each macro invocation is
+desired, e.g. to name single-line macros without using the context
+feature (\k{ctxlocal}).
+
 
 \S{mlmacgre} \i{Greedy Macro Parameters}
 
@@ -4047,7 +4052,8 @@ which specifies a line increment value; each line of the input file
 read in is considered to correspond to \c{mmm} lines of the original
 source file.  Finally, \c{filename} is an optional parameter which
 specifies the file name of the original source file. It may be a
-quoted string.
+quoted string, in which case any additional argument after the quoted
+string will be ignored.
 
 After reading a \c{%line} preprocessor directive, NASM will report
 all file name and line numbers relative to the values specified
@@ -4060,6 +4066,13 @@ code. See \k{opt-no-line}.
 Starting in NASM 2.15, \c{%line} directives are processed before any
 other processing takes place.
 
+For compatibility with the output from some other preprocessors,
+including many C preprocessors, a \c{#} character followed by
+whitespace \e{at the very beginning of a line} is also treated as a
+\c{%line} directive, except that double quotes surrounding the
+filename are treated like NASM backquotes, with \c{\\}-escaped
+sequences decoded.
+
 \# This isn't a directive, it should be moved elsewhere...
 \S{getenv} \i\c{%!}\e{variable}: Read an Environment Variable.
 


More information about the Nasm-commits mailing list