diff --git a/Makefile.in b/Makefile.in index 4a5b3b08..1479a626 100644 --- a/Makefile.in +++ b/Makefile.in @@ -74,7 +74,7 @@ endif #-- Begin File Lists --# NASM = nasm.$(O) nasmlib.$(O) ver.$(O) \ - raa.$(O) saa.$(O) rbtree.$(O) \ + raa.$(O) saa.$(O) rbtree.$(O) srcfile.$(O) \ realpath.$(O) \ float.$(O) insnsa.$(O) insnsb.$(O) \ directiv.$(O) \ @@ -444,6 +444,7 @@ regflags.$(O): regflags.c compiler.h config.h directiv.h insnsi.h nasm.h \ regs.$(O): regs.c compiler.h config.h insnsi.h tables.h regvals.$(O): regvals.c compiler.h config.h insnsi.h tables.h saa.$(O): saa.c compiler.h config.h nasmlib.h saa.h +srcfile.$(O): srcfile.c compiler.h config.h hashtbl.h nasmlib.h stdscan.$(O): stdscan.c compiler.h config.h directiv.h iflag.h iflaggen.h \ insns.h insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h quote.h \ regs.h stdscan.h tables.h tokens.h diff --git a/Mkfiles/msvc.mak b/Mkfiles/msvc.mak index 890ad43d..35dc9ead 100644 --- a/Mkfiles/msvc.mak +++ b/Mkfiles/msvc.mak @@ -47,7 +47,7 @@ X = .exe #-- Begin File Lists --# # Edit in Makefile.in, not here! NASM = nasm.$(O) nasmlib.$(O) ver.$(O) \ - raa.$(O) saa.$(O) rbtree.$(O) \ + raa.$(O) saa.$(O) rbtree.$(O) srcfile.$(O) \ realpath.$(O) \ float.$(O) insnsa.$(O) insnsb.$(O) \ directiv.$(O) \ @@ -350,6 +350,7 @@ regflags.$(O): regflags.c compiler.h directiv.h insnsi.h nasm.h nasmlib.h \ regs.$(O): regs.c compiler.h insnsi.h tables.h regvals.$(O): regvals.c compiler.h insnsi.h tables.h saa.$(O): saa.c compiler.h nasmlib.h saa.h +srcfile.$(O): srcfile.c compiler.h hashtbl.h nasmlib.h stdscan.$(O): stdscan.c compiler.h directiv.h iflag.h iflaggen.h insns.h \ insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h quote.h regs.h \ stdscan.h tables.h tokens.h diff --git a/Mkfiles/netware.mak b/Mkfiles/netware.mak index c3c8bf64..56509ee4 100644 --- a/Mkfiles/netware.mak +++ b/Mkfiles/netware.mak @@ -31,7 +31,7 @@ O = o #-- Begin File Lists --# # Edit in Makefile.in, not here! NASM = nasm.o nasmlib.o ver.o \ - raa.o saa.o rbtree.o \ + raa.o saa.o rbtree.o srcfile.o \ realpath.o \ float.o insnsa.o insnsb.o \ directiv.o \ @@ -251,6 +251,7 @@ regflags.o: regflags.c compiler.h config.h directiv.h insnsi.h nasm.h \ regs.o: regs.c compiler.h config.h insnsi.h tables.h regvals.o: regvals.c compiler.h config.h insnsi.h tables.h saa.o: saa.c compiler.h config.h nasmlib.h saa.h +srcfile.o: srcfile.c compiler.h config.h hashtbl.h nasmlib.h stdscan.o: stdscan.c compiler.h config.h directiv.h iflag.h iflaggen.h \ insns.h insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h quote.h \ regs.h stdscan.h tables.h tokens.h diff --git a/Mkfiles/openwcom.mak b/Mkfiles/openwcom.mak index 7fb9ba51..3dffb117 100644 --- a/Mkfiles/openwcom.mak +++ b/Mkfiles/openwcom.mak @@ -47,7 +47,7 @@ X = .exe #-- Begin File Lists --# # Edit in Makefile.in, not here! NASM = nasm.$(O) nasmlib.$(O) ver.$(O) & - raa.$(O) saa.$(O) rbtree.$(O) & + raa.$(O) saa.$(O) rbtree.$(O) srcfile.$(O) & realpath.$(O) & float.$(O) insnsa.$(O) insnsb.$(O) & directiv.$(O) & @@ -399,6 +399,7 @@ regflags.$(O): regflags.c compiler.h config.h directiv.h insnsi.h nasm.h & regs.$(O): regs.c compiler.h config.h insnsi.h tables.h regvals.$(O): regvals.c compiler.h config.h insnsi.h tables.h saa.$(O): saa.c compiler.h config.h nasmlib.h saa.h +srcfile.$(O): srcfile.c compiler.h config.h hashtbl.h nasmlib.h stdscan.$(O): stdscan.c compiler.h config.h directiv.h iflag.h iflaggen.h & insns.h insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h quote.h & regs.h stdscan.h tables.h tokens.h diff --git a/Mkfiles/owlinux.mak b/Mkfiles/owlinux.mak index b6ddad91..ad27d177 100644 --- a/Mkfiles/owlinux.mak +++ b/Mkfiles/owlinux.mak @@ -58,7 +58,7 @@ X = .exe #-- Begin File Lists --# # Edit in Makefile.in, not here! NASM = nasm.$(O) nasmlib.$(O) ver.$(O) \ - raa.$(O) saa.$(O) rbtree.$(O) \ + raa.$(O) saa.$(O) rbtree.$(O) srcfile.$(O) \ realpath.$(O) \ float.$(O) insnsa.$(O) insnsb.$(O) \ directiv.$(O) \ @@ -361,6 +361,7 @@ regflags.$(O): regflags.c compiler.h directiv.h insnsi.h nasm.h nasmlib.h \ regs.$(O): regs.c compiler.h insnsi.h tables.h regvals.$(O): regvals.c compiler.h insnsi.h tables.h saa.$(O): saa.c compiler.h nasmlib.h saa.h +srcfile.$(O): srcfile.c compiler.h hashtbl.h nasmlib.h stdscan.$(O): stdscan.c compiler.h directiv.h iflag.h iflaggen.h insns.h \ insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h quote.h regs.h \ stdscan.h tables.h tokens.h diff --git a/assemble.c b/assemble.c index 584bed72..b9e01e64 100644 --- a/assemble.c +++ b/assemble.c @@ -335,7 +335,7 @@ static void out(int64_t offset, int32_t segto, const void *data, int32_t segment, int32_t wrt) { static int32_t lineno = 0; /* static!!! */ - static char *lnfname = NULL; + static const char *lnfname = NULL; uint8_t p[8]; int asize = addrsize(type, size); /* Address size in bytes */ const int amax = ofmt->maxbits >> 3; /* Maximum address size in bytes */ diff --git a/nasm.c b/nasm.c index 3bf98af7..4df3c373 100644 --- a/nasm.c +++ b/nasm.c @@ -340,6 +340,7 @@ int main(int argc, char **argv) error_file = stderr; tolower_init(); + src_init(); offsets = raa_init(); forwrefs = saa_init((int32_t)sizeof(struct forwrefinfo)); @@ -402,7 +403,7 @@ int main(int argc, char **argv) preproc->cleanup(0); } else if (operating_mode & OP_PREPROCESS) { char *line; - char *file_name = NULL; + const char *file_name = NULL; int32_t prior_linnum = 0; int lineinc = 0; @@ -442,7 +443,6 @@ int main(int argc, char **argv) nasm_fputs(line, ofile); nasm_free(line); } - nasm_free(file_name); preproc->cleanup(0); if (ofile) fclose(ofile); @@ -482,9 +482,11 @@ int main(int argc, char **argv) ofmt->cleanup(); cleanup_labels(); fflush(ofile); - if (ferror(ofile)) + if (ferror(ofile)) { nasm_error(ERR_NONFATAL|ERR_NOFILE, "write error on output file `%s'", outname); + terminate_after_phase = true; + } } if (ofile) { @@ -505,6 +507,7 @@ int main(int argc, char **argv) saa_free(forwrefs); eval_cleanup(); stdscan_cleanup(); + src_free(); return terminate_after_phase; } @@ -1869,7 +1872,7 @@ static enum directives getkw(char **directive, char **value) */ static void nasm_verror_gnu(int severity, const char *fmt, va_list ap) { - char *currentfile = NULL; + const char *currentfile = NULL; int32_t lineno = 0; if (is_suppressed_warning(severity)) @@ -1906,7 +1909,7 @@ static void nasm_verror_gnu(int severity, const char *fmt, va_list ap) */ static void nasm_verror_vc(int severity, const char *fmt, va_list ap) { - char *currentfile = NULL; + const char *currentfile = NULL; int32_t lineno = 0; if (is_suppressed_warning(severity)) @@ -1918,7 +1921,6 @@ static void nasm_verror_vc(int severity, const char *fmt, va_list ap) if (!skip_this_pass(severity)) { if (currentfile) { fprintf(error_file, "%s(%"PRId32") : ", currentfile, lineno); - nasm_free(currentfile); } else { fputs("nasm: ", error_file); } diff --git a/nasmlib.c b/nasmlib.c index 2bea64b3..f299f354 100644 --- a/nasmlib.c +++ b/nasmlib.c @@ -553,50 +553,6 @@ int bsii(const char *string, const char **array, int size) return -1; /* we haven't got it :( */ } -static char *file_name = NULL; -static int32_t line_number = 0; - -char *src_set_fname(char *newname) -{ - char *oldname = file_name; - file_name = newname; - return oldname; -} - -int32_t src_set_linnum(int32_t newline) -{ - int32_t oldline = line_number; - line_number = newline; - return oldline; -} - -/* This returns a pointer, not a copy, to the current fname */ -const char *src_get_fname(void) -{ - return file_name; -} - -int32_t src_get_linnum(void) -{ - return line_number; -} - -int src_get(int32_t *xline, char **xname) -{ - if (!file_name || !*xname || strcmp(*xname, file_name)) { - nasm_free(*xname); - *xname = file_name ? nasm_strdup(file_name) : NULL; - *xline = line_number; - return -2; - } - if (*xline != line_number) { - int32_t tmp = line_number - *xline; - *xline = line_number; - return tmp; - } - return 0; -} - char *nasm_strcat(const char *one, const char *two) { char *rslt; diff --git a/nasmlib.h b/nasmlib.h index 08b2dc30..a4870d87 100644 --- a/nasmlib.h +++ b/nasmlib.h @@ -392,17 +392,24 @@ void fwriteaddr(uint64_t data, int size, FILE * fp); int bsi(const char *string, const char **array, int size); int bsii(const char *string, const char **array, int size); -char *src_set_fname(char *newname); +/* + * These functions are used to keep track of the source code file and name. + */ +void src_init(void); +void src_free(void); +const char *src_set_fname(const char *newname); const char *src_get_fname(void); int32_t src_set_linnum(int32_t newline); int32_t src_get_linnum(void); +/* Can be used when there is no need for the old information */ +void src_set(int32_t line, const char *filename); /* - * src_get may be used if you simply want to know the source file and line. + * src_get gets both the source file name and line. * It is also used if you maintain private status about the source location * It return 0 if the information was the same as the last time you - * checked, -1 if the name changed and (new-old) if just the line changed. + * checked, -2 if the name changed and (new-old) if just the line changed. */ -int src_get(int32_t *xline, char **xname); +int32_t src_get(int32_t *xline, const char **xname); char *nasm_strcat(const char *one, const char *two); diff --git a/preproc-nop.c b/preproc-nop.c index f8513a8a..56ef031d 100644 --- a/preproc-nop.c +++ b/preproc-nop.c @@ -60,8 +60,7 @@ static int32_t nop_lineinc; static void nop_reset(char *file, int pass, StrList **deplist) { - src_set_fname(nasm_strdup(file)); - src_set_linnum(0); + src_set(0, file); nop_lineinc = 1; nop_fp = fopen(file, "r"); @@ -121,9 +120,9 @@ static char *nop_getline(void) int li; char *nm = nasm_malloc(strlen(buffer)); if (sscanf(buffer + 5, "%"PRId32"+%d %s", &ln, &li, nm) == 3) { - nasm_free(src_set_fname(nm)); - src_set_linnum(ln); + src_set(ln, nm); nop_lineinc = li; + nasm_free(nm); continue; } nasm_free(nm); diff --git a/preproc.c b/preproc.c index d2352808..0c9bf2d3 100644 --- a/preproc.c +++ b/preproc.c @@ -156,7 +156,7 @@ struct MMacro { int lineno; /* Current line number on expansion */ uint64_t condcnt; /* number of if blocks... */ - char *fname; /* File where defined */ + const char *fname; /* File where defined */ int32_t xline; /* First line in macro */ }; @@ -271,7 +271,7 @@ struct Include { FILE *fp; Cond *conds; Line *expansion; - char *fname; + const char *fname; int lineno, lineinc; MMacro *mstk; /* stack of active macros/reps */ }; @@ -628,7 +628,6 @@ static void free_mmacro(MMacro * m) free_tlist(m->dlist); nasm_free(m->defaults); free_llist(m->expansion); - nasm_free(m->fname); nasm_free(m); } @@ -2522,7 +2521,7 @@ static int do_directive(Token * tline) /* -MG given but file not found */ nasm_free(inc); } else { - inc->fname = src_set_fname(nasm_strdup(p)); + inc->fname = src_set_fname(p); inc->lineno = src_set_linnum(0); inc->lineinc = 1; inc->expansion = NULL; @@ -3578,7 +3577,9 @@ issue_error: src_set_linnum(k); istk->lineinc = m; if (tline) { - nasm_free(src_set_fname(detoken(tline, false))); + char *fname = detoken(tline, false); + src_set_fname(fname); + nasm_free(fname); } free_tlist(origline); return DIRECTIVE_FOUND; @@ -4135,12 +4136,10 @@ again: */ if (!m->expansion) { if (!strcmp("__FILE__", m->name)) { - int32_t num = 0; - char *file = NULL; - src_get(&num, &file); + const char *file = src_get_fname(); + /* nasm_free(tline->text); here? */ tline->text = nasm_quote(file, strlen(file)); tline->type = TOK_STRING; - nasm_free(file); continue; } if (!strcmp("__LINE__", m->name)) { @@ -4855,8 +4854,7 @@ pp_reset(char *file, int apass, StrList **deplist) istk->mstk = NULL; istk->fp = fopen(file, "r"); istk->fname = NULL; - src_set_fname(nasm_strdup(file)); - src_set_linnum(0); + src_set(0, file); istk->lineinc = 1; if (!istk->fp) nasm_fatal(ERR_NOFILE, "unable to open input file `%s'", file); @@ -5032,10 +5030,8 @@ static char *pp_getline(void) "expected `%%endif' before end of file"); } /* only set line and file name if there's a next node */ - if (i->next) { - src_set_linnum(i->lineno); - src_set_fname(nasm_strdup(i->fname)); - } + if (i->next) + src_set(i->lineno, i->fname); istk = i->next; lfmt->downlevel(LIST_INCLUDE); nasm_free(i); @@ -5146,12 +5142,11 @@ static void pp_cleanup(int pass) Include *i = istk; istk = istk->next; fclose(i->fp); - nasm_free(i->fname); nasm_free(i); } while (cstk) ctx_pop(); - nasm_free(src_set_fname(NULL)); + src_set_fname(NULL); if (pass == 0) { IncPath *i; free_llist(predef); @@ -5269,8 +5264,7 @@ static void pp_list_one_macro(MMacro *m, int severity) pp_list_one_macro(m->next_active, severity); if (m->name && !m->nolist) { - src_set_linnum(m->xline + m->lineno); - src_set_fname(m->fname); + src_set(m->xline + m->lineno, m->fname); nasm_error(severity, "... from macro `%s' defined here", m->name); } } @@ -5281,13 +5275,11 @@ static void pp_error_list_macros(int severity) const char *saved_fname = NULL; severity |= ERR_PP_LISTMACRO | ERR_NO_SEVERITY; - saved_line = src_get_linnum(); - saved_fname = src_get_fname(); + src_get(&saved_line, &saved_fname); pp_list_one_macro(istk->mstk, severity); - src_set_fname((char *)saved_fname); - src_set_linnum(saved_line); + src_set(saved_line, saved_fname); } const struct preproc_ops nasmpp = { diff --git a/srcfile.c b/srcfile.c new file mode 100644 index 00000000..e84a8fb8 --- /dev/null +++ b/srcfile.c @@ -0,0 +1,132 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * 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 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * srcfile.c - keep track of the current position in the input stream + */ + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include + +#include "nasmlib.h" +#include "hashtbl.h" + +static const char *file_name = NULL; +static int32_t line_number = 0; + +static struct hash_table filename_hash; + +void src_init(void) +{ + hash_init(&filename_hash, HASH_MEDIUM); +} + +void src_free(void) +{ + struct hash_tbl_node *iter = NULL; + void *dp; + + while ((dp = hash_iterate(&filename_hash, &iter, NULL)) != NULL) + nasm_free(dp); + + hash_free(&filename_hash); +} + +/* + * Set the current filename, returning the old one. The input + * filename is duplicated if needed. + */ +const char *src_set_fname(const char *newname) +{ + struct hash_insert hi; + const char *oldname; + void **dp; + + if (newname) { + dp = hash_find(&filename_hash, newname, &hi); + if (dp) { + newname = (const char *)(*dp); + } else { + newname = nasm_strdup(newname); + hash_add(&hi, newname, (void *)newname); + } + } + + oldname = file_name; + file_name = newname; + return oldname; +} + +int32_t src_set_linnum(int32_t newline) +{ + int32_t oldline = line_number; + line_number = newline; + return oldline; +} + +void src_set(int32_t line, const char *fname) +{ + src_set_fname(fname); + src_set_linnum(line); +} + +const char *src_get_fname(void) +{ + return file_name; +} + +int32_t src_get_linnum(void) +{ + return line_number; +} + +int32_t src_get(int32_t *xline, const char **xname) +{ + const char *xn = *xname; + int32_t xl = *xline; + + *xline = line_number; + *xname = file_name; + + /* XXX: Is the strcmp() really needed here? */ + if (!file_name || !xn || (xn != file_name && strcmp(xn, file_name))) + return -2; + else + return line_number - xl; +}