Protect %use from multi-inclusion and provide a test macro
authorH. Peter Anvin <hpa@zytor.com>
Fri, 20 Jun 2008 01:39:24 +0000 (18:39 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 20 Jun 2008 01:39:24 +0000 (18:39 -0700)
Automatically provide an include guard for %use packages; the macro
__USE_package__ is automatically defined, and inclusion is suppressed
if it is already defined.

doc/nasmdoc.src
preproc.c

index 05b62ca..79d072a 100644 (file)
@@ -3064,6 +3064,10 @@ lines are equivalent, unless \c{altreg} is defined as a macro:
 \c %use altreg
 \c %use 'altreg'
 
+Standard macro packages are protected from multiple inclusion.  When a
+standard macro package is used, a testable single-line macro of the
+form \c{__USE_}\e{package}\c{__} is also defined, see \k{use_def}.
+
 \H{ctxstack} The \i{Context Stack}
 
 Having labels that are local to a macro definition is sometimes not
@@ -3587,6 +3591,19 @@ clock:
 \c __UTC_TIME_NUM__     210042
 \c __POSIX_TIME__       1262293242
 
+
+\S{use_def} \I\c{__USE_*__}\c{__USE_}\e{package}\c{__}: Package
+Include Test
+
+When a standard macro package is included with the \c{%use} directive
+(see \k{use}), a single-line macro of the form
+\c{__USE_}\e{package}\c{__} is automatically defined.  This allows
+testing if a particular package is invoked or not.
+
+For example, if the \c{altreg} package is included (see
+\k{pkg_altreg}), then the macro \c{__USE_ALTREG__} is defined.
+
+
 \S{struc} \i\c{STRUC} and \i\c{ENDSTRUC}: \i{Declaring Structure} Data Types
 
 The core of NASM contains no intrinsic means of defining data
index 7ea031e..6653136 100644 (file)
--- a/preproc.c
+++ b/preproc.c
@@ -2152,6 +2152,11 @@ static int do_directive(Token * tline)
         return DIRECTIVE_FOUND;
 
     case PP_USE:
+    {
+       static const char * const *use_pkg;
+       const char *s;
+       char *pkg_macro;
+
        t = tline->next = expand_smacro(tline->next);
        skip_white_(t);
 
@@ -2165,15 +2170,25 @@ static int do_directive(Token * tline)
         if (t->next)
             error(ERR_WARNING,
                   "trailing garbage after `%%use' ignored");
-       p = t->text;
        if (t->type == TOK_STRING)
-           nasm_unquote(p, NULL);
-       stdmacpos = nasm_stdmac_find_package(p);
-       if (!stdmacpos)
-           error(ERR_NONFATAL, "unknown `%%use' package: %s", p);
+           nasm_unquote(t->text, NULL);
+       use_pkg = nasm_stdmac_find_package(t->text);
+       if (!use_pkg)
+           error(ERR_NONFATAL, "unknown `%%use' package: %s", t->text);
+       p = pkg_macro = nasm_malloc(strlen(t->text) + 9);
+       strcpy(p, "__USE_"); p += 6;
+       for (s = t->text; *s; s++)
+           *p++ = toupper(*s);
+       strcpy(p, "__");
+       if (!smacro_defined(NULL, pkg_macro, 0, NULL, true)) {
+           /* Not already included, go ahead and include it */
+           define_smacro(NULL, pkg_macro, true, 0, NULL);
+           stdmacpos = use_pkg;
+       }
+       nasm_free(pkg_macro);
        free_tlist(origline);
         return DIRECTIVE_FOUND;
-
+    }
     case PP_PUSH:
         tline = tline->next;
         skip_white_(tline);