Modularize errwarn. gettext()-ize in errwarn, not in every module, eliminating
authorPeter Johnson <peter@tortall.net>
Fri, 1 Nov 2002 10:05:03 +0000 (10:05 -0000)
committerPeter Johnson <peter@tortall.net>
Fri, 1 Nov 2002 10:05:03 +0000 (10:05 -0000)
libintl dependency in modules.
Also standardize initialize() and cleanup() functions.
Move replace_extension() from file.c to main.c.
Clean up some extern variable declarations in various places (particularly
nasm-compatible parser).

svn path=/trunk/yasm/; revision=792

105 files changed:
frontends/yasm/Makefile.inc
frontends/yasm/yasm-options.c
frontends/yasm/yasm.c
libyasm/Makefile.inc
libyasm/arch.h
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/coretype.h
libyasm/errwarn.c
libyasm/errwarn.h
libyasm/expr.c
libyasm/expr.h
libyasm/file.c
libyasm/file.h
libyasm/floatnum.c
libyasm/floatnum.h
libyasm/hamt.c
libyasm/hamt.h
libyasm/intnum.c
libyasm/intnum.h
libyasm/linemgr.c
libyasm/linemgr.h
libyasm/objfmt.h
libyasm/optimizer.h
libyasm/parser.h
libyasm/preproc.h
libyasm/section.c
libyasm/section.h
libyasm/symrec.c
libyasm/symrec.h
libyasm/tests/floatnum_test.c
libyasm/util.h
libyasm/xmalloc.c
modules/Makefile.inc
modules/arch/x86/x86arch.c
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86expr.c
modules/arch/x86/x86id.re
modules/objfmts/bin/bin-objfmt.c
modules/objfmts/coff/coff-objfmt.c
modules/objfmts/dbg/dbg-objfmt.c
modules/optimizers/basic/basic-optimizer.c
modules/parsers/nasm/Makefile.inc
modules/parsers/nasm/nasm-bison.y
modules/parsers/nasm/nasm-parser.c
modules/parsers/nasm/nasm-parser.h [new file with mode: 0644]
modules/parsers/nasm/nasm-token.re
modules/preprocs/raw/raw-preproc.c
modules/preprocs/yapp/yapp-preproc.c
modules/preprocs/yapp/yapp-preproc.h
modules/preprocs/yapp/yapp-token.h
modules/preprocs/yapp/yapp-token.l
src/Makefile.inc
src/arch.h
src/arch/x86/x86arch.c
src/arch/x86/x86arch.h
src/arch/x86/x86bc.c
src/arch/x86/x86expr.c
src/arch/x86/x86id.re
src/bytecode.c
src/bytecode.h
src/coretype.h
src/errwarn.c
src/errwarn.h
src/expr.c
src/expr.h
src/file.c
src/file.h
src/floatnum.c
src/floatnum.h
src/hamt.c
src/hamt.h
src/intnum.c
src/intnum.h
src/linemgr.c
src/linemgr.h
src/main.c
src/objfmt.h
src/objfmts/bin/bin-objfmt.c
src/objfmts/coff/coff-objfmt.c
src/objfmts/dbg/dbg-objfmt.c
src/optimizer.h
src/optimizers/basic/basic-optimizer.c
src/options.c
src/parser.h
src/parsers/nasm/Makefile.inc
src/parsers/nasm/nasm-bison.y
src/parsers/nasm/nasm-parser.c
src/parsers/nasm/nasm-parser.h [new file with mode: 0644]
src/parsers/nasm/nasm-token.re
src/preproc.h
src/preprocs/raw/raw-preproc.c
src/preprocs/yapp/yapp-preproc.c
src/preprocs/yapp/yapp-preproc.h
src/preprocs/yapp/yapp-token.h
src/preprocs/yapp/yapp-token.l
src/section.c
src/section.h
src/symrec.c
src/symrec.h
src/tests/floatnum_test.c
src/util.h
src/xmalloc.c
util.h

index 1926b5ae87939daaa9fa5e654f9529cfd1a509f0..27ce27918f4bd50348e2f22c2c18f4dde33eb1c5 100644 (file)
@@ -4,7 +4,6 @@ libyasm_la_SOURCES = \
        src/bytecode.c          \
        src/bytecode.h          \
        src/bc-int.h            \
-       src/errwarn.c           \
        src/errwarn.h           \
        src/expr.c              \
        src/expr.h              \
@@ -47,6 +46,7 @@ yasm_SOURCES += \
        src/parser.c            \
        src/module.h            \
        src/module.c            \
+       src/errwarn.c           \
        src/linemgr.c
 
 
index 9b4c7faa951108979295925297ea019b499ea197..f48dfb4e1ea5dfeff9e8a2b40b51115da434c0fe 100644 (file)
@@ -67,9 +67,9 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts)
                        if (options[i].takes_param) {
                            param = strchr(&argv[0][2], '=');
                            if (!param) {
-                               ErrorNow(_
-                                        ("option '--%s' needs an argument!"),
-                                        options[i].lopt);
+                               fprintf(stderr,
+                                       _("option '--%s' needs an argument!"),
+                                       options[i].lopt);
                                errors++;
                                goto fail;
                            } else {
@@ -86,7 +86,7 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts)
                    }
                }
                if (!got_it) {
-                   ErrorNow(_("unrecognized option '%s'"), argv[0]);
+                   fprintf(stderr, _("unrecognized option '%s'"), argv[0]);
                    errors++;
                }
            } else {            /* sopt */
@@ -101,8 +101,9 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts)
                            if (argv[0][2] != '\0')
                                param = &argv[0][2];
                            else if (param == NULL || *param == '-') {
-                               ErrorNow(_("option '-%c' needs an argument!"),
-                                        options[i].sopt);
+                               fprintf(stderr,
+                                       _("option '-%c' needs an argument!"),
+                                       options[i].sopt);
                                errors++;
                                goto fail;
                            } else {
@@ -118,7 +119,7 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts)
                    }
                }
                if (!got_it) {
-                   ErrorNow(_("unrecognized option '%s'"), argv[0]);
+                   fprintf(stderr, _("unrecognized option '%s'"), argv[0]);
                    errors++;
                }
            }
index a63bc53feb99c8a40049bc82b7efeee12cd95a9f..b8689b13ed90b743cd057b25665bad8397e941de 100644 (file)
@@ -50,6 +50,9 @@
 /* YASM's line manager (for parse stage). */
 extern linemgr yasm_linemgr;
 
+/* YASM's errwarn handlers. */
+extern errwarn yasm_errwarn;
+
 /* Extra path to search for our modules. */
 #ifndef YASM_MODULE_PATH_ENV
 # define YASM_MODULE_PATH_ENV  "YASM_MODULE_PATH"
@@ -67,6 +70,7 @@ static int special_options = 0;
 /*@null@*/ /*@dependent@*/ static optimizer *cur_optimizer = NULL;
 /*@null@*/ /*@dependent@*/ static dbgfmt *cur_dbgfmt = NULL;
 static int preproc_only = 0;
+static int warning_error = 0;  /* warnings being treated as errors */
 
 /*@null@*/ /*@dependent@*/ static FILE *open_obj(const char *mode);
 static void cleanup(/*@null@*/ sectionhead *sections);
@@ -81,6 +85,9 @@ static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
 static int opt_warning_handler(char *cmd, /*@null@*/ char *param, int extra);
 static int preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra);
 
+static /*@only@*/ char *replace_extension(const char *orig, /*@null@*/
+                                         const char *ext, const char *def);
+
 /* values for special_options */
 #define SPECIAL_SHOW_HELP 0x01
 #define SPECIAL_SHOW_VERSION 0x02
@@ -102,15 +109,16 @@ static opt_option options[] =
 
 /* version message */
 /*@observer@*/ static const char *version_msg[] = {
-    N_("yasm " VERSION "\n"),
-    N_("Copyright (c) 2001-2002 Peter Johnson and other " PACKAGE " developers\n"),
+    PACKAGE " " VERSION "\n",
+    N_("Copyright (c) 2001-2002 Peter Johnson and other"), " " PACKAGE " ",
+    N_("developers.\n"),
     N_("This program is free software; you may redistribute it under the\n"),
     N_("terms of the GNU General Public License.  Portions of this program\n"),
     N_("are licensed under the GNU Lesser General Public License or the\n"),
     N_("3-clause BSD license; see individual file comments for details.\n"),
     N_("This program has absolutely no warranty; not even for\n"),
     N_("merchantibility or fitness for a particular purpose.\n"),
-    N_("Compiled on " __DATE__ ".\n"),
+    N_("Compiled on"), " " __DATE__ ".\n",
 };
 
 /* help messages */
@@ -144,6 +152,12 @@ main(int argc, char *argv[])
 #endif
     textdomain(PACKAGE);
 
+    /* Initialize errwarn handling */
+    yasm_errwarn.initialize();
+
+    /* Initialize memory allocation */
+    xalloc_initialize((void (*) (int))yasm_errwarn.fatal, FATAL_NOMEM);
+
     /* Set libltdl malloc/free functions. */
 #ifdef WITH_DMALLOC
     lt_dlmalloc = malloc;
@@ -166,7 +180,7 @@ main(int argc, char *argv[])
            errors = lt_dladdsearchdir(path);
     }
     if (errors != 0) {
-       ErrorNow(_("Module loader initialization failed"));
+       fprintf(stderr, _("Module loader initialization failed"));
        return EXIT_FAILURE;
     }
 
@@ -186,7 +200,7 @@ main(int argc, char *argv[])
 
     /* Initialize BitVector (needed for floating point). */
     if (BitVector_Boot() != ErrCode_Ok) {
-       ErrorNow(_("Could not initialize BitVector"));
+       fprintf(stderr, _("Could not initialize BitVector"));
        return EXIT_FAILURE;
     }
 
@@ -194,7 +208,7 @@ main(int argc, char *argv[])
        /* Open the input file (if not standard input) */
        in = fopen(in_filename, "rt");
        if (!in) {
-           ErrorNow(_("could not open file `%s'"), in_filename);
+           fprintf(stderr, _("could not open file `%s'"), in_filename);
            xfree(in_filename);
            if (obj_filename)
                xfree(obj_filename);
@@ -208,9 +222,16 @@ main(int argc, char *argv[])
     }
 
     /* Initialize line manager */
-    yasm_linemgr.initialize();
+    yasm_linemgr.initialize(yasm_errwarn.internal_error_);
     yasm_linemgr.set(in_filename, 1, 1);
 
+    /* Initialize intnum and floatnum */
+    intnum_initialize(&yasm_errwarn);
+    floatnum_initialize(&yasm_errwarn);
+
+    /* Initialize symbol table */
+    symrec_initialize(&yasm_errwarn);
+
     /* handle preproc-only case here */
     if (preproc_only) {
        char *preproc_buf = xmalloc(PREPROC_BUF_SIZE);
@@ -233,15 +254,14 @@ main(int argc, char *argv[])
            cur_preproc = load_preproc("yapp");
 
        if (!cur_preproc) {
-           ErrorNow(_("Could not load default preprocessor"));
+           fprintf(stderr, _("Could not load default preprocessor"));
            cleanup(NULL);
            return EXIT_FAILURE;
        }
 
        /* Pre-process until done */
-       cur_preproc->initialize(in, in_filename);
-       while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE,
-                                        &yasm_linemgr)) != 0)
+       cur_preproc->initialize(in, in_filename, &yasm_linemgr, &yasm_errwarn);
+       while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0)
            fwrite(preproc_buf, got, 1, obj);
 
        if (in != stdin)
@@ -250,8 +270,8 @@ main(int argc, char *argv[])
        if (obj != stdout)
            fclose(obj);
 
-       if (GetNumErrors() > 0) {
-           OutputAllErrorWarning(&yasm_linemgr);
+       if (yasm_errwarn.get_num_errors(warning_error) > 0) {
+           yasm_errwarn.output_all(&yasm_linemgr, warning_error);
            if (obj != stdout)
                remove(obj_filename);
            xfree(preproc_buf);
@@ -267,28 +287,30 @@ main(int argc, char *argv[])
     cur_arch = load_arch("x86");
 
     if (!cur_arch) {
-       ErrorNow(_("Could not load default architecture"));
+       fprintf(stderr, _("Could not load default architecture"));
        return EXIT_FAILURE;
     }
 
+    cur_arch->initialize(&yasm_errwarn);
+
     /* Set basic as the optimizer (TODO: user choice) */
     cur_optimizer = load_optimizer("basic");
 
     if (!cur_optimizer) {
-       ErrorNow(_("Could not load default optimizer"));
+       fprintf(stderr, _("Could not load default optimizer"));
        return EXIT_FAILURE;
     }
 
     arch_common_initialize(cur_arch);
-    expr_initialize(cur_arch);
-    bc_initialize(cur_arch);
+    expr_initialize(cur_arch, &yasm_errwarn);
+    bc_initialize(cur_arch, &yasm_errwarn);
 
     /* If not already specified, default to bin as the object format. */
     if (!cur_objfmt)
        cur_objfmt = load_objfmt("bin");
 
     if (!cur_objfmt) {
-       ErrorNow(_("Could not load default object format"));
+       fprintf(stderr, _("Could not load default object format"));
        return EXIT_FAILURE;
     }
 
@@ -305,8 +327,9 @@ main(int argc, char *argv[])
                           cur_dbgfmt->keyword) == 0)
                matched_dbgfmt = 1;
        if (!matched_dbgfmt) {
-           ErrorNow(_("`%s' is not a valid debug format for object format `%s'"),
-                    cur_dbgfmt->keyword, cur_objfmt->keyword);
+           fprintf(stderr,
+               _("`%s' is not a valid debug format for object format `%s'"),
+               cur_dbgfmt->keyword, cur_objfmt->keyword);
            if (in != stdin)
                fclose(in);
            cleanup(NULL);
@@ -315,7 +338,7 @@ main(int argc, char *argv[])
     }
 
     if (!cur_dbgfmt) {
-       ErrorNow(_("Could not load default debug format"));
+       fprintf(stderr, _("Could not load default debug format"));
        return EXIT_FAILURE;
     }
 
@@ -334,12 +357,12 @@ main(int argc, char *argv[])
     /* Initialize the object format */
     if (cur_objfmt->initialize)
        cur_objfmt->initialize(in_filename, obj_filename, cur_dbgfmt,
-                              cur_arch);
+                              cur_arch, &yasm_errwarn);
 
     /* Set NASM as the parser */
     cur_parser = load_parser("nasm");
     if (!cur_parser) {
-       ErrorNow(_("unrecognized parser `%s'"), "nasm");
+       fprintf(stderr, _("unrecognized parser `%s'"), "nasm");
        cleanup(NULL);
        return EXIT_FAILURE;
     }
@@ -357,8 +380,9 @@ main(int argc, char *argv[])
                           cur_preproc->keyword) == 0)
                matched_preproc = 1;
        if (!matched_preproc) {
-           ErrorNow(_("`%s' is not a valid preprocessor for parser `%s'"),
-                    cur_preproc->keyword, cur_parser->keyword);
+           fprintf(stderr,
+                   _("`%s' is not a valid preprocessor for parser `%s'"),
+                   cur_preproc->keyword, cur_parser->keyword);
            if (in != stdin)
                fclose(in);
            cleanup(NULL);
@@ -376,23 +400,24 @@ main(int argc, char *argv[])
 
     /* Parse! */
     sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt,
-                                   &yasm_linemgr, in, in_filename);
+                                   &yasm_linemgr, &yasm_errwarn, in,
+                                   in_filename);
 
     /* Close input file */
     if (in != stdin)
        fclose(in);
 
-    if (GetNumErrors() > 0) {
-       OutputAllErrorWarning(&yasm_linemgr);
+    if (yasm_errwarn.get_num_errors(warning_error) > 0) {
+       yasm_errwarn.output_all(&yasm_linemgr, warning_error);
        cleanup(sections);
        return EXIT_FAILURE;
     }
 
     symrec_parser_finalize();
-    cur_optimizer->optimize(sections);
+    cur_optimizer->optimize(sections, &yasm_errwarn);
 
-    if (GetNumErrors() > 0) {
-       OutputAllErrorWarning(&yasm_linemgr);
+    if (yasm_errwarn.get_num_errors(warning_error) > 0) {
+       yasm_errwarn.output_all(&yasm_linemgr, warning_error);
        cleanup(sections);
        return EXIT_FAILURE;
     }
@@ -416,14 +441,14 @@ main(int argc, char *argv[])
     /* If we had an error at this point, we also need to delete the output
      * object file (to make sure it's not left newer than the source).
      */
-    if (GetNumErrors() > 0) {
-       OutputAllErrorWarning(&yasm_linemgr);
+    if (yasm_errwarn.get_num_errors(warning_error) > 0) {
+       yasm_errwarn.output_all(&yasm_linemgr, warning_error);
        remove(obj_filename);
        cleanup(sections);
        return EXIT_FAILURE;
     }
 
-    OutputAllErrorWarning(&yasm_linemgr);
+    yasm_errwarn.output_all(&yasm_linemgr, warning_error);
 
     cleanup(sections);
     return EXIT_SUCCESS;
@@ -440,7 +465,7 @@ open_obj(const char *mode)
 
     obj = fopen(obj_filename, mode);
     if (!obj)
-       ErrorNow(_("could not open file `%s'"), obj_filename);
+       fprintf(stderr, _("could not open file `%s'"), obj_filename);
     return obj;
 }
 
@@ -450,13 +475,21 @@ cleanup(sectionhead *sections)
 {
     if (cur_objfmt && cur_objfmt->cleanup)
        cur_objfmt->cleanup();
+    if (cur_dbgfmt && cur_dbgfmt->cleanup)
+       cur_dbgfmt->cleanup();
+    if (cur_preproc)
+       cur_preproc->cleanup();
     if (sections)
        sections_delete(sections);
-    symrec_delete_all();
-    yasm_linemgr.cleanup();
+    symrec_cleanup();
+    if (cur_arch)
+       cur_arch->cleanup();
+
+    floatnum_cleanup();
+    intnum_cleanup();
 
-    floatnum_shutdown();
-    intnum_shutdown();
+    yasm_errwarn.cleanup();
+    yasm_linemgr.cleanup();
 
     BitVector_Shutdown();
 
@@ -478,7 +511,8 @@ int
 not_an_option_handler(char *param)
 {
     if (in_filename) {
-       WarningNow(_("can open only one input file, only the last file will be processed"));
+       fprintf(stderr,
+           _("warning: can open only one input file, only the last file will be processed"));
        xfree(in_filename);
     }
 
@@ -501,7 +535,7 @@ opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
     assert(param != NULL);
     cur_parser = load_parser(param);
     if (!cur_parser) {
-       ErrorNow(_("unrecognized parser `%s'"), param);
+       fprintf(stderr, _("unrecognized parser `%s'"), param);
        return 1;
     }
     return 0;
@@ -513,7 +547,7 @@ opt_preproc_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
     assert(param != NULL);
     cur_preproc = load_preproc(param);
     if (!cur_preproc) {
-       ErrorNow(_("unrecognized preprocessor `%s'"), param);
+       fprintf(stderr, _("unrecognized preprocessor `%s'"), param);
        return 1;
     }
     return 0;
@@ -525,7 +559,7 @@ opt_objfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
     assert(param != NULL);
     cur_objfmt = load_objfmt(param);
     if (!cur_objfmt) {
-       ErrorNow(_("unrecognized object format `%s'"), param);
+       fprintf(stderr, _("unrecognized object format `%s'"), param);
        return 1;
     }
     return 0;
@@ -537,7 +571,7 @@ opt_dbgfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
     assert(param != NULL);
     cur_dbgfmt = load_objfmt(param);
     if (!cur_dbgfmt) {
-       ErrorNow(_("unrecognized debugging format `%s'"), param);
+       fprintf(stderr, _("unrecognized debugging format `%s'"), param);
        return 1;
     }
     return 0;
@@ -548,7 +582,8 @@ opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
                    /*@unused@*/ int extra)
 {
     if (obj_filename) {
-       WarningNow(_("can output to only one object file, last specified used"));
+       fprintf(stderr,
+           _("warning: can output to only one object file, last specified used"));
        xfree(obj_filename);
     }
 
@@ -565,7 +600,7 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra)
 
     if (extra == 1) {
        /* -w, disable warnings */
-       warnings_disabled = 1;
+       yasm_errwarn.warn_disable_all();
        return 0;
     }
 
@@ -584,7 +619,10 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra)
     else if (strcmp(cmd, "error") == 0) {
        warning_error = enable;
     } else if (strcmp(cmd, "unrecognized-char") == 0) {
-       WARN_ENABLE(WARN_UNRECOGNIZED_CHAR, enable);
+       if (enable)
+           yasm_errwarn.warn_enable(WARN_UNREC_CHAR);
+       else
+           yasm_errwarn.warn_disable(WARN_UNREC_CHAR);
     } else
        return 1;
 
@@ -598,3 +636,58 @@ preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param,
     preproc_only = 1;
     return 0;
 }
+
+/* Replace extension on a filename (or append one if none is present).
+ * If output filename would be identical to input (same extension out as in),
+ * returns (copy of) def.
+ * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext
+ * means the trailing '.' should be included.
+ */
+static char *
+replace_extension(const char *orig, /*@null@*/ const char *ext,
+                 const char *def)
+{
+    char *out, *outext;
+
+    /* allocate enough space for full existing name + extension */
+    out = xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1));
+    strcpy(out, orig);
+    outext = strrchr(out, '.');
+    if (outext) {
+       /* Existing extension: make sure it's not the same as the replacement
+        * (as we don't want to overwrite the source file).
+        */
+       outext++;   /* advance past '.' */
+       if (ext && strcmp(outext, ext) == 0) {
+           outext = NULL;  /* indicate default should be used */
+           fprintf(stderr,
+               _("file name already ends in `.%s': output will be in `%s'"),
+               ext, def);
+       }
+    } else {
+       /* No extension: make sure the output extension is not empty
+        * (again, we don't want to overwrite the source file).
+        */
+       if (!ext)
+           fprintf(stderr,
+               _("file name already has no extension: output will be in `%s'"),
+               def);
+       else {
+           outext = strrchr(out, '\0');    /* point to end of the string */
+           *outext++ = '.';                /* append '.' */
+       }
+    }
+
+    /* replace extension or use default name */
+    if (outext) {
+       if (!ext) {
+           /* Back up and replace '.' with string terminator */
+           outext--;
+           *outext = '\0';
+       } else
+           strcpy(outext, ext);
+    } else
+       strcpy(out, def);
+
+    return out;
+}
index 1926b5ae87939daaa9fa5e654f9529cfd1a509f0..27ce27918f4bd50348e2f22c2c18f4dde33eb1c5 100644 (file)
@@ -4,7 +4,6 @@ libyasm_la_SOURCES = \
        src/bytecode.c          \
        src/bytecode.h          \
        src/bc-int.h            \
-       src/errwarn.c           \
        src/errwarn.h           \
        src/expr.c              \
        src/expr.h              \
@@ -47,6 +46,7 @@ yasm_SOURCES += \
        src/parser.c            \
        src/module.h            \
        src/module.c            \
+       src/errwarn.c           \
        src/linemgr.c
 
 
index 3d23ea8ca72bcbeebe529f81b87d9895543bbf7a..fb26d312c3d3d47286bf28b73856e261c28e6199 100644 (file)
@@ -58,6 +58,9 @@ struct arch {
     /* keyword used to select architecture */
     const char *keyword;
 
+    void (*initialize) (errwarn *we);
+    void (*cleanup) (void);
+
     struct {
        /* All "data" below starts the parse initialized to 0.  Thus, it is
         * okay for a funtion to use/check previously stored data to see if
index 3a1132d3b1acac1898d2d60bef1734003dabadee..2f84a64e2109b530b33b3d963896efc70bc70d74 100644 (file)
@@ -96,12 +96,14 @@ typedef struct bytecode_objfmt_data {
 unsigned char bytes_static[16];
 
 /*@dependent@*/ static arch *cur_arch;
+/*@dependent@*/ static errwarn *cur_we;
 
 
 void
-bc_initialize(arch *a)
+bc_initialize(arch *a, errwarn *we)
 {
     cur_arch = a;
+    cur_we = we;
 }
 
 immval *
@@ -328,13 +330,14 @@ bc_delete(bytecode *bc)
                objfmt_data->of->bc_objfmt_data_delete(objfmt_data->type,
                                                       objfmt_data->data);
            else
-               InternalError(_("objfmt can't handle its own objfmt data bytecode"));
+               cur_we->internal_error(
+                   N_("objfmt can't handle its own objfmt data bytecode"));
            break;
        default:
            if (bc->type < cur_arch->bc.type_max)
                cur_arch->bc.bc_delete(bc);
            else
-               InternalError(_("Unknown bytecode type"));
+               cur_we->internal_error(N_("Unknown bytecode type"));
            break;
     }
     /*@=branchstate@*/
@@ -500,10 +503,11 @@ bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len, int save,
         * the circular reference error to filter through.
         */
        if (temp && expr_contains(temp, EXPR_FLOAT))
-           Error(line, _("expression must not contain floating point value"));
+           cur_we->error(line,
+               N_("expression must not contain floating point value"));
        else
-           Error(line,
-                 _("attempt to reserve non-constant quantity of space"));
+           cur_we->error(line,
+               N_("attempt to reserve non-constant quantity of space"));
        retval = BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
     } else
        *len += intnum_get_uint(num)*reserve->itemsize;
@@ -565,12 +569,13 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
     /* Open file and determine its length */
     f = fopen(incbin->filename, "rb");
     if (!f) {
-       Error(line, _("`incbin': unable to open file `%s'"), incbin->filename);
+       cur_we->error(line, N_("`incbin': unable to open file `%s'"),
+                     incbin->filename);
        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
     }
     if (fseek(f, 0L, SEEK_END) < 0) {
-       Error(line, _("`incbin': unable to seek on file `%s'"),
-             incbin->filename);
+       cur_we->error(line, N_("`incbin': unable to seek on file `%s'"),
+                     incbin->filename);
        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
     }
     flen = (unsigned long)ftell(f);
@@ -578,8 +583,9 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
 
     /* Compute length of incbin from start, maxlen, and len */
     if (start > flen) {
-       Warning(line, _("`incbin': start past end of file `%s'"),
-               incbin->filename);
+       cur_we->warning(WARN_GENERAL, line,
+                       N_("`incbin': start past end of file `%s'"),
+                       incbin->filename);
        start = flen;
     }
     flen -= start;
@@ -603,7 +609,7 @@ bc_resolve(bytecode *bc, int save, const section *sect,
 
     switch (bc->type) {
        case BC_EMPTY:
-           InternalError(_("got empty bytecode in bc_calc_len"));
+           cur_we->internal_error(N_("got empty bytecode in bc_calc_len"));
        case BC_DATA:
            retval = bc_resolve_data((bytecode_data *)bc, &bc->len);
            break;
@@ -617,17 +623,18 @@ bc_resolve(bytecode *bc, int save, const section *sect,
            break;
        case BC_ALIGN:
            /* TODO */
-           InternalError(_("TODO: align bytecode not implemented!"));
+           cur_we->internal_error(
+               N_("TODO: align bytecode not implemented!"));
            /*break;*/
        case BC_OBJFMT_DATA:
-           InternalError(_("resolving objfmt data bytecode?"));
+           cur_we->internal_error(N_("resolving objfmt data bytecode?"));
            /*break;*/
        default:
            if (bc->type < cur_arch->bc.type_max)
                retval = cur_arch->bc.bc_resolve(bc, save, sect,
                                                 calc_bc_dist);
            else
-               InternalError(_("Unknown bytecode type"));
+               cur_we->internal_error(N_("Unknown bytecode type"));
     }
 
     /* Multiply len by number of multiples */
@@ -644,8 +651,8 @@ bc_resolve(bytecode *bc, int save, const section *sect,
        if (!num) {
            retval = BC_RESOLVE_UNKNOWN_LEN;
            if (temp && expr_contains(temp, EXPR_FLOAT)) {
-               Error(bc->line,
-                     _("expression must not contain floating point value"));
+               cur_we->error(bc->line,
+                   N_("expression must not contain floating point value"));
                retval |= BC_RESOLVE_ERROR;
            }
        } else
@@ -711,29 +718,32 @@ bc_tobytes_incbin(bytecode_incbin *incbin, unsigned char **bufp,
     if (incbin->start) {
        num = expr_get_intnum(&incbin->start, NULL);
        if (!num)
-           InternalError(_("could not determine start in bc_tobytes_incbin"));
+           cur_we->internal_error(
+               N_("could not determine start in bc_tobytes_incbin"));
        start = intnum_get_uint(num);
     }
 
     /* Open file */
     f = fopen(incbin->filename, "rb");
     if (!f) {
-       Error(line, _("`incbin': unable to open file `%s'"), incbin->filename);
+       cur_we->error(line, N_("`incbin': unable to open file `%s'"),
+                     incbin->filename);
        return 1;
     }
 
     /* Seek to start of data */
     if (fseek(f, (long)start, SEEK_SET) < 0) {
-       Error(line, _("`incbin': unable to seek on file `%s'"),
-             incbin->filename);
+       cur_we->error(line, N_("`incbin': unable to seek on file `%s'"),
+                     incbin->filename);
        fclose(f);
        return 1;
     }
 
     /* Read len bytes */
     if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) {
-       Error(line, _("`incbin': unable to read %lu bytes from file `%s'"),
-             len, incbin->filename);
+       cur_we->error(line,
+                     N_("`incbin': unable to read %lu bytes from file `%s'"),
+                     len, incbin->filename);
        fclose(f);
        return 1;
     }
@@ -760,7 +770,8 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize,
     if (bc->multiple) {
        num = expr_get_intnum(&bc->multiple, NULL);
        if (!num)
-           InternalError(_("could not determine multiple in bc_tobytes"));
+           cur_we->internal_error(
+               N_("could not determine multiple in bc_tobytes"));
        *multiple = intnum_get_uint(num);
        if (*multiple == 0) {
            *bufsize = 0;
@@ -790,7 +801,7 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize,
 
     switch (bc->type) {
        case BC_EMPTY:
-           InternalError(_("got empty bytecode in bc_tobytes"));
+           cur_we->internal_error(N_("got empty bytecode in bc_tobytes"));
        case BC_DATA:
            error = bc_tobytes_data((bytecode_data *)bc, &destbuf, sect, bc, d,
                                    output_expr);
@@ -801,7 +812,8 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize,
            break;
        case BC_ALIGN:
            /* TODO */
-           InternalError(_("TODO: align bytecode not implemented!"));
+           cur_we->internal_error(
+               N_("TODO: align bytecode not implemented!"));
            /*break;*/
        case BC_OBJFMT_DATA:
            objfmt_data = (bytecode_objfmt_data *)bc;
@@ -809,18 +821,20 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize,
                error = output_bc_objfmt_data(objfmt_data->type,
                                              objfmt_data->data, &destbuf);
            else
-               InternalError(_("Have objfmt data bytecode but no way to output it"));
+               cur_we->internal_error(
+                   N_("Have objfmt data bytecode but no way to output it"));
            break;
        default:
            if (bc->type < cur_arch->bc.type_max)
                error = cur_arch->bc.bc_tobytes(bc, &destbuf, sect, d,
                                                output_expr);
            else
-               InternalError(_("Unknown bytecode type"));
+               cur_we->internal_error(N_("Unknown bytecode type"));
     }
 
     if (!error && ((unsigned long)(destbuf - origbuf) != datasize))
-       InternalError(_("written length does not match optimized length"));
+       cur_we->internal_error(
+           N_("written length does not match optimized length"));
     return mybuf;
 }
 
index f2938ef44961a1eb30e7fd07d53232819f3a3d85..2259400e828abb61613ec034d044b48aea7d697b 100644 (file)
@@ -40,7 +40,7 @@ typedef enum {
 } bytecode_type;
 #define BYTECODE_TYPE_BASE  BC_OBJFMT_DATA+1
 
-void bc_initialize(arch *a);
+void bc_initialize(arch *a, errwarn *we);
 
 /*@only@*/ immval *imm_new_int(unsigned long int_val, unsigned long lindex);
 /*@only@*/ immval *imm_new_expr(/*@keep@*/ expr *e);
index d1585fa9a5c9920f24f9f627f5446bca6ee64016..0701d56d0bdde8b348d73f621f3cf9188f183a36 100644 (file)
@@ -43,6 +43,7 @@ typedef struct intnum intnum;
 typedef struct floatnum floatnum;
 
 typedef struct linemgr linemgr;
+typedef struct errwarn errwarn;
 
 typedef enum {
     EXPR_ADD,
index c74d533730fec04f4d022f27762c2de41c937aed..6278a3e1ca17658649f691a2f3ae03b67eca87d9 100644 (file)
 
 #define MSG_MAXSIZE    1024
 
-/* ALL warnings are disabled if this is nonzero. */
-int warnings_disabled = 0;
+/* Enabled warnings.  See errwarn.h for a list. */
+static unsigned long warn_class_enabled;
 
-/* Warnings are treated as errors if this is nonzero.
- * =2 indicates that warnings are treated as errors, and the message to the
- * user saying that has been output.
- */
-int warning_error = 0;
-
-/* Default enabled warnings.  See errwarn.h for a list. */
-unsigned long warning_flags =
-    (1UL<<WARN_UNRECOGNIZED_CHAR);
+/* Total error count */
+static unsigned int error_count;
 
-/* Total error count for entire assembler run.
- * Assembler should exit with EXIT_FAILURE if this is >= 0 on finish. */
-static unsigned int error_count = 0;
-
-/* Total warning count for entire assembler run.
- * Should not affect exit value of assembler. */
-static unsigned int warning_count = 0;
+/* Total warning count */
+static unsigned int warning_count;
 
 /* See errwarn.h for constants that match up to these strings.
- * When adding a string here, keep errwarn.h in sync! */
+ * When adding a string here, keep errwarn.h in sync!
+ */
 
 /* Fatal error messages.  Match up with fatal_num enum in errwarn.h. */
 /*@-observertrans@*/
@@ -66,12 +55,12 @@ static const char *fatal_msgs[] = {
 };
 /*@=observertrans@*/
 
-typedef /*@reldef@*/ SLIST_HEAD(errwarnhead_s, errwarn_s) errwarnhead;
-static /*@only@*/ /*@null@*/ errwarnhead errwarns =
-    SLIST_HEAD_INITIALIZER(errwarns);
+typedef /*@reldef@*/ SLIST_HEAD(errwarndatahead_s, errwarn_data)
+    errwarndatahead;
+static /*@only@*/ /*@null@*/ errwarndatahead errwarns;
 
-typedef struct errwarn_s {
-    /*@reldef@*/ SLIST_ENTRY(errwarn_s) link;
+typedef struct errwarn_data {
+    /*@reldef@*/ SLIST_ENTRY(errwarn_data) link;
 
     enum { WE_UNKNOWN, WE_ERROR, WE_WARNING, WE_PARSERERROR } type;
 
@@ -79,18 +68,47 @@ typedef struct errwarn_s {
     /* FIXME: This should not be a fixed size.  But we don't have vasprintf()
      * right now. */
     char msg[MSG_MAXSIZE];
-} errwarn;
+} errwarn_data;
 
 /* Last inserted error/warning.  Used to speed up insertions. */
-static /*@null@*/ errwarn *previous_we = NULL;
+static /*@null@*/ errwarn_data *previous_we;
 
 /* Static buffer for use by conv_unprint(). */
 static char unprint[5];
 
+
+static void
+yasm_errwarn_initialize(void)
+{
+    /* Default enabled warnings.  See errwarn.h for a list. */
+    warn_class_enabled = 
+       (1UL<<WARN_GENERAL) | (1UL<<WARN_UNREC_CHAR) | (1UL<<WARN_PREPROC);
+
+    error_count = 0;
+    warning_count = 0;
+    SLIST_INIT(&errwarns);
+    previous_we = NULL;
+}
+
+static void
+yasm_errwarn_cleanup(void)
+{
+    errwarn_data *we;
+
+    /* Delete all error/warnings */
+    while (!SLIST_EMPTY(&errwarns)) {
+       we = SLIST_FIRST(&errwarns);
+
+       SLIST_REMOVE_HEAD(&errwarns, link);
+       xfree(we);
+    }
+}
+
 /* Convert a possibly unprintable character into a printable string, using
- * standard cat(1) convention for unprintable characters. */
-char *
-conv_unprint(char ch)
+ * standard cat(1) convention for unprintable characters.
+ */
+static char *
+yasm_errwarn_conv_unprint(char ch)
 {
     int pos = 0;
 
@@ -110,12 +128,14 @@ conv_unprint(char ch)
 }
 
 /* Report an internal error.  Essentially a fatal error with trace info.
- * Exit immediately because it's essentially an assert() trap. */
-void
-InternalError_(const char *file, unsigned int line, const char *message)
+ * Exit immediately because it's essentially an assert() trap.
+ */
+static void
+yasm_errwarn_internal_error_(const char *file, unsigned int line,
+                            const char *message)
 {
     fprintf(stderr, _("INTERNAL ERROR at %s, line %u: %s\n"), file, line,
-           message);
+           gettext(message));
 #ifdef HAVE_ABORT
     abort();
 #else
@@ -124,11 +144,12 @@ InternalError_(const char *file, unsigned int line, const char *message)
 }
 
 /* Report a fatal error.  These are unrecoverable (such as running out of
- * memory), so just exit immediately. */
-void
-Fatal(fatal_num num)
+ * memory), so just exit immediately.
+ */
+static void
+yasm_errwarn_fatal(fatal_num num)
 {
-    fprintf(stderr, "%s %s\n", _("FATAL:"), gettext(fatal_msgs[num]));
+    fprintf(stderr, _("FATAL: %s\n"), gettext(fatal_msgs[num]));
 #ifdef HAVE_ABORT
     abort();
 #else
@@ -140,10 +161,10 @@ Fatal(fatal_num num)
  * If replace_parser_error is nonzero, overwrites the last error if its
  * type is WE_PARSERERROR.
  */
-static errwarn *
-errwarn_new(unsigned long lindex, int replace_parser_error)
+static errwarn_data *
+errwarn_data_new(unsigned long lindex, int replace_parser_error)
 {
-    errwarn *first, *next, *ins_we, *we;
+    errwarn_data *first, *next, *ins_we, *we;
     enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE;
 
     /* Find the entry with either line=lindex or the last one with line<lindex.
@@ -173,7 +194,7 @@ errwarn_new(unsigned long lindex, int replace_parser_error)
        we = ins_we;
     } else {
        /* add a new error */
-       we = xmalloc(sizeof(errwarn));
+       we = xmalloc(sizeof(errwarn_data));
 
        we->type = WE_UNKNOWN;
        we->line = lindex;
@@ -184,7 +205,8 @@ errwarn_new(unsigned long lindex, int replace_parser_error)
            assert(ins_we != NULL);
            SLIST_INSERT_AFTER(ins_we, we, link);
        } else
-           InternalError(_("Unexpected errwarn insert action"));
+           yasm_errwarn_internal_error_(__FILE__, __LINE__,
+               N_("Unexpected errwarn insert action"));
     }
 
     /* Remember previous err/warn */
@@ -193,40 +215,52 @@ errwarn_new(unsigned long lindex, int replace_parser_error)
     return we;
 }
 
-/* Register an error.  Does not print the error, only stores it for
- * OutputAllErrorWarning() to print.
+/* Register an error at line lindex.  Does not print the error, only stores it
+ * for output_all() to print.
  */
 static void
-error_common(unsigned long lindex, const char *fmt, va_list ap)
+yasm_errwarn_error(unsigned long lindex, const char *fmt, ...)
 {
-    errwarn *we = errwarn_new(lindex, 1);
+    va_list va;
+    errwarn_data *we = errwarn_data_new(lindex, 1);
 
     we->type = WE_ERROR;
 
+    va_start(va, fmt);
 #ifdef HAVE_VSNPRINTF
-    vsnprintf(we->msg, MSG_MAXSIZE, fmt, ap);
+    vsnprintf(we->msg, MSG_MAXSIZE, gettext(fmt), va);
 #else
-    vsprintf(we->msg, fmt, ap);
+    vsprintf(we->msg, gettext(fmt), va);
 #endif
+    va_end(va);
 
     error_count++;
 }
 
-/* Register an warning.  Does not print the warning, only stores it for
- * OutputAllErrorWarning() to print.
+/* Register an warning at line lindex.  Does not print the warning, only stores
+ * it for output_all() to print.
  */
 static void
-warning_common(unsigned long lindex, const char *fmt, va_list va)
+yasm_errwarn_warning(warn_class_num num, unsigned long lindex, const char *fmt,
+                    ...)
 {
-    errwarn *we = errwarn_new(lindex, 0);
+    va_list va;
+    errwarn_data *we;
+
+    if (!(warn_class_enabled & (1UL<<num)))
+       return;     /* warning is part of disabled class */
+
+    we = errwarn_data_new(lindex, 0);
 
     we->type = WE_WARNING;
 
+    va_start(va, fmt);
 #ifdef HAVE_VSNPRINTF
-    vsnprintf(we->msg, MSG_MAXSIZE, fmt, va);
+    vsnprintf(we->msg, MSG_MAXSIZE, gettext(fmt), va);
 #else
-    vsprintf(we->msg, fmt, va);
+    vsprintf(we->msg, gettext(fmt), va);
 #endif
+    va_end(va);
 
     warning_count++;
 }
@@ -234,92 +268,59 @@ warning_common(unsigned long lindex, const char *fmt, va_list va)
 /* Parser error handler.  Moves YACC-style error into our error handling
  * system.
  */
-void
-ParserError(unsigned long lindex, const char *s)
+static void
+yasm_errwarn_parser_error(unsigned long lindex, const char *s)
 {
-    Error(lindex, "%s %s", _("parser error:"), s);
+    yasm_errwarn_error(lindex, N_("parser error: %s"), s);
     previous_we->type = WE_PARSERERROR;
 }
 
-/* Register an error at line lindex.  Does not print the error, only stores it
- * for OutputAllErrorWarning() to print.
- */
-void
-Error(unsigned long lindex, const char *fmt, ...)
+static void
+yasm_errwarn_warn_enable(warn_class_num num)
 {
-    va_list va;
-    va_start(va, fmt);
-    error_common(lindex, fmt, va);
-    va_end(va);
+    warn_class_enabled |= (1UL<<num);
 }
 
-/* Register an warning at line lindex.  Does not print the warning, only stores
- * it for OutputAllErrorWarning() to print.
- */
-void
-Warning(unsigned long lindex, const char *fmt, ...)
-{
-    va_list va;
-    va_start(va, fmt);
-    warning_common(lindex, fmt, va);
-    va_end(va);
-}
-
-void
-ErrorNow(const char *fmt, ...)
+static void
+yasm_errwarn_warn_disable(warn_class_num num)
 {
-    va_list ap;
-
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-    fprintf(stderr, "\n");
+    warn_class_enabled &= ~(1UL<<num);
 }
 
-void
-WarningNow(const char *fmt, ...)
+static void
+yasm_errwarn_warn_disable_all(void)
 {
-    va_list ap;
-
-    if (warnings_disabled)
-       return;
-
-    fprintf(stderr, "%s ", _("warning:"));
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-    fprintf(stderr, "\n");
+    warn_class_enabled = 0;
 }
 
 /* Get the number of errors (including warnings if warnings are being treated
  * as errors).
  */
-unsigned int
-GetNumErrors(void)
+static unsigned int
+yasm_errwarn_get_num_errors(int warning_as_error)
 {
-    if (warning_error)
+    if (warning_as_error)
        return error_count+warning_count;
     else
        return error_count;
 }
 
 /* Output all previously stored errors and warnings to stderr. */
-void
-OutputAllErrorWarning(linemgr *lm)
+static void
+yasm_errwarn_output_all(linemgr *lm, int warning_as_error)
 {
-    errwarn *we;
+    errwarn_data *we;
     const char *filename;
     unsigned long line;
 
     /* If we're treating warnings as errors, tell the user about it. */
-    if (warning_error && warning_error != 2) {
+    if (warning_as_error && warning_as_error != 2) {
        fprintf(stderr, "%s\n", _("warnings being treated as errors"));
-       warning_error = 2;
+       warning_as_error = 2;
     }
 
-    /* Output error/warning, then delete each message. */
-    while (!SLIST_EMPTY(&errwarns)) {
-       we = SLIST_FIRST(&errwarns);
+    /* Output error/warnings. */
+    SLIST_FOREACH(we, &errwarns, link) {
        /* Output error/warning */
        lm->lookup(we->line, &filename, &line);
        if (we->type == WE_ERROR)
@@ -327,9 +328,21 @@ OutputAllErrorWarning(linemgr *lm)
        else
            fprintf(stderr, "%s:%lu: %s %s\n", filename, line, _("warning:"),
                    we->msg);
-
-       /* Delete */
-       SLIST_REMOVE_HEAD(&errwarns, link);
-       xfree(we);
     }
 }
+
+errwarn yasm_errwarn = {
+    yasm_errwarn_initialize,
+    yasm_errwarn_cleanup,
+    yasm_errwarn_internal_error_,
+    yasm_errwarn_fatal,
+    yasm_errwarn_error,
+    yasm_errwarn_warning,
+    yasm_errwarn_parser_error,
+    yasm_errwarn_warn_enable,
+    yasm_errwarn_warn_disable,
+    yasm_errwarn_warn_disable_all,
+    yasm_errwarn_get_num_errors,
+    yasm_errwarn_output_all,
+    yasm_errwarn_conv_unprint
+};
index 75ee91a375425a608981345f7290e3cd306054a2..e3c3014eedd9c26b7f611a7e92e5969470a54dbf 100644 (file)
 #ifndef YASM_ERRWARN_H
 #define YASM_ERRWARN_H
 
-/* ALL warnings disabled? */
-extern int warnings_disabled;
-
-/* Warnings treated as errors? */
-extern int warning_error;
-
-/* Warning flags.  Currently a maximum of 32 are allowed.  This can be
- * increased by making this an array and modifying the WARN_ macros to use the
- * proper array index based on the warning number.
- *
- * If a bit is 1, it means that particular warning is enabled.  The bit numbers
- * are assigned according to the warn_flag_num enum.
- *
- * See errwarn.c for what warnings are enabled by default.
- */
-extern unsigned long warning_flags;
+/* Warning classes (may be enabled/disabled). */
 typedef enum {
-    WARN_UNRECOGNIZED_CHAR = 0
-} warn_flag_num;
-
-/* Tests the warning flags to see if warning "warn" is enabled */
-#define WARN_ENABLED(warn)     (warning_flags & (1<<(warn)))
-/* Sets warning "warn" to be enabled or disabled based on "s" (1=en, 0=dis). */
-#define WARN_ENABLE(warn, s)   do { \
-       warning_flags &= ~(1<<(warn)); \
-       warning_flags |= (s)<<(warn); \
-    } while(0)
+    WARN_GENERAL = 0,      /* non-specific warnings */
+    WARN_UNREC_CHAR,       /* unrecognized characters (while tokenizing) */
+    WARN_PREPROC           /* preprocessor warnings */
+} warn_class_num;
 
 /* Fatal error constants.
  * See fatal_msgs in errwarn.c for strings that match up to these constants.
- * When adding a constant here, keep errwarn.c in sync! */
+ * When adding a constant here, keep errwarn.c in sync!
+ */
 typedef enum {
     FATAL_UNKNOWN = 0,
     FATAL_NOMEM
 } fatal_num;
 
-/*@shared@*/ char *conv_unprint(char ch);
+struct errwarn {
+    /* Initialize any internal data structures. */
+    void (*initialize) (void);
 
-void ParserError(unsigned long lindex, const char *);
+    /* Cleans up any memory allocated by initialize or other functions. */
+    void (*cleanup) (void);
 
-/*@exits@*/ void InternalError_(const char *file, unsigned int line,
-                               const char *message);
-#define InternalError(msg)     InternalError_(__FILE__, __LINE__, msg)
+    /* Reporting point of internal errors.  These are usually due to sanity
+     * check failures in the code.
+     * This function must NOT return to calling code.  Either exit or longjmp.
+     */
+    /*@exits@*/ void (*internal_error_) (const char *file, unsigned int line,
+                                        const char *message);
+#define internal_error(msg)    internal_error_(__FILE__, __LINE__, msg)
 
-/*@exits@*/ void Fatal(fatal_num);
+    /* Reporting point of fatal errors.
+     * This function must NOT return to calling code.  Either exit or longjmp.
+     */
+    /*@exits@*/ void (*fatal) (fatal_num);
 
-void Error(unsigned long lindex, const char *, ...) /*@printflike@*/;
-void Warning(unsigned long lindex, const char *, ...) /*@printflike@*/;
+    void (*error) (unsigned long lindex, const char *, ...) /*@printflike@*/;
+    void (*warning) (warn_class_num, unsigned long lindex, const char *, ...)
+       /*@printflike@*/;
 
-/* These two functions immediately output the error or warning, with no file
- * or line information.  They should be used for errors and warnings outside
- * the parser stage (at program startup, for instance).
- */
-void ErrorNow(const char *, ...) /*@printflike@*/;
-void WarningNow(const char *, ...) /*@printflike@*/;
+    /* Logs a parser error.  These can be overwritten by non-parser errors on
+     * the same line.
+     */
+    void (*parser_error) (unsigned long lindex, const char *);
+
+    /* Enables/disables a class of warnings. */
+    void (*warn_enable) (warn_class_num);
+    void (*warn_disable) (warn_class_num);
+    void (*warn_disable_all) (void);
+
+    /* Returns total number of errors logged to this point.
+     * If warning_as_error is nonzero, warnings are treated as errors.
+     */
+    unsigned int (*get_num_errors) (int warning_as_error);
 
-/* Returns total number of errors to this point in assembly. */
-unsigned int GetNumErrors(void);
+    /* Outputs all errors/warnings (e.g. to stderr or elsewhere). */
+    void (*output_all) (linemgr *lm, int warning_as_error);
 
-/* Outputs all errors/warnings to standard error. */
-void OutputAllErrorWarning(linemgr *lm);
+    /* Convert a possibly unprintable character into a printable string. */
+    char * (*conv_unprint) (char ch);
+};
 
 #endif
index a56762aa4af35e4a3a92f18b1dd329bbe225c756..8f76aec0a2add4657de203f320eeb86390be71c4 100644 (file)
@@ -43,12 +43,14 @@ static int expr_traverse_nodes_post(/*@null@*/ expr *e, /*@null@*/ void *d,
                                                 /*@null@*/ void *d));
 
 static /*@dependent@*/ arch *cur_arch;
+static /*@dependent@*/ errwarn *cur_we;
 
 
 void
-expr_initialize(arch *a)
+expr_initialize(arch *a, errwarn *we)
 {
     cur_arch = a;
+    cur_we = we;
 }
 
 /* allocate a new expression node, with children as defined.
@@ -81,7 +83,7 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right, unsigned long lindex)
            /*@=usereleased@*/
        }
     } else {
-       InternalError(_("Right side of expression must exist"));
+       cur_we->internal_error(N_("Right side of expression must exist"));
     }
 
     if (right) {
@@ -700,7 +702,8 @@ expr_level_tree(expr *e, int fold_const, int simplify_ident,
                /* Check for circular reference */
                SLIST_FOREACH(np, eh, next) {
                    if (np->e == equ_expr) {
-                       Error(e->line, _("circular reference detected."));
+                       cur_we->error(e->line,
+                                     N_("circular reference detected."));
                        return e;
                    }
                }
index 36e5397201166fe75d1a09cb9b83b4f2760bfbe3..73aee9253bd52a64179788a120e459fe41694ce0 100644 (file)
@@ -24,7 +24,7 @@
 
 typedef struct ExprItem ExprItem;
 
-void expr_initialize(arch *a);
+void expr_initialize(arch *a, errwarn *we);
 
 /*@only@*/ expr *expr_new(ExprOp, /*@only@*/ ExprItem *,
                          /*@only@*/ /*@null@*/ ExprItem *,
index 77f1aa9e310bdddc28920fafe49c3655261049bd..ae05f5138930641159f1a3a4fb832307a10b3915 100644 (file)
 
 #include "file.h"
 
-#include "errwarn.h"
-
-
-char *
-replace_extension(const char *orig, /*@null@*/ const char *ext,
-                 const char *def)
-{
-    char *out, *outext;
-
-    /* allocate enough space for full existing name + extension */
-    out = xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1));
-    strcpy(out, orig);
-    outext = strrchr(out, '.');
-    if (outext) {
-       /* Existing extension: make sure it's not the same as the replacement
-        * (as we don't want to overwrite the source file).
-        */
-       outext++;   /* advance past '.' */
-       if (ext && strcmp(outext, ext) == 0) {
-           outext = NULL;  /* indicate default should be used */
-           WarningNow(_("file name already ends in `.%s': output will be in `%s'"),
-                      ext, def);
-       }
-    } else {
-       /* No extension: make sure the output extension is not empty
-        * (again, we don't want to overwrite the source file).
-        */
-       if (!ext)
-           WarningNow(_("file name already has no extension: output will be in `%s'"),
-                      def);
-       else {
-           outext = strrchr(out, '\0');    /* point to end of the string */
-           *outext++ = '.';                /* append '.' */
-       }
-    }
-
-    /* replace extension or use default name */
-    if (outext) {
-       if (!ext) {
-           /* Back up and replace '.' with string terminator */
-           outext--;
-           *outext = '\0';
-       } else
-           strcpy(outext, ext);
-    } else
-       strcpy(out, def);
-
-    return out;
-}
 
 size_t
 fwrite_16_l(unsigned short val, FILE *f)
index 3940747874bde8d1ad5116ad56461556e4698a1c..be83f779b67c73339a119e55ce5ae7135fe54613 100644 (file)
 #ifndef YASM_FILE_H
 #define YASM_FILE_H
 
-/* Replace extension on a filename (or append one if none is present).
- * If output filename would be identical to input (same extension out as in),
- * returns (copy of) def.
- * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext
- * means the trailing '.' should be included.
- */
-/*@only@*/ char *replace_extension(const char *orig, /*@null@*/
-                                  const char *ext, const char *def);
-
 /* These functions only work properly if p is an (unsigned char *) */
 
 #define WRITE_8(ptr, val)                      \
index f7b4fe60a2cee8f0fa75626cfc68ac986bf73613..73da72d97f6fef127c1b9f751eb51831d703c387 100644 (file)
@@ -84,9 +84,7 @@ typedef struct POT_Entry_Source_s {
  * entry[12-n] = 10 ** (-2 ** n) for 0 <= n <= 12.
  * entry[13] = 1.0
  */
-/*@-nullassign@*/
-static /*@only@*/ POT_Entry *POT_TableN = (POT_Entry *)NULL;
-/*@=nullassign@*/
+static /*@only@*/ POT_Entry *POT_TableN;
 static POT_Entry_Source POT_TableN_Source[] = {
     {{0xe3,0x2d,0xde,0x9f,0xce,0xd2,0xc8,0x04,0xdd,0xa6},0x4ad8}, /* 1e-4096 */
     {{0x25,0x49,0xe4,0x2d,0x36,0x34,0x4f,0x53,0xae,0xce},0x656b}, /* 1e-2048 */
@@ -132,6 +130,9 @@ static POT_Entry_Source POT_TableP_Source[] = {
     {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7fff}, /* 1e+0 */
 };
 
+static /*@dependent@*/ errwarn *cur_we;
+
+
 static void
 POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
 {
@@ -153,14 +154,16 @@ POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
 }
 
 /*@-compdef@*/
-static void
-POT_Table_Init(void)
+void
+floatnum_initialize(errwarn *we)
 /*@globals undef POT_TableN, undef POT_TableP, POT_TableP_Source,
    POT_TableN_Source @*/
 {
     int dec_exp = 1;
     int i;
 
+    cur_we = we;
+
     /* Allocate space for two POT tables */
     POT_TableN = xmalloc(14*sizeof(POT_Entry));
     POT_TableP = xmalloc(15*sizeof(POT_Entry));        /* note 1 extra for -1 */
@@ -186,13 +189,10 @@ POT_Table_Init(void)
 
 /*@-globstate@*/
 void
-floatnum_shutdown(void)
+floatnum_cleanup(void)
 {
     int i;
 
-    if (!POT_TableN)
-       return;
-
     /* Un-offset POT_TableP */
     POT_TableP--;
 
@@ -310,10 +310,6 @@ floatnum_new(const char *str)
     int decimal_pt;
     boolean carry;
 
-    /* Initialize POT tables if necessary */
-    if (!POT_TableN)
-       POT_Table_Init();
-
     flt = xmalloc(sizeof(floatnum));
 
     flt->mantissa = BitVector_Create(MANT_BITS, TRUE);
@@ -515,7 +511,8 @@ floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand,
              unsigned long lindex)
 {
     if (op != EXPR_NEG)
-       Error(lindex, _("Unsupported floating-point arithmetic operation"));
+       cur_we->error(lindex,
+                     N_("Unsupported floating-point arithmetic operation"));
     else
        acc->sign ^= 1;
 }
@@ -590,7 +587,7 @@ floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr,
 
     /* underflow and overflow both set!? */
     if (underflow && overflow)
-       InternalError(_("Both underflow and overflow set"));
+       cur_we->internal_error(N_("Both underflow and overflow set"));
 
     /* check for underflow or overflow and set up appropriate output */
     if (underflow) {
@@ -613,7 +610,8 @@ floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr,
     /* get little-endian bytes */
     buf = BitVector_Block_Read(output, &len);
     if (len < byte_size)
-       InternalError(_("Byte length of BitVector does not match bit length"));
+       cur_we->internal_error(
+           N_("Byte length of BitVector does not match bit length"));
 
     /* copy to output */
     memcpy(ptr, buf, byte_size*sizeof(unsigned char));
@@ -667,7 +665,7 @@ floatnum_get_sized(const floatnum *flt, unsigned char *ptr, size_t size)
        case 10:
            return floatnum_get_common(flt, ptr, 10, 64, 0, 15);
        default:
-           InternalError(_("Invalid float conversion size"));
+           cur_we->internal_error(N_("Invalid float conversion size"));
            /*@notreached@*/
            return 1;       /* never reached, but silence GCC warning */
     }
index a5d05bbaf40bcb5c19ae03477524d22dc4f50598..60f200505935b5363fae2c5af2de10524187bc09 100644 (file)
@@ -24,8 +24,9 @@
 #ifndef YASM_FLOATNUM_H
 #define YASM_FLOATNUM_H
 
+void floatnum_initialize(errwarn *we);
 /* Clean up internal allocations */
-void floatnum_shutdown(void);
+void floatnum_cleanup(void);
 
 /*@only@*/ floatnum *floatnum_new(const char *str);
 /*@only@*/ floatnum *floatnum_copy(const floatnum *flt);
index 26606d70009e9d9fdd5eb5c1755c9007f7995b26..a1fa2c3bea2c4fc0fc0e013d6892d58fd9cfe949 100644 (file)
@@ -35,7 +35,6 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
-#include "errwarn.h"
 #include "hamt.h"
 
 typedef struct HAMTEntry {
@@ -52,6 +51,8 @@ typedef struct HAMTNode {
 struct HAMT {
     SLIST_HEAD(HAMTEntryHead, HAMTEntry) entries;
     HAMTNode *root;
+    /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                   const char *message);
 };
 
 /* XXX make a portable version of this.  This depends on the pointer being
@@ -59,9 +60,10 @@ struct HAMT {
  * the subtrie flag!
  */
 #define IsSubTrie(n)           ((unsigned long)((n)->BaseValue) & 1)
-#define SetSubTrie(n, v)       do {                            \
+#define SetSubTrie(h, n, v)    do {                            \
        if ((unsigned long)(v) & 1)                             \
-           InternalError(_("Subtrie is seen as subtrie before flag is set (misaligned?)"));    \
+           h->error_func(__FILE__, __LINE__,                   \
+                         N_("Subtrie is seen as subtrie before flag is set (misaligned?)"));   \
        (n)->BaseValue = (void *)((unsigned long)(v) | 1);      \
     } while (0)
 #define GetSubTrie(n)          (HAMTNode *)((unsigned long)((n)->BaseValue)&~1UL)
@@ -85,7 +87,8 @@ ReHashKey(const char *key, int Level)
 }
 
 HAMT *
-HAMT_new(void)
+HAMT_new(/*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                        const char *message))
 {
     /*@out@*/ HAMT *hamt = xmalloc(sizeof(HAMT));
     int i;
@@ -98,6 +101,8 @@ HAMT_new(void)
        hamt->root[i].BaseValue = NULL;
     }
 
+    hamt->error_func = error_func;
+
     return hamt;
 }
 
@@ -174,7 +179,8 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
        SLIST_INSERT_HEAD(&hamt->entries, entry, next);
        node->BaseValue = entry;
        if (IsSubTrie(node))
-           InternalError(_("Data is seen as subtrie (misaligned?)"));
+           hamt->error_func(__FILE__, __LINE__,
+                            N_("Data is seen as subtrie (misaligned?)"));
        *replace = 1;
        return data;
     }
@@ -216,7 +222,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
                        newnodes = xmalloc(sizeof(HAMTNode));
                        newnodes[0] = *node;    /* structure copy */
                        node->BitMapKey = 1<<keypart;
-                       SetSubTrie(node, newnodes);
+                       SetSubTrie(hamt, node, newnodes);
                        node = &newnodes[0];
                        level++;
                    } else {
@@ -241,7 +247,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
 
                        /* Set bits in bitmap corresponding to keys */
                        node->BitMapKey = (1UL<<keypart) | (1UL<<keypart2);
-                       SetSubTrie(node, newnodes);
+                       SetSubTrie(hamt, node, newnodes);
                        *replace = 1;
                        return data;
                    }
@@ -285,7 +291,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
            entry->data = data;
            SLIST_INSERT_HEAD(&hamt->entries, entry, next);
            newnodes[Map].BaseValue = entry;
-           SetSubTrie(node, newnodes);
+           SetSubTrie(hamt, node, newnodes);
 
            *replace = 1;
            return data;
index b3cd79319c71f8fb2951b0c12c206c61b17a1608..c21d520118c99a1fbce536ecc92215e1c0979186 100644 (file)
 
 typedef struct HAMT HAMT;
 
-/* Creates new, empty, HAMT. */
-HAMT *HAMT_new(void);
+/* Creates new, empty, HAMT.  error_func() is called when an internal error is
+ * encountered--it should NOT return to the calling function.
+ */
+HAMT *HAMT_new(/*@exits@*/ void (*error_func) (const char *file,
+                                              unsigned int line,
+                                              const char *message));
 
 /* Deletes HAMT and all data associated with it using deletefunc() on each data
  * item.
index 3ca4775d90901f2e2d4a9d7680a2ace52a3e290f..5fba7ab742aa1957d37768346e881117502e5222 100644 (file)
@@ -43,15 +43,23 @@ struct intnum {
 };
 
 /* static bitvect used for conversions */
-static /*@only@*/ /*@null@*/ wordptr conv_bv = NULL;
+static /*@only@*/ wordptr conv_bv;
+static /*@dependent@*/ errwarn *cur_we;
+
 
 void
-intnum_shutdown(void)
+intnum_initialize(errwarn *we)
 {
-    if (conv_bv) {
-       BitVector_Destroy(conv_bv);
-       conv_bv = NULL;
-    }
+    cur_we = we;
+
+    conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+}
+
+void
+intnum_cleanup(void)
+{
+    BitVector_Destroy(conv_bv);
     BitVector_from_Dec_static_Shutdown();
 }
 
@@ -62,13 +70,10 @@ intnum_new_dec(char *str, unsigned long lindex)
 
     intn->origsize = 0;            /* no reliable way to figure this out */
 
-    if (!conv_bv) {
-       conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-    }
     if (BitVector_from_Dec_static(conv_bv,
                                  (unsigned char *)str) == ErrCode_Ovfl)
-       Warning(lindex, _("Numeric constant too large for internal format"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("Numeric constant too large for internal format"));
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
        intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
@@ -88,12 +93,9 @@ intnum_new_bin(char *str, unsigned long lindex)
     intn->origsize = (unsigned char)strlen(str);
 
     if(intn->origsize > BITVECT_ALLOC_SIZE)
-       Warning(lindex, _("Numeric constant too large for internal format"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("Numeric constant too large for internal format"));
 
-    if (!conv_bv) {
-       conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-    }
     BitVector_from_Bin(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -114,12 +116,9 @@ intnum_new_oct(char *str, unsigned long lindex)
     intn->origsize = strlen(str)*3;
 
     if(intn->origsize > BITVECT_ALLOC_SIZE)
-       Warning(lindex, _("Numeric constant too large for internal format"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("Numeric constant too large for internal format"));
 
-    if (!conv_bv) {
-       conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-    }
     BitVector_from_Oct(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -140,12 +139,9 @@ intnum_new_hex(char *str, unsigned long lindex)
     intn->origsize = strlen(str)*4;
 
     if(intn->origsize > BITVECT_ALLOC_SIZE)
-       Warning(lindex, _("Numeric constant too large for internal format"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("Numeric constant too large for internal format"));
 
-    if (!conv_bv) {
-       conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-    }
     BitVector_from_Hex(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -166,8 +162,8 @@ intnum_new_charconst_nasm(const char *str, unsigned long lindex)
     size_t len = strlen(str);
 
     if (len > 4)
-       Warning(lindex,
-               _("character constant too large, ignoring trailing characters"));
+       cur_we->warning(WARN_GENERAL, lindex,
+           N_("character constant too large, ignoring trailing characters"));
 
     intn->val.ul = 0;
     intn->type = INTNUM_UL;
@@ -273,7 +269,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
     }
 
     if (!operand && op != EXPR_NEG && op != EXPR_NOT && op != EXPR_LNOT)
-       InternalError(_("Operation needs an operand"));
+       cur_we->internal_error(N_("Operation needs an operand"));
 
     /* A operation does a bitvector computation if result is allocated. */
     switch (op) {
@@ -444,7 +440,8 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
                BitVector_Copy(result, op1);
            break;
        default:
-           InternalError(_("invalid operation in intnum calculation"));
+           cur_we->internal_error(
+               N_("invalid operation in intnum calculation"));
     }
 
     /* If we were doing a bitvector computation... */
@@ -507,7 +504,7 @@ intnum_get_uint(const intnum *intn)
        case INTNUM_BV:
            return BitVector_Chunk_Read(intn->val.bv, 32, 0);
        default:
-           InternalError(_("unknown intnum type"));
+           cur_we->internal_error(N_("unknown intnum type"));
            /*@notreached@*/
            return 0;
     }
@@ -535,7 +532,7 @@ intnum_get_int(const intnum *intn)
            } else
                return (long)BitVector_Chunk_Read(intn->val.bv, 32, 0);
        default:
-           InternalError(_("unknown intnum type"));
+           cur_we->internal_error(N_("unknown intnum type"));
            /*@notreached@*/
            return 0;
     }
@@ -560,7 +557,8 @@ intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size)
        case INTNUM_BV:
            buf = BitVector_Block_Read(intn->val.bv, &len);
            if (len < (unsigned int)size)
-               InternalError(_("Invalid size specified (too large)"));
+               cur_we->internal_error(
+                   N_("Invalid size specified (too large)"));
            memcpy(ptr, buf, size);
            xfree(buf);
            break;
index 99f1a1056cb3c91cb1d1b80335585fceb56ddbec..cd05c7375af372c7c058836f983ea25fffdc0adc 100644 (file)
@@ -22,8 +22,9 @@
 #ifndef YASM_INTNUM_H
 #define YASM_INTNUM_H
 
+void intnum_initialize(errwarn *we);
 /* Clean up internal allocations */
-void intnum_shutdown(void);
+void intnum_cleanup(void);
 
 /*@only@*/ intnum *intnum_new_dec(char *str, unsigned long lindex);
 /*@only@*/ intnum *intnum_new_bin(char *str, unsigned long lindex);
index 718b01b9cb7e015283bd6dcbc7f6dc638c09b673..5bdbc7ae2e4f5dc5ef2b648d061a2cda70be94cc 100644 (file)
@@ -93,9 +93,12 @@ yasm_linemgr_set(const char *filename, unsigned long line,
 }
 
 static void
-yasm_linemgr_initialize(void)
+yasm_linemgr_initialize(/*@exits@*/
+                       void (*error_func) (const char *file,
+                                           unsigned int line,
+                                           const char *message))
 {
-    filename_table = HAMT_new();
+    filename_table = HAMT_new(error_func);
 
     line_index = 1;
 
index 85d474e0f5c9b4c55c32ea96aa100bda359dad68..0412df6fdd01e0081b1b62e41b910fb66c0fc851 100644 (file)
 
 struct linemgr {
     /* Initialize cur_lindex and any manager internal data structures. */
-    void (*initialize) (void);
+    void (*initialize) (/*@exits@*/
+                       void (*error_func) (const char *file,
+                                           unsigned int line,
+                                           const char *message));
 
     /* Cleans up any memory allocated by initialize. */
     void (*cleanup) (void);
index 55f7b9cc0030921b3e4e601f7780c6f5563b04dd..9735ae4ee7e631eda804484d33845549b343e823 100644 (file)
@@ -57,7 +57,7 @@ struct objfmt {
      * provided solely for informational purposes.
      */
     void (*initialize) (const char *in_filename, const char *obj_filename,
-                       dbgfmt *df, arch *a);
+                       dbgfmt *df, arch *a, errwarn *we);
 
     /* Write out (post-optimized) sections to the object file.
      * This function may call symrec functions as necessary (including
index 56c907200aff4bf4140efcd9a89d5295342dd6a0..44c6a124ac8d93d2437b7b568854a78502337eea 100644 (file)
@@ -37,7 +37,7 @@ struct optimizer {
      * object file.  (A failure is indicated by calling ErrorAt() from within
      * this function).
      */
-    void (*optimize) (sectionhead *sections);
+    void (*optimize) (sectionhead *sections, errwarn *we);
 };
 
 #endif
index 01b0db32a7d7a2b211eba4421c2d4602b15c4f6a..c2e606ff0f26930f503e72a342b77860bb211f23 100644 (file)
@@ -51,7 +51,7 @@ struct parser {
      * (whatever was in the file).
      */
     sectionhead *(*do_parse) (preproc *pp, arch *a, objfmt *of, linemgr *lm,
-                             FILE *f, const char *in_filename);
+                             errwarn *we, FILE *f, const char *in_filename);
 };
 
 /* Generic functions for all parsers - implemented in src/parser.c */
index 9b4874bb768fe9e32b196a79e5159131ce176a83..96d07cffce58886d0cc0d6c9c1336e9f271ec4f9 100644 (file)
@@ -38,11 +38,15 @@ struct preproc {
      * This function also takes the FILE * to the initial starting file and
      * the filename.
      */
-    void (*initialize) (FILE *f, const char *in_filename);
+    void (*initialize) (FILE *f, const char *in_filename, linemgr *lm,
+                       errwarn *we);
+
+    /* Cleans up any allocated memory. */
+    void (*cleanup) (void);
 
     /* Gets more preprocessed source code (up to max_size bytes) into buf.
      * Note that more than a single line may be returned in buf. */
-    size_t (*input) (/*@out@*/ char *buf, size_t max_size, linemgr *lm);
+    size_t (*input) (/*@out@*/ char *buf, size_t max_size);
 };
 
 #endif
index 430c73bfd46ca7c16ad894201d62390e6e4cf096..a85811372aa8aad3af52903e75c998b87678d29d 100644 (file)
@@ -54,6 +54,9 @@ struct section {
     int res_only;              /* allow only resb family of bytecodes? */
 
     bytecodehead bc;           /* the bytecodes for the section's contents */
+
+    /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                   const char *message);
 };
 
 /*@-compdestroy@*/
@@ -82,7 +85,10 @@ sections_initialize(sectionhead *headp, objfmt *of)
 section *
 sections_switch_general(sectionhead *headp, const char *name,
                        unsigned long start, int res_only, int *isnew,
-                       unsigned long lindex)
+                       unsigned long lindex,
+                       /*@exits@*/ void (*error_func) (const char *file,
+                                                       unsigned int line,
+                                                       const char *message))
 {
     section *s;
 
@@ -113,6 +119,8 @@ sections_switch_general(sectionhead *headp, const char *name,
     s->opt_flags = 0;
     s->res_only = res_only;
 
+    s->error_func = error_func;
+
     *isnew = 1;
     return s;
 }
@@ -120,7 +128,10 @@ sections_switch_general(sectionhead *headp, const char *name,
 
 /*@-onlytrans@*/
 section *
-sections_switch_absolute(sectionhead *headp, expr *start)
+sections_switch_absolute(sectionhead *headp, expr *start,
+                        /*@exits@*/ void (*error_func) (const char *file,
+                                                        unsigned int line,
+                                                        const char *message))
 {
     section *s;
 
@@ -134,6 +145,8 @@ sections_switch_absolute(sectionhead *headp, expr *start)
     s->opt_flags = 0;
     s->res_only = 1;
 
+    s->error_func = error_func;
+
     return s;
 }
 /*@=onlytrans@*/
@@ -164,7 +177,8 @@ section_set_of_data(section *sect, objfmt *of, void *of_data)
        if (of->section_data_delete)
            of->section_data_delete(of_data);
        else
-           InternalError(_("don't know how to delete objfmt-specific section data"));
+           sect->error_func(__FILE__, __LINE__,
+               N_("don't know how to delete objfmt-specific section data"));
        return;
     }
 
@@ -174,7 +188,8 @@ section_set_of_data(section *sect, objfmt *of, void *of_data)
        if (of2->section_data_delete)
            of2->section_data_delete(sect->data.general.of_data);
        else
-           InternalError(_("don't know how to delete objfmt-specific section data"));
+           sect->error_func(__FILE__, __LINE__,
+               N_("don't know how to delete objfmt-specific section data"));
     }
 
     /* Assign new of_data */
@@ -285,7 +300,8 @@ section_delete(section *sect)
            if (of->section_data_delete)
                of->section_data_delete(sect->data.general.of_data);
            else
-               InternalError(_("don't know how to delete objfmt-specific section data"));
+               sect->error_func(__FILE__, __LINE__,
+                   N_("don't know how to delete objfmt-specific section data"));
        }
     }
     expr_delete(sect->start);
index c7f5e954e723758e923213c08774175880e47485..82536fd77edee213e0a72a6cdc38df6fe07c2425 100644 (file)
 /*@dependent@*/ section *sections_initialize(sectionhead *headp, objfmt *of);
 
 /*@dependent@*/ section *sections_switch_general(sectionhead *headp,
-                                                const char *name,
-                                                unsigned long start,
-                                                int res_only,
-                                                /*@out@*/ int *isnew,
-                                                unsigned long lindex);
+    const char *name, unsigned long start, int res_only, /*@out@*/ int *isnew,
+    unsigned long lindex,
+    /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                   const char *message));
 
 /*@dependent@*/ section *sections_switch_absolute(sectionhead *headp,
-                                                 /*@keep@*/ expr *start);
+    /*@keep@*/ expr *start,
+    /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                   const char *message));
 
 int section_is_absolute(section *sect);
 
index fe32457b7f19f354010a8398787e92b9e1f33709..80e6f4d43d7c4577e400634ee9432b9b0ace054a 100644 (file)
@@ -76,7 +76,7 @@ struct symrec {
 };
 
 /* The symbol table: a hash array mapped trie (HAMT). */
-static /*@only@*/ /*@null@*/ HAMT *sym_table = NULL;
+static /*@only@*/ HAMT *sym_table;
 
 /* Linked list of symbols not in the symbol table. */
 typedef struct non_table_symrec_s {
@@ -85,8 +85,20 @@ typedef struct non_table_symrec_s {
 } non_table_symrec;
 typedef /*@reldef@*/ SLIST_HEAD(nontablesymhead_s, non_table_symrec_s)
        nontablesymhead;
-static /*@only@*/ /*@null@*/ nontablesymhead *non_table_syms = NULL;
+static /*@only@*/ nontablesymhead *non_table_syms;
 
+static /*@dependent@*/ errwarn *cur_we;
+
+
+void
+symrec_initialize(errwarn *we)
+{
+    cur_we = we;
+
+    sym_table = HAMT_new(cur_we->internal_error_);
+    non_table_syms = xmalloc(sizeof(nontablesymhead));
+    SLIST_INIT(non_table_syms);
+}
 
 static void
 symrec_delete_one(/*@only@*/ void *d)
@@ -99,7 +111,8 @@ symrec_delete_one(/*@only@*/ void *d)
        if (sym->of->symrec_data_delete)
            sym->of->symrec_data_delete(sym->of_data);
        else
-           InternalError(_("don't know how to delete objfmt-specific data"));
+           cur_we->internal_error(
+               N_("don't know how to delete objfmt-specific data"));
     }
     xfree(sym);
 }
@@ -124,9 +137,6 @@ symrec_get_or_new_in_table(/*@only@*/ char *name)
     symrec *rec = symrec_new_common(name);
     int replace = 0;
 
-    if (!sym_table)
-       sym_table = HAMT_new();
-
     rec->status = SYM_NOSTATUS;
 
     return HAMT_insert(sym_table, name, rec, &replace, symrec_delete_one);
@@ -138,11 +148,6 @@ symrec_get_or_new_not_in_table(/*@only@*/ char *name)
     non_table_symrec *sym = xmalloc(sizeof(non_table_symrec));
     sym->rec = symrec_new_common(name);
 
-    if (!non_table_syms) {
-       non_table_syms = xmalloc(sizeof(nontablesymhead));
-       SLIST_INIT(non_table_syms);
-    }
-
     sym->rec->status = SYM_NOTINTABLE;
 
     SLIST_INSERT_HEAD(non_table_syms, sym, link);
@@ -169,10 +174,7 @@ symrec_get_or_new(const char *name, int in_table)
 int
 symrec_traverse(void *d, int (*func) (symrec *sym, void *d))
 {
-    if (sym_table)
-       return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func);
-    else
-       return 1;
+    return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func);
 }
 
 symrec *
@@ -194,9 +196,9 @@ symrec_define(const char *name, SymType type, int in_table,
     /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
     if ((rec->status & SYM_DEFINED) ||
        (rec->visibility & (SYM_COMMON | SYM_EXTERN))) {
-       Error(lindex,
-             _("duplicate definition of `%s'; first defined on line %lu"),
-             name, rec->line);
+       cur_we->error(lindex,
+           N_("duplicate definition of `%s'; first defined on line %lu"),
+           name, rec->line);
     } else {
        rec->line = lindex;     /* set line number of definition */
        rec->type = type;
@@ -247,9 +249,9 @@ symrec_declare(const char *name, SymVisibility vis, unsigned long lindex)
          ((rec->visibility & SYM_EXTERN) && (vis == SYM_EXTERN)))))
        rec->visibility |= vis;
     else
-       Error(lindex,
-             _("duplicate definition of `%s'; first defined on line %lu"),
-             name, rec->line);
+       cur_we->error(lindex,
+           N_("duplicate definition of `%s'; first defined on line %lu"),
+           name, rec->line);
     return rec;
 }
 
@@ -312,7 +314,8 @@ symrec_set_of_data(symrec *sym, objfmt *of, void *of_data)
        if (sym->of->symrec_data_delete)
            sym->of->symrec_data_delete(sym->of_data);
        else
-           InternalError(_("don't know how to delete objfmt-specific data"));
+           cur_we->internal_error(
+               N_("don't know how to delete objfmt-specific data"));
     }
     sym->of = of;
     sym->of_data = of_data;
@@ -325,7 +328,8 @@ symrec_parser_finalize_checksym(symrec *sym, /*@unused@*/ /*@null@*/ void *d)
     /* error if a symbol is used but never defined or extern/common declared */
     if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) &&
        !(sym->visibility & (SYM_EXTERN | SYM_COMMON))) {
-       Error(sym->line, _("undefined symbol `%s' (first use)"), sym->name);
+       cur_we->error(sym->line, N_("undefined symbol `%s' (first use)"),
+                     sym->name);
        if (sym->line < firstundef_line)
            firstundef_line = sym->line;
     }
@@ -339,27 +343,22 @@ symrec_parser_finalize(void)
     firstundef_line = ULONG_MAX;
     symrec_traverse(NULL, symrec_parser_finalize_checksym);
     if (firstundef_line < ULONG_MAX)
-       Error(firstundef_line,
-             _(" (Each undefined symbol is reported only once.)"));
+       cur_we->error(firstundef_line,
+           N_(" (Each undefined symbol is reported only once.)"));
 }
 
 void
-symrec_delete_all(void)
+symrec_cleanup(void)
 {
-    if (sym_table) {
-       HAMT_delete(sym_table, symrec_delete_one);
-       sym_table = NULL;
-    }
-    if (non_table_syms) {
-       while (!SLIST_EMPTY(non_table_syms)) {
-           non_table_symrec *sym = SLIST_FIRST(non_table_syms);
-           SLIST_REMOVE_HEAD(non_table_syms, link);
-           symrec_delete_one(sym->rec);
-           xfree(sym);
-       }
-       xfree(non_table_syms);
-       non_table_syms = NULL;
+    HAMT_delete(sym_table, symrec_delete_one);
+
+    while (!SLIST_EMPTY(non_table_syms)) {
+       non_table_symrec *sym = SLIST_FIRST(non_table_syms);
+       SLIST_REMOVE_HEAD(non_table_syms, link);
+       symrec_delete_one(sym->rec);
+       xfree(sym);
     }
+    xfree(non_table_syms);
 }
 
 typedef struct symrec_print_data {
index 47d148e811e3c3074c387cb1caa9e0c0565235e9..b4c8231a01f1f9c6304fce382e69cd7f7ef08c76 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
+void symrec_initialize(errwarn *we);
+
 /*@dependent@*/ symrec *symrec_use(const char *name, unsigned long lindex);
 /*@dependent@*/ symrec *symrec_define_equ(const char *name, /*@keep@*/ expr *e,
                                          unsigned long lindex);
@@ -64,7 +66,7 @@ int /*@alt void@*/ symrec_traverse(/*@null@*/ void *d,
 
 void symrec_parser_finalize(void);
 
-void symrec_delete_all(void);
+void symrec_cleanup(void);
 
 void symrec_print_all(FILE *f, int indent_level);
 
index 84a4bdadcf64f9d9b04daf33852f3ac80ddaddc2..6972c9375025f38c2701cf9e2dfd91078f5e0bed 100644 (file)
@@ -421,6 +421,7 @@ main(void)
     Suite *s = floatnum_suite();
     SRunner *sr = srunner_create(s);
     BitVector_Boot();
+    floatnum_initialize(NULL);
     srunner_run_all(sr, CRNORMAL);
     nf = srunner_ntests_failed(sr);
     srunner_free(sr);
index c9d2e2bdea613bb30e8ce882eb793ed4596dbfd5..89fa46c8aff6dd715632c0e663b4b548764123ba 100644 (file)
@@ -129,6 +129,8 @@ int strncasecmp(const char *s1, const char *s2, size_t n);
 /*@only@*/ char *xstrdup(const char *str);
 
 /* Error-checking memory allocation routines in xmalloc.c. */
+void xalloc_initialize(/*@exits@*/ void (*fatal_func) (int type),
+                      int nomem_fatal_type);
 /*@only@*/ /*@out@*/ void *xmalloc(size_t size);
 /*@only@*/ void *xcalloc(size_t nelem, size_t elsize);
 /*@only@*/ void *xrealloc(/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/
index c1a38d45f4d0ac8f3320352dfc957a9ae197e4f2..5691f3bff9ed8e8ca787fe3ea35d568a549cff6f 100644 (file)
 #include "util.h"
 RCSID("$IdPath$");
 
-#include "errwarn.h"
 
+static /*@exits@*/ void (*fatal_func) (int type);
+static int nomem_fatal_type;
+
+
+void
+xalloc_initialize(/*@exits@*/ void (*f) (int type), int t)
+{
+    fatal_func = f;
+    nomem_fatal_type = t;
+}
 
 #ifndef WITH_DMALLOC
 
@@ -36,7 +45,7 @@ xmalloc(size_t size)
        size = 1;
     newmem = malloc(size);
     if (!newmem)
-       Fatal(FATAL_NOMEM);
+       fatal_func(nomem_fatal_type);
 
     return newmem;
 }
@@ -51,7 +60,7 @@ xcalloc(size_t nelem, size_t elsize)
 
     newmem = calloc(nelem, elsize);
     if (!newmem)
-       Fatal(FATAL_NOMEM);
+       fatal_func(nomem_fatal_type);
 
     return newmem;
 }
@@ -68,7 +77,7 @@ xrealloc(void *oldmem, size_t size)
     else
        newmem = realloc(oldmem, size);
     if (!newmem)
-       Fatal(FATAL_NOMEM);
+       fatal_func(nomem_fatal_type);
 
     return newmem;
 }
index 1926b5ae87939daaa9fa5e654f9529cfd1a509f0..27ce27918f4bd50348e2f22c2c18f4dde33eb1c5 100644 (file)
@@ -4,7 +4,6 @@ libyasm_la_SOURCES = \
        src/bytecode.c          \
        src/bytecode.h          \
        src/bc-int.h            \
-       src/errwarn.c           \
        src/errwarn.h           \
        src/expr.c              \
        src/expr.h              \
@@ -47,6 +46,7 @@ yasm_SOURCES += \
        src/parser.c            \
        src/module.h            \
        src/module.c            \
+       src/errwarn.c           \
        src/linemgr.c
 
 
index 36d3db9f0bb93bfe4c3a326a5be4b691258965a1..906434e689ba41a86be5d3ddd3707e4460c05b16 100644 (file)
 
 
 unsigned char yasm_x86_LTX_mode_bits = 0;
+/*@dependent@*/ errwarn *yasm_x86_errwarn;
+
+
+static void
+x86_initialize(errwarn *we)
+{
+    yasm_x86_errwarn = we;
+}
+
+static void
+x86_cleanup(void)
+{
+}
 
 int
 x86_directive(const char *name, valparamhead *valparams,
@@ -53,7 +66,7 @@ x86_directive(const char *name, valparamhead *valparams,
            (lval = intnum_get_int(intn)) && (lval == 16 || lval == 32))
            yasm_x86_LTX_mode_bits = (unsigned char)lval;
        else
-           Error(lindex, _("invalid argument to [%s]"), "BITS");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "BITS");
        return 0;
     } else
        return 1;
@@ -79,7 +92,7 @@ x86_get_reg_size(unsigned long reg)
        case X86_FPUREG:
            return 10;
        default:
-           InternalError(_("unknown register size"));
+           cur_we->internal_error(N_("unknown register size"));
     }
     return 0;
 }
@@ -119,7 +132,7 @@ x86_reg_print(FILE *f, unsigned long reg)
            fprintf(f, "st%d", (int)(reg&7));
            break;
        default:
-           InternalError(_("unknown register size"));
+           cur_we->internal_error(N_("unknown register size"));
     }
 }
 
@@ -165,6 +178,8 @@ x86_handle_seg_override(effaddr *ea, unsigned long segreg,
 arch yasm_x86_LTX_arch = {
     "x86 (IA-32, x86-64)",
     "x86",
+    x86_initialize,
+    x86_cleanup,
     {
        x86_switch_cpu,
        x86_check_identifier,
index 4674070bbb6107f031ba549e88a8b8422204eaf4..724e703b05c3f8b33b1d8846ea6dc609bc8b4b85 100644 (file)
@@ -114,6 +114,8 @@ typedef struct x86_new_jmprel_data {
 bytecode *x86_bc_new_jmprel(x86_new_jmprel_data *d);
 
 extern unsigned char yasm_x86_LTX_mode_bits;
+extern /*@dependent@*/ errwarn *yasm_x86_errwarn;
+#define cur_we yasm_x86_errwarn
 
 void x86_bc_delete(bytecode *bc);
 void x86_bc_print(FILE *f, int indent_level, const bytecode *bc);
index 26d7605543ee22de51240ab6734902f3bf3ee037..5eae04b64c58bf1b72ed00ef251da84d78cbe96f 100644 (file)
@@ -170,9 +170,11 @@ x86_bc_new_jmprel(x86_new_jmprel_data *d)
     jmprel->op_sel = d->op_sel;
 
     if ((d->op_sel == JR_SHORT_FORCED) && (d->near_op_len == 0))
-       Error(d->lindex, _("no SHORT form of that jump instruction exists"));
+       cur_we->error(d->lindex,
+                     N_("no SHORT form of that jump instruction exists"));
     if ((d->op_sel == JR_NEAR_FORCED) && (d->short_op_len == 0))
-       Error(d->lindex, _("no NEAR form of that jump instruction exists"));
+       cur_we->error(d->lindex,
+                     N_("no NEAR form of that jump instruction exists"));
 
     jmprel->shortop.opcode[0] = d->short_op[0];
     jmprel->shortop.opcode[1] = d->short_op[1];
@@ -203,7 +205,8 @@ x86_ea_set_segment(effaddr *ea, unsigned char segment, unsigned long lindex)
        return;
 
     if (segment != 0 && x86_ea->segment != 0)
-       Warning(lindex, _("multiple segment overrides, using leftmost"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("multiple segment overrides, using leftmost"));
 
     x86_ea->segment = segment;
 }
@@ -294,7 +297,7 @@ x86_bc_insn_get_ea(bytecode *bc)
        return NULL;
 
     if ((x86_bytecode_type)bc->type != X86_BC_INSN)
-       InternalError(_("Trying to get EA of non-instruction"));
+       cur_we->internal_error(N_("Trying to get EA of non-instruction"));
 
     return (effaddr *)(((x86_insn *)bc)->ea);
 }
@@ -318,7 +321,8 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
            jmprel->opersize = opersize;
            break;
        default:
-           InternalError(_("OperSize override applied to non-instruction"));
+           cur_we->internal_error(
+               N_("OperSize override applied to non-instruction"));
     }
 }
 
@@ -341,7 +345,8 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
            jmprel->addrsize = addrsize;
            break;
        default:
-           InternalError(_("AddrSize override applied to non-instruction"));
+           cur_we->internal_error(
+               N_("AddrSize override applied to non-instruction"));
     }
 }
 
@@ -366,11 +371,13 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix,
            lockrep_pre = &jmprel->lockrep_pre;
            break;
        default:
-           InternalError(_("LockRep prefix applied to non-instruction"));
+           cur_we->internal_error(
+               N_("LockRep prefix applied to non-instruction"));
     }
 
     if (*lockrep_pre != 0)
-       Warning(lindex, _("multiple LOCK or REP prefixes, using leftmost"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("multiple LOCK or REP prefixes, using leftmost"));
 
     *lockrep_pre = prefix;
 }
@@ -654,20 +661,21 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
                temp = expr_copy(jmprel->target);
                num = expr_get_intnum(&temp, calc_bc_dist);
                if (!num) {
-                   Error(bc->line,
-                         _("short jump target external or out of segment"));
+                   cur_we->error(bc->line,
+                       N_("short jump target external or out of segment"));
                    return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                } else {
                    rel = intnum_get_int(num);
                    rel -= jmprel->shortop.opcode_len+1;
                    /* does a short form exist? */
                    if (jmprel->shortop.opcode_len == 0) {
-                       Error(bc->line, _("short jump does not exist"));
+                       cur_we->error(bc->line,
+                                     N_("short jump does not exist"));
                        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                    }
                    /* short displacement must fit in -128 <= rel <= +127 */
                    if (rel < -128 || rel > 127) {
-                       Error(bc->line, _("short jump out of range"));
+                       cur_we->error(bc->line, N_("short jump out of range"));
                        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                    }
                }
@@ -678,7 +686,7 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
            jrshort = 0;
            if (save) {
                if (jmprel->nearop.opcode_len == 0) {
-                   Error(bc->line, _("near jump does not exist"));
+                   cur_we->error(bc->line, N_("near jump does not exist"));
                    return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                }
            }
@@ -713,8 +721,8 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
                     * it to actually be within short range).
                     */
                    if (save) {
-                       Error(bc->line,
-                             _("short jump out of range (near jump does not exist)"));
+                       cur_we->error(bc->line,
+                           N_("short jump out of range (near jump does not exist)"));
                        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                    }
                    jrshort = 1;
@@ -730,8 +738,8 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
                    jrshort = 0;
                } else {
                    if (save) {
-                       Error(bc->line,
-                             _("short jump out of range (near jump does not exist)"));
+                       cur_we->error(bc->line,
+                           N_("short jump out of range (near jump does not exist)"));
                        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                    }
                    jrshort = 1;
@@ -780,7 +788,7 @@ x86_bc_resolve(bytecode *bc, int save, const section *sect,
        default:
            break;
     }
-    InternalError(_("Didn't handle bytecode type in x86 arch"));
+    cur_we->internal_error(N_("Didn't handle bytecode type in x86 arch"));
     /*@notreached@*/
     return BC_RESOLVE_UNKNOWN_LEN;
 }
@@ -806,7 +814,8 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
        WRITE_8(*bufp, 0x67);
     if (insn->rex != 0) {
        if (insn->mode_bits != 64)
-           InternalError(_("x86: got a REX prefix in non-64-bit mode"));
+           cur_we->internal_error(
+               N_("x86: got a REX prefix in non-64-bit mode"));
        WRITE_8(*bufp, insn->rex);
     }
 
@@ -820,13 +829,14 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
     if (ea) {
        if (x86_ea->need_modrm) {
            if (!x86_ea->valid_modrm)
-               InternalError(_("invalid Mod/RM in x86 tobytes_insn"));
+               cur_we->internal_error(
+                   N_("invalid Mod/RM in x86 tobytes_insn"));
            WRITE_8(*bufp, x86_ea->modrm);
        }
 
        if (x86_ea->need_sib) {
            if (!x86_ea->valid_sib)
-               InternalError(_("invalid SIB in x86 tobytes_insn"));
+               cur_we->internal_error(N_("invalid SIB in x86 tobytes_insn"));
            WRITE_8(*bufp, x86_ea->sib);
        }
 
@@ -846,7 +856,7 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
                                  &eat.valid_modrm, &eat.need_modrm,
                                  &eat.sib, &eat.valid_sib,
                                  &eat.need_sib, common_calc_bc_dist))
-               InternalError(_("checkea failed"));
+               cur_we->internal_error(N_("checkea failed"));
 
            if (ea->disp) {
                if (output_expr(&ea->disp, bufp, ea->len, *bufp-bufp_orig,
@@ -901,7 +911,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
        case JR_SHORT:
            /* 1 byte relative displacement */
            if (jmprel->shortop.opcode_len == 0)
-               InternalError(_("short jump does not exist"));
+               cur_we->internal_error(N_("short jump does not exist"));
 
            /* Opcode */
            for (i=0; i<jmprel->shortop.opcode_len; i++)
@@ -916,7 +926,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
        case JR_NEAR:
            /* 2/4 byte relative displacement (depending on operand size) */
            if (jmprel->nearop.opcode_len == 0) {
-               Error(bc->line, _("near jump does not exist"));
+               cur_we->error(bc->line, N_("near jump does not exist"));
                return 1;
            }
 
@@ -931,7 +941,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
                return 1;
            break;
        default:
-           InternalError(_("unrecognized relative jump op_sel"));
+           cur_we->internal_error(N_("unrecognized relative jump op_sel"));
     }
     return 0;
 }
@@ -961,7 +971,8 @@ x86_intnum_tobytes(const intnum *intn, unsigned char **bufp,
     if (rel) {
        long val;
        if (valsize != 1 && valsize != 2 && valsize != 4)
-           InternalError(_("tried to do PC-relative offset from invalid sized value"));
+           cur_we->internal_error(
+               N_("tried to do PC-relative offset from invalid sized value"));
        val = intnum_get_uint(intn);
        val -= bc->len;
        switch (valsize) {
index ea022f6dc57a50a29dc93b17c98501b057b6b9ef..c6552531e4a67e973ca3f76034bb3cd80a4182e7 100644 (file)
@@ -183,7 +183,7 @@ x86_expr_checkea_distcheck_reg(expr **ep)
        /* The reg expn *must* be EXPR_ADD at this point.  Sanity check. */
        if (e->terms[havereg_expr].type != EXPR_EXPR ||
            e->terms[havereg_expr].data.expn->op != EXPR_ADD)
-           InternalError(_("Register expression not ADD or EXPN"));
+           cur_we->internal_error(N_("Register expression not ADD or EXPN"));
 
        /* Iterate over each term in reg expn */
        for (i=0; i<e->terms[havereg_expr].data.expn->numterms; i++) {
@@ -282,9 +282,11 @@ x86_expr_checkea_getregusage(expr **ep, /*@null@*/ int *indexreg, void *data,
                     * Sanity check for EXPR_INT.
                     */
                    if (e->terms[i].data.expn->terms[0].type != EXPR_REG)
-                       InternalError(_("Register not found in reg expn"));
+                       cur_we->internal_error(
+                           N_("Register not found in reg expn"));
                    if (e->terms[i].data.expn->terms[1].type != EXPR_INT)
-                       InternalError(_("Non-integer value in reg expn"));
+                       cur_we->internal_error(
+                           N_("Non-integer value in reg expn"));
                    reg = get_reg(&e->terms[i].data.expn->terms[0], data);
                    if (!reg)
                        return 0;
@@ -378,7 +380,7 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
             */
            if (!intnum_check_size(intn, (size_t)wordsize, 0) &&
                !intnum_check_size(intn, 1, 1)) {
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            }
 
@@ -442,8 +444,8 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
        case 2:
        case 4:
            if (wordsize != *displen) {
-               Error(e->line,
-                     _("invalid effective address (displacement size)"));
+               cur_we->error(e->line,
+                   N_("invalid effective address (displacement size)"));
                return 0;
            }
            /* TODO: Add optional warning here about 2/4 not being valid
@@ -455,7 +457,7 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
            break;
        default:
            /* we shouldn't ever get any other size! */
-           InternalError(_("strange EA displacement size"));
+           cur_we->internal_error(N_("strange EA displacement size"));
     }
 
     return 1;
@@ -535,7 +537,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
                                             calc_bc_dist)) {
            case 0:
                e = *ep;
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            case 1:
                return 1;
@@ -557,7 +559,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
         */
        for (i=0; i<8; i++) {
            if (reg32mult[i] < 0) {
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            }
            if (i != indexreg && reg32mult[i] == 1 && basereg == REG32_NONE)
@@ -598,7 +600,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
         */
        for (i=0; i<8; i++)
            if (i != basereg && i != indexreg && reg32mult[i] != 0) {
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            }
 
@@ -606,7 +608,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
        if (indexreg != REG32_NONE && reg32mult[indexreg] != 1 &&
            reg32mult[indexreg] != 2 && reg32mult[indexreg] != 4 &&
            reg32mult[indexreg] != 8) {
-           Error(e->line, _("invalid effective address"));
+           cur_we->error(e->line, N_("invalid effective address"));
            return 0;
        }
 
@@ -616,7 +618,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
             * legal.
             */
            if (reg32mult[REG32_ESP] > 1 || basereg == REG32_ESP) {
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            }
            /* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */
@@ -720,7 +722,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
                                             calc_bc_dist)) {
            case 0:
                e = *ep;
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            case 1:
                return 1;
@@ -732,7 +734,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
        /* reg multipliers not 0 or 1 are illegal. */
        if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 ||
            reg16mult.bp & ~1) {
-           Error(e->line, _("invalid effective address"));
+           cur_we->error(e->line, N_("invalid effective address"));
            return 0;
        }
 
@@ -748,7 +750,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
 
        /* Check the modrm value for invalid combinations. */
        if (modrm16[havereg] & 0070) {
-           Error(e->line, _("invalid effective address"));
+           cur_we->error(e->line, N_("invalid effective address"));
            return 0;
        }
 
@@ -776,17 +778,17 @@ x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp,
     int fltret;
 
     if (!floatnum_check_size(flt, (size_t)valsize)) {
-       Error(e->line, _("invalid floating point constant size"));
+       cur_we->error(e->line, N_("invalid floating point constant size"));
        return 1;
     }
 
     fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize);
     if (fltret < 0) {
-       Error(e->line, _("underflow in floating point expression"));
+       cur_we->error(e->line, N_("underflow in floating point expression"));
        return 1;
     }
     if (fltret > 0) {
-       Error(e->line, _("overflow in floating point expression"));
+       cur_we->error(e->line, N_("overflow in floating point expression"));
        return 1;
     }
     *bufp += valsize;
index 4cee4eed8ad6dcf9ffde6b51e0c733dd16bed315..b57ea32a54222cb148c6a45547e02eb9a5817b39 100644 (file)
@@ -1322,7 +1322,7 @@ x86_new_jmprel(const unsigned long data[4], int num_operands,
     /* We know the target is in operand 0, but sanity check for Imm. */
     op = ops_first(operands);
     if (op->type != INSN_OPERAND_IMM)
-       InternalError(_("invalid operand conversion"));
+       cur_we->internal_error(N_("invalid operand conversion"));
     d.target = expr_new(EXPR_SUB, ExprExpr(op->data.val),
                        ExprSym(symrec_define_label("$", cur_section, prev_bc,
                                                    0, lindex)), lindex);
@@ -1556,7 +1556,7 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                        mismatch = 1;
                    break;
                default:
-                   InternalError(_("invalid operand type"));
+                   cur_we->internal_error(N_("invalid operand type"));
            }
 
            if (mismatch)
@@ -1606,7 +1606,7 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                        mismatch = 1;
                    break;
                default:
-                   InternalError(_("invalid target modifier type"));
+                   cur_we->internal_error(N_("invalid target modifier type"));
            }
        }
 
@@ -1618,7 +1618,8 @@ x86_new_insn(const unsigned long data[4], int num_operands,
 
     if (!found) {
        /* Didn't find a matching one */
-       Error(lindex, _("invalid combination of opcode and operands"));
+       cur_we->error(lindex,
+                     N_("invalid combination of opcode and operands"));
        return NULL;
     }
 
@@ -1630,23 +1631,25 @@ x86_new_insn(const unsigned long data[4], int num_operands,
        case MOD_ExtErr:
            switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) {
                case 0:
-                   Error(lindex, _("mismatch in operand sizes"));
+                   cur_we->error(lindex, N_("mismatch in operand sizes"));
                    break;
                case 1:
-                   Error(lindex, _("operand size not specified"));
+                   cur_we->error(lindex, N_("operand size not specified"));
                    break;
                default:
-                   InternalError(_("unrecognized x86 ext mod index"));
+                   cur_we->internal_error(
+                       N_("unrecognized x86 ext mod index"));
            }
            return NULL;    /* It was an error */
        case MOD_ExtWarn:
            switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) {
                default:
-                   InternalError(_("unrecognized x86 ext mod index"));
+                   cur_we->internal_error(
+                       N_("unrecognized x86 ext mod index"));
            }
            break;
        default:
-           InternalError(_("unrecognized x86 extended modifier"));
+           cur_we->internal_error(N_("unrecognized x86 extended modifier"));
     }
 
     /* Shortcut to JmpRel */
@@ -1726,7 +1729,8 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                            d.ea = x86_ea_new_reg((unsigned char)op->data.reg);
                            break;
                        case INSN_OPERAND_SEGREG:
-                           InternalError(_("invalid operand conversion"));
+                           cur_we->internal_error(
+                               N_("invalid operand conversion"));
                        case INSN_OPERAND_MEMORY:
                            d.ea = op->data.ea;
                            if ((info->operands[i] & OPT_MASK) == OPT_MemOffs)
@@ -1746,7 +1750,8 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                        d.im_len = size_lookup[(info->operands[i] &
                                                OPS_MASK)>>OPS_SHIFT];
                    } else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_SImm:
                    if (op->type == INSN_OPERAND_IMM) {
@@ -1755,36 +1760,41 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                                                OPS_MASK)>>OPS_SHIFT];
                        d.im_sign = 1;
                    } else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_Spare:
                    if (op->type == INSN_OPERAND_REG ||
                        op->type == INSN_OPERAND_SEGREG)
                        d.spare = (unsigned char)(op->data.reg&7);
                    else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_Op0Add:
                    if (op->type == INSN_OPERAND_REG)
                        d.op[0] += (unsigned char)(op->data.reg&7);
                    else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_Op1Add:
                    if (op->type == INSN_OPERAND_REG)
                        d.op[1] += (unsigned char)(op->data.reg&7);
                    else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_SpareEA:
                    if (op->type == INSN_OPERAND_REG) {
                        d.spare = (unsigned char)(op->data.reg&7);
                        d.ea = x86_ea_new_reg((unsigned char)op->data.reg);
                    } else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                default:
-                   InternalError(_("unknown operand action"));
+                   cur_we->internal_error(N_("unknown operand action"));
            }
 
            switch (info->operands[i] & OPAP_MASK) {
@@ -1797,7 +1807,8 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                    d.signext_imm8_op = 1;
                    break;
                default:
-                   InternalError(_("unknown operand postponed action"));
+                   cur_we->internal_error(
+                       N_("unknown operand postponed action"));
            }
        }
     }
@@ -1953,11 +1964,13 @@ x86_switch_cpu(const char *id, unsigned long lindex)
 
        /* catchalls */
        [\001-\377]+    {
-           Warning(lindex, _("unrecognized CPU identifier `%s'"), id);
+           cur_we->warning(WARN_GENERAL, lindex,
+                           N_("unrecognized CPU identifier `%s'"), id);
            return;
        }
        [\000]          {
-           Warning(lindex, _("unrecognized CPU identifier `%s'"), id);
+           cur_we->warning(WARN_GENERAL, lindex,
+                           N_("unrecognized CPU identifier `%s'"), id);
            return;
        }
     */
index 1ff0534cf2c0fd5d934bd71f58bad7d25a92ac64..d28bac1c942a751c6add40026743962566c04306 100644 (file)
 
 objfmt yasm_bin_LTX_objfmt;
 static /*@dependent@*/ arch *cur_arch;
+static /*@dependent@*/ errwarn *cur_we;
 
 
 static void
 bin_objfmt_initialize(/*@unused@*/ const char *in_filename,
                      /*@unused@*/ const char *obj_filename,
-                     /*@unused@*/ dbgfmt *df, arch *a)
+                     /*@unused@*/ dbgfmt *df, arch *a, errwarn *we)
 {
     cur_arch = a;
+    cur_we = we;
 }
 
 /* Aligns sect to either its specified alignment (in its objfmt-specific data)
@@ -163,13 +165,14 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
 
     /* Check for complex float expressions */
     if (expr_contains(*ep, EXPR_FLOAT)) {
-       Error((*ep)->line, _("floating point expression too complex"));
+       cur_we->error((*ep)->line,
+                     N_("floating point expression too complex"));
        return 1;
     }
 
     /* Couldn't output, assume it contains an external reference. */
-    Error((*ep)->line,
-         _("binary object format does not support external references"));
+    cur_we->error((*ep)->line,
+       N_("binary object format does not support external references"));
     return 1;
 }
 
@@ -198,8 +201,8 @@ bin_objfmt_output_bytecode(bytecode *bc, /*@null@*/ void *d)
     /* Warn that gaps are converted to 0 and write out the 0's. */
     if (gap) {
        unsigned long left;
-       Warning(bc->line,
-               _("uninitialized space declared in code/data section: zeroing"));
+       cur_we->warning(WARN_GENERAL, bc->line,
+           N_("uninitialized space declared in code/data section: zeroing"));
        /* Write out in chunks */
        memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
        left = multiple*size;
@@ -241,7 +244,7 @@ bin_objfmt_output(FILE *f, sectionhead *sections)
     bss = sections_find_general(sections, ".bss");
 
     if (!text)
-       InternalError(_("No `.text' section in bin objfmt output"));
+       cur_we->internal_error(N_("No `.text' section in bin objfmt output"));
 
     /* First determine the actual starting offsets for .data and .bss.
      * As the order in the file is .text -> .data -> .bss (not present),
@@ -255,7 +258,8 @@ bin_objfmt_output(FILE *f, sectionhead *sections)
     assert(startexpr != NULL);
     startnum = expr_get_intnum(&startexpr, NULL);
     if (!startnum)
-       InternalError(_("Complex expr for start in bin objfmt output"));
+       cur_we->internal_error(
+           N_("Complex expr for start in bin objfmt output"));
     start = intnum_get_uint(startnum);
     expr_delete(startexpr);
     textstart = start;
@@ -340,7 +344,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
            resonly = 1;
        } else {
            /* other section names not recognized. */
-           Error(lindex, _("segment name `%s' not recognized"), sectname);
+           cur_we->error(lindex, N_("segment name `%s' not recognized"),
+                         sectname);
            return NULL;
        }
 
@@ -351,16 +356,17 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                unsigned long bitcnt;
 
                if (strcmp(sectname, ".text") == 0) {
-                   Error(lindex,
-                         _("cannot specify an alignment to the `%s' section"),
-                         sectname);
+                   cur_we->error(lindex,
+                       N_("cannot specify an alignment to the `%s' section"),
+                       sectname);
                    return NULL;
                }
                
                align = expr_get_intnum(&vp->param, NULL);
                if (!align) {
-                   Error(lindex, _("argument to `%s' is not a power of two"),
-                         vp->val);
+                   cur_we->error(lindex,
+                                 N_("argument to `%s' is not a power of two"),
+                                 vp->val);
                    return NULL;
                }
                alignval = intnum_get_uint(align);
@@ -370,8 +376,9 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                 */
                BitCount(bitcnt, alignval);
                if (bitcnt > 1) {
-                   Error(lindex, _("argument to `%s' is not a power of two"),
-                         vp->val);
+                   cur_we->error(lindex,
+                                 N_("argument to `%s' is not a power of two"),
+                                 vp->val);
                    return NULL;
                }
 
@@ -380,7 +387,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
        }
 
        retval = sections_switch_general(headp, sectname, start, resonly,
-                                        &isnew, lindex);
+                                        &isnew, lindex,
+                                        cur_we->internal_error_);
 
        if (isnew) {
            if (have_alignval) {
@@ -391,8 +399,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
 
            symrec_define_label(sectname, retval, (bytecode *)NULL, 1, lindex);
        } else if (have_alignval)
-           Warning(lindex,
-                   _("alignment value ignored on section redeclaration"));
+           cur_we->warning(WARN_GENERAL, lindex,
+               N_("alignment value ignored on section redeclaration"));
 
        return retval;
     } else
@@ -411,7 +419,8 @@ bin_objfmt_common_declare(/*@unused@*/ symrec *sym, /*@only@*/ expr *size,
                          valparamhead *objext_valparams, unsigned long lindex)
 {
     expr_delete(size);
-    Error(lindex, _("binary object format does not support common variables"));
+    cur_we->error(lindex,
+       N_("binary object format does not support common variables"));
 }
 
 static int
@@ -428,20 +437,21 @@ bin_objfmt_directive(const char *name, valparamhead *valparams,
        /* ORG takes just a simple integer as param */
        vp = vps_first(valparams);
        if (vp->val) {
-           Error(lindex, _("argument to ORG should be numeric"));
+           cur_we->error(lindex, N_("argument to ORG should be numeric"));
            return 0;
        } else if (vp->param)
            start = expr_get_intnum(&vp->param, NULL);
 
        if (!start) {
-           Error(lindex, _("argument to ORG should be numeric"));
+           cur_we->error(lindex, N_("argument to ORG should be numeric"));
            return 0;
        }
 
        /* ORG changes the start of the .text section */
        sect = sections_find_general(headp, ".text");
        if (!sect)
-           InternalError(_("bin objfmt: .text section does not exist before ORG is called?"));
+           cur_we->internal_error(
+               N_("bin objfmt: .text section does not exist before ORG is called?"));
        section_set_start(sect, intnum_get_uint(start), lindex);
 
        return 0;           /* directive recognized */
index db6d30759fcd4b86c20a044ae7c4b63e38048177..c7c28432edb40ff57791a762b1df7670464c44c9 100644 (file)
@@ -158,6 +158,7 @@ static coff_symtab_head coff_symtab;            /* symbol table of indexed syms */
 
 objfmt yasm_coff_LTX_objfmt;
 static /*@dependent@*/ arch *cur_arch;
+static /*@dependent@*/ errwarn *cur_we;
 
 
 static /*@dependent@*/ coff_symtab_entry *
@@ -170,7 +171,7 @@ coff_objfmt_symtab_append(symrec *sym, coff_symrec_sclass sclass,
     coff_symtab_entry *entry;
 
     if (STAILQ_EMPTY(&coff_symtab))
-       InternalError(_("empty COFF symbol table"));
+       cur_we->internal_error(N_("empty COFF symbol table"));
     entry = STAILQ_LAST(&coff_symtab, coff_symtab_entry, link);
     sym_data_prev = symrec_get_of_data(entry->sym);
     assert(sym_data_prev != NULL);
@@ -194,13 +195,14 @@ coff_objfmt_symtab_append(symrec *sym, coff_symrec_sclass sclass,
 static void
 coff_objfmt_initialize(const char *in_filename,
                       /*@unused@*/ const char *obj_filename,
-                      /*@unused@*/ dbgfmt *df, arch *a)
+                      /*@unused@*/ dbgfmt *df, arch *a, errwarn *we)
 {
     symrec *filesym;
     coff_symrec_data *data;
     coff_symtab_entry *entry;
 
     cur_arch = a;
+    cur_we = we;
 
     coff_objfmt_parse_scnum = 1;    /* section numbering starts at 1 */
     STAILQ_INIT(&coff_symtab);
@@ -273,7 +275,7 @@ coff_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
        SymVisibility vis;
 
        if (valsize != 4) {
-           Error((*ep)->line, _("coff: invalid relocation size"));
+           cur_we->error((*ep)->line, N_("coff: invalid relocation size"));
            return 1;
        }
 
@@ -326,11 +328,12 @@ coff_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
 
     /* Check for complex float expressions */
     if (expr_contains(*ep, EXPR_FLOAT)) {
-       Error((*ep)->line, _("floating point expression too complex"));
+       cur_we->error((*ep)->line,
+                     N_("floating point expression too complex"));
        return 1;
     }
 
-    Error((*ep)->line, _("coff: relocation too complex"));
+    cur_we->error((*ep)->line, N_("coff: relocation too complex"));
     return 1;
 }
 
@@ -361,8 +364,8 @@ coff_objfmt_output_bytecode(bytecode *bc, /*@null@*/ void *d)
     /* Warn that gaps are converted to 0 and write out the 0's. */
     if (gap) {
        unsigned long left;
-       Warning(bc->line,
-               _("uninitialized space declared in code/data section: zeroing"));
+       cur_we->warning(WARN_GENERAL, bc->line,
+           N_("uninitialized space declared in code/data section: zeroing"));
        /* Write out in chunks */
        memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
        left = multiple*size;
@@ -414,7 +417,7 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d)
     } else {
        pos = ftell(info->f);
        if (pos == -1) {
-           ErrorNow(_("could not get file position on output file"));
+           cur_we->error(0, N_("could not get file position on output file"));
            return 1;
        }
 
@@ -437,7 +440,7 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d)
 
     pos = ftell(info->f);
     if (pos == -1) {
-       ErrorNow(_("could not get file position on output file"));
+       cur_we->error(0, N_("could not get file position on output file"));
        return 1;
     }
     csd->relptr = (unsigned long)pos;
@@ -448,7 +451,8 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d)
 
        csymd = symrec_get_of_data(reloc->sym);
        if (!csymd)
-           InternalError(_("coff: no symbol data for relocated symbol"));
+           cur_we->internal_error(
+               N_("coff: no symbol data for relocated symbol"));
 
        WRITE_32_L(localbuf, reloc->addr);  /* address of relocation */
        WRITE_32_L(localbuf, csymd->index); /* relocated symbol */
@@ -487,8 +491,9 @@ coff_objfmt_output_secthead(section *sect, /*@null@*/ void *d)
     WRITE_32_L(localbuf, csd->relptr); /* file ptr to relocs */
     WRITE_32_L(localbuf, 0);           /* file ptr to line nums */
     if (csd->nreloc >= 64*1024) {
-       WarningNow(_("too many relocations in section `%s'"),
-                  section_get_name(sect));
+       cur_we->warning(WARN_GENERAL, 0,
+                       N_("too many relocations in section `%s'"),
+                       section_get_name(sect));
        WRITE_16_L(localbuf, 0xFFFF);       /* max out */
     } else
        WRITE_16_L(localbuf, csd->nreloc);  /* number of relocation entries */
@@ -515,7 +520,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
 
     /* Allocate space for headers by seeking forward */
     if (fseek(f, 20+40*(coff_objfmt_parse_scnum-1), SEEK_SET) < 0) {
-       ErrorNow(_("could not seek on output file"));
+       cur_we->error(0, N_("could not seek on output file"));
        return;
     }
 
@@ -537,7 +542,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
     /* Symbol table */
     pos = ftell(f);
     if (pos == -1) {
-       ErrorNow(_("could not get file position on output file"));
+       cur_we->error(0, N_("could not get file position on output file"));
        return;
     }
     symtab_pos = (unsigned long)pos;
@@ -556,7 +561,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
        /* Get symrec's of_data (needed for storage class) */
        csymd = symrec_get_of_data(entry->sym);
        if (!csymd)
-           InternalError(_("coff: expected sym data to be present"));
+           cur_we->internal_error(
+               N_("coff: expected sym data to be present"));
 
        /* Look at symrec for value/scnum/etc. */
        if (symrec_get_label(entry->sym, &sect, &precbc)) {
@@ -580,8 +586,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
                const intnum *intn;
                intn = expr_get_intnum(&csymd->size, common_calc_bc_dist);
                if (!intn)
-                   Error(csymd->size->line,
-                         _("COMMON data size not an integer expression"));
+                   cur_we->error(csymd->size->line,
+                       N_("COMMON data size not an integer expression"));
                else
                    value = intnum_get_uint(intn);
                scnum = 0;
@@ -627,7 +633,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
                        strncpy((char *)localbuf, entry->aux[0].fname, 14);
                    break;
                default:
-                   InternalError(_("coff: unrecognized aux symtab type"));
+                   cur_we->internal_error(
+                       N_("coff: unrecognized aux symtab type"));
            }
            fwrite(info.buf, 18, 1, f);
            symtab_count++;
@@ -659,7 +666,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
 
     /* Write headers */
     if (fseek(f, 0, SEEK_SET) < 0) {
-       ErrorNow(_("could not seek on output file"));
+       cur_we->error(0, N_("could not seek on output file"));
        return;
     }
 
@@ -713,8 +720,8 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
 
     sectname = vp->val;
     if (strlen(sectname) > 8) {
-       Warning(lindex,
-               _("COFF section names limited to 8 characters: truncating"));
+       cur_we->warning(WARN_GENERAL, lindex,
+           N_("COFF section names limited to 8 characters: truncating"));
        sectname[8] = '\0';
     }
 
@@ -742,7 +749,7 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
     }
 
     retval = sections_switch_general(headp, sectname, 0, resonly, &isnew,
-                                    lindex);
+                                    lindex, cur_we->internal_error_);
 
     if (isnew) {
        coff_section_data *data;
@@ -765,7 +772,8 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                                  COFF_SYMTAB_AUX_SECT);
        data->sym = sym;
     } else if (flags_override)
-       Warning(lindex, _("section flags ignored on section redeclaration"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("section flags ignored on section redeclaration"));
     return retval;
 }
 
index 3b10a44234f1785f891ceaf5ec828efa59e52a81..5f2233ab3583e2134ceb062cbe30887ee1162ce2 100644 (file)
@@ -46,14 +46,17 @@ objfmt yasm_dbg_LTX_objfmt;
  */
 static FILE *dbg_objfmt_file;
 
+static /*@dependent@*/ errwarn *cur_we;
 
 static void
 dbg_objfmt_initialize(const char *in_filename, const char *obj_filename,
-                     dbgfmt *df, arch *a)
+                     dbgfmt *df, arch *a, errwarn *we)
 {
+    cur_we = we;
+
     dbg_objfmt_file = fopen(obj_filename, "wt");
     if (!dbg_objfmt_file) {
-       ErrorNow(_("could not open file `%s'"), obj_filename);
+       fprintf(stderr, N_("could not open file `%s'"), obj_filename);
        return;
     }
     fprintf(dbg_objfmt_file,
@@ -95,7 +98,7 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
 
     if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
        retval = sections_switch_general(headp, vp->val, 200, 0, &isnew,
-                                        lindex);
+                                        lindex, cur_we->internal_error_);
        if (isnew) {
            fprintf(dbg_objfmt_file, "(new) ");
            symrec_define_label(vp->val, retval, (bytecode *)NULL, 1, lindex);
index 5c654b7de9e2ab37efd273bcd01b2af73714b1cc..1b87423c28d21102a1f597e0e3abc02b459dd6bd 100644 (file)
@@ -43,6 +43,8 @@
 #define BCFLAG_INPROGRESS      (1UL<<0)
 #define BCFLAG_DONE            (1UL<<1)
 
+static /*@dependent@*/ errwarn *cur_we;
+
 static int basic_optimize_section_1(section *sect,
                                    /*@unused@*/ /*@null@*/ void *d);
 
@@ -129,7 +131,7 @@ basic_optimize_bytecode_1(/*@observer@*/ bytecode *bc, void *d)
     bcr_retval = bc_resolve(bc, 0, data->sect, basic_optimize_calc_bc_dist_1);
     if (bcr_retval & BC_RESOLVE_UNKNOWN_LEN) {
        if (!(bcr_retval & BC_RESOLVE_ERROR))
-           Error(bc->line, _("circular reference detected."));
+           cur_we->error(bc->line, N_("circular reference detected."));
        data->saw_unknown = -1;
        return 0;
     }
@@ -181,7 +183,7 @@ basic_optimize_bytecode_2(/*@observer@*/ bytecode *bc, /*@null@*/ void *d)
     assert(data != NULL);
 
     if (bc->opt_flags != BCFLAG_DONE)
-       InternalError(_("Optimizer pass 1 missed a bytecode!"));
+       cur_we->internal_error(N_("Optimizer pass 1 missed a bytecode!"));
 
     if (!data->precbc)
        bc->offset = 0;
@@ -203,17 +205,19 @@ basic_optimize_section_2(section *sect, /*@unused@*/ /*@null@*/ void *d)
     data.sect = sect;
 
     if (section_get_opt_flags(sect) != SECTFLAG_DONE)
-       InternalError(_("Optimizer pass 1 missed a section!"));
+       cur_we->internal_error(N_("Optimizer pass 1 missed a section!"));
 
     return bcs_traverse(section_get_bytecodes(sect), &data,
                        basic_optimize_bytecode_2);
 }
 
 static void
-basic_optimize(sectionhead *sections)
+basic_optimize(sectionhead *sections, errwarn *we)
 {
     int saw_unknown = 0;
 
+    cur_we = we;
+
     /* Optimization process: (essentially NASM's pass 1)
      *  Determine the size of all bytecodes.
      *  Forward references are /not/ resolved (only backward references are
index 7cfd19547e63d9f9f8b58bc8f0e6c68c2e20a70f..80df154dbeceee650b79afdc07d36fa0fc98fa6f 100644 (file)
@@ -3,6 +3,7 @@
 lib_LTLIBRARIES += yasm-nasm.la
 
 yasm_nasm_la_SOURCES = \
+       src/parsers/nasm/nasm-parser.h          \
        src/parsers/nasm/nasm-parser.c          \
        src/parsers/nasm/nasm-defs.h            \
        src/parsers/nasm/nasm-bison.y           \
index 996ef57467370bb8408ec20b74a95c81d1d2d52e..c8e41db36e8951e4e9595c1a615e68a560f23f5c 100644 (file)
@@ -42,32 +42,14 @@ RCSID("$IdPath$");
 
 #include "arch.h"
 
+#include "src/parsers/nasm/nasm-parser.h"
 #include "src/parsers/nasm/nasm-defs.h"
 
 
-void init_table(void);
-extern int nasm_parser_lex(void);
-extern void nasm_parser_set_directive_state(void);
-void nasm_parser_error(const char *);
-static void nasm_parser_directive(const char *name,
-                                 valparamhead *valparams,
+static void nasm_parser_error(const char *);
+static void nasm_parser_directive(const char *name, valparamhead *valparams,
                                  /*@null@*/ valparamhead *objext_valparams);
 
-extern objfmt *nasm_parser_objfmt;
-extern sectionhead nasm_parser_sections;
-extern section *nasm_parser_cur_section;
-extern char *nasm_parser_locallabel_base;
-extern size_t nasm_parser_locallabel_base_len;
-extern /*@dependent@*/ arch *nasm_parser_arch;
-extern /*@dependent@*/ objfmt *nasm_parser_objfmt;
-extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
-
-#define p_line_index   (nasm_parser_linemgr->get_current())
-
-#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,p_line_index)
-#define p_expr_new_branch(o,r) expr_new_branch(o,r,p_line_index)
-#define p_expr_new_ident(r)    expr_new_ident(r,p_line_index)
-
 static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
 static bytecode *nasm_parser_temp_bc;
 
@@ -162,8 +144,8 @@ line: '\n'          { $$ = (bytecode *)NULL; }
        $$ = (bytecode *)NULL;
     }
     | error '\n'       {
-       Error(p_line_index,
-             _("label or instruction expected at start of line"));
+       cur_we->error(cur_lindex,
+                     N_("label or instruction expected at start of line"));
        $$ = (bytecode *)NULL;
        yyerrok;
     }
@@ -175,7 +157,7 @@ lineexp: exp
     | label exp                                { $$ = $2; }
     | label TIMES expr exp             { $$ = $4; bc_set_multiple($$, $3); }
     | label_id_equ EQU expr            {
-       symrec_define_equ($1, $3, p_line_index);
+       symrec_define_equ($1, $3, cur_lindex);
        xfree($1);
        $$ = (bytecode *)NULL;
     }
@@ -183,47 +165,45 @@ lineexp: exp
 
 exp: instr
     | DECLARE_DATA datavals            {
-       $$ = bc_new_data(&$2, $1, p_line_index);
+       $$ = bc_new_data(&$2, $1, cur_lindex);
     }
     | RESERVE_SPACE expr               {
-       $$ = bc_new_reserve($2, $1, p_line_index);
+       $$ = bc_new_reserve($2, $1, cur_lindex);
     }
     | INCBIN STRING                    {
-       $$ = bc_new_incbin($2, NULL, NULL, p_line_index);
+       $$ = bc_new_incbin($2, NULL, NULL, cur_lindex);
     }
     | INCBIN STRING ',' expr           {
-       $$ = bc_new_incbin($2, $4, NULL, p_line_index);
+       $$ = bc_new_incbin($2, $4, NULL, cur_lindex);
     }
     | INCBIN STRING ',' expr ',' expr  {
-       $$ = bc_new_incbin($2, $4, $6, p_line_index);
+       $$ = bc_new_incbin($2, $4, $6, cur_lindex);
     }
 ;
 
 instr: INSN            {
        $$ = nasm_parser_arch->parse.new_insn($1, 0, NULL,
                                              nasm_parser_cur_section,
-                                             nasm_parser_prev_bc,
-                                             p_line_index);
+                                             nasm_parser_prev_bc, cur_lindex);
     }
     | INSN operands    {
        $$ = nasm_parser_arch->parse.new_insn($1, $2.num_operands,
                                              &$2.operands,
                                              nasm_parser_cur_section,
-                                             nasm_parser_prev_bc,
-                                             p_line_index);
+                                             nasm_parser_prev_bc, cur_lindex);
        ops_delete(&$2.operands, 0);
     }
     | INSN error       {
-       Error(p_line_index, _("expression syntax error"));
+       cur_we->error(cur_lindex, N_("expression syntax error"));
        $$ = NULL;
     }
     | PREFIX instr     {
        $$ = $2;
-       nasm_parser_arch->parse.handle_prefix($$, $1, p_line_index);
+       nasm_parser_arch->parse.handle_prefix($$, $1, cur_lindex);
     }
     | SEGREG instr     {
        $$ = $2;
-       nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], p_line_index);
+       nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], cur_lindex);
     }
 ;
 
@@ -234,19 +214,19 @@ datavals: dataval     { dvs_initialize(&$$); dvs_append(&$$, $1); }
 dataval: dvexpr                { $$ = dv_new_expr($1); }
     | STRING           { $$ = dv_new_string($1); }
     | error            {
-       Error(p_line_index, _("expression syntax error"));
+       cur_we->error(cur_lindex, N_("expression syntax error"));
        $$ = (dataval *)NULL;
     }
 ;
 
 label: label_id            {
        symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
-                           1, p_line_index);
+                           1, cur_lindex);
        xfree($1);
     }
     | label_id ':'  {
        symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
-                           1, p_line_index);
+                           1, cur_lindex);
        xfree($1);
     }
 ;
@@ -274,7 +254,7 @@ directive: DIRECTIVE_NAME directive_val     {
        xfree($1);
     }
     | DIRECTIVE_NAME error             {
-       Error(p_line_index, _("invalid arguments to [%s]"), $1);
+       cur_we->error(cur_lindex, N_("invalid arguments to [%s]"), $1);
        xfree($1);
     }
 ;
@@ -318,7 +298,7 @@ memaddr: expr                   {
     }
     | SEGREG ':' memaddr    {
        $$ = $3;
-       nasm_parser_arch->parse.handle_seg_override($$, $1[0], p_line_index);
+       nasm_parser_arch->parse.handle_seg_override($$, $1[0], cur_lindex);
     }
     | BYTE memaddr         { $$ = $2; ea_set_len($$, 1); }
     | WORD memaddr         { $$ = $2; ea_set_len($$, 2); }
@@ -346,7 +326,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 1)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 1;
     }
@@ -354,7 +334,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 2)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 2;
     }
@@ -362,7 +342,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 4)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 4;
     }
@@ -370,7 +350,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 8)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 8;
     }
@@ -378,7 +358,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 10)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 10;
     }
@@ -386,7 +366,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 16)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 16;
     }
@@ -399,7 +379,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
 direxpr: INTNUM                        { $$ = p_expr_new_ident(ExprInt($1)); }
     | ID                       {
        $$ = p_expr_new_ident(ExprSym(symrec_define_label($1, NULL, NULL, 0,
-                                                         p_line_index)));
+                                                         cur_lindex)));
        xfree($1);
     }
     | direxpr '|' direxpr      { $$ = p_expr_new_tree($1, EXPR_OR, $3); }
@@ -460,7 +440,7 @@ expr: INTNUM                        { $$ = p_expr_new_ident(ExprInt($1)); }
     | REG                      { $$ = p_expr_new_ident(ExprReg($1[0])); }
     | STRING                   {
        $$ = p_expr_new_ident(ExprInt(intnum_new_charconst_nasm($1,
-                                                               p_line_index)));
+                                                               cur_lindex)));
        xfree($1);
     }
     | explabel                 { $$ = p_expr_new_ident(ExprSym($1)); }
@@ -495,26 +475,26 @@ expr: INTNUM                      { $$ = p_expr_new_ident(ExprInt($1)); }
 ;
 
 explabel: ID           {
-       $$ = symrec_use($1, p_line_index);
+       $$ = symrec_use($1, cur_lindex);
        xfree($1);
     }
     | SPECIAL_ID       {
-       $$ = symrec_use($1, p_line_index);
+       $$ = symrec_use($1, cur_lindex);
        xfree($1);
     }
     | LOCAL_ID         {
-       $$ = symrec_use($1, p_line_index);
+       $$ = symrec_use($1, cur_lindex);
        xfree($1);
     }
     | '$'              {
        /* "$" references the current assembly position */
        $$ = symrec_define_label("$", nasm_parser_cur_section,
-                                nasm_parser_prev_bc, 0, p_line_index);
+                                nasm_parser_prev_bc, 0, cur_lindex);
     }
     | START_SECTION_ID {
        /* "$$" references the start of the current section */
        $$ = symrec_define_label("$$", nasm_parser_cur_section, NULL, 0,
-                                p_line_index);
+                                cur_lindex);
     }
 ;
 
@@ -527,7 +507,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
 {
     valparam *vp, *vp2;
     symrec *sym;
-    unsigned long lindex = p_line_index;
+    unsigned long lindex = cur_lindex;
 
     /* Handle (mostly) output-format independent directives here */
     if (strcasecmp(name, "extern") == 0) {
@@ -538,7 +518,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
                nasm_parser_objfmt->extern_declare(sym, objext_valparams,
                                                   lindex);
        } else
-           Error(lindex, _("invalid argument to [%s]"), "EXTERN");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "EXTERN");
     } else if (strcasecmp(name, "global") == 0) {
        vp = vps_first(valparams);
        if (vp->val) {
@@ -547,14 +527,15 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
                nasm_parser_objfmt->global_declare(sym, objext_valparams,
                                                   lindex);
        } else
-           Error(lindex, _("invalid argument to [%s]"), "GLOBAL");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "GLOBAL");
     } else if (strcasecmp(name, "common") == 0) {
        vp = vps_first(valparams);
        if (vp->val) {
            vp2 = vps_next(vp);
            if (!vp2 || (!vp2->val && !vp2->param))
-               Error(lindex, _("no size specified in %s declaration"),
-                     "COMMON");
+               cur_we->error(lindex,
+                             N_("no size specified in %s declaration"),
+                             "COMMON");
            else {
                if (vp2->val) {
                    sym = symrec_declare(vp->val, SYM_COMMON, lindex);
@@ -573,7 +554,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
                }
            }
        } else
-           Error(lindex, _("invalid argument to [%s]"), "COMMON");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "COMMON");
     } else if (strcasecmp(name, "section") == 0 ||
               strcasecmp(name, "segment") == 0) {
        section *new_section =
@@ -584,17 +565,19 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
            nasm_parser_cur_section = new_section;
            nasm_parser_prev_bc = bcs_last(section_get_bytecodes(new_section));
        } else
-           Error(lindex, _("invalid argument to [%s]"), "SECTION");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "SECTION");
     } else if (strcasecmp(name, "absolute") == 0) {
        /* it can be just an ID or a complete expression, so handle both. */
        vp = vps_first(valparams);
        if (vp->val)
            nasm_parser_cur_section =
                sections_switch_absolute(&nasm_parser_sections,
-                   p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex))));
+                   p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex))),
+                   cur_we->internal_error_);
        else if (vp->param) {
            nasm_parser_cur_section =
-               sections_switch_absolute(&nasm_parser_sections, vp->param);
+               sections_switch_absolute(&nasm_parser_sections, vp->param,
+                                        cur_we->internal_error_);
            vp->param = NULL;
        }
        nasm_parser_prev_bc = (bytecode *)NULL;
@@ -606,7 +589,8 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
                const intnum *intcpu;
                intcpu = expr_get_intnum(&vp->param, NULL);
                if (!intcpu)
-                   Error(lindex, _("invalid argument to [%s]"), "CPU");
+                   cur_we->error(lindex, N_("invalid argument to [%s]"),
+                                 "CPU");
                else {
                    char strcpu[16];
                    sprintf(strcpu, "%lu", intnum_get_uint(intcpu));
@@ -621,7 +605,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
        ;
     } else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams,
                                             &nasm_parser_sections, lindex)) {
-       Error(lindex, _("unrecognized directive [%s]"), name);
+       cur_we->error(lindex, N_("unrecognized directive [%s]"), name);
     }
 
     vps_delete(valparams);
@@ -629,9 +613,9 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
        vps_delete(objext_valparams);
 }
 
-void
+static void
 nasm_parser_error(const char *s)
 {
-    ParserError(p_line_index, s);
+    cur_we->parser_error(cur_lindex, s);
 }
 
index bb78777c1472019737dc5c118d353212390b4d01..a38a28d1b121eb10f3e2243f11d2bfbd0986071a 100644 (file)
 #include "preproc.h"
 #include "parser.h"
 
+#include "nasm-parser.h"
 
-extern FILE *nasm_parser_in;
-extern int nasm_parser_debug;
 
-extern int nasm_parser_parse(void);
-extern void nasm_parser_cleanup(void);
-
-size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm);
+FILE *nasm_parser_in = NULL;
+size_t (*nasm_parser_input) (char *buf, size_t max_size);
 
 sectionhead nasm_parser_sections;
 /*@dependent@*/ section *nasm_parser_cur_section;
 
-extern /*@only@*/ char *nasm_parser_locallabel_base;
+/* last "base" label for local (.) labels */
+char *nasm_parser_locallabel_base = (char *)NULL;
+size_t nasm_parser_locallabel_base_len = 0;
 
 /*@dependent@*/ arch *nasm_parser_arch;
 /*@dependent@*/ objfmt *nasm_parser_objfmt;
 /*@dependent@*/ linemgr *nasm_parser_linemgr;
+/*@dependent@*/ errwarn *nasm_parser_errwarn;
 
 static /*@dependent@*/ sectionhead *
-nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm, FILE *f,
-                    const char *in_filename)
+nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm,
+                    errwarn *we, FILE *f, const char *in_filename)
     /*@globals killed nasm_parser_locallabel_base @*/
 {
-    pp->initialize(f, in_filename);
+    pp->initialize(f, in_filename, lm, we);
     nasm_parser_in = f;
     nasm_parser_input = pp->input;
     nasm_parser_arch = a;
     nasm_parser_objfmt = of;
     nasm_parser_linemgr = lm;
+    nasm_parser_errwarn = we;
 
     /* Initialize section list */
     nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of);
diff --git a/modules/parsers/nasm/nasm-parser.h b/modules/parsers/nasm/nasm-parser.h
new file mode 100644 (file)
index 0000000..f0b63c7
--- /dev/null
@@ -0,0 +1,53 @@
+/* $IdPath$
+ * NASM-compatible parser header file
+ *
+ *  Copyright (C) 2002  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef YASM_NASM_PARSER_H
+#define YASM_NASM_PARSER_H
+
+int nasm_parser_parse(void);
+void nasm_parser_cleanup(void);
+int nasm_parser_lex(void);
+void nasm_parser_set_directive_state(void);
+
+extern FILE *nasm_parser_in;
+extern int nasm_parser_debug;
+extern size_t (*nasm_parser_input) (char *buf, size_t max_size);
+
+extern sectionhead nasm_parser_sections;
+extern /*@dependent@*/ section *nasm_parser_cur_section;
+
+extern char *nasm_parser_locallabel_base;
+extern size_t nasm_parser_locallabel_base_len;
+
+extern /*@dependent@*/ arch *nasm_parser_arch;
+extern /*@dependent@*/ objfmt *nasm_parser_objfmt;
+extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
+extern /*@dependent@*/ errwarn *nasm_parser_errwarn;
+
+#define cur_lindex     (nasm_parser_linemgr->get_current())
+
+#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,cur_lindex)
+#define p_expr_new_branch(o,r) expr_new_branch(o,r,cur_lindex)
+#define p_expr_new_ident(r)    expr_new_ident(r,cur_lindex)
+
+#define cur_we         nasm_parser_errwarn
+
+#endif
index fc1dd26a1b189ae62f64ec3143e1cf62aed792ae..46daee4ce4c48c31518d68d9acf13ac952ac5700 100644 (file)
@@ -37,6 +37,7 @@ RCSID("$IdPath$");
 
 #include "arch.h"
 
+#include "src/parsers/nasm/nasm-parser.h"
 #include "src/parsers/nasm/nasm-defs.h"
 #include "nasm-bison.h"
 
@@ -59,17 +60,6 @@ RCSID("$IdPath$");
 
 #define TOKLEN         (cursor-s.tok)
 
-void nasm_parser_cleanup(void);
-void nasm_parser_set_directive_state(void);
-int nasm_parser_lex(void);
-
-extern size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm);
-extern /*@dependent@*/ arch *nasm_parser_arch;
-extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
-
-#define p_line_index   (nasm_parser_linemgr->get_current())
-
-
 typedef struct Scanner {
     YYCTYPE            *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
     unsigned int       tchar, tline, cline;
@@ -77,8 +67,6 @@ typedef struct Scanner {
 
 static Scanner s = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1 };
 
-FILE *nasm_parser_in = NULL;
-
 static YYCTYPE *
 fill(YYCTYPE *cursor)
 {
@@ -105,8 +93,7 @@ fill(YYCTYPE *cursor)
                xfree(s.bot);
            s.bot = buf;
        }
-       if((cnt = nasm_parser_input(s.lim, BSIZE,
-                                   nasm_parser_linemgr)) != BSIZE){
+       if((cnt = nasm_parser_input(s.lim, BSIZE)) != BSIZE){
            s.eof = &s.lim[cnt]; *s.eof++ = '\n';
        }
        s.lim += cnt;
@@ -130,10 +117,6 @@ static char *strbuf = (char *)NULL;
 /* length of strbuf (including terminating NULL character) */
 static size_t strbuf_size = 0;
 
-/* last "base" label for local (.) labels */
-char *nasm_parser_locallabel_base = (char *)NULL;
-size_t nasm_parser_locallabel_base_len = 0;
-
 static int linechg_numcount;
 
 /*!re2c
@@ -220,7 +203,7 @@ scan:
        digit+ {
            savech = s.tok[TOKLEN];
            s.tok[TOKLEN] = '\0';
-           yylval.intn = intnum_new_dec(s.tok, p_line_index);
+           yylval.intn = intnum_new_dec(s.tok, cur_lindex);
            s.tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
@@ -228,21 +211,21 @@ scan:
 
        bindigit+ "b" {
            s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */
-           yylval.intn = intnum_new_bin(s.tok, p_line_index);
+           yylval.intn = intnum_new_bin(s.tok, cur_lindex);
            RETURN(INTNUM);
        }
 
        /* 777q - octal number */
        octdigit+ "q" {
            s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */
-           yylval.intn = intnum_new_oct(s.tok, p_line_index);
+           yylval.intn = intnum_new_oct(s.tok, cur_lindex);
            RETURN(INTNUM);
        }
 
        /* 0AAh form of hexidecimal number */
        digit hexdigit* "h" {
            s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */
-           yylval.intn = intnum_new_hex(s.tok, p_line_index);
+           yylval.intn = intnum_new_hex(s.tok, cur_lindex);
            RETURN(INTNUM);
        }
 
@@ -252,10 +235,10 @@ scan:
            s.tok[TOKLEN] = '\0';
            if (s.tok[1] == 'x')
                /* skip 0 and x */
-               yylval.intn = intnum_new_hex(s.tok+2, p_line_index);
+               yylval.intn = intnum_new_hex(s.tok+2, cur_lindex);
            else
                /* don't skip 0 */
-               yylval.intn = intnum_new_hex(s.tok+1, p_line_index);
+               yylval.intn = intnum_new_hex(s.tok+1, cur_lindex);
            s.tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
@@ -342,8 +325,9 @@ scan:
                yylval.str_val = xstrndup(s.tok, TOKLEN);
                RETURN(ID);
            } else if (!nasm_parser_locallabel_base) {
-               Warning(p_line_index, _("no non-local label before `%s'"),
-                       s.tok[0]);
+               cur_we->warning(WARN_GENERAL, cur_lindex,
+                               N_("no non-local label before `%s'"),
+                               s.tok[0]);
                yylval.str_val = xstrndup(s.tok, TOKLEN);
            } else {
                len = TOKLEN + nasm_parser_locallabel_base_len;
@@ -367,7 +351,7 @@ scan:
            savech = s.tok[TOKLEN];
            s.tok[TOKLEN] = '\0';
            check_id_ret = nasm_parser_arch->parse.check_identifier(
-               yylval.arch_data, s.tok, p_line_index);
+               yylval.arch_data, s.tok, cur_lindex);
            s.tok[TOKLEN] = savech;
            switch (check_id_ret) {
                case ARCH_CHECK_ID_NONE:
@@ -385,8 +369,8 @@ scan:
                case ARCH_CHECK_ID_TARGETMOD:
                    RETURN(TARGETMOD);
                default:
-                   Warning(p_line_index,
-                           _("Arch feature not supported, treating as identifier"));
+                   cur_we->warning(WARN_GENERAL, cur_lindex,
+                       N_("Arch feature not supported, treating as identifier"));
                    yylval.str_val = xstrndup(s.tok, TOKLEN);
                    RETURN(ID);
            }
@@ -399,10 +383,9 @@ scan:
        "\n"                    { state = INITIAL; RETURN(s.tok[0]); }
 
        any {
-           if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
-               Warning(p_line_index,
-                       _("ignoring unrecognized character `%s'"),
-                       conv_unprint(s.tok[0]));
+           cur_we->warning(WARN_UNREC_CHAR, cur_lindex,
+                           N_("ignoring unrecognized character `%s'"),
+                           cur_we->conv_unprint(s.tok[0]));
            goto scan;
        }
     */
@@ -416,7 +399,7 @@ linechg:
            linechg_numcount++;
            savech = s.tok[TOKLEN];
            s.tok[TOKLEN] = '\0';
-           yylval.intn = intnum_new_dec(s.tok, p_line_index);
+           yylval.intn = intnum_new_dec(s.tok, cur_lindex);
            s.tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
@@ -439,10 +422,9 @@ linechg:
        }
 
        any {
-           if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
-               Warning(p_line_index,
-                       _("ignoring unrecognized character `%s'"),
-                       conv_unprint(s.tok[0]));
+           cur_we->warning(WARN_UNREC_CHAR, cur_lindex,
+                           N_("ignoring unrecognized character `%s'"),
+                           cur_we->conv_unprint(s.tok[0]));
            goto linechg;
        }
     */
@@ -482,10 +464,9 @@ directive:
        }
 
        any {
-           if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
-               Warning(p_line_index,
-                       _("ignoring unrecognized character `%s'"),
-                       conv_unprint(s.tok[0]));
+           cur_we->warning(WARN_UNREC_CHAR, cur_lindex,
+                           N_("ignoring unrecognized character `%s'"),
+                           cur_we->conv_unprint(s.tok[0]));
            goto directive;
        }
     */
@@ -502,9 +483,10 @@ stringconst_scan:
     /*!re2c
        "\n"    {
            if (cursor == s.eof)
-               Error(p_line_index, _("unexpected end of file in string"));
+               cur_we->error(cur_lindex,
+                             N_("unexpected end of file in string"));
            else
-               Error(p_line_index, _("unterminated string"));
+               cur_we->error(cur_lindex, N_("unterminated string"));
            strbuf[count] = '\0';
            yylval.str_val = strbuf;
            RETURN(STRING);
index b251f841a20122c0f3e64589d15665cbcb4eb579..95bad927e516f16e7f0d66627f3a855a7919215c 100644 (file)
 
 static int is_interactive;
 static FILE *in;
+static linemgr *cur_lm;
+static errwarn *cur_we;
 
 int isatty(int);
 
 static void
-raw_preproc_initialize(FILE *f, const char *in_filename)
+raw_preproc_initialize(FILE *f, const char *in_filename, linemgr *lm,
+                      errwarn *we)
 {
     in = f;
+    cur_lm = lm;
+    cur_we = we;
     /*@-unrecog@*/
     is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
     /*@=unrecog@*/
 }
 
+static void
+raw_preproc_cleanup(void)
+{
+}
+
 static size_t
-raw_preproc_input(char *buf, size_t max_size, linemgr *lm)
+raw_preproc_input(char *buf, size_t max_size)
 {
     int c = '*';
     size_t n;
@@ -54,9 +64,11 @@ raw_preproc_input(char *buf, size_t max_size, linemgr *lm)
        if (c == '\n')
            buf[n++] = (char)c;
        if (c == EOF && ferror(in))
-           Error(lm->get_current(), _("error when reading from file"));
+           cur_we->error(cur_lm->get_current(),
+                         N_("error when reading from file"));
     } else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in))
-       Error(lm->get_current(), _("error when reading from file"));
+       cur_we->error(cur_lm->get_current(),
+                     N_("error when reading from file"));
 
     return n;
 }
@@ -66,5 +78,6 @@ preproc yasm_raw_LTX_preproc = {
     "Disable preprocessing",
     "raw",
     raw_preproc_initialize,
+    raw_preproc_cleanup,
     raw_preproc_input
 };
index 681f7b7818744e5b0c5147588755f532576db156..a59ee5c2ba961abcb67286d62b0a251d912e9f8d 100644 (file)
@@ -41,7 +41,7 @@ static YAPP_Output current_output;
 YYSTYPE yapp_preproc_lval;
 
 /*@dependent@*/ linemgr *yapp_preproc_linemgr;
-#define p_line_index   (yapp_preproc_linemgr->get_current())
+/*@dependent@*/ errwarn *yapp_preproc_errwarn;
 
 int isatty(int);
 
@@ -120,13 +120,13 @@ yapp_macro_insert (char *name, int argc, int fillargs)
 void
 yapp_macro_error_exists (YAPP_Macro *v)
 {
-    if (v) Error(p_line_index, _("Redefining macro of the same name %d:%d"), v->type, v->args);
+    if (v) cur_we->error(cur_lindex, N_("Redefining macro of the same name %d:%d"), v->type, v->args);
 }
 
 void
 yapp_macro_error_sameargname (YAPP_Macro *v)
 {
-    if (v) Error(p_line_index, _("Duplicate argument names in macro"));
+    if (v) cur_we->error(cur_lindex, N_("Duplicate argument names in macro"));
 }
 
 YAPP_Macro *
@@ -141,7 +141,7 @@ yapp_define_insert (char *name, int argc, int fillargs)
        if ((argc >= 0 && ym->args < 0)
            || (argc < 0 && ym->args >= 0))
        {
-           Warning(p_line_index, _("Attempted %%define both with and without parameters"));
+           cur_we->warning(WARN_PREPROC, cur_lindex, N_("Attempted %%define both with and without parameters"));
            return NULL;
        }
     }
@@ -189,10 +189,10 @@ yapp_macro_delete (YAPP_Macro *ym)
 {
     while (!SLIST_EMPTY(&ym->macro_head)) {
        source *s = SLIST_FIRST(&ym->macro_head);
-       free(s);
+       xfree(s);
        SLIST_REMOVE_HEAD(&ym->macro_head, next);
     }
-    free(ym);
+    xfree(ym);
 }
 
 static YAPP_Macro *
@@ -237,9 +237,12 @@ void
 expand_token_list(struct source_head *paramexp, struct source_head *to_head, source **to_tail);
 
 static void
-yapp_preproc_initialize(FILE *f, const char *in_filename)
+yapp_preproc_initialize(FILE *f, const char *in_filename, linemgr *lm,
+                       errwarn *we)
 {
     is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
+    yapp_preproc_linemgr = lm;
+    yapp_preproc_errwarn = we;
     yapp_preproc_current_file = xstrdup(in_filename);
     yapp_preproc_line_number = 1;
     yapp_lex_initialize(f);
@@ -251,7 +254,7 @@ yapp_preproc_initialize(FILE *f, const char *in_filename)
     out->out = current_output = YAPP_OUTPUT;
     SLIST_INSERT_HEAD(&output_head, out, next);
 
-    macro_table = HAMT_new();
+    macro_table = HAMT_new(we->internal_error_);
 
     source_tail = SLIST_FIRST(&source_head);
     macro_tail = SLIST_FIRST(&macro_head);
@@ -260,6 +263,12 @@ yapp_preproc_initialize(FILE *f, const char *in_filename)
     append_token(LINE, &source_head, &source_tail);
 }
 
+static void
+yapp_preproc_cleanup(void)
+{
+    /* TODO: clean up */
+}
+
 /* Generate a new level of if* context
  * if val is true, this module of the current level will be output IFF the
  * surrounding one is.
@@ -321,7 +330,7 @@ pop_if(void)
     out = SLIST_FIRST(&output_head);
     current_output = out->out;
     SLIST_REMOVE_HEAD(&output_head, next);
-    free(out);
+    xfree(out);
     if (current_output != YAPP_OUTPUT) set_inhibit();
 }
 
@@ -367,7 +376,7 @@ append_token(int token, struct source_head *to_head, source **to_tail)
     if ((*to_tail) && (*to_tail)->token.type == LINE
        && (token == '\n' || token == LINE))
     {
-       free ((*to_tail)->token.str);
+       xfree ((*to_tail)->token.str);
        (*to_tail)->token.str = xmalloc(23+strlen(yapp_preproc_current_file));
        sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file);
     }
@@ -409,7 +418,7 @@ append_token(int token, struct source_head *to_head, source **to_tail)
                break;
 
            default:
-               free(src);
+               xfree(src);
                return;
        }
        append_processed_token(src, to_head, to_tail);
@@ -461,7 +470,7 @@ eat_through_return(struct source_head *to_head, source **to_tail)
     while ((token = yapp_preproc_lex()) != '\n') {
        if (token == 0)
            return 0;
-       Error(p_line_index, _("Skipping possibly valid %%define stuff"));
+       cur_we->error(cur_lindex, N_("Skipping possibly valid %%define stuff"));
     }
     append_token('\n', to_head, to_tail);
     return '\n';
@@ -474,7 +483,7 @@ yapp_get_ident(const char *synlvl)
     if (token == WHITESPACE)
        token = yapp_preproc_lex();
     if (token != IDENT) {
-       Error(p_line_index, _("Identifier expected after %%%s"), synlvl);
+       cur_we->error(cur_lindex, N_("Identifier expected after %%%s"), synlvl);
     }
     return token;
 }
@@ -502,7 +511,7 @@ expand_macro(char *name,
 
     ydebug(("YAPP: +Expand macro %s...\n", name));
 
-    if (ym->expanding) InternalError(_("Recursively expanding a macro!"));
+    if (ym->expanding) cur_we->internal_error(N_("Recursively expanding a macro!"));
 
     if (ym->type == YAPP_DEFINE) {
        if (ym->args == -1) {
@@ -534,7 +543,7 @@ expand_macro(char *name,
 
            /* find out what we got */
            if (from_head) {
-               InternalError("Expanding macro with non-null from_head ugh\n");
+               cur_we->internal_error(N_("Expanding macro with non-null from_head ugh\n"));
            }
            token = yapp_preproc_lex();
            append_token(token, &replay_head, &replay_tail);
@@ -581,9 +590,9 @@ expand_macro(char *name,
 
                    default:
                        if (token < 256)
-                           InternalError(_("Unexpected character token in parameter expansion"));
+                           cur_we->internal_error(N_("Unexpected character token in parameter expansion"));
                        else
-                           Error(p_line_index, _("Cannot handle preprocessor items inside possible macro invocation"));
+                           cur_we->error(cur_lindex, N_("Cannot handle preprocessor items inside possible macro invocation"));
                }
            }
 
@@ -603,7 +612,7 @@ expand_macro(char *name,
            ym->expanding = 1;
 
            /* so the macro exists. build a HAMT parameter table */
-           param_table = HAMT_new();
+           param_table = HAMT_new(cur_we->internal_error_);
            /* fill the entries by walking the replay buffer and create
             * "macros".  coincidentally, clear the replay buffer. */
 
@@ -612,16 +621,16 @@ expand_macro(char *name,
            while (replay->token.type != '(') {
                ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str));
                SLIST_REMOVE_HEAD(&replay_head, next);
-               free(replay->token.str);
-               free(replay);
+               xfree(replay->token.str);
+               xfree(replay);
                replay = SLIST_FIRST(&replay_head);
            }
            ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str));
 
            /* free the open paren */
            SLIST_REMOVE_HEAD(&replay_head, next);
-           free(replay->token.str);
-           free(replay);
+           xfree(replay->token.str);
+           xfree(replay);
 
            param = SLIST_FIRST(&ym->param_head);
 
@@ -651,8 +660,8 @@ expand_macro(char *name,
                    arg_tail = SLIST_FIRST(&arg_head);
 
                    /* don't save the comma */
-                   free(replay->token.str);
-                   free(replay);
+                   xfree(replay->token.str);
+                   xfree(replay);
 
                    HAMT_insert(param_table,
                                param->token.str,
@@ -675,15 +684,15 @@ expand_macro(char *name,
                if (replay) SLIST_REMOVE_HEAD(&replay_head, next);
            }
            if (replay) {
-               free(replay->token.str);
-               free(replay);
+               xfree(replay->token.str);
+               xfree(replay);
            }
            else if (param) {
-                 InternalError(_("Got to end of arglist before end of replay!"));
+                 cur_we->internal_error(N_("Got to end of arglist before end of replay!"));
            }
            replay = SLIST_FIRST(&replay_head);
            if (replay || param)
-               InternalError(_("Count and distribution of define args mismatched!"));
+               cur_we->internal_error(N_("Count and distribution of define args mismatched!"));
 
            /* the param_table is set up without errors, so expansion is ready
             * to go */
@@ -717,7 +726,7 @@ expand_macro(char *name,
        }
     }
     else
-       InternalError(_("Invoking Macros not yet supported"));
+       cur_we->internal_error(N_("Invoking Macros not yet supported"));
 
     ym->expanding = 0;
 }
@@ -743,15 +752,13 @@ expand_token_list(struct source_head *paramexp, struct source_head *to_head, sou
 }
 
 static size_t
-yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
+yapp_preproc_input(char *buf, size_t max_size)
 {
     static YAPP_State state = YAPP_STATE_INITIAL;
     int n = 0;
     int token;
     int need_line_directive = 0;
 
-    yapp_preproc_linemgr = lm;
-
     while (saved_length < max_size && state != YAPP_STATE_EOF)
     {
        token = yapp_preproc_lex();
@@ -765,7 +772,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
                        append_token(token, &source_head, &source_tail);
                        /*if (append_to_return()==0) state=YAPP_STATE_EOF;*/
                        ydebug(("YAPP: default: '%c' \"%s\"\n", token, yapp_preproc_lval.str_val));
-                       /*Error(p_line_index, _("YAPP got an unhandled token."));*/
+                       /*cur_we->error(cur_lindex, N_("YAPP got an unhandled token."));*/
                        break;
 
                    case IDENT:
@@ -788,7 +795,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
 
                    case CLEAR:
                        HAMT_delete(macro_table, (void (*)(void *))yapp_macro_delete);
-                       macro_table = HAMT_new();
+                       macro_table = HAMT_new(cur_we->internal_error_);
                        break;
 
                    case DEFINE:
@@ -834,7 +841,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
                                    break;
                                }
                                else if (last_token == ',' || token != ',')
-                                   Error(p_line_index, _("Unexpected token in %%define parameters"));
+                                   cur_we->error(cur_lindex, N_("Unexpected token in %%define parameters"));
                                last_token = token;
                            }
                            if (token == ')') {
@@ -851,7 +858,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
                            append_token('\n', &source_head, &source_tail);
                        }
                        else {
-                           InternalError(_("%%define ... failed miserably - neither \\n, WS, or ( followed ident"));
+                           cur_we->internal_error(N_("%%define ... failed miserably - neither \\n, WS, or ( followed ident"));
                        }
                        break;
 
@@ -914,7 +921,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
                }
                break;
            default:
-               Error(p_line_index, _("YAPP got into a bad state"));
+               cur_we->error(cur_lindex, N_("YAPP got into a bad state"));
        }
        if (need_line_directive) {
            append_token(LINE, &source_head, &source_tail);
@@ -932,8 +939,8 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
 
            saved_length -= strlen(src->token.str);
            SLIST_REMOVE_HEAD(&source_head, next);
-           free(src->token.str);
-           free(src);
+           xfree(src->token.str);
+           xfree(src);
        }
     }
 
@@ -945,5 +952,6 @@ preproc yasm_yapp_LTX_preproc = {
     "YAPP preprocessing (NASM style)",
     "yapp",
     yapp_preproc_initialize,
+    yapp_preproc_cleanup,
     yapp_preproc_input
 };
index 428b65f0ae7c3cc660a4f1c4e7629ea883361074..5e2bdf767d68359f9e1f30e136f9cb22284a77fa 100644 (file)
@@ -52,3 +52,9 @@ typedef enum {
 
 void yapp_lex_initialize(FILE *f);
 void set_inhibit(void);
+
+extern /*@dependent@*/ linemgr *yapp_preproc_linemgr;
+extern /*@dependent@*/ errwarn *yapp_preproc_errwarn;
+#define cur_lindex     (yapp_preproc_linemgr->get_current())
+#define cur_we         yapp_preproc_errwarn
+
index 01c67b7a921da31066cda4e7b7844e545332713e..4301249532bb827e227d4f4560b7fc3bdc2cc432 100644 (file)
@@ -60,7 +60,5 @@ typedef union {
 extern YYSTYPE yapp_preproc_lval;
 extern char *yapp_preproc_current_file;
 extern int yapp_preproc_line_number;
-extern /*@dependent@*/ linemgr *yapp_preproc_linemgr;
-#define p_line_index   (yapp_preproc_linemgr->get_current())
 
 int yapp_preproc_lex(void);
index 17072e20b0b62bd681f7a3a92c159170718a87a8..d45ed6131a8e64bb56aaebc1b508fae553c29fb4 100644 (file)
@@ -124,9 +124,7 @@ DIR  %[ \t]*
     int inch, count;
     char endch = yytext[0];
 
-    strbuf = malloc(STRBUF_ALLOC_SIZE);
-    if(!strbuf)
-       Fatal(FATAL_NOMEM);
+    strbuf = xmalloc(STRBUF_ALLOC_SIZE);
 
     strbuf_size = STRBUF_ALLOC_SIZE;
     inch = input();
@@ -134,18 +132,16 @@ DIR        %[ \t]*
     while(inch != EOF && inch != endch && inch != '\n') {
        strbuf[count++] = inch;
        if(count >= strbuf_size) {
-           strbuf = realloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
-           if(!strbuf)
-               Fatal(FATAL_NOMEM);
+           strbuf = xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
            strbuf_size += STRBUF_ALLOC_SIZE;
        }
        inch = input();
     }
 
     if(inch == '\n')
-       Error(p_line_index, _("unterminated string"));
+       cur_we->error(cur_lindex, _("unterminated string"));
     else if(inch == EOF)
-       Error(p_line_index, _("unexpected end of file in string"));
+       cur_we->error(cur_lindex, _("unexpected end of file in string"));
 
     strbuf[count] = '\0';
 
@@ -176,9 +172,9 @@ DIR  %[ \t]*
     /* FIXME: handle includes that aren't relative */
     incfile = fopen (yytext, "r");
     if(!incfile) {
-       Error(p_line_index, _("include file `%s': %s"),
+       cur_we->error(cur_lindex, _("include file `%s': %s"),
                yytext, strerror(errno));
-       free(inc);
+       xfree(inc);
     }
     else {
        yyin = incfile;
@@ -204,11 +200,11 @@ DIR        %[ \t]*
        inc = SLIST_FIRST(&includes_head);
        yy_delete_buffer (YY_CURRENT_BUFFER);
        yy_switch_to_buffer (inc->include_state);
-       free(yapp_preproc_current_file);
+       xfree(yapp_preproc_current_file);
        yapp_preproc_current_file = inc->filename;
        yapp_preproc_line_number = inc->line_number + 1;
        SLIST_REMOVE_HEAD(&includes_head, next);
-       free(inc);
+       xfree(inc);
 
        BEGIN(incl);
        return INCLUDE;
@@ -232,7 +228,7 @@ DIR  %[ \t]*
 }
 <line>{WS}+["]     ;   /* eat space before file */
 <line>[^ \t\n"]*    { /* have the filename */
-    free(yapp_preproc_current_file);
+    xfree(yapp_preproc_current_file);
     yapp_preproc_current_file = xstrdup(yytext);
 }
 <line>["]{WS}*\n    {
@@ -334,12 +330,12 @@ DIR        %[ \t]*
 [][+*/,()-] { return yytext[0]; }
 
 <inhibit>.  {
-    Warning(p_line_index, _("Unhandled character in <inhibit> `%s'"), conv_unprint(yytext[0]));
+    cur_we->warning(WARN_PREPROC, cur_lindex, _("Unhandled character in <inhibit> `%s'"), cur_we->conv_unprint(yytext[0]));
 }
 
 .      {
-    Warning(p_line_index, _("ignoring unrecognized character `%s'"),
-           conv_unprint(yytext[0]));
+    cur_we->warning(WARN_PREPROC, cur_lindex, _("ignoring unrecognized character `%s'"),
+                   cur_we->conv_unprint(yytext[0]));
 }
 
 %%
index 1926b5ae87939daaa9fa5e654f9529cfd1a509f0..27ce27918f4bd50348e2f22c2c18f4dde33eb1c5 100644 (file)
@@ -4,7 +4,6 @@ libyasm_la_SOURCES = \
        src/bytecode.c          \
        src/bytecode.h          \
        src/bc-int.h            \
-       src/errwarn.c           \
        src/errwarn.h           \
        src/expr.c              \
        src/expr.h              \
@@ -47,6 +46,7 @@ yasm_SOURCES += \
        src/parser.c            \
        src/module.h            \
        src/module.c            \
+       src/errwarn.c           \
        src/linemgr.c
 
 
index 3d23ea8ca72bcbeebe529f81b87d9895543bbf7a..fb26d312c3d3d47286bf28b73856e261c28e6199 100644 (file)
@@ -58,6 +58,9 @@ struct arch {
     /* keyword used to select architecture */
     const char *keyword;
 
+    void (*initialize) (errwarn *we);
+    void (*cleanup) (void);
+
     struct {
        /* All "data" below starts the parse initialized to 0.  Thus, it is
         * okay for a funtion to use/check previously stored data to see if
index 36d3db9f0bb93bfe4c3a326a5be4b691258965a1..906434e689ba41a86be5d3ddd3707e4460c05b16 100644 (file)
 
 
 unsigned char yasm_x86_LTX_mode_bits = 0;
+/*@dependent@*/ errwarn *yasm_x86_errwarn;
+
+
+static void
+x86_initialize(errwarn *we)
+{
+    yasm_x86_errwarn = we;
+}
+
+static void
+x86_cleanup(void)
+{
+}
 
 int
 x86_directive(const char *name, valparamhead *valparams,
@@ -53,7 +66,7 @@ x86_directive(const char *name, valparamhead *valparams,
            (lval = intnum_get_int(intn)) && (lval == 16 || lval == 32))
            yasm_x86_LTX_mode_bits = (unsigned char)lval;
        else
-           Error(lindex, _("invalid argument to [%s]"), "BITS");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "BITS");
        return 0;
     } else
        return 1;
@@ -79,7 +92,7 @@ x86_get_reg_size(unsigned long reg)
        case X86_FPUREG:
            return 10;
        default:
-           InternalError(_("unknown register size"));
+           cur_we->internal_error(N_("unknown register size"));
     }
     return 0;
 }
@@ -119,7 +132,7 @@ x86_reg_print(FILE *f, unsigned long reg)
            fprintf(f, "st%d", (int)(reg&7));
            break;
        default:
-           InternalError(_("unknown register size"));
+           cur_we->internal_error(N_("unknown register size"));
     }
 }
 
@@ -165,6 +178,8 @@ x86_handle_seg_override(effaddr *ea, unsigned long segreg,
 arch yasm_x86_LTX_arch = {
     "x86 (IA-32, x86-64)",
     "x86",
+    x86_initialize,
+    x86_cleanup,
     {
        x86_switch_cpu,
        x86_check_identifier,
index 4674070bbb6107f031ba549e88a8b8422204eaf4..724e703b05c3f8b33b1d8846ea6dc609bc8b4b85 100644 (file)
@@ -114,6 +114,8 @@ typedef struct x86_new_jmprel_data {
 bytecode *x86_bc_new_jmprel(x86_new_jmprel_data *d);
 
 extern unsigned char yasm_x86_LTX_mode_bits;
+extern /*@dependent@*/ errwarn *yasm_x86_errwarn;
+#define cur_we yasm_x86_errwarn
 
 void x86_bc_delete(bytecode *bc);
 void x86_bc_print(FILE *f, int indent_level, const bytecode *bc);
index 26d7605543ee22de51240ab6734902f3bf3ee037..5eae04b64c58bf1b72ed00ef251da84d78cbe96f 100644 (file)
@@ -170,9 +170,11 @@ x86_bc_new_jmprel(x86_new_jmprel_data *d)
     jmprel->op_sel = d->op_sel;
 
     if ((d->op_sel == JR_SHORT_FORCED) && (d->near_op_len == 0))
-       Error(d->lindex, _("no SHORT form of that jump instruction exists"));
+       cur_we->error(d->lindex,
+                     N_("no SHORT form of that jump instruction exists"));
     if ((d->op_sel == JR_NEAR_FORCED) && (d->short_op_len == 0))
-       Error(d->lindex, _("no NEAR form of that jump instruction exists"));
+       cur_we->error(d->lindex,
+                     N_("no NEAR form of that jump instruction exists"));
 
     jmprel->shortop.opcode[0] = d->short_op[0];
     jmprel->shortop.opcode[1] = d->short_op[1];
@@ -203,7 +205,8 @@ x86_ea_set_segment(effaddr *ea, unsigned char segment, unsigned long lindex)
        return;
 
     if (segment != 0 && x86_ea->segment != 0)
-       Warning(lindex, _("multiple segment overrides, using leftmost"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("multiple segment overrides, using leftmost"));
 
     x86_ea->segment = segment;
 }
@@ -294,7 +297,7 @@ x86_bc_insn_get_ea(bytecode *bc)
        return NULL;
 
     if ((x86_bytecode_type)bc->type != X86_BC_INSN)
-       InternalError(_("Trying to get EA of non-instruction"));
+       cur_we->internal_error(N_("Trying to get EA of non-instruction"));
 
     return (effaddr *)(((x86_insn *)bc)->ea);
 }
@@ -318,7 +321,8 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
            jmprel->opersize = opersize;
            break;
        default:
-           InternalError(_("OperSize override applied to non-instruction"));
+           cur_we->internal_error(
+               N_("OperSize override applied to non-instruction"));
     }
 }
 
@@ -341,7 +345,8 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
            jmprel->addrsize = addrsize;
            break;
        default:
-           InternalError(_("AddrSize override applied to non-instruction"));
+           cur_we->internal_error(
+               N_("AddrSize override applied to non-instruction"));
     }
 }
 
@@ -366,11 +371,13 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix,
            lockrep_pre = &jmprel->lockrep_pre;
            break;
        default:
-           InternalError(_("LockRep prefix applied to non-instruction"));
+           cur_we->internal_error(
+               N_("LockRep prefix applied to non-instruction"));
     }
 
     if (*lockrep_pre != 0)
-       Warning(lindex, _("multiple LOCK or REP prefixes, using leftmost"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("multiple LOCK or REP prefixes, using leftmost"));
 
     *lockrep_pre = prefix;
 }
@@ -654,20 +661,21 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
                temp = expr_copy(jmprel->target);
                num = expr_get_intnum(&temp, calc_bc_dist);
                if (!num) {
-                   Error(bc->line,
-                         _("short jump target external or out of segment"));
+                   cur_we->error(bc->line,
+                       N_("short jump target external or out of segment"));
                    return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                } else {
                    rel = intnum_get_int(num);
                    rel -= jmprel->shortop.opcode_len+1;
                    /* does a short form exist? */
                    if (jmprel->shortop.opcode_len == 0) {
-                       Error(bc->line, _("short jump does not exist"));
+                       cur_we->error(bc->line,
+                                     N_("short jump does not exist"));
                        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                    }
                    /* short displacement must fit in -128 <= rel <= +127 */
                    if (rel < -128 || rel > 127) {
-                       Error(bc->line, _("short jump out of range"));
+                       cur_we->error(bc->line, N_("short jump out of range"));
                        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                    }
                }
@@ -678,7 +686,7 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
            jrshort = 0;
            if (save) {
                if (jmprel->nearop.opcode_len == 0) {
-                   Error(bc->line, _("near jump does not exist"));
+                   cur_we->error(bc->line, N_("near jump does not exist"));
                    return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                }
            }
@@ -713,8 +721,8 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
                     * it to actually be within short range).
                     */
                    if (save) {
-                       Error(bc->line,
-                             _("short jump out of range (near jump does not exist)"));
+                       cur_we->error(bc->line,
+                           N_("short jump out of range (near jump does not exist)"));
                        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                    }
                    jrshort = 1;
@@ -730,8 +738,8 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
                    jrshort = 0;
                } else {
                    if (save) {
-                       Error(bc->line,
-                             _("short jump out of range (near jump does not exist)"));
+                       cur_we->error(bc->line,
+                           N_("short jump out of range (near jump does not exist)"));
                        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
                    }
                    jrshort = 1;
@@ -780,7 +788,7 @@ x86_bc_resolve(bytecode *bc, int save, const section *sect,
        default:
            break;
     }
-    InternalError(_("Didn't handle bytecode type in x86 arch"));
+    cur_we->internal_error(N_("Didn't handle bytecode type in x86 arch"));
     /*@notreached@*/
     return BC_RESOLVE_UNKNOWN_LEN;
 }
@@ -806,7 +814,8 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
        WRITE_8(*bufp, 0x67);
     if (insn->rex != 0) {
        if (insn->mode_bits != 64)
-           InternalError(_("x86: got a REX prefix in non-64-bit mode"));
+           cur_we->internal_error(
+               N_("x86: got a REX prefix in non-64-bit mode"));
        WRITE_8(*bufp, insn->rex);
     }
 
@@ -820,13 +829,14 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
     if (ea) {
        if (x86_ea->need_modrm) {
            if (!x86_ea->valid_modrm)
-               InternalError(_("invalid Mod/RM in x86 tobytes_insn"));
+               cur_we->internal_error(
+                   N_("invalid Mod/RM in x86 tobytes_insn"));
            WRITE_8(*bufp, x86_ea->modrm);
        }
 
        if (x86_ea->need_sib) {
            if (!x86_ea->valid_sib)
-               InternalError(_("invalid SIB in x86 tobytes_insn"));
+               cur_we->internal_error(N_("invalid SIB in x86 tobytes_insn"));
            WRITE_8(*bufp, x86_ea->sib);
        }
 
@@ -846,7 +856,7 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
                                  &eat.valid_modrm, &eat.need_modrm,
                                  &eat.sib, &eat.valid_sib,
                                  &eat.need_sib, common_calc_bc_dist))
-               InternalError(_("checkea failed"));
+               cur_we->internal_error(N_("checkea failed"));
 
            if (ea->disp) {
                if (output_expr(&ea->disp, bufp, ea->len, *bufp-bufp_orig,
@@ -901,7 +911,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
        case JR_SHORT:
            /* 1 byte relative displacement */
            if (jmprel->shortop.opcode_len == 0)
-               InternalError(_("short jump does not exist"));
+               cur_we->internal_error(N_("short jump does not exist"));
 
            /* Opcode */
            for (i=0; i<jmprel->shortop.opcode_len; i++)
@@ -916,7 +926,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
        case JR_NEAR:
            /* 2/4 byte relative displacement (depending on operand size) */
            if (jmprel->nearop.opcode_len == 0) {
-               Error(bc->line, _("near jump does not exist"));
+               cur_we->error(bc->line, N_("near jump does not exist"));
                return 1;
            }
 
@@ -931,7 +941,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
                return 1;
            break;
        default:
-           InternalError(_("unrecognized relative jump op_sel"));
+           cur_we->internal_error(N_("unrecognized relative jump op_sel"));
     }
     return 0;
 }
@@ -961,7 +971,8 @@ x86_intnum_tobytes(const intnum *intn, unsigned char **bufp,
     if (rel) {
        long val;
        if (valsize != 1 && valsize != 2 && valsize != 4)
-           InternalError(_("tried to do PC-relative offset from invalid sized value"));
+           cur_we->internal_error(
+               N_("tried to do PC-relative offset from invalid sized value"));
        val = intnum_get_uint(intn);
        val -= bc->len;
        switch (valsize) {
index ea022f6dc57a50a29dc93b17c98501b057b6b9ef..c6552531e4a67e973ca3f76034bb3cd80a4182e7 100644 (file)
@@ -183,7 +183,7 @@ x86_expr_checkea_distcheck_reg(expr **ep)
        /* The reg expn *must* be EXPR_ADD at this point.  Sanity check. */
        if (e->terms[havereg_expr].type != EXPR_EXPR ||
            e->terms[havereg_expr].data.expn->op != EXPR_ADD)
-           InternalError(_("Register expression not ADD or EXPN"));
+           cur_we->internal_error(N_("Register expression not ADD or EXPN"));
 
        /* Iterate over each term in reg expn */
        for (i=0; i<e->terms[havereg_expr].data.expn->numterms; i++) {
@@ -282,9 +282,11 @@ x86_expr_checkea_getregusage(expr **ep, /*@null@*/ int *indexreg, void *data,
                     * Sanity check for EXPR_INT.
                     */
                    if (e->terms[i].data.expn->terms[0].type != EXPR_REG)
-                       InternalError(_("Register not found in reg expn"));
+                       cur_we->internal_error(
+                           N_("Register not found in reg expn"));
                    if (e->terms[i].data.expn->terms[1].type != EXPR_INT)
-                       InternalError(_("Non-integer value in reg expn"));
+                       cur_we->internal_error(
+                           N_("Non-integer value in reg expn"));
                    reg = get_reg(&e->terms[i].data.expn->terms[0], data);
                    if (!reg)
                        return 0;
@@ -378,7 +380,7 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
             */
            if (!intnum_check_size(intn, (size_t)wordsize, 0) &&
                !intnum_check_size(intn, 1, 1)) {
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            }
 
@@ -442,8 +444,8 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
        case 2:
        case 4:
            if (wordsize != *displen) {
-               Error(e->line,
-                     _("invalid effective address (displacement size)"));
+               cur_we->error(e->line,
+                   N_("invalid effective address (displacement size)"));
                return 0;
            }
            /* TODO: Add optional warning here about 2/4 not being valid
@@ -455,7 +457,7 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
            break;
        default:
            /* we shouldn't ever get any other size! */
-           InternalError(_("strange EA displacement size"));
+           cur_we->internal_error(N_("strange EA displacement size"));
     }
 
     return 1;
@@ -535,7 +537,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
                                             calc_bc_dist)) {
            case 0:
                e = *ep;
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            case 1:
                return 1;
@@ -557,7 +559,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
         */
        for (i=0; i<8; i++) {
            if (reg32mult[i] < 0) {
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            }
            if (i != indexreg && reg32mult[i] == 1 && basereg == REG32_NONE)
@@ -598,7 +600,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
         */
        for (i=0; i<8; i++)
            if (i != basereg && i != indexreg && reg32mult[i] != 0) {
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            }
 
@@ -606,7 +608,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
        if (indexreg != REG32_NONE && reg32mult[indexreg] != 1 &&
            reg32mult[indexreg] != 2 && reg32mult[indexreg] != 4 &&
            reg32mult[indexreg] != 8) {
-           Error(e->line, _("invalid effective address"));
+           cur_we->error(e->line, N_("invalid effective address"));
            return 0;
        }
 
@@ -616,7 +618,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
             * legal.
             */
            if (reg32mult[REG32_ESP] > 1 || basereg == REG32_ESP) {
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            }
            /* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */
@@ -720,7 +722,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
                                             calc_bc_dist)) {
            case 0:
                e = *ep;
-               Error(e->line, _("invalid effective address"));
+               cur_we->error(e->line, N_("invalid effective address"));
                return 0;
            case 1:
                return 1;
@@ -732,7 +734,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
        /* reg multipliers not 0 or 1 are illegal. */
        if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 ||
            reg16mult.bp & ~1) {
-           Error(e->line, _("invalid effective address"));
+           cur_we->error(e->line, N_("invalid effective address"));
            return 0;
        }
 
@@ -748,7 +750,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
 
        /* Check the modrm value for invalid combinations. */
        if (modrm16[havereg] & 0070) {
-           Error(e->line, _("invalid effective address"));
+           cur_we->error(e->line, N_("invalid effective address"));
            return 0;
        }
 
@@ -776,17 +778,17 @@ x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp,
     int fltret;
 
     if (!floatnum_check_size(flt, (size_t)valsize)) {
-       Error(e->line, _("invalid floating point constant size"));
+       cur_we->error(e->line, N_("invalid floating point constant size"));
        return 1;
     }
 
     fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize);
     if (fltret < 0) {
-       Error(e->line, _("underflow in floating point expression"));
+       cur_we->error(e->line, N_("underflow in floating point expression"));
        return 1;
     }
     if (fltret > 0) {
-       Error(e->line, _("overflow in floating point expression"));
+       cur_we->error(e->line, N_("overflow in floating point expression"));
        return 1;
     }
     *bufp += valsize;
index 4cee4eed8ad6dcf9ffde6b51e0c733dd16bed315..b57ea32a54222cb148c6a45547e02eb9a5817b39 100644 (file)
@@ -1322,7 +1322,7 @@ x86_new_jmprel(const unsigned long data[4], int num_operands,
     /* We know the target is in operand 0, but sanity check for Imm. */
     op = ops_first(operands);
     if (op->type != INSN_OPERAND_IMM)
-       InternalError(_("invalid operand conversion"));
+       cur_we->internal_error(N_("invalid operand conversion"));
     d.target = expr_new(EXPR_SUB, ExprExpr(op->data.val),
                        ExprSym(symrec_define_label("$", cur_section, prev_bc,
                                                    0, lindex)), lindex);
@@ -1556,7 +1556,7 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                        mismatch = 1;
                    break;
                default:
-                   InternalError(_("invalid operand type"));
+                   cur_we->internal_error(N_("invalid operand type"));
            }
 
            if (mismatch)
@@ -1606,7 +1606,7 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                        mismatch = 1;
                    break;
                default:
-                   InternalError(_("invalid target modifier type"));
+                   cur_we->internal_error(N_("invalid target modifier type"));
            }
        }
 
@@ -1618,7 +1618,8 @@ x86_new_insn(const unsigned long data[4], int num_operands,
 
     if (!found) {
        /* Didn't find a matching one */
-       Error(lindex, _("invalid combination of opcode and operands"));
+       cur_we->error(lindex,
+                     N_("invalid combination of opcode and operands"));
        return NULL;
     }
 
@@ -1630,23 +1631,25 @@ x86_new_insn(const unsigned long data[4], int num_operands,
        case MOD_ExtErr:
            switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) {
                case 0:
-                   Error(lindex, _("mismatch in operand sizes"));
+                   cur_we->error(lindex, N_("mismatch in operand sizes"));
                    break;
                case 1:
-                   Error(lindex, _("operand size not specified"));
+                   cur_we->error(lindex, N_("operand size not specified"));
                    break;
                default:
-                   InternalError(_("unrecognized x86 ext mod index"));
+                   cur_we->internal_error(
+                       N_("unrecognized x86 ext mod index"));
            }
            return NULL;    /* It was an error */
        case MOD_ExtWarn:
            switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) {
                default:
-                   InternalError(_("unrecognized x86 ext mod index"));
+                   cur_we->internal_error(
+                       N_("unrecognized x86 ext mod index"));
            }
            break;
        default:
-           InternalError(_("unrecognized x86 extended modifier"));
+           cur_we->internal_error(N_("unrecognized x86 extended modifier"));
     }
 
     /* Shortcut to JmpRel */
@@ -1726,7 +1729,8 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                            d.ea = x86_ea_new_reg((unsigned char)op->data.reg);
                            break;
                        case INSN_OPERAND_SEGREG:
-                           InternalError(_("invalid operand conversion"));
+                           cur_we->internal_error(
+                               N_("invalid operand conversion"));
                        case INSN_OPERAND_MEMORY:
                            d.ea = op->data.ea;
                            if ((info->operands[i] & OPT_MASK) == OPT_MemOffs)
@@ -1746,7 +1750,8 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                        d.im_len = size_lookup[(info->operands[i] &
                                                OPS_MASK)>>OPS_SHIFT];
                    } else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_SImm:
                    if (op->type == INSN_OPERAND_IMM) {
@@ -1755,36 +1760,41 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                                                OPS_MASK)>>OPS_SHIFT];
                        d.im_sign = 1;
                    } else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_Spare:
                    if (op->type == INSN_OPERAND_REG ||
                        op->type == INSN_OPERAND_SEGREG)
                        d.spare = (unsigned char)(op->data.reg&7);
                    else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_Op0Add:
                    if (op->type == INSN_OPERAND_REG)
                        d.op[0] += (unsigned char)(op->data.reg&7);
                    else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_Op1Add:
                    if (op->type == INSN_OPERAND_REG)
                        d.op[1] += (unsigned char)(op->data.reg&7);
                    else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                case OPA_SpareEA:
                    if (op->type == INSN_OPERAND_REG) {
                        d.spare = (unsigned char)(op->data.reg&7);
                        d.ea = x86_ea_new_reg((unsigned char)op->data.reg);
                    } else
-                       InternalError(_("invalid operand conversion"));
+                       cur_we->internal_error(
+                           N_("invalid operand conversion"));
                    break;
                default:
-                   InternalError(_("unknown operand action"));
+                   cur_we->internal_error(N_("unknown operand action"));
            }
 
            switch (info->operands[i] & OPAP_MASK) {
@@ -1797,7 +1807,8 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                    d.signext_imm8_op = 1;
                    break;
                default:
-                   InternalError(_("unknown operand postponed action"));
+                   cur_we->internal_error(
+                       N_("unknown operand postponed action"));
            }
        }
     }
@@ -1953,11 +1964,13 @@ x86_switch_cpu(const char *id, unsigned long lindex)
 
        /* catchalls */
        [\001-\377]+    {
-           Warning(lindex, _("unrecognized CPU identifier `%s'"), id);
+           cur_we->warning(WARN_GENERAL, lindex,
+                           N_("unrecognized CPU identifier `%s'"), id);
            return;
        }
        [\000]          {
-           Warning(lindex, _("unrecognized CPU identifier `%s'"), id);
+           cur_we->warning(WARN_GENERAL, lindex,
+                           N_("unrecognized CPU identifier `%s'"), id);
            return;
        }
     */
index 3a1132d3b1acac1898d2d60bef1734003dabadee..2f84a64e2109b530b33b3d963896efc70bc70d74 100644 (file)
@@ -96,12 +96,14 @@ typedef struct bytecode_objfmt_data {
 unsigned char bytes_static[16];
 
 /*@dependent@*/ static arch *cur_arch;
+/*@dependent@*/ static errwarn *cur_we;
 
 
 void
-bc_initialize(arch *a)
+bc_initialize(arch *a, errwarn *we)
 {
     cur_arch = a;
+    cur_we = we;
 }
 
 immval *
@@ -328,13 +330,14 @@ bc_delete(bytecode *bc)
                objfmt_data->of->bc_objfmt_data_delete(objfmt_data->type,
                                                       objfmt_data->data);
            else
-               InternalError(_("objfmt can't handle its own objfmt data bytecode"));
+               cur_we->internal_error(
+                   N_("objfmt can't handle its own objfmt data bytecode"));
            break;
        default:
            if (bc->type < cur_arch->bc.type_max)
                cur_arch->bc.bc_delete(bc);
            else
-               InternalError(_("Unknown bytecode type"));
+               cur_we->internal_error(N_("Unknown bytecode type"));
            break;
     }
     /*@=branchstate@*/
@@ -500,10 +503,11 @@ bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len, int save,
         * the circular reference error to filter through.
         */
        if (temp && expr_contains(temp, EXPR_FLOAT))
-           Error(line, _("expression must not contain floating point value"));
+           cur_we->error(line,
+               N_("expression must not contain floating point value"));
        else
-           Error(line,
-                 _("attempt to reserve non-constant quantity of space"));
+           cur_we->error(line,
+               N_("attempt to reserve non-constant quantity of space"));
        retval = BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
     } else
        *len += intnum_get_uint(num)*reserve->itemsize;
@@ -565,12 +569,13 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
     /* Open file and determine its length */
     f = fopen(incbin->filename, "rb");
     if (!f) {
-       Error(line, _("`incbin': unable to open file `%s'"), incbin->filename);
+       cur_we->error(line, N_("`incbin': unable to open file `%s'"),
+                     incbin->filename);
        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
     }
     if (fseek(f, 0L, SEEK_END) < 0) {
-       Error(line, _("`incbin': unable to seek on file `%s'"),
-             incbin->filename);
+       cur_we->error(line, N_("`incbin': unable to seek on file `%s'"),
+                     incbin->filename);
        return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
     }
     flen = (unsigned long)ftell(f);
@@ -578,8 +583,9 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
 
     /* Compute length of incbin from start, maxlen, and len */
     if (start > flen) {
-       Warning(line, _("`incbin': start past end of file `%s'"),
-               incbin->filename);
+       cur_we->warning(WARN_GENERAL, line,
+                       N_("`incbin': start past end of file `%s'"),
+                       incbin->filename);
        start = flen;
     }
     flen -= start;
@@ -603,7 +609,7 @@ bc_resolve(bytecode *bc, int save, const section *sect,
 
     switch (bc->type) {
        case BC_EMPTY:
-           InternalError(_("got empty bytecode in bc_calc_len"));
+           cur_we->internal_error(N_("got empty bytecode in bc_calc_len"));
        case BC_DATA:
            retval = bc_resolve_data((bytecode_data *)bc, &bc->len);
            break;
@@ -617,17 +623,18 @@ bc_resolve(bytecode *bc, int save, const section *sect,
            break;
        case BC_ALIGN:
            /* TODO */
-           InternalError(_("TODO: align bytecode not implemented!"));
+           cur_we->internal_error(
+               N_("TODO: align bytecode not implemented!"));
            /*break;*/
        case BC_OBJFMT_DATA:
-           InternalError(_("resolving objfmt data bytecode?"));
+           cur_we->internal_error(N_("resolving objfmt data bytecode?"));
            /*break;*/
        default:
            if (bc->type < cur_arch->bc.type_max)
                retval = cur_arch->bc.bc_resolve(bc, save, sect,
                                                 calc_bc_dist);
            else
-               InternalError(_("Unknown bytecode type"));
+               cur_we->internal_error(N_("Unknown bytecode type"));
     }
 
     /* Multiply len by number of multiples */
@@ -644,8 +651,8 @@ bc_resolve(bytecode *bc, int save, const section *sect,
        if (!num) {
            retval = BC_RESOLVE_UNKNOWN_LEN;
            if (temp && expr_contains(temp, EXPR_FLOAT)) {
-               Error(bc->line,
-                     _("expression must not contain floating point value"));
+               cur_we->error(bc->line,
+                   N_("expression must not contain floating point value"));
                retval |= BC_RESOLVE_ERROR;
            }
        } else
@@ -711,29 +718,32 @@ bc_tobytes_incbin(bytecode_incbin *incbin, unsigned char **bufp,
     if (incbin->start) {
        num = expr_get_intnum(&incbin->start, NULL);
        if (!num)
-           InternalError(_("could not determine start in bc_tobytes_incbin"));
+           cur_we->internal_error(
+               N_("could not determine start in bc_tobytes_incbin"));
        start = intnum_get_uint(num);
     }
 
     /* Open file */
     f = fopen(incbin->filename, "rb");
     if (!f) {
-       Error(line, _("`incbin': unable to open file `%s'"), incbin->filename);
+       cur_we->error(line, N_("`incbin': unable to open file `%s'"),
+                     incbin->filename);
        return 1;
     }
 
     /* Seek to start of data */
     if (fseek(f, (long)start, SEEK_SET) < 0) {
-       Error(line, _("`incbin': unable to seek on file `%s'"),
-             incbin->filename);
+       cur_we->error(line, N_("`incbin': unable to seek on file `%s'"),
+                     incbin->filename);
        fclose(f);
        return 1;
     }
 
     /* Read len bytes */
     if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) {
-       Error(line, _("`incbin': unable to read %lu bytes from file `%s'"),
-             len, incbin->filename);
+       cur_we->error(line,
+                     N_("`incbin': unable to read %lu bytes from file `%s'"),
+                     len, incbin->filename);
        fclose(f);
        return 1;
     }
@@ -760,7 +770,8 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize,
     if (bc->multiple) {
        num = expr_get_intnum(&bc->multiple, NULL);
        if (!num)
-           InternalError(_("could not determine multiple in bc_tobytes"));
+           cur_we->internal_error(
+               N_("could not determine multiple in bc_tobytes"));
        *multiple = intnum_get_uint(num);
        if (*multiple == 0) {
            *bufsize = 0;
@@ -790,7 +801,7 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize,
 
     switch (bc->type) {
        case BC_EMPTY:
-           InternalError(_("got empty bytecode in bc_tobytes"));
+           cur_we->internal_error(N_("got empty bytecode in bc_tobytes"));
        case BC_DATA:
            error = bc_tobytes_data((bytecode_data *)bc, &destbuf, sect, bc, d,
                                    output_expr);
@@ -801,7 +812,8 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize,
            break;
        case BC_ALIGN:
            /* TODO */
-           InternalError(_("TODO: align bytecode not implemented!"));
+           cur_we->internal_error(
+               N_("TODO: align bytecode not implemented!"));
            /*break;*/
        case BC_OBJFMT_DATA:
            objfmt_data = (bytecode_objfmt_data *)bc;
@@ -809,18 +821,20 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize,
                error = output_bc_objfmt_data(objfmt_data->type,
                                              objfmt_data->data, &destbuf);
            else
-               InternalError(_("Have objfmt data bytecode but no way to output it"));
+               cur_we->internal_error(
+                   N_("Have objfmt data bytecode but no way to output it"));
            break;
        default:
            if (bc->type < cur_arch->bc.type_max)
                error = cur_arch->bc.bc_tobytes(bc, &destbuf, sect, d,
                                                output_expr);
            else
-               InternalError(_("Unknown bytecode type"));
+               cur_we->internal_error(N_("Unknown bytecode type"));
     }
 
     if (!error && ((unsigned long)(destbuf - origbuf) != datasize))
-       InternalError(_("written length does not match optimized length"));
+       cur_we->internal_error(
+           N_("written length does not match optimized length"));
     return mybuf;
 }
 
index f2938ef44961a1eb30e7fd07d53232819f3a3d85..2259400e828abb61613ec034d044b48aea7d697b 100644 (file)
@@ -40,7 +40,7 @@ typedef enum {
 } bytecode_type;
 #define BYTECODE_TYPE_BASE  BC_OBJFMT_DATA+1
 
-void bc_initialize(arch *a);
+void bc_initialize(arch *a, errwarn *we);
 
 /*@only@*/ immval *imm_new_int(unsigned long int_val, unsigned long lindex);
 /*@only@*/ immval *imm_new_expr(/*@keep@*/ expr *e);
index d1585fa9a5c9920f24f9f627f5446bca6ee64016..0701d56d0bdde8b348d73f621f3cf9188f183a36 100644 (file)
@@ -43,6 +43,7 @@ typedef struct intnum intnum;
 typedef struct floatnum floatnum;
 
 typedef struct linemgr linemgr;
+typedef struct errwarn errwarn;
 
 typedef enum {
     EXPR_ADD,
index c74d533730fec04f4d022f27762c2de41c937aed..6278a3e1ca17658649f691a2f3ae03b67eca87d9 100644 (file)
 
 #define MSG_MAXSIZE    1024
 
-/* ALL warnings are disabled if this is nonzero. */
-int warnings_disabled = 0;
+/* Enabled warnings.  See errwarn.h for a list. */
+static unsigned long warn_class_enabled;
 
-/* Warnings are treated as errors if this is nonzero.
- * =2 indicates that warnings are treated as errors, and the message to the
- * user saying that has been output.
- */
-int warning_error = 0;
-
-/* Default enabled warnings.  See errwarn.h for a list. */
-unsigned long warning_flags =
-    (1UL<<WARN_UNRECOGNIZED_CHAR);
+/* Total error count */
+static unsigned int error_count;
 
-/* Total error count for entire assembler run.
- * Assembler should exit with EXIT_FAILURE if this is >= 0 on finish. */
-static unsigned int error_count = 0;
-
-/* Total warning count for entire assembler run.
- * Should not affect exit value of assembler. */
-static unsigned int warning_count = 0;
+/* Total warning count */
+static unsigned int warning_count;
 
 /* See errwarn.h for constants that match up to these strings.
- * When adding a string here, keep errwarn.h in sync! */
+ * When adding a string here, keep errwarn.h in sync!
+ */
 
 /* Fatal error messages.  Match up with fatal_num enum in errwarn.h. */
 /*@-observertrans@*/
@@ -66,12 +55,12 @@ static const char *fatal_msgs[] = {
 };
 /*@=observertrans@*/
 
-typedef /*@reldef@*/ SLIST_HEAD(errwarnhead_s, errwarn_s) errwarnhead;
-static /*@only@*/ /*@null@*/ errwarnhead errwarns =
-    SLIST_HEAD_INITIALIZER(errwarns);
+typedef /*@reldef@*/ SLIST_HEAD(errwarndatahead_s, errwarn_data)
+    errwarndatahead;
+static /*@only@*/ /*@null@*/ errwarndatahead errwarns;
 
-typedef struct errwarn_s {
-    /*@reldef@*/ SLIST_ENTRY(errwarn_s) link;
+typedef struct errwarn_data {
+    /*@reldef@*/ SLIST_ENTRY(errwarn_data) link;
 
     enum { WE_UNKNOWN, WE_ERROR, WE_WARNING, WE_PARSERERROR } type;
 
@@ -79,18 +68,47 @@ typedef struct errwarn_s {
     /* FIXME: This should not be a fixed size.  But we don't have vasprintf()
      * right now. */
     char msg[MSG_MAXSIZE];
-} errwarn;
+} errwarn_data;
 
 /* Last inserted error/warning.  Used to speed up insertions. */
-static /*@null@*/ errwarn *previous_we = NULL;
+static /*@null@*/ errwarn_data *previous_we;
 
 /* Static buffer for use by conv_unprint(). */
 static char unprint[5];
 
+
+static void
+yasm_errwarn_initialize(void)
+{
+    /* Default enabled warnings.  See errwarn.h for a list. */
+    warn_class_enabled = 
+       (1UL<<WARN_GENERAL) | (1UL<<WARN_UNREC_CHAR) | (1UL<<WARN_PREPROC);
+
+    error_count = 0;
+    warning_count = 0;
+    SLIST_INIT(&errwarns);
+    previous_we = NULL;
+}
+
+static void
+yasm_errwarn_cleanup(void)
+{
+    errwarn_data *we;
+
+    /* Delete all error/warnings */
+    while (!SLIST_EMPTY(&errwarns)) {
+       we = SLIST_FIRST(&errwarns);
+
+       SLIST_REMOVE_HEAD(&errwarns, link);
+       xfree(we);
+    }
+}
+
 /* Convert a possibly unprintable character into a printable string, using
- * standard cat(1) convention for unprintable characters. */
-char *
-conv_unprint(char ch)
+ * standard cat(1) convention for unprintable characters.
+ */
+static char *
+yasm_errwarn_conv_unprint(char ch)
 {
     int pos = 0;
 
@@ -110,12 +128,14 @@ conv_unprint(char ch)
 }
 
 /* Report an internal error.  Essentially a fatal error with trace info.
- * Exit immediately because it's essentially an assert() trap. */
-void
-InternalError_(const char *file, unsigned int line, const char *message)
+ * Exit immediately because it's essentially an assert() trap.
+ */
+static void
+yasm_errwarn_internal_error_(const char *file, unsigned int line,
+                            const char *message)
 {
     fprintf(stderr, _("INTERNAL ERROR at %s, line %u: %s\n"), file, line,
-           message);
+           gettext(message));
 #ifdef HAVE_ABORT
     abort();
 #else
@@ -124,11 +144,12 @@ InternalError_(const char *file, unsigned int line, const char *message)
 }
 
 /* Report a fatal error.  These are unrecoverable (such as running out of
- * memory), so just exit immediately. */
-void
-Fatal(fatal_num num)
+ * memory), so just exit immediately.
+ */
+static void
+yasm_errwarn_fatal(fatal_num num)
 {
-    fprintf(stderr, "%s %s\n", _("FATAL:"), gettext(fatal_msgs[num]));
+    fprintf(stderr, _("FATAL: %s\n"), gettext(fatal_msgs[num]));
 #ifdef HAVE_ABORT
     abort();
 #else
@@ -140,10 +161,10 @@ Fatal(fatal_num num)
  * If replace_parser_error is nonzero, overwrites the last error if its
  * type is WE_PARSERERROR.
  */
-static errwarn *
-errwarn_new(unsigned long lindex, int replace_parser_error)
+static errwarn_data *
+errwarn_data_new(unsigned long lindex, int replace_parser_error)
 {
-    errwarn *first, *next, *ins_we, *we;
+    errwarn_data *first, *next, *ins_we, *we;
     enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE;
 
     /* Find the entry with either line=lindex or the last one with line<lindex.
@@ -173,7 +194,7 @@ errwarn_new(unsigned long lindex, int replace_parser_error)
        we = ins_we;
     } else {
        /* add a new error */
-       we = xmalloc(sizeof(errwarn));
+       we = xmalloc(sizeof(errwarn_data));
 
        we->type = WE_UNKNOWN;
        we->line = lindex;
@@ -184,7 +205,8 @@ errwarn_new(unsigned long lindex, int replace_parser_error)
            assert(ins_we != NULL);
            SLIST_INSERT_AFTER(ins_we, we, link);
        } else
-           InternalError(_("Unexpected errwarn insert action"));
+           yasm_errwarn_internal_error_(__FILE__, __LINE__,
+               N_("Unexpected errwarn insert action"));
     }
 
     /* Remember previous err/warn */
@@ -193,40 +215,52 @@ errwarn_new(unsigned long lindex, int replace_parser_error)
     return we;
 }
 
-/* Register an error.  Does not print the error, only stores it for
- * OutputAllErrorWarning() to print.
+/* Register an error at line lindex.  Does not print the error, only stores it
+ * for output_all() to print.
  */
 static void
-error_common(unsigned long lindex, const char *fmt, va_list ap)
+yasm_errwarn_error(unsigned long lindex, const char *fmt, ...)
 {
-    errwarn *we = errwarn_new(lindex, 1);
+    va_list va;
+    errwarn_data *we = errwarn_data_new(lindex, 1);
 
     we->type = WE_ERROR;
 
+    va_start(va, fmt);
 #ifdef HAVE_VSNPRINTF
-    vsnprintf(we->msg, MSG_MAXSIZE, fmt, ap);
+    vsnprintf(we->msg, MSG_MAXSIZE, gettext(fmt), va);
 #else
-    vsprintf(we->msg, fmt, ap);
+    vsprintf(we->msg, gettext(fmt), va);
 #endif
+    va_end(va);
 
     error_count++;
 }
 
-/* Register an warning.  Does not print the warning, only stores it for
- * OutputAllErrorWarning() to print.
+/* Register an warning at line lindex.  Does not print the warning, only stores
+ * it for output_all() to print.
  */
 static void
-warning_common(unsigned long lindex, const char *fmt, va_list va)
+yasm_errwarn_warning(warn_class_num num, unsigned long lindex, const char *fmt,
+                    ...)
 {
-    errwarn *we = errwarn_new(lindex, 0);
+    va_list va;
+    errwarn_data *we;
+
+    if (!(warn_class_enabled & (1UL<<num)))
+       return;     /* warning is part of disabled class */
+
+    we = errwarn_data_new(lindex, 0);
 
     we->type = WE_WARNING;
 
+    va_start(va, fmt);
 #ifdef HAVE_VSNPRINTF
-    vsnprintf(we->msg, MSG_MAXSIZE, fmt, va);
+    vsnprintf(we->msg, MSG_MAXSIZE, gettext(fmt), va);
 #else
-    vsprintf(we->msg, fmt, va);
+    vsprintf(we->msg, gettext(fmt), va);
 #endif
+    va_end(va);
 
     warning_count++;
 }
@@ -234,92 +268,59 @@ warning_common(unsigned long lindex, const char *fmt, va_list va)
 /* Parser error handler.  Moves YACC-style error into our error handling
  * system.
  */
-void
-ParserError(unsigned long lindex, const char *s)
+static void
+yasm_errwarn_parser_error(unsigned long lindex, const char *s)
 {
-    Error(lindex, "%s %s", _("parser error:"), s);
+    yasm_errwarn_error(lindex, N_("parser error: %s"), s);
     previous_we->type = WE_PARSERERROR;
 }
 
-/* Register an error at line lindex.  Does not print the error, only stores it
- * for OutputAllErrorWarning() to print.
- */
-void
-Error(unsigned long lindex, const char *fmt, ...)
+static void
+yasm_errwarn_warn_enable(warn_class_num num)
 {
-    va_list va;
-    va_start(va, fmt);
-    error_common(lindex, fmt, va);
-    va_end(va);
+    warn_class_enabled |= (1UL<<num);
 }
 
-/* Register an warning at line lindex.  Does not print the warning, only stores
- * it for OutputAllErrorWarning() to print.
- */
-void
-Warning(unsigned long lindex, const char *fmt, ...)
-{
-    va_list va;
-    va_start(va, fmt);
-    warning_common(lindex, fmt, va);
-    va_end(va);
-}
-
-void
-ErrorNow(const char *fmt, ...)
+static void
+yasm_errwarn_warn_disable(warn_class_num num)
 {
-    va_list ap;
-
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-    fprintf(stderr, "\n");
+    warn_class_enabled &= ~(1UL<<num);
 }
 
-void
-WarningNow(const char *fmt, ...)
+static void
+yasm_errwarn_warn_disable_all(void)
 {
-    va_list ap;
-
-    if (warnings_disabled)
-       return;
-
-    fprintf(stderr, "%s ", _("warning:"));
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-    fprintf(stderr, "\n");
+    warn_class_enabled = 0;
 }
 
 /* Get the number of errors (including warnings if warnings are being treated
  * as errors).
  */
-unsigned int
-GetNumErrors(void)
+static unsigned int
+yasm_errwarn_get_num_errors(int warning_as_error)
 {
-    if (warning_error)
+    if (warning_as_error)
        return error_count+warning_count;
     else
        return error_count;
 }
 
 /* Output all previously stored errors and warnings to stderr. */
-void
-OutputAllErrorWarning(linemgr *lm)
+static void
+yasm_errwarn_output_all(linemgr *lm, int warning_as_error)
 {
-    errwarn *we;
+    errwarn_data *we;
     const char *filename;
     unsigned long line;
 
     /* If we're treating warnings as errors, tell the user about it. */
-    if (warning_error && warning_error != 2) {
+    if (warning_as_error && warning_as_error != 2) {
        fprintf(stderr, "%s\n", _("warnings being treated as errors"));
-       warning_error = 2;
+       warning_as_error = 2;
     }
 
-    /* Output error/warning, then delete each message. */
-    while (!SLIST_EMPTY(&errwarns)) {
-       we = SLIST_FIRST(&errwarns);
+    /* Output error/warnings. */
+    SLIST_FOREACH(we, &errwarns, link) {
        /* Output error/warning */
        lm->lookup(we->line, &filename, &line);
        if (we->type == WE_ERROR)
@@ -327,9 +328,21 @@ OutputAllErrorWarning(linemgr *lm)
        else
            fprintf(stderr, "%s:%lu: %s %s\n", filename, line, _("warning:"),
                    we->msg);
-
-       /* Delete */
-       SLIST_REMOVE_HEAD(&errwarns, link);
-       xfree(we);
     }
 }
+
+errwarn yasm_errwarn = {
+    yasm_errwarn_initialize,
+    yasm_errwarn_cleanup,
+    yasm_errwarn_internal_error_,
+    yasm_errwarn_fatal,
+    yasm_errwarn_error,
+    yasm_errwarn_warning,
+    yasm_errwarn_parser_error,
+    yasm_errwarn_warn_enable,
+    yasm_errwarn_warn_disable,
+    yasm_errwarn_warn_disable_all,
+    yasm_errwarn_get_num_errors,
+    yasm_errwarn_output_all,
+    yasm_errwarn_conv_unprint
+};
index 75ee91a375425a608981345f7290e3cd306054a2..e3c3014eedd9c26b7f611a7e92e5969470a54dbf 100644 (file)
 #ifndef YASM_ERRWARN_H
 #define YASM_ERRWARN_H
 
-/* ALL warnings disabled? */
-extern int warnings_disabled;
-
-/* Warnings treated as errors? */
-extern int warning_error;
-
-/* Warning flags.  Currently a maximum of 32 are allowed.  This can be
- * increased by making this an array and modifying the WARN_ macros to use the
- * proper array index based on the warning number.
- *
- * If a bit is 1, it means that particular warning is enabled.  The bit numbers
- * are assigned according to the warn_flag_num enum.
- *
- * See errwarn.c for what warnings are enabled by default.
- */
-extern unsigned long warning_flags;
+/* Warning classes (may be enabled/disabled). */
 typedef enum {
-    WARN_UNRECOGNIZED_CHAR = 0
-} warn_flag_num;
-
-/* Tests the warning flags to see if warning "warn" is enabled */
-#define WARN_ENABLED(warn)     (warning_flags & (1<<(warn)))
-/* Sets warning "warn" to be enabled or disabled based on "s" (1=en, 0=dis). */
-#define WARN_ENABLE(warn, s)   do { \
-       warning_flags &= ~(1<<(warn)); \
-       warning_flags |= (s)<<(warn); \
-    } while(0)
+    WARN_GENERAL = 0,      /* non-specific warnings */
+    WARN_UNREC_CHAR,       /* unrecognized characters (while tokenizing) */
+    WARN_PREPROC           /* preprocessor warnings */
+} warn_class_num;
 
 /* Fatal error constants.
  * See fatal_msgs in errwarn.c for strings that match up to these constants.
- * When adding a constant here, keep errwarn.c in sync! */
+ * When adding a constant here, keep errwarn.c in sync!
+ */
 typedef enum {
     FATAL_UNKNOWN = 0,
     FATAL_NOMEM
 } fatal_num;
 
-/*@shared@*/ char *conv_unprint(char ch);
+struct errwarn {
+    /* Initialize any internal data structures. */
+    void (*initialize) (void);
 
-void ParserError(unsigned long lindex, const char *);
+    /* Cleans up any memory allocated by initialize or other functions. */
+    void (*cleanup) (void);
 
-/*@exits@*/ void InternalError_(const char *file, unsigned int line,
-                               const char *message);
-#define InternalError(msg)     InternalError_(__FILE__, __LINE__, msg)
+    /* Reporting point of internal errors.  These are usually due to sanity
+     * check failures in the code.
+     * This function must NOT return to calling code.  Either exit or longjmp.
+     */
+    /*@exits@*/ void (*internal_error_) (const char *file, unsigned int line,
+                                        const char *message);
+#define internal_error(msg)    internal_error_(__FILE__, __LINE__, msg)
 
-/*@exits@*/ void Fatal(fatal_num);
+    /* Reporting point of fatal errors.
+     * This function must NOT return to calling code.  Either exit or longjmp.
+     */
+    /*@exits@*/ void (*fatal) (fatal_num);
 
-void Error(unsigned long lindex, const char *, ...) /*@printflike@*/;
-void Warning(unsigned long lindex, const char *, ...) /*@printflike@*/;
+    void (*error) (unsigned long lindex, const char *, ...) /*@printflike@*/;
+    void (*warning) (warn_class_num, unsigned long lindex, const char *, ...)
+       /*@printflike@*/;
 
-/* These two functions immediately output the error or warning, with no file
- * or line information.  They should be used for errors and warnings outside
- * the parser stage (at program startup, for instance).
- */
-void ErrorNow(const char *, ...) /*@printflike@*/;
-void WarningNow(const char *, ...) /*@printflike@*/;
+    /* Logs a parser error.  These can be overwritten by non-parser errors on
+     * the same line.
+     */
+    void (*parser_error) (unsigned long lindex, const char *);
+
+    /* Enables/disables a class of warnings. */
+    void (*warn_enable) (warn_class_num);
+    void (*warn_disable) (warn_class_num);
+    void (*warn_disable_all) (void);
+
+    /* Returns total number of errors logged to this point.
+     * If warning_as_error is nonzero, warnings are treated as errors.
+     */
+    unsigned int (*get_num_errors) (int warning_as_error);
 
-/* Returns total number of errors to this point in assembly. */
-unsigned int GetNumErrors(void);
+    /* Outputs all errors/warnings (e.g. to stderr or elsewhere). */
+    void (*output_all) (linemgr *lm, int warning_as_error);
 
-/* Outputs all errors/warnings to standard error. */
-void OutputAllErrorWarning(linemgr *lm);
+    /* Convert a possibly unprintable character into a printable string. */
+    char * (*conv_unprint) (char ch);
+};
 
 #endif
index a56762aa4af35e4a3a92f18b1dd329bbe225c756..8f76aec0a2add4657de203f320eeb86390be71c4 100644 (file)
@@ -43,12 +43,14 @@ static int expr_traverse_nodes_post(/*@null@*/ expr *e, /*@null@*/ void *d,
                                                 /*@null@*/ void *d));
 
 static /*@dependent@*/ arch *cur_arch;
+static /*@dependent@*/ errwarn *cur_we;
 
 
 void
-expr_initialize(arch *a)
+expr_initialize(arch *a, errwarn *we)
 {
     cur_arch = a;
+    cur_we = we;
 }
 
 /* allocate a new expression node, with children as defined.
@@ -81,7 +83,7 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right, unsigned long lindex)
            /*@=usereleased@*/
        }
     } else {
-       InternalError(_("Right side of expression must exist"));
+       cur_we->internal_error(N_("Right side of expression must exist"));
     }
 
     if (right) {
@@ -700,7 +702,8 @@ expr_level_tree(expr *e, int fold_const, int simplify_ident,
                /* Check for circular reference */
                SLIST_FOREACH(np, eh, next) {
                    if (np->e == equ_expr) {
-                       Error(e->line, _("circular reference detected."));
+                       cur_we->error(e->line,
+                                     N_("circular reference detected."));
                        return e;
                    }
                }
index 36e5397201166fe75d1a09cb9b83b4f2760bfbe3..73aee9253bd52a64179788a120e459fe41694ce0 100644 (file)
@@ -24,7 +24,7 @@
 
 typedef struct ExprItem ExprItem;
 
-void expr_initialize(arch *a);
+void expr_initialize(arch *a, errwarn *we);
 
 /*@only@*/ expr *expr_new(ExprOp, /*@only@*/ ExprItem *,
                          /*@only@*/ /*@null@*/ ExprItem *,
index 77f1aa9e310bdddc28920fafe49c3655261049bd..ae05f5138930641159f1a3a4fb832307a10b3915 100644 (file)
 
 #include "file.h"
 
-#include "errwarn.h"
-
-
-char *
-replace_extension(const char *orig, /*@null@*/ const char *ext,
-                 const char *def)
-{
-    char *out, *outext;
-
-    /* allocate enough space for full existing name + extension */
-    out = xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1));
-    strcpy(out, orig);
-    outext = strrchr(out, '.');
-    if (outext) {
-       /* Existing extension: make sure it's not the same as the replacement
-        * (as we don't want to overwrite the source file).
-        */
-       outext++;   /* advance past '.' */
-       if (ext && strcmp(outext, ext) == 0) {
-           outext = NULL;  /* indicate default should be used */
-           WarningNow(_("file name already ends in `.%s': output will be in `%s'"),
-                      ext, def);
-       }
-    } else {
-       /* No extension: make sure the output extension is not empty
-        * (again, we don't want to overwrite the source file).
-        */
-       if (!ext)
-           WarningNow(_("file name already has no extension: output will be in `%s'"),
-                      def);
-       else {
-           outext = strrchr(out, '\0');    /* point to end of the string */
-           *outext++ = '.';                /* append '.' */
-       }
-    }
-
-    /* replace extension or use default name */
-    if (outext) {
-       if (!ext) {
-           /* Back up and replace '.' with string terminator */
-           outext--;
-           *outext = '\0';
-       } else
-           strcpy(outext, ext);
-    } else
-       strcpy(out, def);
-
-    return out;
-}
 
 size_t
 fwrite_16_l(unsigned short val, FILE *f)
index 3940747874bde8d1ad5116ad56461556e4698a1c..be83f779b67c73339a119e55ce5ae7135fe54613 100644 (file)
 #ifndef YASM_FILE_H
 #define YASM_FILE_H
 
-/* Replace extension on a filename (or append one if none is present).
- * If output filename would be identical to input (same extension out as in),
- * returns (copy of) def.
- * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext
- * means the trailing '.' should be included.
- */
-/*@only@*/ char *replace_extension(const char *orig, /*@null@*/
-                                  const char *ext, const char *def);
-
 /* These functions only work properly if p is an (unsigned char *) */
 
 #define WRITE_8(ptr, val)                      \
index f7b4fe60a2cee8f0fa75626cfc68ac986bf73613..73da72d97f6fef127c1b9f751eb51831d703c387 100644 (file)
@@ -84,9 +84,7 @@ typedef struct POT_Entry_Source_s {
  * entry[12-n] = 10 ** (-2 ** n) for 0 <= n <= 12.
  * entry[13] = 1.0
  */
-/*@-nullassign@*/
-static /*@only@*/ POT_Entry *POT_TableN = (POT_Entry *)NULL;
-/*@=nullassign@*/
+static /*@only@*/ POT_Entry *POT_TableN;
 static POT_Entry_Source POT_TableN_Source[] = {
     {{0xe3,0x2d,0xde,0x9f,0xce,0xd2,0xc8,0x04,0xdd,0xa6},0x4ad8}, /* 1e-4096 */
     {{0x25,0x49,0xe4,0x2d,0x36,0x34,0x4f,0x53,0xae,0xce},0x656b}, /* 1e-2048 */
@@ -132,6 +130,9 @@ static POT_Entry_Source POT_TableP_Source[] = {
     {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7fff}, /* 1e+0 */
 };
 
+static /*@dependent@*/ errwarn *cur_we;
+
+
 static void
 POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
 {
@@ -153,14 +154,16 @@ POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
 }
 
 /*@-compdef@*/
-static void
-POT_Table_Init(void)
+void
+floatnum_initialize(errwarn *we)
 /*@globals undef POT_TableN, undef POT_TableP, POT_TableP_Source,
    POT_TableN_Source @*/
 {
     int dec_exp = 1;
     int i;
 
+    cur_we = we;
+
     /* Allocate space for two POT tables */
     POT_TableN = xmalloc(14*sizeof(POT_Entry));
     POT_TableP = xmalloc(15*sizeof(POT_Entry));        /* note 1 extra for -1 */
@@ -186,13 +189,10 @@ POT_Table_Init(void)
 
 /*@-globstate@*/
 void
-floatnum_shutdown(void)
+floatnum_cleanup(void)
 {
     int i;
 
-    if (!POT_TableN)
-       return;
-
     /* Un-offset POT_TableP */
     POT_TableP--;
 
@@ -310,10 +310,6 @@ floatnum_new(const char *str)
     int decimal_pt;
     boolean carry;
 
-    /* Initialize POT tables if necessary */
-    if (!POT_TableN)
-       POT_Table_Init();
-
     flt = xmalloc(sizeof(floatnum));
 
     flt->mantissa = BitVector_Create(MANT_BITS, TRUE);
@@ -515,7 +511,8 @@ floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand,
              unsigned long lindex)
 {
     if (op != EXPR_NEG)
-       Error(lindex, _("Unsupported floating-point arithmetic operation"));
+       cur_we->error(lindex,
+                     N_("Unsupported floating-point arithmetic operation"));
     else
        acc->sign ^= 1;
 }
@@ -590,7 +587,7 @@ floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr,
 
     /* underflow and overflow both set!? */
     if (underflow && overflow)
-       InternalError(_("Both underflow and overflow set"));
+       cur_we->internal_error(N_("Both underflow and overflow set"));
 
     /* check for underflow or overflow and set up appropriate output */
     if (underflow) {
@@ -613,7 +610,8 @@ floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr,
     /* get little-endian bytes */
     buf = BitVector_Block_Read(output, &len);
     if (len < byte_size)
-       InternalError(_("Byte length of BitVector does not match bit length"));
+       cur_we->internal_error(
+           N_("Byte length of BitVector does not match bit length"));
 
     /* copy to output */
     memcpy(ptr, buf, byte_size*sizeof(unsigned char));
@@ -667,7 +665,7 @@ floatnum_get_sized(const floatnum *flt, unsigned char *ptr, size_t size)
        case 10:
            return floatnum_get_common(flt, ptr, 10, 64, 0, 15);
        default:
-           InternalError(_("Invalid float conversion size"));
+           cur_we->internal_error(N_("Invalid float conversion size"));
            /*@notreached@*/
            return 1;       /* never reached, but silence GCC warning */
     }
index a5d05bbaf40bcb5c19ae03477524d22dc4f50598..60f200505935b5363fae2c5af2de10524187bc09 100644 (file)
@@ -24,8 +24,9 @@
 #ifndef YASM_FLOATNUM_H
 #define YASM_FLOATNUM_H
 
+void floatnum_initialize(errwarn *we);
 /* Clean up internal allocations */
-void floatnum_shutdown(void);
+void floatnum_cleanup(void);
 
 /*@only@*/ floatnum *floatnum_new(const char *str);
 /*@only@*/ floatnum *floatnum_copy(const floatnum *flt);
index 26606d70009e9d9fdd5eb5c1755c9007f7995b26..a1fa2c3bea2c4fc0fc0e013d6892d58fd9cfe949 100644 (file)
@@ -35,7 +35,6 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
-#include "errwarn.h"
 #include "hamt.h"
 
 typedef struct HAMTEntry {
@@ -52,6 +51,8 @@ typedef struct HAMTNode {
 struct HAMT {
     SLIST_HEAD(HAMTEntryHead, HAMTEntry) entries;
     HAMTNode *root;
+    /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                   const char *message);
 };
 
 /* XXX make a portable version of this.  This depends on the pointer being
@@ -59,9 +60,10 @@ struct HAMT {
  * the subtrie flag!
  */
 #define IsSubTrie(n)           ((unsigned long)((n)->BaseValue) & 1)
-#define SetSubTrie(n, v)       do {                            \
+#define SetSubTrie(h, n, v)    do {                            \
        if ((unsigned long)(v) & 1)                             \
-           InternalError(_("Subtrie is seen as subtrie before flag is set (misaligned?)"));    \
+           h->error_func(__FILE__, __LINE__,                   \
+                         N_("Subtrie is seen as subtrie before flag is set (misaligned?)"));   \
        (n)->BaseValue = (void *)((unsigned long)(v) | 1);      \
     } while (0)
 #define GetSubTrie(n)          (HAMTNode *)((unsigned long)((n)->BaseValue)&~1UL)
@@ -85,7 +87,8 @@ ReHashKey(const char *key, int Level)
 }
 
 HAMT *
-HAMT_new(void)
+HAMT_new(/*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                        const char *message))
 {
     /*@out@*/ HAMT *hamt = xmalloc(sizeof(HAMT));
     int i;
@@ -98,6 +101,8 @@ HAMT_new(void)
        hamt->root[i].BaseValue = NULL;
     }
 
+    hamt->error_func = error_func;
+
     return hamt;
 }
 
@@ -174,7 +179,8 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
        SLIST_INSERT_HEAD(&hamt->entries, entry, next);
        node->BaseValue = entry;
        if (IsSubTrie(node))
-           InternalError(_("Data is seen as subtrie (misaligned?)"));
+           hamt->error_func(__FILE__, __LINE__,
+                            N_("Data is seen as subtrie (misaligned?)"));
        *replace = 1;
        return data;
     }
@@ -216,7 +222,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
                        newnodes = xmalloc(sizeof(HAMTNode));
                        newnodes[0] = *node;    /* structure copy */
                        node->BitMapKey = 1<<keypart;
-                       SetSubTrie(node, newnodes);
+                       SetSubTrie(hamt, node, newnodes);
                        node = &newnodes[0];
                        level++;
                    } else {
@@ -241,7 +247,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
 
                        /* Set bits in bitmap corresponding to keys */
                        node->BitMapKey = (1UL<<keypart) | (1UL<<keypart2);
-                       SetSubTrie(node, newnodes);
+                       SetSubTrie(hamt, node, newnodes);
                        *replace = 1;
                        return data;
                    }
@@ -285,7 +291,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
            entry->data = data;
            SLIST_INSERT_HEAD(&hamt->entries, entry, next);
            newnodes[Map].BaseValue = entry;
-           SetSubTrie(node, newnodes);
+           SetSubTrie(hamt, node, newnodes);
 
            *replace = 1;
            return data;
index b3cd79319c71f8fb2951b0c12c206c61b17a1608..c21d520118c99a1fbce536ecc92215e1c0979186 100644 (file)
 
 typedef struct HAMT HAMT;
 
-/* Creates new, empty, HAMT. */
-HAMT *HAMT_new(void);
+/* Creates new, empty, HAMT.  error_func() is called when an internal error is
+ * encountered--it should NOT return to the calling function.
+ */
+HAMT *HAMT_new(/*@exits@*/ void (*error_func) (const char *file,
+                                              unsigned int line,
+                                              const char *message));
 
 /* Deletes HAMT and all data associated with it using deletefunc() on each data
  * item.
index 3ca4775d90901f2e2d4a9d7680a2ace52a3e290f..5fba7ab742aa1957d37768346e881117502e5222 100644 (file)
@@ -43,15 +43,23 @@ struct intnum {
 };
 
 /* static bitvect used for conversions */
-static /*@only@*/ /*@null@*/ wordptr conv_bv = NULL;
+static /*@only@*/ wordptr conv_bv;
+static /*@dependent@*/ errwarn *cur_we;
+
 
 void
-intnum_shutdown(void)
+intnum_initialize(errwarn *we)
 {
-    if (conv_bv) {
-       BitVector_Destroy(conv_bv);
-       conv_bv = NULL;
-    }
+    cur_we = we;
+
+    conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+}
+
+void
+intnum_cleanup(void)
+{
+    BitVector_Destroy(conv_bv);
     BitVector_from_Dec_static_Shutdown();
 }
 
@@ -62,13 +70,10 @@ intnum_new_dec(char *str, unsigned long lindex)
 
     intn->origsize = 0;            /* no reliable way to figure this out */
 
-    if (!conv_bv) {
-       conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-    }
     if (BitVector_from_Dec_static(conv_bv,
                                  (unsigned char *)str) == ErrCode_Ovfl)
-       Warning(lindex, _("Numeric constant too large for internal format"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("Numeric constant too large for internal format"));
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
        intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
@@ -88,12 +93,9 @@ intnum_new_bin(char *str, unsigned long lindex)
     intn->origsize = (unsigned char)strlen(str);
 
     if(intn->origsize > BITVECT_ALLOC_SIZE)
-       Warning(lindex, _("Numeric constant too large for internal format"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("Numeric constant too large for internal format"));
 
-    if (!conv_bv) {
-       conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-    }
     BitVector_from_Bin(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -114,12 +116,9 @@ intnum_new_oct(char *str, unsigned long lindex)
     intn->origsize = strlen(str)*3;
 
     if(intn->origsize > BITVECT_ALLOC_SIZE)
-       Warning(lindex, _("Numeric constant too large for internal format"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("Numeric constant too large for internal format"));
 
-    if (!conv_bv) {
-       conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-    }
     BitVector_from_Oct(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -140,12 +139,9 @@ intnum_new_hex(char *str, unsigned long lindex)
     intn->origsize = strlen(str)*4;
 
     if(intn->origsize > BITVECT_ALLOC_SIZE)
-       Warning(lindex, _("Numeric constant too large for internal format"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("Numeric constant too large for internal format"));
 
-    if (!conv_bv) {
-       conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-    }
     BitVector_from_Hex(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -166,8 +162,8 @@ intnum_new_charconst_nasm(const char *str, unsigned long lindex)
     size_t len = strlen(str);
 
     if (len > 4)
-       Warning(lindex,
-               _("character constant too large, ignoring trailing characters"));
+       cur_we->warning(WARN_GENERAL, lindex,
+           N_("character constant too large, ignoring trailing characters"));
 
     intn->val.ul = 0;
     intn->type = INTNUM_UL;
@@ -273,7 +269,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
     }
 
     if (!operand && op != EXPR_NEG && op != EXPR_NOT && op != EXPR_LNOT)
-       InternalError(_("Operation needs an operand"));
+       cur_we->internal_error(N_("Operation needs an operand"));
 
     /* A operation does a bitvector computation if result is allocated. */
     switch (op) {
@@ -444,7 +440,8 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
                BitVector_Copy(result, op1);
            break;
        default:
-           InternalError(_("invalid operation in intnum calculation"));
+           cur_we->internal_error(
+               N_("invalid operation in intnum calculation"));
     }
 
     /* If we were doing a bitvector computation... */
@@ -507,7 +504,7 @@ intnum_get_uint(const intnum *intn)
        case INTNUM_BV:
            return BitVector_Chunk_Read(intn->val.bv, 32, 0);
        default:
-           InternalError(_("unknown intnum type"));
+           cur_we->internal_error(N_("unknown intnum type"));
            /*@notreached@*/
            return 0;
     }
@@ -535,7 +532,7 @@ intnum_get_int(const intnum *intn)
            } else
                return (long)BitVector_Chunk_Read(intn->val.bv, 32, 0);
        default:
-           InternalError(_("unknown intnum type"));
+           cur_we->internal_error(N_("unknown intnum type"));
            /*@notreached@*/
            return 0;
     }
@@ -560,7 +557,8 @@ intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size)
        case INTNUM_BV:
            buf = BitVector_Block_Read(intn->val.bv, &len);
            if (len < (unsigned int)size)
-               InternalError(_("Invalid size specified (too large)"));
+               cur_we->internal_error(
+                   N_("Invalid size specified (too large)"));
            memcpy(ptr, buf, size);
            xfree(buf);
            break;
index 99f1a1056cb3c91cb1d1b80335585fceb56ddbec..cd05c7375af372c7c058836f983ea25fffdc0adc 100644 (file)
@@ -22,8 +22,9 @@
 #ifndef YASM_INTNUM_H
 #define YASM_INTNUM_H
 
+void intnum_initialize(errwarn *we);
 /* Clean up internal allocations */
-void intnum_shutdown(void);
+void intnum_cleanup(void);
 
 /*@only@*/ intnum *intnum_new_dec(char *str, unsigned long lindex);
 /*@only@*/ intnum *intnum_new_bin(char *str, unsigned long lindex);
index 718b01b9cb7e015283bd6dcbc7f6dc638c09b673..5bdbc7ae2e4f5dc5ef2b648d061a2cda70be94cc 100644 (file)
@@ -93,9 +93,12 @@ yasm_linemgr_set(const char *filename, unsigned long line,
 }
 
 static void
-yasm_linemgr_initialize(void)
+yasm_linemgr_initialize(/*@exits@*/
+                       void (*error_func) (const char *file,
+                                           unsigned int line,
+                                           const char *message))
 {
-    filename_table = HAMT_new();
+    filename_table = HAMT_new(error_func);
 
     line_index = 1;
 
index 85d474e0f5c9b4c55c32ea96aa100bda359dad68..0412df6fdd01e0081b1b62e41b910fb66c0fc851 100644 (file)
 
 struct linemgr {
     /* Initialize cur_lindex and any manager internal data structures. */
-    void (*initialize) (void);
+    void (*initialize) (/*@exits@*/
+                       void (*error_func) (const char *file,
+                                           unsigned int line,
+                                           const char *message));
 
     /* Cleans up any memory allocated by initialize. */
     void (*cleanup) (void);
index a63bc53feb99c8a40049bc82b7efeee12cd95a9f..b8689b13ed90b743cd057b25665bad8397e941de 100644 (file)
@@ -50,6 +50,9 @@
 /* YASM's line manager (for parse stage). */
 extern linemgr yasm_linemgr;
 
+/* YASM's errwarn handlers. */
+extern errwarn yasm_errwarn;
+
 /* Extra path to search for our modules. */
 #ifndef YASM_MODULE_PATH_ENV
 # define YASM_MODULE_PATH_ENV  "YASM_MODULE_PATH"
@@ -67,6 +70,7 @@ static int special_options = 0;
 /*@null@*/ /*@dependent@*/ static optimizer *cur_optimizer = NULL;
 /*@null@*/ /*@dependent@*/ static dbgfmt *cur_dbgfmt = NULL;
 static int preproc_only = 0;
+static int warning_error = 0;  /* warnings being treated as errors */
 
 /*@null@*/ /*@dependent@*/ static FILE *open_obj(const char *mode);
 static void cleanup(/*@null@*/ sectionhead *sections);
@@ -81,6 +85,9 @@ static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
 static int opt_warning_handler(char *cmd, /*@null@*/ char *param, int extra);
 static int preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra);
 
+static /*@only@*/ char *replace_extension(const char *orig, /*@null@*/
+                                         const char *ext, const char *def);
+
 /* values for special_options */
 #define SPECIAL_SHOW_HELP 0x01
 #define SPECIAL_SHOW_VERSION 0x02
@@ -102,15 +109,16 @@ static opt_option options[] =
 
 /* version message */
 /*@observer@*/ static const char *version_msg[] = {
-    N_("yasm " VERSION "\n"),
-    N_("Copyright (c) 2001-2002 Peter Johnson and other " PACKAGE " developers\n"),
+    PACKAGE " " VERSION "\n",
+    N_("Copyright (c) 2001-2002 Peter Johnson and other"), " " PACKAGE " ",
+    N_("developers.\n"),
     N_("This program is free software; you may redistribute it under the\n"),
     N_("terms of the GNU General Public License.  Portions of this program\n"),
     N_("are licensed under the GNU Lesser General Public License or the\n"),
     N_("3-clause BSD license; see individual file comments for details.\n"),
     N_("This program has absolutely no warranty; not even for\n"),
     N_("merchantibility or fitness for a particular purpose.\n"),
-    N_("Compiled on " __DATE__ ".\n"),
+    N_("Compiled on"), " " __DATE__ ".\n",
 };
 
 /* help messages */
@@ -144,6 +152,12 @@ main(int argc, char *argv[])
 #endif
     textdomain(PACKAGE);
 
+    /* Initialize errwarn handling */
+    yasm_errwarn.initialize();
+
+    /* Initialize memory allocation */
+    xalloc_initialize((void (*) (int))yasm_errwarn.fatal, FATAL_NOMEM);
+
     /* Set libltdl malloc/free functions. */
 #ifdef WITH_DMALLOC
     lt_dlmalloc = malloc;
@@ -166,7 +180,7 @@ main(int argc, char *argv[])
            errors = lt_dladdsearchdir(path);
     }
     if (errors != 0) {
-       ErrorNow(_("Module loader initialization failed"));
+       fprintf(stderr, _("Module loader initialization failed"));
        return EXIT_FAILURE;
     }
 
@@ -186,7 +200,7 @@ main(int argc, char *argv[])
 
     /* Initialize BitVector (needed for floating point). */
     if (BitVector_Boot() != ErrCode_Ok) {
-       ErrorNow(_("Could not initialize BitVector"));
+       fprintf(stderr, _("Could not initialize BitVector"));
        return EXIT_FAILURE;
     }
 
@@ -194,7 +208,7 @@ main(int argc, char *argv[])
        /* Open the input file (if not standard input) */
        in = fopen(in_filename, "rt");
        if (!in) {
-           ErrorNow(_("could not open file `%s'"), in_filename);
+           fprintf(stderr, _("could not open file `%s'"), in_filename);
            xfree(in_filename);
            if (obj_filename)
                xfree(obj_filename);
@@ -208,9 +222,16 @@ main(int argc, char *argv[])
     }
 
     /* Initialize line manager */
-    yasm_linemgr.initialize();
+    yasm_linemgr.initialize(yasm_errwarn.internal_error_);
     yasm_linemgr.set(in_filename, 1, 1);
 
+    /* Initialize intnum and floatnum */
+    intnum_initialize(&yasm_errwarn);
+    floatnum_initialize(&yasm_errwarn);
+
+    /* Initialize symbol table */
+    symrec_initialize(&yasm_errwarn);
+
     /* handle preproc-only case here */
     if (preproc_only) {
        char *preproc_buf = xmalloc(PREPROC_BUF_SIZE);
@@ -233,15 +254,14 @@ main(int argc, char *argv[])
            cur_preproc = load_preproc("yapp");
 
        if (!cur_preproc) {
-           ErrorNow(_("Could not load default preprocessor"));
+           fprintf(stderr, _("Could not load default preprocessor"));
            cleanup(NULL);
            return EXIT_FAILURE;
        }
 
        /* Pre-process until done */
-       cur_preproc->initialize(in, in_filename);
-       while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE,
-                                        &yasm_linemgr)) != 0)
+       cur_preproc->initialize(in, in_filename, &yasm_linemgr, &yasm_errwarn);
+       while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0)
            fwrite(preproc_buf, got, 1, obj);
 
        if (in != stdin)
@@ -250,8 +270,8 @@ main(int argc, char *argv[])
        if (obj != stdout)
            fclose(obj);
 
-       if (GetNumErrors() > 0) {
-           OutputAllErrorWarning(&yasm_linemgr);
+       if (yasm_errwarn.get_num_errors(warning_error) > 0) {
+           yasm_errwarn.output_all(&yasm_linemgr, warning_error);
            if (obj != stdout)
                remove(obj_filename);
            xfree(preproc_buf);
@@ -267,28 +287,30 @@ main(int argc, char *argv[])
     cur_arch = load_arch("x86");
 
     if (!cur_arch) {
-       ErrorNow(_("Could not load default architecture"));
+       fprintf(stderr, _("Could not load default architecture"));
        return EXIT_FAILURE;
     }
 
+    cur_arch->initialize(&yasm_errwarn);
+
     /* Set basic as the optimizer (TODO: user choice) */
     cur_optimizer = load_optimizer("basic");
 
     if (!cur_optimizer) {
-       ErrorNow(_("Could not load default optimizer"));
+       fprintf(stderr, _("Could not load default optimizer"));
        return EXIT_FAILURE;
     }
 
     arch_common_initialize(cur_arch);
-    expr_initialize(cur_arch);
-    bc_initialize(cur_arch);
+    expr_initialize(cur_arch, &yasm_errwarn);
+    bc_initialize(cur_arch, &yasm_errwarn);
 
     /* If not already specified, default to bin as the object format. */
     if (!cur_objfmt)
        cur_objfmt = load_objfmt("bin");
 
     if (!cur_objfmt) {
-       ErrorNow(_("Could not load default object format"));
+       fprintf(stderr, _("Could not load default object format"));
        return EXIT_FAILURE;
     }
 
@@ -305,8 +327,9 @@ main(int argc, char *argv[])
                           cur_dbgfmt->keyword) == 0)
                matched_dbgfmt = 1;
        if (!matched_dbgfmt) {
-           ErrorNow(_("`%s' is not a valid debug format for object format `%s'"),
-                    cur_dbgfmt->keyword, cur_objfmt->keyword);
+           fprintf(stderr,
+               _("`%s' is not a valid debug format for object format `%s'"),
+               cur_dbgfmt->keyword, cur_objfmt->keyword);
            if (in != stdin)
                fclose(in);
            cleanup(NULL);
@@ -315,7 +338,7 @@ main(int argc, char *argv[])
     }
 
     if (!cur_dbgfmt) {
-       ErrorNow(_("Could not load default debug format"));
+       fprintf(stderr, _("Could not load default debug format"));
        return EXIT_FAILURE;
     }
 
@@ -334,12 +357,12 @@ main(int argc, char *argv[])
     /* Initialize the object format */
     if (cur_objfmt->initialize)
        cur_objfmt->initialize(in_filename, obj_filename, cur_dbgfmt,
-                              cur_arch);
+                              cur_arch, &yasm_errwarn);
 
     /* Set NASM as the parser */
     cur_parser = load_parser("nasm");
     if (!cur_parser) {
-       ErrorNow(_("unrecognized parser `%s'"), "nasm");
+       fprintf(stderr, _("unrecognized parser `%s'"), "nasm");
        cleanup(NULL);
        return EXIT_FAILURE;
     }
@@ -357,8 +380,9 @@ main(int argc, char *argv[])
                           cur_preproc->keyword) == 0)
                matched_preproc = 1;
        if (!matched_preproc) {
-           ErrorNow(_("`%s' is not a valid preprocessor for parser `%s'"),
-                    cur_preproc->keyword, cur_parser->keyword);
+           fprintf(stderr,
+                   _("`%s' is not a valid preprocessor for parser `%s'"),
+                   cur_preproc->keyword, cur_parser->keyword);
            if (in != stdin)
                fclose(in);
            cleanup(NULL);
@@ -376,23 +400,24 @@ main(int argc, char *argv[])
 
     /* Parse! */
     sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt,
-                                   &yasm_linemgr, in, in_filename);
+                                   &yasm_linemgr, &yasm_errwarn, in,
+                                   in_filename);
 
     /* Close input file */
     if (in != stdin)
        fclose(in);
 
-    if (GetNumErrors() > 0) {
-       OutputAllErrorWarning(&yasm_linemgr);
+    if (yasm_errwarn.get_num_errors(warning_error) > 0) {
+       yasm_errwarn.output_all(&yasm_linemgr, warning_error);
        cleanup(sections);
        return EXIT_FAILURE;
     }
 
     symrec_parser_finalize();
-    cur_optimizer->optimize(sections);
+    cur_optimizer->optimize(sections, &yasm_errwarn);
 
-    if (GetNumErrors() > 0) {
-       OutputAllErrorWarning(&yasm_linemgr);
+    if (yasm_errwarn.get_num_errors(warning_error) > 0) {
+       yasm_errwarn.output_all(&yasm_linemgr, warning_error);
        cleanup(sections);
        return EXIT_FAILURE;
     }
@@ -416,14 +441,14 @@ main(int argc, char *argv[])
     /* If we had an error at this point, we also need to delete the output
      * object file (to make sure it's not left newer than the source).
      */
-    if (GetNumErrors() > 0) {
-       OutputAllErrorWarning(&yasm_linemgr);
+    if (yasm_errwarn.get_num_errors(warning_error) > 0) {
+       yasm_errwarn.output_all(&yasm_linemgr, warning_error);
        remove(obj_filename);
        cleanup(sections);
        return EXIT_FAILURE;
     }
 
-    OutputAllErrorWarning(&yasm_linemgr);
+    yasm_errwarn.output_all(&yasm_linemgr, warning_error);
 
     cleanup(sections);
     return EXIT_SUCCESS;
@@ -440,7 +465,7 @@ open_obj(const char *mode)
 
     obj = fopen(obj_filename, mode);
     if (!obj)
-       ErrorNow(_("could not open file `%s'"), obj_filename);
+       fprintf(stderr, _("could not open file `%s'"), obj_filename);
     return obj;
 }
 
@@ -450,13 +475,21 @@ cleanup(sectionhead *sections)
 {
     if (cur_objfmt && cur_objfmt->cleanup)
        cur_objfmt->cleanup();
+    if (cur_dbgfmt && cur_dbgfmt->cleanup)
+       cur_dbgfmt->cleanup();
+    if (cur_preproc)
+       cur_preproc->cleanup();
     if (sections)
        sections_delete(sections);
-    symrec_delete_all();
-    yasm_linemgr.cleanup();
+    symrec_cleanup();
+    if (cur_arch)
+       cur_arch->cleanup();
+
+    floatnum_cleanup();
+    intnum_cleanup();
 
-    floatnum_shutdown();
-    intnum_shutdown();
+    yasm_errwarn.cleanup();
+    yasm_linemgr.cleanup();
 
     BitVector_Shutdown();
 
@@ -478,7 +511,8 @@ int
 not_an_option_handler(char *param)
 {
     if (in_filename) {
-       WarningNow(_("can open only one input file, only the last file will be processed"));
+       fprintf(stderr,
+           _("warning: can open only one input file, only the last file will be processed"));
        xfree(in_filename);
     }
 
@@ -501,7 +535,7 @@ opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
     assert(param != NULL);
     cur_parser = load_parser(param);
     if (!cur_parser) {
-       ErrorNow(_("unrecognized parser `%s'"), param);
+       fprintf(stderr, _("unrecognized parser `%s'"), param);
        return 1;
     }
     return 0;
@@ -513,7 +547,7 @@ opt_preproc_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
     assert(param != NULL);
     cur_preproc = load_preproc(param);
     if (!cur_preproc) {
-       ErrorNow(_("unrecognized preprocessor `%s'"), param);
+       fprintf(stderr, _("unrecognized preprocessor `%s'"), param);
        return 1;
     }
     return 0;
@@ -525,7 +559,7 @@ opt_objfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
     assert(param != NULL);
     cur_objfmt = load_objfmt(param);
     if (!cur_objfmt) {
-       ErrorNow(_("unrecognized object format `%s'"), param);
+       fprintf(stderr, _("unrecognized object format `%s'"), param);
        return 1;
     }
     return 0;
@@ -537,7 +571,7 @@ opt_dbgfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
     assert(param != NULL);
     cur_dbgfmt = load_objfmt(param);
     if (!cur_dbgfmt) {
-       ErrorNow(_("unrecognized debugging format `%s'"), param);
+       fprintf(stderr, _("unrecognized debugging format `%s'"), param);
        return 1;
     }
     return 0;
@@ -548,7 +582,8 @@ opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
                    /*@unused@*/ int extra)
 {
     if (obj_filename) {
-       WarningNow(_("can output to only one object file, last specified used"));
+       fprintf(stderr,
+           _("warning: can output to only one object file, last specified used"));
        xfree(obj_filename);
     }
 
@@ -565,7 +600,7 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra)
 
     if (extra == 1) {
        /* -w, disable warnings */
-       warnings_disabled = 1;
+       yasm_errwarn.warn_disable_all();
        return 0;
     }
 
@@ -584,7 +619,10 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra)
     else if (strcmp(cmd, "error") == 0) {
        warning_error = enable;
     } else if (strcmp(cmd, "unrecognized-char") == 0) {
-       WARN_ENABLE(WARN_UNRECOGNIZED_CHAR, enable);
+       if (enable)
+           yasm_errwarn.warn_enable(WARN_UNREC_CHAR);
+       else
+           yasm_errwarn.warn_disable(WARN_UNREC_CHAR);
     } else
        return 1;
 
@@ -598,3 +636,58 @@ preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param,
     preproc_only = 1;
     return 0;
 }
+
+/* Replace extension on a filename (or append one if none is present).
+ * If output filename would be identical to input (same extension out as in),
+ * returns (copy of) def.
+ * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext
+ * means the trailing '.' should be included.
+ */
+static char *
+replace_extension(const char *orig, /*@null@*/ const char *ext,
+                 const char *def)
+{
+    char *out, *outext;
+
+    /* allocate enough space for full existing name + extension */
+    out = xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1));
+    strcpy(out, orig);
+    outext = strrchr(out, '.');
+    if (outext) {
+       /* Existing extension: make sure it's not the same as the replacement
+        * (as we don't want to overwrite the source file).
+        */
+       outext++;   /* advance past '.' */
+       if (ext && strcmp(outext, ext) == 0) {
+           outext = NULL;  /* indicate default should be used */
+           fprintf(stderr,
+               _("file name already ends in `.%s': output will be in `%s'"),
+               ext, def);
+       }
+    } else {
+       /* No extension: make sure the output extension is not empty
+        * (again, we don't want to overwrite the source file).
+        */
+       if (!ext)
+           fprintf(stderr,
+               _("file name already has no extension: output will be in `%s'"),
+               def);
+       else {
+           outext = strrchr(out, '\0');    /* point to end of the string */
+           *outext++ = '.';                /* append '.' */
+       }
+    }
+
+    /* replace extension or use default name */
+    if (outext) {
+       if (!ext) {
+           /* Back up and replace '.' with string terminator */
+           outext--;
+           *outext = '\0';
+       } else
+           strcpy(outext, ext);
+    } else
+       strcpy(out, def);
+
+    return out;
+}
index 55f7b9cc0030921b3e4e601f7780c6f5563b04dd..9735ae4ee7e631eda804484d33845549b343e823 100644 (file)
@@ -57,7 +57,7 @@ struct objfmt {
      * provided solely for informational purposes.
      */
     void (*initialize) (const char *in_filename, const char *obj_filename,
-                       dbgfmt *df, arch *a);
+                       dbgfmt *df, arch *a, errwarn *we);
 
     /* Write out (post-optimized) sections to the object file.
      * This function may call symrec functions as necessary (including
index 1ff0534cf2c0fd5d934bd71f58bad7d25a92ac64..d28bac1c942a751c6add40026743962566c04306 100644 (file)
 
 objfmt yasm_bin_LTX_objfmt;
 static /*@dependent@*/ arch *cur_arch;
+static /*@dependent@*/ errwarn *cur_we;
 
 
 static void
 bin_objfmt_initialize(/*@unused@*/ const char *in_filename,
                      /*@unused@*/ const char *obj_filename,
-                     /*@unused@*/ dbgfmt *df, arch *a)
+                     /*@unused@*/ dbgfmt *df, arch *a, errwarn *we)
 {
     cur_arch = a;
+    cur_we = we;
 }
 
 /* Aligns sect to either its specified alignment (in its objfmt-specific data)
@@ -163,13 +165,14 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
 
     /* Check for complex float expressions */
     if (expr_contains(*ep, EXPR_FLOAT)) {
-       Error((*ep)->line, _("floating point expression too complex"));
+       cur_we->error((*ep)->line,
+                     N_("floating point expression too complex"));
        return 1;
     }
 
     /* Couldn't output, assume it contains an external reference. */
-    Error((*ep)->line,
-         _("binary object format does not support external references"));
+    cur_we->error((*ep)->line,
+       N_("binary object format does not support external references"));
     return 1;
 }
 
@@ -198,8 +201,8 @@ bin_objfmt_output_bytecode(bytecode *bc, /*@null@*/ void *d)
     /* Warn that gaps are converted to 0 and write out the 0's. */
     if (gap) {
        unsigned long left;
-       Warning(bc->line,
-               _("uninitialized space declared in code/data section: zeroing"));
+       cur_we->warning(WARN_GENERAL, bc->line,
+           N_("uninitialized space declared in code/data section: zeroing"));
        /* Write out in chunks */
        memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
        left = multiple*size;
@@ -241,7 +244,7 @@ bin_objfmt_output(FILE *f, sectionhead *sections)
     bss = sections_find_general(sections, ".bss");
 
     if (!text)
-       InternalError(_("No `.text' section in bin objfmt output"));
+       cur_we->internal_error(N_("No `.text' section in bin objfmt output"));
 
     /* First determine the actual starting offsets for .data and .bss.
      * As the order in the file is .text -> .data -> .bss (not present),
@@ -255,7 +258,8 @@ bin_objfmt_output(FILE *f, sectionhead *sections)
     assert(startexpr != NULL);
     startnum = expr_get_intnum(&startexpr, NULL);
     if (!startnum)
-       InternalError(_("Complex expr for start in bin objfmt output"));
+       cur_we->internal_error(
+           N_("Complex expr for start in bin objfmt output"));
     start = intnum_get_uint(startnum);
     expr_delete(startexpr);
     textstart = start;
@@ -340,7 +344,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
            resonly = 1;
        } else {
            /* other section names not recognized. */
-           Error(lindex, _("segment name `%s' not recognized"), sectname);
+           cur_we->error(lindex, N_("segment name `%s' not recognized"),
+                         sectname);
            return NULL;
        }
 
@@ -351,16 +356,17 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                unsigned long bitcnt;
 
                if (strcmp(sectname, ".text") == 0) {
-                   Error(lindex,
-                         _("cannot specify an alignment to the `%s' section"),
-                         sectname);
+                   cur_we->error(lindex,
+                       N_("cannot specify an alignment to the `%s' section"),
+                       sectname);
                    return NULL;
                }
                
                align = expr_get_intnum(&vp->param, NULL);
                if (!align) {
-                   Error(lindex, _("argument to `%s' is not a power of two"),
-                         vp->val);
+                   cur_we->error(lindex,
+                                 N_("argument to `%s' is not a power of two"),
+                                 vp->val);
                    return NULL;
                }
                alignval = intnum_get_uint(align);
@@ -370,8 +376,9 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                 */
                BitCount(bitcnt, alignval);
                if (bitcnt > 1) {
-                   Error(lindex, _("argument to `%s' is not a power of two"),
-                         vp->val);
+                   cur_we->error(lindex,
+                                 N_("argument to `%s' is not a power of two"),
+                                 vp->val);
                    return NULL;
                }
 
@@ -380,7 +387,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
        }
 
        retval = sections_switch_general(headp, sectname, start, resonly,
-                                        &isnew, lindex);
+                                        &isnew, lindex,
+                                        cur_we->internal_error_);
 
        if (isnew) {
            if (have_alignval) {
@@ -391,8 +399,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
 
            symrec_define_label(sectname, retval, (bytecode *)NULL, 1, lindex);
        } else if (have_alignval)
-           Warning(lindex,
-                   _("alignment value ignored on section redeclaration"));
+           cur_we->warning(WARN_GENERAL, lindex,
+               N_("alignment value ignored on section redeclaration"));
 
        return retval;
     } else
@@ -411,7 +419,8 @@ bin_objfmt_common_declare(/*@unused@*/ symrec *sym, /*@only@*/ expr *size,
                          valparamhead *objext_valparams, unsigned long lindex)
 {
     expr_delete(size);
-    Error(lindex, _("binary object format does not support common variables"));
+    cur_we->error(lindex,
+       N_("binary object format does not support common variables"));
 }
 
 static int
@@ -428,20 +437,21 @@ bin_objfmt_directive(const char *name, valparamhead *valparams,
        /* ORG takes just a simple integer as param */
        vp = vps_first(valparams);
        if (vp->val) {
-           Error(lindex, _("argument to ORG should be numeric"));
+           cur_we->error(lindex, N_("argument to ORG should be numeric"));
            return 0;
        } else if (vp->param)
            start = expr_get_intnum(&vp->param, NULL);
 
        if (!start) {
-           Error(lindex, _("argument to ORG should be numeric"));
+           cur_we->error(lindex, N_("argument to ORG should be numeric"));
            return 0;
        }
 
        /* ORG changes the start of the .text section */
        sect = sections_find_general(headp, ".text");
        if (!sect)
-           InternalError(_("bin objfmt: .text section does not exist before ORG is called?"));
+           cur_we->internal_error(
+               N_("bin objfmt: .text section does not exist before ORG is called?"));
        section_set_start(sect, intnum_get_uint(start), lindex);
 
        return 0;           /* directive recognized */
index db6d30759fcd4b86c20a044ae7c4b63e38048177..c7c28432edb40ff57791a762b1df7670464c44c9 100644 (file)
@@ -158,6 +158,7 @@ static coff_symtab_head coff_symtab;            /* symbol table of indexed syms */
 
 objfmt yasm_coff_LTX_objfmt;
 static /*@dependent@*/ arch *cur_arch;
+static /*@dependent@*/ errwarn *cur_we;
 
 
 static /*@dependent@*/ coff_symtab_entry *
@@ -170,7 +171,7 @@ coff_objfmt_symtab_append(symrec *sym, coff_symrec_sclass sclass,
     coff_symtab_entry *entry;
 
     if (STAILQ_EMPTY(&coff_symtab))
-       InternalError(_("empty COFF symbol table"));
+       cur_we->internal_error(N_("empty COFF symbol table"));
     entry = STAILQ_LAST(&coff_symtab, coff_symtab_entry, link);
     sym_data_prev = symrec_get_of_data(entry->sym);
     assert(sym_data_prev != NULL);
@@ -194,13 +195,14 @@ coff_objfmt_symtab_append(symrec *sym, coff_symrec_sclass sclass,
 static void
 coff_objfmt_initialize(const char *in_filename,
                       /*@unused@*/ const char *obj_filename,
-                      /*@unused@*/ dbgfmt *df, arch *a)
+                      /*@unused@*/ dbgfmt *df, arch *a, errwarn *we)
 {
     symrec *filesym;
     coff_symrec_data *data;
     coff_symtab_entry *entry;
 
     cur_arch = a;
+    cur_we = we;
 
     coff_objfmt_parse_scnum = 1;    /* section numbering starts at 1 */
     STAILQ_INIT(&coff_symtab);
@@ -273,7 +275,7 @@ coff_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
        SymVisibility vis;
 
        if (valsize != 4) {
-           Error((*ep)->line, _("coff: invalid relocation size"));
+           cur_we->error((*ep)->line, N_("coff: invalid relocation size"));
            return 1;
        }
 
@@ -326,11 +328,12 @@ coff_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
 
     /* Check for complex float expressions */
     if (expr_contains(*ep, EXPR_FLOAT)) {
-       Error((*ep)->line, _("floating point expression too complex"));
+       cur_we->error((*ep)->line,
+                     N_("floating point expression too complex"));
        return 1;
     }
 
-    Error((*ep)->line, _("coff: relocation too complex"));
+    cur_we->error((*ep)->line, N_("coff: relocation too complex"));
     return 1;
 }
 
@@ -361,8 +364,8 @@ coff_objfmt_output_bytecode(bytecode *bc, /*@null@*/ void *d)
     /* Warn that gaps are converted to 0 and write out the 0's. */
     if (gap) {
        unsigned long left;
-       Warning(bc->line,
-               _("uninitialized space declared in code/data section: zeroing"));
+       cur_we->warning(WARN_GENERAL, bc->line,
+           N_("uninitialized space declared in code/data section: zeroing"));
        /* Write out in chunks */
        memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
        left = multiple*size;
@@ -414,7 +417,7 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d)
     } else {
        pos = ftell(info->f);
        if (pos == -1) {
-           ErrorNow(_("could not get file position on output file"));
+           cur_we->error(0, N_("could not get file position on output file"));
            return 1;
        }
 
@@ -437,7 +440,7 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d)
 
     pos = ftell(info->f);
     if (pos == -1) {
-       ErrorNow(_("could not get file position on output file"));
+       cur_we->error(0, N_("could not get file position on output file"));
        return 1;
     }
     csd->relptr = (unsigned long)pos;
@@ -448,7 +451,8 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d)
 
        csymd = symrec_get_of_data(reloc->sym);
        if (!csymd)
-           InternalError(_("coff: no symbol data for relocated symbol"));
+           cur_we->internal_error(
+               N_("coff: no symbol data for relocated symbol"));
 
        WRITE_32_L(localbuf, reloc->addr);  /* address of relocation */
        WRITE_32_L(localbuf, csymd->index); /* relocated symbol */
@@ -487,8 +491,9 @@ coff_objfmt_output_secthead(section *sect, /*@null@*/ void *d)
     WRITE_32_L(localbuf, csd->relptr); /* file ptr to relocs */
     WRITE_32_L(localbuf, 0);           /* file ptr to line nums */
     if (csd->nreloc >= 64*1024) {
-       WarningNow(_("too many relocations in section `%s'"),
-                  section_get_name(sect));
+       cur_we->warning(WARN_GENERAL, 0,
+                       N_("too many relocations in section `%s'"),
+                       section_get_name(sect));
        WRITE_16_L(localbuf, 0xFFFF);       /* max out */
     } else
        WRITE_16_L(localbuf, csd->nreloc);  /* number of relocation entries */
@@ -515,7 +520,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
 
     /* Allocate space for headers by seeking forward */
     if (fseek(f, 20+40*(coff_objfmt_parse_scnum-1), SEEK_SET) < 0) {
-       ErrorNow(_("could not seek on output file"));
+       cur_we->error(0, N_("could not seek on output file"));
        return;
     }
 
@@ -537,7 +542,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
     /* Symbol table */
     pos = ftell(f);
     if (pos == -1) {
-       ErrorNow(_("could not get file position on output file"));
+       cur_we->error(0, N_("could not get file position on output file"));
        return;
     }
     symtab_pos = (unsigned long)pos;
@@ -556,7 +561,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
        /* Get symrec's of_data (needed for storage class) */
        csymd = symrec_get_of_data(entry->sym);
        if (!csymd)
-           InternalError(_("coff: expected sym data to be present"));
+           cur_we->internal_error(
+               N_("coff: expected sym data to be present"));
 
        /* Look at symrec for value/scnum/etc. */
        if (symrec_get_label(entry->sym, &sect, &precbc)) {
@@ -580,8 +586,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
                const intnum *intn;
                intn = expr_get_intnum(&csymd->size, common_calc_bc_dist);
                if (!intn)
-                   Error(csymd->size->line,
-                         _("COMMON data size not an integer expression"));
+                   cur_we->error(csymd->size->line,
+                       N_("COMMON data size not an integer expression"));
                else
                    value = intnum_get_uint(intn);
                scnum = 0;
@@ -627,7 +633,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
                        strncpy((char *)localbuf, entry->aux[0].fname, 14);
                    break;
                default:
-                   InternalError(_("coff: unrecognized aux symtab type"));
+                   cur_we->internal_error(
+                       N_("coff: unrecognized aux symtab type"));
            }
            fwrite(info.buf, 18, 1, f);
            symtab_count++;
@@ -659,7 +666,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections)
 
     /* Write headers */
     if (fseek(f, 0, SEEK_SET) < 0) {
-       ErrorNow(_("could not seek on output file"));
+       cur_we->error(0, N_("could not seek on output file"));
        return;
     }
 
@@ -713,8 +720,8 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
 
     sectname = vp->val;
     if (strlen(sectname) > 8) {
-       Warning(lindex,
-               _("COFF section names limited to 8 characters: truncating"));
+       cur_we->warning(WARN_GENERAL, lindex,
+           N_("COFF section names limited to 8 characters: truncating"));
        sectname[8] = '\0';
     }
 
@@ -742,7 +749,7 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
     }
 
     retval = sections_switch_general(headp, sectname, 0, resonly, &isnew,
-                                    lindex);
+                                    lindex, cur_we->internal_error_);
 
     if (isnew) {
        coff_section_data *data;
@@ -765,7 +772,8 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                                  COFF_SYMTAB_AUX_SECT);
        data->sym = sym;
     } else if (flags_override)
-       Warning(lindex, _("section flags ignored on section redeclaration"));
+       cur_we->warning(WARN_GENERAL, lindex,
+                       N_("section flags ignored on section redeclaration"));
     return retval;
 }
 
index 3b10a44234f1785f891ceaf5ec828efa59e52a81..5f2233ab3583e2134ceb062cbe30887ee1162ce2 100644 (file)
@@ -46,14 +46,17 @@ objfmt yasm_dbg_LTX_objfmt;
  */
 static FILE *dbg_objfmt_file;
 
+static /*@dependent@*/ errwarn *cur_we;
 
 static void
 dbg_objfmt_initialize(const char *in_filename, const char *obj_filename,
-                     dbgfmt *df, arch *a)
+                     dbgfmt *df, arch *a, errwarn *we)
 {
+    cur_we = we;
+
     dbg_objfmt_file = fopen(obj_filename, "wt");
     if (!dbg_objfmt_file) {
-       ErrorNow(_("could not open file `%s'"), obj_filename);
+       fprintf(stderr, N_("could not open file `%s'"), obj_filename);
        return;
     }
     fprintf(dbg_objfmt_file,
@@ -95,7 +98,7 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
 
     if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
        retval = sections_switch_general(headp, vp->val, 200, 0, &isnew,
-                                        lindex);
+                                        lindex, cur_we->internal_error_);
        if (isnew) {
            fprintf(dbg_objfmt_file, "(new) ");
            symrec_define_label(vp->val, retval, (bytecode *)NULL, 1, lindex);
index 56c907200aff4bf4140efcd9a89d5295342dd6a0..44c6a124ac8d93d2437b7b568854a78502337eea 100644 (file)
@@ -37,7 +37,7 @@ struct optimizer {
      * object file.  (A failure is indicated by calling ErrorAt() from within
      * this function).
      */
-    void (*optimize) (sectionhead *sections);
+    void (*optimize) (sectionhead *sections, errwarn *we);
 };
 
 #endif
index 5c654b7de9e2ab37efd273bcd01b2af73714b1cc..1b87423c28d21102a1f597e0e3abc02b459dd6bd 100644 (file)
@@ -43,6 +43,8 @@
 #define BCFLAG_INPROGRESS      (1UL<<0)
 #define BCFLAG_DONE            (1UL<<1)
 
+static /*@dependent@*/ errwarn *cur_we;
+
 static int basic_optimize_section_1(section *sect,
                                    /*@unused@*/ /*@null@*/ void *d);
 
@@ -129,7 +131,7 @@ basic_optimize_bytecode_1(/*@observer@*/ bytecode *bc, void *d)
     bcr_retval = bc_resolve(bc, 0, data->sect, basic_optimize_calc_bc_dist_1);
     if (bcr_retval & BC_RESOLVE_UNKNOWN_LEN) {
        if (!(bcr_retval & BC_RESOLVE_ERROR))
-           Error(bc->line, _("circular reference detected."));
+           cur_we->error(bc->line, N_("circular reference detected."));
        data->saw_unknown = -1;
        return 0;
     }
@@ -181,7 +183,7 @@ basic_optimize_bytecode_2(/*@observer@*/ bytecode *bc, /*@null@*/ void *d)
     assert(data != NULL);
 
     if (bc->opt_flags != BCFLAG_DONE)
-       InternalError(_("Optimizer pass 1 missed a bytecode!"));
+       cur_we->internal_error(N_("Optimizer pass 1 missed a bytecode!"));
 
     if (!data->precbc)
        bc->offset = 0;
@@ -203,17 +205,19 @@ basic_optimize_section_2(section *sect, /*@unused@*/ /*@null@*/ void *d)
     data.sect = sect;
 
     if (section_get_opt_flags(sect) != SECTFLAG_DONE)
-       InternalError(_("Optimizer pass 1 missed a section!"));
+       cur_we->internal_error(N_("Optimizer pass 1 missed a section!"));
 
     return bcs_traverse(section_get_bytecodes(sect), &data,
                        basic_optimize_bytecode_2);
 }
 
 static void
-basic_optimize(sectionhead *sections)
+basic_optimize(sectionhead *sections, errwarn *we)
 {
     int saw_unknown = 0;
 
+    cur_we = we;
+
     /* Optimization process: (essentially NASM's pass 1)
      *  Determine the size of all bytecodes.
      *  Forward references are /not/ resolved (only backward references are
index 9b4c7faa951108979295925297ea019b499ea197..f48dfb4e1ea5dfeff9e8a2b40b51115da434c0fe 100644 (file)
@@ -67,9 +67,9 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts)
                        if (options[i].takes_param) {
                            param = strchr(&argv[0][2], '=');
                            if (!param) {
-                               ErrorNow(_
-                                        ("option '--%s' needs an argument!"),
-                                        options[i].lopt);
+                               fprintf(stderr,
+                                       _("option '--%s' needs an argument!"),
+                                       options[i].lopt);
                                errors++;
                                goto fail;
                            } else {
@@ -86,7 +86,7 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts)
                    }
                }
                if (!got_it) {
-                   ErrorNow(_("unrecognized option '%s'"), argv[0]);
+                   fprintf(stderr, _("unrecognized option '%s'"), argv[0]);
                    errors++;
                }
            } else {            /* sopt */
@@ -101,8 +101,9 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts)
                            if (argv[0][2] != '\0')
                                param = &argv[0][2];
                            else if (param == NULL || *param == '-') {
-                               ErrorNow(_("option '-%c' needs an argument!"),
-                                        options[i].sopt);
+                               fprintf(stderr,
+                                       _("option '-%c' needs an argument!"),
+                                       options[i].sopt);
                                errors++;
                                goto fail;
                            } else {
@@ -118,7 +119,7 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts)
                    }
                }
                if (!got_it) {
-                   ErrorNow(_("unrecognized option '%s'"), argv[0]);
+                   fprintf(stderr, _("unrecognized option '%s'"), argv[0]);
                    errors++;
                }
            }
index 01b0db32a7d7a2b211eba4421c2d4602b15c4f6a..c2e606ff0f26930f503e72a342b77860bb211f23 100644 (file)
@@ -51,7 +51,7 @@ struct parser {
      * (whatever was in the file).
      */
     sectionhead *(*do_parse) (preproc *pp, arch *a, objfmt *of, linemgr *lm,
-                             FILE *f, const char *in_filename);
+                             errwarn *we, FILE *f, const char *in_filename);
 };
 
 /* Generic functions for all parsers - implemented in src/parser.c */
index 7cfd19547e63d9f9f8b58bc8f0e6c68c2e20a70f..80df154dbeceee650b79afdc07d36fa0fc98fa6f 100644 (file)
@@ -3,6 +3,7 @@
 lib_LTLIBRARIES += yasm-nasm.la
 
 yasm_nasm_la_SOURCES = \
+       src/parsers/nasm/nasm-parser.h          \
        src/parsers/nasm/nasm-parser.c          \
        src/parsers/nasm/nasm-defs.h            \
        src/parsers/nasm/nasm-bison.y           \
index 996ef57467370bb8408ec20b74a95c81d1d2d52e..c8e41db36e8951e4e9595c1a615e68a560f23f5c 100644 (file)
@@ -42,32 +42,14 @@ RCSID("$IdPath$");
 
 #include "arch.h"
 
+#include "src/parsers/nasm/nasm-parser.h"
 #include "src/parsers/nasm/nasm-defs.h"
 
 
-void init_table(void);
-extern int nasm_parser_lex(void);
-extern void nasm_parser_set_directive_state(void);
-void nasm_parser_error(const char *);
-static void nasm_parser_directive(const char *name,
-                                 valparamhead *valparams,
+static void nasm_parser_error(const char *);
+static void nasm_parser_directive(const char *name, valparamhead *valparams,
                                  /*@null@*/ valparamhead *objext_valparams);
 
-extern objfmt *nasm_parser_objfmt;
-extern sectionhead nasm_parser_sections;
-extern section *nasm_parser_cur_section;
-extern char *nasm_parser_locallabel_base;
-extern size_t nasm_parser_locallabel_base_len;
-extern /*@dependent@*/ arch *nasm_parser_arch;
-extern /*@dependent@*/ objfmt *nasm_parser_objfmt;
-extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
-
-#define p_line_index   (nasm_parser_linemgr->get_current())
-
-#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,p_line_index)
-#define p_expr_new_branch(o,r) expr_new_branch(o,r,p_line_index)
-#define p_expr_new_ident(r)    expr_new_ident(r,p_line_index)
-
 static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
 static bytecode *nasm_parser_temp_bc;
 
@@ -162,8 +144,8 @@ line: '\n'          { $$ = (bytecode *)NULL; }
        $$ = (bytecode *)NULL;
     }
     | error '\n'       {
-       Error(p_line_index,
-             _("label or instruction expected at start of line"));
+       cur_we->error(cur_lindex,
+                     N_("label or instruction expected at start of line"));
        $$ = (bytecode *)NULL;
        yyerrok;
     }
@@ -175,7 +157,7 @@ lineexp: exp
     | label exp                                { $$ = $2; }
     | label TIMES expr exp             { $$ = $4; bc_set_multiple($$, $3); }
     | label_id_equ EQU expr            {
-       symrec_define_equ($1, $3, p_line_index);
+       symrec_define_equ($1, $3, cur_lindex);
        xfree($1);
        $$ = (bytecode *)NULL;
     }
@@ -183,47 +165,45 @@ lineexp: exp
 
 exp: instr
     | DECLARE_DATA datavals            {
-       $$ = bc_new_data(&$2, $1, p_line_index);
+       $$ = bc_new_data(&$2, $1, cur_lindex);
     }
     | RESERVE_SPACE expr               {
-       $$ = bc_new_reserve($2, $1, p_line_index);
+       $$ = bc_new_reserve($2, $1, cur_lindex);
     }
     | INCBIN STRING                    {
-       $$ = bc_new_incbin($2, NULL, NULL, p_line_index);
+       $$ = bc_new_incbin($2, NULL, NULL, cur_lindex);
     }
     | INCBIN STRING ',' expr           {
-       $$ = bc_new_incbin($2, $4, NULL, p_line_index);
+       $$ = bc_new_incbin($2, $4, NULL, cur_lindex);
     }
     | INCBIN STRING ',' expr ',' expr  {
-       $$ = bc_new_incbin($2, $4, $6, p_line_index);
+       $$ = bc_new_incbin($2, $4, $6, cur_lindex);
     }
 ;
 
 instr: INSN            {
        $$ = nasm_parser_arch->parse.new_insn($1, 0, NULL,
                                              nasm_parser_cur_section,
-                                             nasm_parser_prev_bc,
-                                             p_line_index);
+                                             nasm_parser_prev_bc, cur_lindex);
     }
     | INSN operands    {
        $$ = nasm_parser_arch->parse.new_insn($1, $2.num_operands,
                                              &$2.operands,
                                              nasm_parser_cur_section,
-                                             nasm_parser_prev_bc,
-                                             p_line_index);
+                                             nasm_parser_prev_bc, cur_lindex);
        ops_delete(&$2.operands, 0);
     }
     | INSN error       {
-       Error(p_line_index, _("expression syntax error"));
+       cur_we->error(cur_lindex, N_("expression syntax error"));
        $$ = NULL;
     }
     | PREFIX instr     {
        $$ = $2;
-       nasm_parser_arch->parse.handle_prefix($$, $1, p_line_index);
+       nasm_parser_arch->parse.handle_prefix($$, $1, cur_lindex);
     }
     | SEGREG instr     {
        $$ = $2;
-       nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], p_line_index);
+       nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], cur_lindex);
     }
 ;
 
@@ -234,19 +214,19 @@ datavals: dataval     { dvs_initialize(&$$); dvs_append(&$$, $1); }
 dataval: dvexpr                { $$ = dv_new_expr($1); }
     | STRING           { $$ = dv_new_string($1); }
     | error            {
-       Error(p_line_index, _("expression syntax error"));
+       cur_we->error(cur_lindex, N_("expression syntax error"));
        $$ = (dataval *)NULL;
     }
 ;
 
 label: label_id            {
        symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
-                           1, p_line_index);
+                           1, cur_lindex);
        xfree($1);
     }
     | label_id ':'  {
        symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
-                           1, p_line_index);
+                           1, cur_lindex);
        xfree($1);
     }
 ;
@@ -274,7 +254,7 @@ directive: DIRECTIVE_NAME directive_val     {
        xfree($1);
     }
     | DIRECTIVE_NAME error             {
-       Error(p_line_index, _("invalid arguments to [%s]"), $1);
+       cur_we->error(cur_lindex, N_("invalid arguments to [%s]"), $1);
        xfree($1);
     }
 ;
@@ -318,7 +298,7 @@ memaddr: expr                   {
     }
     | SEGREG ':' memaddr    {
        $$ = $3;
-       nasm_parser_arch->parse.handle_seg_override($$, $1[0], p_line_index);
+       nasm_parser_arch->parse.handle_seg_override($$, $1[0], cur_lindex);
     }
     | BYTE memaddr         { $$ = $2; ea_set_len($$, 1); }
     | WORD memaddr         { $$ = $2; ea_set_len($$, 2); }
@@ -346,7 +326,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 1)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 1;
     }
@@ -354,7 +334,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 2)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 2;
     }
@@ -362,7 +342,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 4)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 4;
     }
@@ -370,7 +350,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 8)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 8;
     }
@@ -378,7 +358,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 10)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 10;
     }
@@ -386,7 +366,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
        $$ = $2;
        if ($$->type == INSN_OPERAND_REG &&
            nasm_parser_arch->get_reg_size($$->data.reg) != 16)
-           Error(p_line_index, _("cannot override register size"));
+           cur_we->error(cur_lindex, N_("cannot override register size"));
        else
            $$->size = 16;
     }
@@ -399,7 +379,7 @@ operand: '[' memaddr ']'    { $$ = operand_new_mem($2); }
 direxpr: INTNUM                        { $$ = p_expr_new_ident(ExprInt($1)); }
     | ID                       {
        $$ = p_expr_new_ident(ExprSym(symrec_define_label($1, NULL, NULL, 0,
-                                                         p_line_index)));
+                                                         cur_lindex)));
        xfree($1);
     }
     | direxpr '|' direxpr      { $$ = p_expr_new_tree($1, EXPR_OR, $3); }
@@ -460,7 +440,7 @@ expr: INTNUM                        { $$ = p_expr_new_ident(ExprInt($1)); }
     | REG                      { $$ = p_expr_new_ident(ExprReg($1[0])); }
     | STRING                   {
        $$ = p_expr_new_ident(ExprInt(intnum_new_charconst_nasm($1,
-                                                               p_line_index)));
+                                                               cur_lindex)));
        xfree($1);
     }
     | explabel                 { $$ = p_expr_new_ident(ExprSym($1)); }
@@ -495,26 +475,26 @@ expr: INTNUM                      { $$ = p_expr_new_ident(ExprInt($1)); }
 ;
 
 explabel: ID           {
-       $$ = symrec_use($1, p_line_index);
+       $$ = symrec_use($1, cur_lindex);
        xfree($1);
     }
     | SPECIAL_ID       {
-       $$ = symrec_use($1, p_line_index);
+       $$ = symrec_use($1, cur_lindex);
        xfree($1);
     }
     | LOCAL_ID         {
-       $$ = symrec_use($1, p_line_index);
+       $$ = symrec_use($1, cur_lindex);
        xfree($1);
     }
     | '$'              {
        /* "$" references the current assembly position */
        $$ = symrec_define_label("$", nasm_parser_cur_section,
-                                nasm_parser_prev_bc, 0, p_line_index);
+                                nasm_parser_prev_bc, 0, cur_lindex);
     }
     | START_SECTION_ID {
        /* "$$" references the start of the current section */
        $$ = symrec_define_label("$$", nasm_parser_cur_section, NULL, 0,
-                                p_line_index);
+                                cur_lindex);
     }
 ;
 
@@ -527,7 +507,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
 {
     valparam *vp, *vp2;
     symrec *sym;
-    unsigned long lindex = p_line_index;
+    unsigned long lindex = cur_lindex;
 
     /* Handle (mostly) output-format independent directives here */
     if (strcasecmp(name, "extern") == 0) {
@@ -538,7 +518,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
                nasm_parser_objfmt->extern_declare(sym, objext_valparams,
                                                   lindex);
        } else
-           Error(lindex, _("invalid argument to [%s]"), "EXTERN");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "EXTERN");
     } else if (strcasecmp(name, "global") == 0) {
        vp = vps_first(valparams);
        if (vp->val) {
@@ -547,14 +527,15 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
                nasm_parser_objfmt->global_declare(sym, objext_valparams,
                                                   lindex);
        } else
-           Error(lindex, _("invalid argument to [%s]"), "GLOBAL");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "GLOBAL");
     } else if (strcasecmp(name, "common") == 0) {
        vp = vps_first(valparams);
        if (vp->val) {
            vp2 = vps_next(vp);
            if (!vp2 || (!vp2->val && !vp2->param))
-               Error(lindex, _("no size specified in %s declaration"),
-                     "COMMON");
+               cur_we->error(lindex,
+                             N_("no size specified in %s declaration"),
+                             "COMMON");
            else {
                if (vp2->val) {
                    sym = symrec_declare(vp->val, SYM_COMMON, lindex);
@@ -573,7 +554,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
                }
            }
        } else
-           Error(lindex, _("invalid argument to [%s]"), "COMMON");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "COMMON");
     } else if (strcasecmp(name, "section") == 0 ||
               strcasecmp(name, "segment") == 0) {
        section *new_section =
@@ -584,17 +565,19 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
            nasm_parser_cur_section = new_section;
            nasm_parser_prev_bc = bcs_last(section_get_bytecodes(new_section));
        } else
-           Error(lindex, _("invalid argument to [%s]"), "SECTION");
+           cur_we->error(lindex, N_("invalid argument to [%s]"), "SECTION");
     } else if (strcasecmp(name, "absolute") == 0) {
        /* it can be just an ID or a complete expression, so handle both. */
        vp = vps_first(valparams);
        if (vp->val)
            nasm_parser_cur_section =
                sections_switch_absolute(&nasm_parser_sections,
-                   p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex))));
+                   p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex))),
+                   cur_we->internal_error_);
        else if (vp->param) {
            nasm_parser_cur_section =
-               sections_switch_absolute(&nasm_parser_sections, vp->param);
+               sections_switch_absolute(&nasm_parser_sections, vp->param,
+                                        cur_we->internal_error_);
            vp->param = NULL;
        }
        nasm_parser_prev_bc = (bytecode *)NULL;
@@ -606,7 +589,8 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
                const intnum *intcpu;
                intcpu = expr_get_intnum(&vp->param, NULL);
                if (!intcpu)
-                   Error(lindex, _("invalid argument to [%s]"), "CPU");
+                   cur_we->error(lindex, N_("invalid argument to [%s]"),
+                                 "CPU");
                else {
                    char strcpu[16];
                    sprintf(strcpu, "%lu", intnum_get_uint(intcpu));
@@ -621,7 +605,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
        ;
     } else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams,
                                             &nasm_parser_sections, lindex)) {
-       Error(lindex, _("unrecognized directive [%s]"), name);
+       cur_we->error(lindex, N_("unrecognized directive [%s]"), name);
     }
 
     vps_delete(valparams);
@@ -629,9 +613,9 @@ nasm_parser_directive(const char *name, valparamhead *valparams,
        vps_delete(objext_valparams);
 }
 
-void
+static void
 nasm_parser_error(const char *s)
 {
-    ParserError(p_line_index, s);
+    cur_we->parser_error(cur_lindex, s);
 }
 
index bb78777c1472019737dc5c118d353212390b4d01..a38a28d1b121eb10f3e2243f11d2bfbd0986071a 100644 (file)
 #include "preproc.h"
 #include "parser.h"
 
+#include "nasm-parser.h"
 
-extern FILE *nasm_parser_in;
-extern int nasm_parser_debug;
 
-extern int nasm_parser_parse(void);
-extern void nasm_parser_cleanup(void);
-
-size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm);
+FILE *nasm_parser_in = NULL;
+size_t (*nasm_parser_input) (char *buf, size_t max_size);
 
 sectionhead nasm_parser_sections;
 /*@dependent@*/ section *nasm_parser_cur_section;
 
-extern /*@only@*/ char *nasm_parser_locallabel_base;
+/* last "base" label for local (.) labels */
+char *nasm_parser_locallabel_base = (char *)NULL;
+size_t nasm_parser_locallabel_base_len = 0;
 
 /*@dependent@*/ arch *nasm_parser_arch;
 /*@dependent@*/ objfmt *nasm_parser_objfmt;
 /*@dependent@*/ linemgr *nasm_parser_linemgr;
+/*@dependent@*/ errwarn *nasm_parser_errwarn;
 
 static /*@dependent@*/ sectionhead *
-nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm, FILE *f,
-                    const char *in_filename)
+nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm,
+                    errwarn *we, FILE *f, const char *in_filename)
     /*@globals killed nasm_parser_locallabel_base @*/
 {
-    pp->initialize(f, in_filename);
+    pp->initialize(f, in_filename, lm, we);
     nasm_parser_in = f;
     nasm_parser_input = pp->input;
     nasm_parser_arch = a;
     nasm_parser_objfmt = of;
     nasm_parser_linemgr = lm;
+    nasm_parser_errwarn = we;
 
     /* Initialize section list */
     nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of);
diff --git a/src/parsers/nasm/nasm-parser.h b/src/parsers/nasm/nasm-parser.h
new file mode 100644 (file)
index 0000000..f0b63c7
--- /dev/null
@@ -0,0 +1,53 @@
+/* $IdPath$
+ * NASM-compatible parser header file
+ *
+ *  Copyright (C) 2002  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef YASM_NASM_PARSER_H
+#define YASM_NASM_PARSER_H
+
+int nasm_parser_parse(void);
+void nasm_parser_cleanup(void);
+int nasm_parser_lex(void);
+void nasm_parser_set_directive_state(void);
+
+extern FILE *nasm_parser_in;
+extern int nasm_parser_debug;
+extern size_t (*nasm_parser_input) (char *buf, size_t max_size);
+
+extern sectionhead nasm_parser_sections;
+extern /*@dependent@*/ section *nasm_parser_cur_section;
+
+extern char *nasm_parser_locallabel_base;
+extern size_t nasm_parser_locallabel_base_len;
+
+extern /*@dependent@*/ arch *nasm_parser_arch;
+extern /*@dependent@*/ objfmt *nasm_parser_objfmt;
+extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
+extern /*@dependent@*/ errwarn *nasm_parser_errwarn;
+
+#define cur_lindex     (nasm_parser_linemgr->get_current())
+
+#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,cur_lindex)
+#define p_expr_new_branch(o,r) expr_new_branch(o,r,cur_lindex)
+#define p_expr_new_ident(r)    expr_new_ident(r,cur_lindex)
+
+#define cur_we         nasm_parser_errwarn
+
+#endif
index fc1dd26a1b189ae62f64ec3143e1cf62aed792ae..46daee4ce4c48c31518d68d9acf13ac952ac5700 100644 (file)
@@ -37,6 +37,7 @@ RCSID("$IdPath$");
 
 #include "arch.h"
 
+#include "src/parsers/nasm/nasm-parser.h"
 #include "src/parsers/nasm/nasm-defs.h"
 #include "nasm-bison.h"
 
@@ -59,17 +60,6 @@ RCSID("$IdPath$");
 
 #define TOKLEN         (cursor-s.tok)
 
-void nasm_parser_cleanup(void);
-void nasm_parser_set_directive_state(void);
-int nasm_parser_lex(void);
-
-extern size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm);
-extern /*@dependent@*/ arch *nasm_parser_arch;
-extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
-
-#define p_line_index   (nasm_parser_linemgr->get_current())
-
-
 typedef struct Scanner {
     YYCTYPE            *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
     unsigned int       tchar, tline, cline;
@@ -77,8 +67,6 @@ typedef struct Scanner {
 
 static Scanner s = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1 };
 
-FILE *nasm_parser_in = NULL;
-
 static YYCTYPE *
 fill(YYCTYPE *cursor)
 {
@@ -105,8 +93,7 @@ fill(YYCTYPE *cursor)
                xfree(s.bot);
            s.bot = buf;
        }
-       if((cnt = nasm_parser_input(s.lim, BSIZE,
-                                   nasm_parser_linemgr)) != BSIZE){
+       if((cnt = nasm_parser_input(s.lim, BSIZE)) != BSIZE){
            s.eof = &s.lim[cnt]; *s.eof++ = '\n';
        }
        s.lim += cnt;
@@ -130,10 +117,6 @@ static char *strbuf = (char *)NULL;
 /* length of strbuf (including terminating NULL character) */
 static size_t strbuf_size = 0;
 
-/* last "base" label for local (.) labels */
-char *nasm_parser_locallabel_base = (char *)NULL;
-size_t nasm_parser_locallabel_base_len = 0;
-
 static int linechg_numcount;
 
 /*!re2c
@@ -220,7 +203,7 @@ scan:
        digit+ {
            savech = s.tok[TOKLEN];
            s.tok[TOKLEN] = '\0';
-           yylval.intn = intnum_new_dec(s.tok, p_line_index);
+           yylval.intn = intnum_new_dec(s.tok, cur_lindex);
            s.tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
@@ -228,21 +211,21 @@ scan:
 
        bindigit+ "b" {
            s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */
-           yylval.intn = intnum_new_bin(s.tok, p_line_index);
+           yylval.intn = intnum_new_bin(s.tok, cur_lindex);
            RETURN(INTNUM);
        }
 
        /* 777q - octal number */
        octdigit+ "q" {
            s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */
-           yylval.intn = intnum_new_oct(s.tok, p_line_index);
+           yylval.intn = intnum_new_oct(s.tok, cur_lindex);
            RETURN(INTNUM);
        }
 
        /* 0AAh form of hexidecimal number */
        digit hexdigit* "h" {
            s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */
-           yylval.intn = intnum_new_hex(s.tok, p_line_index);
+           yylval.intn = intnum_new_hex(s.tok, cur_lindex);
            RETURN(INTNUM);
        }
 
@@ -252,10 +235,10 @@ scan:
            s.tok[TOKLEN] = '\0';
            if (s.tok[1] == 'x')
                /* skip 0 and x */
-               yylval.intn = intnum_new_hex(s.tok+2, p_line_index);
+               yylval.intn = intnum_new_hex(s.tok+2, cur_lindex);
            else
                /* don't skip 0 */
-               yylval.intn = intnum_new_hex(s.tok+1, p_line_index);
+               yylval.intn = intnum_new_hex(s.tok+1, cur_lindex);
            s.tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
@@ -342,8 +325,9 @@ scan:
                yylval.str_val = xstrndup(s.tok, TOKLEN);
                RETURN(ID);
            } else if (!nasm_parser_locallabel_base) {
-               Warning(p_line_index, _("no non-local label before `%s'"),
-                       s.tok[0]);
+               cur_we->warning(WARN_GENERAL, cur_lindex,
+                               N_("no non-local label before `%s'"),
+                               s.tok[0]);
                yylval.str_val = xstrndup(s.tok, TOKLEN);
            } else {
                len = TOKLEN + nasm_parser_locallabel_base_len;
@@ -367,7 +351,7 @@ scan:
            savech = s.tok[TOKLEN];
            s.tok[TOKLEN] = '\0';
            check_id_ret = nasm_parser_arch->parse.check_identifier(
-               yylval.arch_data, s.tok, p_line_index);
+               yylval.arch_data, s.tok, cur_lindex);
            s.tok[TOKLEN] = savech;
            switch (check_id_ret) {
                case ARCH_CHECK_ID_NONE:
@@ -385,8 +369,8 @@ scan:
                case ARCH_CHECK_ID_TARGETMOD:
                    RETURN(TARGETMOD);
                default:
-                   Warning(p_line_index,
-                           _("Arch feature not supported, treating as identifier"));
+                   cur_we->warning(WARN_GENERAL, cur_lindex,
+                       N_("Arch feature not supported, treating as identifier"));
                    yylval.str_val = xstrndup(s.tok, TOKLEN);
                    RETURN(ID);
            }
@@ -399,10 +383,9 @@ scan:
        "\n"                    { state = INITIAL; RETURN(s.tok[0]); }
 
        any {
-           if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
-               Warning(p_line_index,
-                       _("ignoring unrecognized character `%s'"),
-                       conv_unprint(s.tok[0]));
+           cur_we->warning(WARN_UNREC_CHAR, cur_lindex,
+                           N_("ignoring unrecognized character `%s'"),
+                           cur_we->conv_unprint(s.tok[0]));
            goto scan;
        }
     */
@@ -416,7 +399,7 @@ linechg:
            linechg_numcount++;
            savech = s.tok[TOKLEN];
            s.tok[TOKLEN] = '\0';
-           yylval.intn = intnum_new_dec(s.tok, p_line_index);
+           yylval.intn = intnum_new_dec(s.tok, cur_lindex);
            s.tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
@@ -439,10 +422,9 @@ linechg:
        }
 
        any {
-           if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
-               Warning(p_line_index,
-                       _("ignoring unrecognized character `%s'"),
-                       conv_unprint(s.tok[0]));
+           cur_we->warning(WARN_UNREC_CHAR, cur_lindex,
+                           N_("ignoring unrecognized character `%s'"),
+                           cur_we->conv_unprint(s.tok[0]));
            goto linechg;
        }
     */
@@ -482,10 +464,9 @@ directive:
        }
 
        any {
-           if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
-               Warning(p_line_index,
-                       _("ignoring unrecognized character `%s'"),
-                       conv_unprint(s.tok[0]));
+           cur_we->warning(WARN_UNREC_CHAR, cur_lindex,
+                           N_("ignoring unrecognized character `%s'"),
+                           cur_we->conv_unprint(s.tok[0]));
            goto directive;
        }
     */
@@ -502,9 +483,10 @@ stringconst_scan:
     /*!re2c
        "\n"    {
            if (cursor == s.eof)
-               Error(p_line_index, _("unexpected end of file in string"));
+               cur_we->error(cur_lindex,
+                             N_("unexpected end of file in string"));
            else
-               Error(p_line_index, _("unterminated string"));
+               cur_we->error(cur_lindex, N_("unterminated string"));
            strbuf[count] = '\0';
            yylval.str_val = strbuf;
            RETURN(STRING);
index 9b4874bb768fe9e32b196a79e5159131ce176a83..96d07cffce58886d0cc0d6c9c1336e9f271ec4f9 100644 (file)
@@ -38,11 +38,15 @@ struct preproc {
      * This function also takes the FILE * to the initial starting file and
      * the filename.
      */
-    void (*initialize) (FILE *f, const char *in_filename);
+    void (*initialize) (FILE *f, const char *in_filename, linemgr *lm,
+                       errwarn *we);
+
+    /* Cleans up any allocated memory. */
+    void (*cleanup) (void);
 
     /* Gets more preprocessed source code (up to max_size bytes) into buf.
      * Note that more than a single line may be returned in buf. */
-    size_t (*input) (/*@out@*/ char *buf, size_t max_size, linemgr *lm);
+    size_t (*input) (/*@out@*/ char *buf, size_t max_size);
 };
 
 #endif
index b251f841a20122c0f3e64589d15665cbcb4eb579..95bad927e516f16e7f0d66627f3a855a7919215c 100644 (file)
 
 static int is_interactive;
 static FILE *in;
+static linemgr *cur_lm;
+static errwarn *cur_we;
 
 int isatty(int);
 
 static void
-raw_preproc_initialize(FILE *f, const char *in_filename)
+raw_preproc_initialize(FILE *f, const char *in_filename, linemgr *lm,
+                      errwarn *we)
 {
     in = f;
+    cur_lm = lm;
+    cur_we = we;
     /*@-unrecog@*/
     is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
     /*@=unrecog@*/
 }
 
+static void
+raw_preproc_cleanup(void)
+{
+}
+
 static size_t
-raw_preproc_input(char *buf, size_t max_size, linemgr *lm)
+raw_preproc_input(char *buf, size_t max_size)
 {
     int c = '*';
     size_t n;
@@ -54,9 +64,11 @@ raw_preproc_input(char *buf, size_t max_size, linemgr *lm)
        if (c == '\n')
            buf[n++] = (char)c;
        if (c == EOF && ferror(in))
-           Error(lm->get_current(), _("error when reading from file"));
+           cur_we->error(cur_lm->get_current(),
+                         N_("error when reading from file"));
     } else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in))
-       Error(lm->get_current(), _("error when reading from file"));
+       cur_we->error(cur_lm->get_current(),
+                     N_("error when reading from file"));
 
     return n;
 }
@@ -66,5 +78,6 @@ preproc yasm_raw_LTX_preproc = {
     "Disable preprocessing",
     "raw",
     raw_preproc_initialize,
+    raw_preproc_cleanup,
     raw_preproc_input
 };
index 681f7b7818744e5b0c5147588755f532576db156..a59ee5c2ba961abcb67286d62b0a251d912e9f8d 100644 (file)
@@ -41,7 +41,7 @@ static YAPP_Output current_output;
 YYSTYPE yapp_preproc_lval;
 
 /*@dependent@*/ linemgr *yapp_preproc_linemgr;
-#define p_line_index   (yapp_preproc_linemgr->get_current())
+/*@dependent@*/ errwarn *yapp_preproc_errwarn;
 
 int isatty(int);
 
@@ -120,13 +120,13 @@ yapp_macro_insert (char *name, int argc, int fillargs)
 void
 yapp_macro_error_exists (YAPP_Macro *v)
 {
-    if (v) Error(p_line_index, _("Redefining macro of the same name %d:%d"), v->type, v->args);
+    if (v) cur_we->error(cur_lindex, N_("Redefining macro of the same name %d:%d"), v->type, v->args);
 }
 
 void
 yapp_macro_error_sameargname (YAPP_Macro *v)
 {
-    if (v) Error(p_line_index, _("Duplicate argument names in macro"));
+    if (v) cur_we->error(cur_lindex, N_("Duplicate argument names in macro"));
 }
 
 YAPP_Macro *
@@ -141,7 +141,7 @@ yapp_define_insert (char *name, int argc, int fillargs)
        if ((argc >= 0 && ym->args < 0)
            || (argc < 0 && ym->args >= 0))
        {
-           Warning(p_line_index, _("Attempted %%define both with and without parameters"));
+           cur_we->warning(WARN_PREPROC, cur_lindex, N_("Attempted %%define both with and without parameters"));
            return NULL;
        }
     }
@@ -189,10 +189,10 @@ yapp_macro_delete (YAPP_Macro *ym)
 {
     while (!SLIST_EMPTY(&ym->macro_head)) {
        source *s = SLIST_FIRST(&ym->macro_head);
-       free(s);
+       xfree(s);
        SLIST_REMOVE_HEAD(&ym->macro_head, next);
     }
-    free(ym);
+    xfree(ym);
 }
 
 static YAPP_Macro *
@@ -237,9 +237,12 @@ void
 expand_token_list(struct source_head *paramexp, struct source_head *to_head, source **to_tail);
 
 static void
-yapp_preproc_initialize(FILE *f, const char *in_filename)
+yapp_preproc_initialize(FILE *f, const char *in_filename, linemgr *lm,
+                       errwarn *we)
 {
     is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
+    yapp_preproc_linemgr = lm;
+    yapp_preproc_errwarn = we;
     yapp_preproc_current_file = xstrdup(in_filename);
     yapp_preproc_line_number = 1;
     yapp_lex_initialize(f);
@@ -251,7 +254,7 @@ yapp_preproc_initialize(FILE *f, const char *in_filename)
     out->out = current_output = YAPP_OUTPUT;
     SLIST_INSERT_HEAD(&output_head, out, next);
 
-    macro_table = HAMT_new();
+    macro_table = HAMT_new(we->internal_error_);
 
     source_tail = SLIST_FIRST(&source_head);
     macro_tail = SLIST_FIRST(&macro_head);
@@ -260,6 +263,12 @@ yapp_preproc_initialize(FILE *f, const char *in_filename)
     append_token(LINE, &source_head, &source_tail);
 }
 
+static void
+yapp_preproc_cleanup(void)
+{
+    /* TODO: clean up */
+}
+
 /* Generate a new level of if* context
  * if val is true, this module of the current level will be output IFF the
  * surrounding one is.
@@ -321,7 +330,7 @@ pop_if(void)
     out = SLIST_FIRST(&output_head);
     current_output = out->out;
     SLIST_REMOVE_HEAD(&output_head, next);
-    free(out);
+    xfree(out);
     if (current_output != YAPP_OUTPUT) set_inhibit();
 }
 
@@ -367,7 +376,7 @@ append_token(int token, struct source_head *to_head, source **to_tail)
     if ((*to_tail) && (*to_tail)->token.type == LINE
        && (token == '\n' || token == LINE))
     {
-       free ((*to_tail)->token.str);
+       xfree ((*to_tail)->token.str);
        (*to_tail)->token.str = xmalloc(23+strlen(yapp_preproc_current_file));
        sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file);
     }
@@ -409,7 +418,7 @@ append_token(int token, struct source_head *to_head, source **to_tail)
                break;
 
            default:
-               free(src);
+               xfree(src);
                return;
        }
        append_processed_token(src, to_head, to_tail);
@@ -461,7 +470,7 @@ eat_through_return(struct source_head *to_head, source **to_tail)
     while ((token = yapp_preproc_lex()) != '\n') {
        if (token == 0)
            return 0;
-       Error(p_line_index, _("Skipping possibly valid %%define stuff"));
+       cur_we->error(cur_lindex, N_("Skipping possibly valid %%define stuff"));
     }
     append_token('\n', to_head, to_tail);
     return '\n';
@@ -474,7 +483,7 @@ yapp_get_ident(const char *synlvl)
     if (token == WHITESPACE)
        token = yapp_preproc_lex();
     if (token != IDENT) {
-       Error(p_line_index, _("Identifier expected after %%%s"), synlvl);
+       cur_we->error(cur_lindex, N_("Identifier expected after %%%s"), synlvl);
     }
     return token;
 }
@@ -502,7 +511,7 @@ expand_macro(char *name,
 
     ydebug(("YAPP: +Expand macro %s...\n", name));
 
-    if (ym->expanding) InternalError(_("Recursively expanding a macro!"));
+    if (ym->expanding) cur_we->internal_error(N_("Recursively expanding a macro!"));
 
     if (ym->type == YAPP_DEFINE) {
        if (ym->args == -1) {
@@ -534,7 +543,7 @@ expand_macro(char *name,
 
            /* find out what we got */
            if (from_head) {
-               InternalError("Expanding macro with non-null from_head ugh\n");
+               cur_we->internal_error(N_("Expanding macro with non-null from_head ugh\n"));
            }
            token = yapp_preproc_lex();
            append_token(token, &replay_head, &replay_tail);
@@ -581,9 +590,9 @@ expand_macro(char *name,
 
                    default:
                        if (token < 256)
-                           InternalError(_("Unexpected character token in parameter expansion"));
+                           cur_we->internal_error(N_("Unexpected character token in parameter expansion"));
                        else
-                           Error(p_line_index, _("Cannot handle preprocessor items inside possible macro invocation"));
+                           cur_we->error(cur_lindex, N_("Cannot handle preprocessor items inside possible macro invocation"));
                }
            }
 
@@ -603,7 +612,7 @@ expand_macro(char *name,
            ym->expanding = 1;
 
            /* so the macro exists. build a HAMT parameter table */
-           param_table = HAMT_new();
+           param_table = HAMT_new(cur_we->internal_error_);
            /* fill the entries by walking the replay buffer and create
             * "macros".  coincidentally, clear the replay buffer. */
 
@@ -612,16 +621,16 @@ expand_macro(char *name,
            while (replay->token.type != '(') {
                ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str));
                SLIST_REMOVE_HEAD(&replay_head, next);
-               free(replay->token.str);
-               free(replay);
+               xfree(replay->token.str);
+               xfree(replay);
                replay = SLIST_FIRST(&replay_head);
            }
            ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str));
 
            /* free the open paren */
            SLIST_REMOVE_HEAD(&replay_head, next);
-           free(replay->token.str);
-           free(replay);
+           xfree(replay->token.str);
+           xfree(replay);
 
            param = SLIST_FIRST(&ym->param_head);
 
@@ -651,8 +660,8 @@ expand_macro(char *name,
                    arg_tail = SLIST_FIRST(&arg_head);
 
                    /* don't save the comma */
-                   free(replay->token.str);
-                   free(replay);
+                   xfree(replay->token.str);
+                   xfree(replay);
 
                    HAMT_insert(param_table,
                                param->token.str,
@@ -675,15 +684,15 @@ expand_macro(char *name,
                if (replay) SLIST_REMOVE_HEAD(&replay_head, next);
            }
            if (replay) {
-               free(replay->token.str);
-               free(replay);
+               xfree(replay->token.str);
+               xfree(replay);
            }
            else if (param) {
-                 InternalError(_("Got to end of arglist before end of replay!"));
+                 cur_we->internal_error(N_("Got to end of arglist before end of replay!"));
            }
            replay = SLIST_FIRST(&replay_head);
            if (replay || param)
-               InternalError(_("Count and distribution of define args mismatched!"));
+               cur_we->internal_error(N_("Count and distribution of define args mismatched!"));
 
            /* the param_table is set up without errors, so expansion is ready
             * to go */
@@ -717,7 +726,7 @@ expand_macro(char *name,
        }
     }
     else
-       InternalError(_("Invoking Macros not yet supported"));
+       cur_we->internal_error(N_("Invoking Macros not yet supported"));
 
     ym->expanding = 0;
 }
@@ -743,15 +752,13 @@ expand_token_list(struct source_head *paramexp, struct source_head *to_head, sou
 }
 
 static size_t
-yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
+yapp_preproc_input(char *buf, size_t max_size)
 {
     static YAPP_State state = YAPP_STATE_INITIAL;
     int n = 0;
     int token;
     int need_line_directive = 0;
 
-    yapp_preproc_linemgr = lm;
-
     while (saved_length < max_size && state != YAPP_STATE_EOF)
     {
        token = yapp_preproc_lex();
@@ -765,7 +772,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
                        append_token(token, &source_head, &source_tail);
                        /*if (append_to_return()==0) state=YAPP_STATE_EOF;*/
                        ydebug(("YAPP: default: '%c' \"%s\"\n", token, yapp_preproc_lval.str_val));
-                       /*Error(p_line_index, _("YAPP got an unhandled token."));*/
+                       /*cur_we->error(cur_lindex, N_("YAPP got an unhandled token."));*/
                        break;
 
                    case IDENT:
@@ -788,7 +795,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
 
                    case CLEAR:
                        HAMT_delete(macro_table, (void (*)(void *))yapp_macro_delete);
-                       macro_table = HAMT_new();
+                       macro_table = HAMT_new(cur_we->internal_error_);
                        break;
 
                    case DEFINE:
@@ -834,7 +841,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
                                    break;
                                }
                                else if (last_token == ',' || token != ',')
-                                   Error(p_line_index, _("Unexpected token in %%define parameters"));
+                                   cur_we->error(cur_lindex, N_("Unexpected token in %%define parameters"));
                                last_token = token;
                            }
                            if (token == ')') {
@@ -851,7 +858,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
                            append_token('\n', &source_head, &source_tail);
                        }
                        else {
-                           InternalError(_("%%define ... failed miserably - neither \\n, WS, or ( followed ident"));
+                           cur_we->internal_error(N_("%%define ... failed miserably - neither \\n, WS, or ( followed ident"));
                        }
                        break;
 
@@ -914,7 +921,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
                }
                break;
            default:
-               Error(p_line_index, _("YAPP got into a bad state"));
+               cur_we->error(cur_lindex, N_("YAPP got into a bad state"));
        }
        if (need_line_directive) {
            append_token(LINE, &source_head, &source_tail);
@@ -932,8 +939,8 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
 
            saved_length -= strlen(src->token.str);
            SLIST_REMOVE_HEAD(&source_head, next);
-           free(src->token.str);
-           free(src);
+           xfree(src->token.str);
+           xfree(src);
        }
     }
 
@@ -945,5 +952,6 @@ preproc yasm_yapp_LTX_preproc = {
     "YAPP preprocessing (NASM style)",
     "yapp",
     yapp_preproc_initialize,
+    yapp_preproc_cleanup,
     yapp_preproc_input
 };
index 428b65f0ae7c3cc660a4f1c4e7629ea883361074..5e2bdf767d68359f9e1f30e136f9cb22284a77fa 100644 (file)
@@ -52,3 +52,9 @@ typedef enum {
 
 void yapp_lex_initialize(FILE *f);
 void set_inhibit(void);
+
+extern /*@dependent@*/ linemgr *yapp_preproc_linemgr;
+extern /*@dependent@*/ errwarn *yapp_preproc_errwarn;
+#define cur_lindex     (yapp_preproc_linemgr->get_current())
+#define cur_we         yapp_preproc_errwarn
+
index 01c67b7a921da31066cda4e7b7844e545332713e..4301249532bb827e227d4f4560b7fc3bdc2cc432 100644 (file)
@@ -60,7 +60,5 @@ typedef union {
 extern YYSTYPE yapp_preproc_lval;
 extern char *yapp_preproc_current_file;
 extern int yapp_preproc_line_number;
-extern /*@dependent@*/ linemgr *yapp_preproc_linemgr;
-#define p_line_index   (yapp_preproc_linemgr->get_current())
 
 int yapp_preproc_lex(void);
index 17072e20b0b62bd681f7a3a92c159170718a87a8..d45ed6131a8e64bb56aaebc1b508fae553c29fb4 100644 (file)
@@ -124,9 +124,7 @@ DIR  %[ \t]*
     int inch, count;
     char endch = yytext[0];
 
-    strbuf = malloc(STRBUF_ALLOC_SIZE);
-    if(!strbuf)
-       Fatal(FATAL_NOMEM);
+    strbuf = xmalloc(STRBUF_ALLOC_SIZE);
 
     strbuf_size = STRBUF_ALLOC_SIZE;
     inch = input();
@@ -134,18 +132,16 @@ DIR        %[ \t]*
     while(inch != EOF && inch != endch && inch != '\n') {
        strbuf[count++] = inch;
        if(count >= strbuf_size) {
-           strbuf = realloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
-           if(!strbuf)
-               Fatal(FATAL_NOMEM);
+           strbuf = xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
            strbuf_size += STRBUF_ALLOC_SIZE;
        }
        inch = input();
     }
 
     if(inch == '\n')
-       Error(p_line_index, _("unterminated string"));
+       cur_we->error(cur_lindex, _("unterminated string"));
     else if(inch == EOF)
-       Error(p_line_index, _("unexpected end of file in string"));
+       cur_we->error(cur_lindex, _("unexpected end of file in string"));
 
     strbuf[count] = '\0';
 
@@ -176,9 +172,9 @@ DIR  %[ \t]*
     /* FIXME: handle includes that aren't relative */
     incfile = fopen (yytext, "r");
     if(!incfile) {
-       Error(p_line_index, _("include file `%s': %s"),
+       cur_we->error(cur_lindex, _("include file `%s': %s"),
                yytext, strerror(errno));
-       free(inc);
+       xfree(inc);
     }
     else {
        yyin = incfile;
@@ -204,11 +200,11 @@ DIR        %[ \t]*
        inc = SLIST_FIRST(&includes_head);
        yy_delete_buffer (YY_CURRENT_BUFFER);
        yy_switch_to_buffer (inc->include_state);
-       free(yapp_preproc_current_file);
+       xfree(yapp_preproc_current_file);
        yapp_preproc_current_file = inc->filename;
        yapp_preproc_line_number = inc->line_number + 1;
        SLIST_REMOVE_HEAD(&includes_head, next);
-       free(inc);
+       xfree(inc);
 
        BEGIN(incl);
        return INCLUDE;
@@ -232,7 +228,7 @@ DIR  %[ \t]*
 }
 <line>{WS}+["]     ;   /* eat space before file */
 <line>[^ \t\n"]*    { /* have the filename */
-    free(yapp_preproc_current_file);
+    xfree(yapp_preproc_current_file);
     yapp_preproc_current_file = xstrdup(yytext);
 }
 <line>["]{WS}*\n    {
@@ -334,12 +330,12 @@ DIR        %[ \t]*
 [][+*/,()-] { return yytext[0]; }
 
 <inhibit>.  {
-    Warning(p_line_index, _("Unhandled character in <inhibit> `%s'"), conv_unprint(yytext[0]));
+    cur_we->warning(WARN_PREPROC, cur_lindex, _("Unhandled character in <inhibit> `%s'"), cur_we->conv_unprint(yytext[0]));
 }
 
 .      {
-    Warning(p_line_index, _("ignoring unrecognized character `%s'"),
-           conv_unprint(yytext[0]));
+    cur_we->warning(WARN_PREPROC, cur_lindex, _("ignoring unrecognized character `%s'"),
+                   cur_we->conv_unprint(yytext[0]));
 }
 
 %%
index 430c73bfd46ca7c16ad894201d62390e6e4cf096..a85811372aa8aad3af52903e75c998b87678d29d 100644 (file)
@@ -54,6 +54,9 @@ struct section {
     int res_only;              /* allow only resb family of bytecodes? */
 
     bytecodehead bc;           /* the bytecodes for the section's contents */
+
+    /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                   const char *message);
 };
 
 /*@-compdestroy@*/
@@ -82,7 +85,10 @@ sections_initialize(sectionhead *headp, objfmt *of)
 section *
 sections_switch_general(sectionhead *headp, const char *name,
                        unsigned long start, int res_only, int *isnew,
-                       unsigned long lindex)
+                       unsigned long lindex,
+                       /*@exits@*/ void (*error_func) (const char *file,
+                                                       unsigned int line,
+                                                       const char *message))
 {
     section *s;
 
@@ -113,6 +119,8 @@ sections_switch_general(sectionhead *headp, const char *name,
     s->opt_flags = 0;
     s->res_only = res_only;
 
+    s->error_func = error_func;
+
     *isnew = 1;
     return s;
 }
@@ -120,7 +128,10 @@ sections_switch_general(sectionhead *headp, const char *name,
 
 /*@-onlytrans@*/
 section *
-sections_switch_absolute(sectionhead *headp, expr *start)
+sections_switch_absolute(sectionhead *headp, expr *start,
+                        /*@exits@*/ void (*error_func) (const char *file,
+                                                        unsigned int line,
+                                                        const char *message))
 {
     section *s;
 
@@ -134,6 +145,8 @@ sections_switch_absolute(sectionhead *headp, expr *start)
     s->opt_flags = 0;
     s->res_only = 1;
 
+    s->error_func = error_func;
+
     return s;
 }
 /*@=onlytrans@*/
@@ -164,7 +177,8 @@ section_set_of_data(section *sect, objfmt *of, void *of_data)
        if (of->section_data_delete)
            of->section_data_delete(of_data);
        else
-           InternalError(_("don't know how to delete objfmt-specific section data"));
+           sect->error_func(__FILE__, __LINE__,
+               N_("don't know how to delete objfmt-specific section data"));
        return;
     }
 
@@ -174,7 +188,8 @@ section_set_of_data(section *sect, objfmt *of, void *of_data)
        if (of2->section_data_delete)
            of2->section_data_delete(sect->data.general.of_data);
        else
-           InternalError(_("don't know how to delete objfmt-specific section data"));
+           sect->error_func(__FILE__, __LINE__,
+               N_("don't know how to delete objfmt-specific section data"));
     }
 
     /* Assign new of_data */
@@ -285,7 +300,8 @@ section_delete(section *sect)
            if (of->section_data_delete)
                of->section_data_delete(sect->data.general.of_data);
            else
-               InternalError(_("don't know how to delete objfmt-specific section data"));
+               sect->error_func(__FILE__, __LINE__,
+                   N_("don't know how to delete objfmt-specific section data"));
        }
     }
     expr_delete(sect->start);
index c7f5e954e723758e923213c08774175880e47485..82536fd77edee213e0a72a6cdc38df6fe07c2425 100644 (file)
 /*@dependent@*/ section *sections_initialize(sectionhead *headp, objfmt *of);
 
 /*@dependent@*/ section *sections_switch_general(sectionhead *headp,
-                                                const char *name,
-                                                unsigned long start,
-                                                int res_only,
-                                                /*@out@*/ int *isnew,
-                                                unsigned long lindex);
+    const char *name, unsigned long start, int res_only, /*@out@*/ int *isnew,
+    unsigned long lindex,
+    /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                   const char *message));
 
 /*@dependent@*/ section *sections_switch_absolute(sectionhead *headp,
-                                                 /*@keep@*/ expr *start);
+    /*@keep@*/ expr *start,
+    /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
+                                   const char *message));
 
 int section_is_absolute(section *sect);
 
index fe32457b7f19f354010a8398787e92b9e1f33709..80e6f4d43d7c4577e400634ee9432b9b0ace054a 100644 (file)
@@ -76,7 +76,7 @@ struct symrec {
 };
 
 /* The symbol table: a hash array mapped trie (HAMT). */
-static /*@only@*/ /*@null@*/ HAMT *sym_table = NULL;
+static /*@only@*/ HAMT *sym_table;
 
 /* Linked list of symbols not in the symbol table. */
 typedef struct non_table_symrec_s {
@@ -85,8 +85,20 @@ typedef struct non_table_symrec_s {
 } non_table_symrec;
 typedef /*@reldef@*/ SLIST_HEAD(nontablesymhead_s, non_table_symrec_s)
        nontablesymhead;
-static /*@only@*/ /*@null@*/ nontablesymhead *non_table_syms = NULL;
+static /*@only@*/ nontablesymhead *non_table_syms;
 
+static /*@dependent@*/ errwarn *cur_we;
+
+
+void
+symrec_initialize(errwarn *we)
+{
+    cur_we = we;
+
+    sym_table = HAMT_new(cur_we->internal_error_);
+    non_table_syms = xmalloc(sizeof(nontablesymhead));
+    SLIST_INIT(non_table_syms);
+}
 
 static void
 symrec_delete_one(/*@only@*/ void *d)
@@ -99,7 +111,8 @@ symrec_delete_one(/*@only@*/ void *d)
        if (sym->of->symrec_data_delete)
            sym->of->symrec_data_delete(sym->of_data);
        else
-           InternalError(_("don't know how to delete objfmt-specific data"));
+           cur_we->internal_error(
+               N_("don't know how to delete objfmt-specific data"));
     }
     xfree(sym);
 }
@@ -124,9 +137,6 @@ symrec_get_or_new_in_table(/*@only@*/ char *name)
     symrec *rec = symrec_new_common(name);
     int replace = 0;
 
-    if (!sym_table)
-       sym_table = HAMT_new();
-
     rec->status = SYM_NOSTATUS;
 
     return HAMT_insert(sym_table, name, rec, &replace, symrec_delete_one);
@@ -138,11 +148,6 @@ symrec_get_or_new_not_in_table(/*@only@*/ char *name)
     non_table_symrec *sym = xmalloc(sizeof(non_table_symrec));
     sym->rec = symrec_new_common(name);
 
-    if (!non_table_syms) {
-       non_table_syms = xmalloc(sizeof(nontablesymhead));
-       SLIST_INIT(non_table_syms);
-    }
-
     sym->rec->status = SYM_NOTINTABLE;
 
     SLIST_INSERT_HEAD(non_table_syms, sym, link);
@@ -169,10 +174,7 @@ symrec_get_or_new(const char *name, int in_table)
 int
 symrec_traverse(void *d, int (*func) (symrec *sym, void *d))
 {
-    if (sym_table)
-       return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func);
-    else
-       return 1;
+    return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func);
 }
 
 symrec *
@@ -194,9 +196,9 @@ symrec_define(const char *name, SymType type, int in_table,
     /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
     if ((rec->status & SYM_DEFINED) ||
        (rec->visibility & (SYM_COMMON | SYM_EXTERN))) {
-       Error(lindex,
-             _("duplicate definition of `%s'; first defined on line %lu"),
-             name, rec->line);
+       cur_we->error(lindex,
+           N_("duplicate definition of `%s'; first defined on line %lu"),
+           name, rec->line);
     } else {
        rec->line = lindex;     /* set line number of definition */
        rec->type = type;
@@ -247,9 +249,9 @@ symrec_declare(const char *name, SymVisibility vis, unsigned long lindex)
          ((rec->visibility & SYM_EXTERN) && (vis == SYM_EXTERN)))))
        rec->visibility |= vis;
     else
-       Error(lindex,
-             _("duplicate definition of `%s'; first defined on line %lu"),
-             name, rec->line);
+       cur_we->error(lindex,
+           N_("duplicate definition of `%s'; first defined on line %lu"),
+           name, rec->line);
     return rec;
 }
 
@@ -312,7 +314,8 @@ symrec_set_of_data(symrec *sym, objfmt *of, void *of_data)
        if (sym->of->symrec_data_delete)
            sym->of->symrec_data_delete(sym->of_data);
        else
-           InternalError(_("don't know how to delete objfmt-specific data"));
+           cur_we->internal_error(
+               N_("don't know how to delete objfmt-specific data"));
     }
     sym->of = of;
     sym->of_data = of_data;
@@ -325,7 +328,8 @@ symrec_parser_finalize_checksym(symrec *sym, /*@unused@*/ /*@null@*/ void *d)
     /* error if a symbol is used but never defined or extern/common declared */
     if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) &&
        !(sym->visibility & (SYM_EXTERN | SYM_COMMON))) {
-       Error(sym->line, _("undefined symbol `%s' (first use)"), sym->name);
+       cur_we->error(sym->line, N_("undefined symbol `%s' (first use)"),
+                     sym->name);
        if (sym->line < firstundef_line)
            firstundef_line = sym->line;
     }
@@ -339,27 +343,22 @@ symrec_parser_finalize(void)
     firstundef_line = ULONG_MAX;
     symrec_traverse(NULL, symrec_parser_finalize_checksym);
     if (firstundef_line < ULONG_MAX)
-       Error(firstundef_line,
-             _(" (Each undefined symbol is reported only once.)"));
+       cur_we->error(firstundef_line,
+           N_(" (Each undefined symbol is reported only once.)"));
 }
 
 void
-symrec_delete_all(void)
+symrec_cleanup(void)
 {
-    if (sym_table) {
-       HAMT_delete(sym_table, symrec_delete_one);
-       sym_table = NULL;
-    }
-    if (non_table_syms) {
-       while (!SLIST_EMPTY(non_table_syms)) {
-           non_table_symrec *sym = SLIST_FIRST(non_table_syms);
-           SLIST_REMOVE_HEAD(non_table_syms, link);
-           symrec_delete_one(sym->rec);
-           xfree(sym);
-       }
-       xfree(non_table_syms);
-       non_table_syms = NULL;
+    HAMT_delete(sym_table, symrec_delete_one);
+
+    while (!SLIST_EMPTY(non_table_syms)) {
+       non_table_symrec *sym = SLIST_FIRST(non_table_syms);
+       SLIST_REMOVE_HEAD(non_table_syms, link);
+       symrec_delete_one(sym->rec);
+       xfree(sym);
     }
+    xfree(non_table_syms);
 }
 
 typedef struct symrec_print_data {
index 47d148e811e3c3074c387cb1caa9e0c0565235e9..b4c8231a01f1f9c6304fce382e69cd7f7ef08c76 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
+void symrec_initialize(errwarn *we);
+
 /*@dependent@*/ symrec *symrec_use(const char *name, unsigned long lindex);
 /*@dependent@*/ symrec *symrec_define_equ(const char *name, /*@keep@*/ expr *e,
                                          unsigned long lindex);
@@ -64,7 +66,7 @@ int /*@alt void@*/ symrec_traverse(/*@null@*/ void *d,
 
 void symrec_parser_finalize(void);
 
-void symrec_delete_all(void);
+void symrec_cleanup(void);
 
 void symrec_print_all(FILE *f, int indent_level);
 
index 84a4bdadcf64f9d9b04daf33852f3ac80ddaddc2..6972c9375025f38c2701cf9e2dfd91078f5e0bed 100644 (file)
@@ -421,6 +421,7 @@ main(void)
     Suite *s = floatnum_suite();
     SRunner *sr = srunner_create(s);
     BitVector_Boot();
+    floatnum_initialize(NULL);
     srunner_run_all(sr, CRNORMAL);
     nf = srunner_ntests_failed(sr);
     srunner_free(sr);
index c9d2e2bdea613bb30e8ce882eb793ed4596dbfd5..89fa46c8aff6dd715632c0e663b4b548764123ba 100644 (file)
@@ -129,6 +129,8 @@ int strncasecmp(const char *s1, const char *s2, size_t n);
 /*@only@*/ char *xstrdup(const char *str);
 
 /* Error-checking memory allocation routines in xmalloc.c. */
+void xalloc_initialize(/*@exits@*/ void (*fatal_func) (int type),
+                      int nomem_fatal_type);
 /*@only@*/ /*@out@*/ void *xmalloc(size_t size);
 /*@only@*/ void *xcalloc(size_t nelem, size_t elsize);
 /*@only@*/ void *xrealloc(/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/
index c1a38d45f4d0ac8f3320352dfc957a9ae197e4f2..5691f3bff9ed8e8ca787fe3ea35d568a549cff6f 100644 (file)
 #include "util.h"
 RCSID("$IdPath$");
 
-#include "errwarn.h"
 
+static /*@exits@*/ void (*fatal_func) (int type);
+static int nomem_fatal_type;
+
+
+void
+xalloc_initialize(/*@exits@*/ void (*f) (int type), int t)
+{
+    fatal_func = f;
+    nomem_fatal_type = t;
+}
 
 #ifndef WITH_DMALLOC
 
@@ -36,7 +45,7 @@ xmalloc(size_t size)
        size = 1;
     newmem = malloc(size);
     if (!newmem)
-       Fatal(FATAL_NOMEM);
+       fatal_func(nomem_fatal_type);
 
     return newmem;
 }
@@ -51,7 +60,7 @@ xcalloc(size_t nelem, size_t elsize)
 
     newmem = calloc(nelem, elsize);
     if (!newmem)
-       Fatal(FATAL_NOMEM);
+       fatal_func(nomem_fatal_type);
 
     return newmem;
 }
@@ -68,7 +77,7 @@ xrealloc(void *oldmem, size_t size)
     else
        newmem = realloc(oldmem, size);
     if (!newmem)
-       Fatal(FATAL_NOMEM);
+       fatal_func(nomem_fatal_type);
 
     return newmem;
 }
diff --git a/util.h b/util.h
index c9d2e2bdea613bb30e8ce882eb793ed4596dbfd5..89fa46c8aff6dd715632c0e663b4b548764123ba 100644 (file)
--- a/util.h
+++ b/util.h
@@ -129,6 +129,8 @@ int strncasecmp(const char *s1, const char *s2, size_t n);
 /*@only@*/ char *xstrdup(const char *str);
 
 /* Error-checking memory allocation routines in xmalloc.c. */
+void xalloc_initialize(/*@exits@*/ void (*fatal_func) (int type),
+                      int nomem_fatal_type);
 /*@only@*/ /*@out@*/ void *xmalloc(size_t size);
 /*@only@*/ void *xcalloc(size_t nelem, size_t elsize);
 /*@only@*/ void *xrealloc(/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/