diff options
author | H. Peter Anvin <hpa@zytor.com> | 2019-08-10 06:45:12 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2019-08-10 06:45:12 -0700 |
commit | 59d4ccc2b06a25e30a4ba0a62ad64905d88e562b (patch) | |
tree | 2ddfe78a83a02388197ac9d1db1032d51a8da715 /asm | |
parent | 06335873ae360054ae08c67762cbe3d8ee9ca489 (diff) | |
download | nasm-59d4ccc2b06a25e30a4ba0a62ad64905d88e562b.tar.gz |
Add %pragma list options
Add a %pragma to set (or clear) listing options. It only takes effect
on the next assembly pass, however!
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'asm')
-rw-r--r-- | asm/directiv.dat | 5 | ||||
-rw-r--r-- | asm/listing.c | 44 | ||||
-rw-r--r-- | asm/listing.h | 28 | ||||
-rw-r--r-- | asm/nasm.c | 26 | ||||
-rw-r--r-- | asm/pragma.c | 3 |
5 files changed, 88 insertions, 18 deletions
diff --git a/asm/directiv.dat b/asm/directiv.dat index 185568a6..4b0ca3f0 100644 --- a/asm/directiv.dat +++ b/asm/directiv.dat @@ -95,7 +95,10 @@ lprefix lsuffix limit -; --- Pragma operations +; --- Listing pragmas +options + +; --- Backend pragmas subsections_via_symbols ; macho no_dead_strip ; macho maxdump ; dbg diff --git a/asm/listing.c b/asm/listing.c index 1104d8ea..224af714 100644 --- a/asm/listing.c +++ b/asm/listing.c @@ -61,10 +61,12 @@ static const char xdigit[] = "0123456789ABCDEF"; #define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]); +uint64_t list_options, active_list_options; + static char listline[LIST_MAX_LEN]; static bool listlinep; -struct strlist *list_errors; +static struct strlist *list_errors; static char listdata[2 * LIST_INDENT]; /* we need less than that actually */ static int32_t listoffset; @@ -395,6 +397,46 @@ static void list_set_offset(uint64_t offset) listoffset = offset; } +static void list_update_options(const char *str) +{ + bool state = true; + unsigned char c; + uint64_t mask; + + while ((c = *str++)) { + switch (c) { + case '+': + state = true; + break; + case '-': + state = false; + break; + default: + c -= '@'; + if (c > 63) + break; + mask = UINT64_C(1) << c; + if (state) + list_options |= mask; + else + list_options &= ~mask; + break; + } + } +} + +enum directive_result list_pragma(const struct pragma *pragma) +{ + switch (pragma->opcode) { + case D_OPTIONS: + list_update_options(pragma->tail); + return DIRR_OK; + + default: + return DIRR_UNKNOWN; + } +} + static const struct lfmt nasm_list = { list_init, list_cleanup, diff --git a/asm/listing.h b/asm/listing.h index 9d4a3353..88931556 100644 --- a/asm/listing.h +++ b/asm/listing.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- * - * + * * Copyright 1996-2019 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. @@ -14,7 +14,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -31,13 +31,15 @@ * * ----------------------------------------------------------------------- */ -/* +/* * listing.h header file for listing.c */ #ifndef NASM_LISTING_H #define NASM_LISTING_H +#include "nasm.h" + /* * List-file generators should look like this: */ @@ -113,7 +115,15 @@ struct lfmt { extern const struct lfmt *lfmt; extern bool user_nolist; -extern uint64_t active_list_options; /* Simply a bitmask of ASCII-64 */ + +/* + * list_options are the requested options; active_list_options gets + * set when a pass starts. + * + * These are simple bitmasks of ASCII-64 mapping directly to option + * letters. + */ +extern uint64_t list_options, active_list_options; static inline bool list_option(char x) { @@ -123,4 +133,14 @@ static inline bool list_option(char x) return unlikely(active_list_options & (UINT64_C(1) << p)); } +/* We can't test this using active_list_options for obvious reasons... */ +static inline bool list_on_every_pass(void) +{ + const unsigned int p = 'p' - '@'; + return unlikely(list_options & (UINT64_C(1) << p)); +} + +/* Pragma handler */ +enum directive_result list_pragma(const struct pragma *); + #endif @@ -117,9 +117,6 @@ const char *outname; static const char *listname; static const char *errname; -static uint64_t list_options; -uint64_t active_list_options; /* Set during the final pass only */ - static int64_t globallineno; /* for forward-reference tracking */ const struct ofmt *ofmt = &OF_DEFAULT; @@ -1020,10 +1017,6 @@ static bool process_arg(char *p, char *q, int pass) list_options |= (UINT64_C(1) << p); param++; } - if (list_options & (UINT64_C(1) << ('p' - '@'))) { - /* Do listings for every pass */ - active_list_options = list_options; - } } break; @@ -1601,9 +1594,20 @@ static void assemble_file(const char *fname, struct strlist *depend_list) globalbits = cmd_sb; /* set 'bits' to command line default */ cpu = cmd_cpu; - if (pass_final() || list_option('p')) { - active_list_options = list_options; - lfmt->init(listname); + if (listname) { + if (pass_final() || list_on_every_pass()) { + active_list_options = list_options; + lfmt->init(listname); + } else if (active_list_options) { + /* + * Looks like we used the list engine on a previous pass, + * but now it is turned off, presumably via %pragma -p + */ + lfmt->cleanup(); + if (!keep_all) + remove(listname); + active_list_options = 0; + } } in_absolute = false; @@ -1705,8 +1709,8 @@ static void assemble_file(const char *fname, struct strlist *depend_list) nasm_info("assembly required 1+%"PRId64"+2 passes\n", pass_count()-3); } - strlist_free(&warn_list); lfmt->cleanup(); + strlist_free(&warn_list); } /** diff --git a/asm/pragma.c b/asm/pragma.c index 43de6e2c..8cfbafb8 100644 --- a/asm/pragma.c +++ b/asm/pragma.c @@ -45,6 +45,7 @@ #include "nasmlib.h" #include "assemble.h" #include "error.h" +#include "listing.h" static enum directive_result output_pragma(const struct pragma *pragma); static enum directive_result limit_pragma(const struct pragma *pragma); @@ -86,7 +87,7 @@ static struct pragma_facility global_pragmas[] = { { "asm", NULL }, { "limit", limit_pragma }, - { "list", NULL }, + { "list", list_pragma }, { "file", NULL }, { "input", NULL }, |