m4-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

head: Re: branch-1_4 error message cleanup


From: Eric Blake
Subject: head: Re: branch-1_4 error message cleanup
Date: Wed, 09 Aug 2006 07:24:06 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.5) Gecko/20060719 Thunderbird/1.5.0.5 Mnenhy/0.7.4.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Eric Blake on 8/8/2006 5:11 PM:
> 
> 2006-08-08  Eric Blake  <address@hidden>
> 
>       Avoid printing `NONE:0:' in error messages.

I've ported this to HEAD as follows.  Apologies for such a big patch, but
I decided that moving to GNU Coding Standards for error messages was an
opportunity to get rid of two more global variables, for current file and
line.  That meant that the context has to be passed to a few more
functions.  And while I was at it, I fixed a few error messages that were
not being translated, changed internal errors to asserts, and flattened
the M4ERROR and M4WARN macros into function calls.  There wasn't a very
clean division into any smaller patches.

This patch does not visit whether messages that we print as errors should
be changed to warnings, or vice versa.  That still needs an audit; my take
on the matter is that warnings should be suppressable, but errors should
not; and only errors should affect the final exit status (unless warnings
are requested to be fatal), even if we can continue processing after
printing the error.

2006-08-09  Eric Blake  <address@hidden>

        * bootstrap: Recent gnulib no longer has jm_* macros to worry
        about.
        * ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
        verror.
        * m4/m4module.h (M4ERROR, M4WARN): Delete, replaced by...
        (m4_error, m4_warn): ... these new prototypes.
        (m4_current_file, m4_current_line): Move into context, rather
        than leaving as globals.
        (m4_insert_file, m4_insert_diversion, m4_freeze_diversions)
        (m4_undivert_all, m4_input_init): Now takes context.
        * m4/utility.c (m4_error, m4_warn): New functions.
        * m4/m4private.h: Assume errno exists.
        (struct m4): Move warning_status to a bit flag,
        and add exit_status.  Adjust accessors accordingly.
        * src/main.c (print_program_name_CB): No longer needed.
        (main): Use new m4_get_fatal_warnings_opt.
        * m4/debug.c: Adjust all callers of M4WARN and M4ERROR, and abort
        instead of issuing "INTERNAL ERROR".  Pass context when needed,
        and use new accessors.
        * m4/input.c: Likewise.
        * m4/macro.c: Likewise.
        * m4/output.c: Likewise.
        * m4/utility.c: Likewise.
        * modules/evalparse.c: Likewise.
        * modules/gnu.c: Likewise.
        * modules/load.c: Likewise.
        * modules/m4.c: Likewise.
        * modules/mpeval.c: Likewise.
        * src/freeze.c: Likewise.
        * src/main.c: Likewise.
        * tests/macros.at: Adjust to new message format.
        * tests/builtins.at: Likewise.
        * tests/freeze.at: Likewise.
        * tests/modules.at: Likewise.
        * doc/m4.texinfo: Likewise.

- --
Life is short - so eat dessert first!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFE2eH284KuGfSFAYARAiMmAJsFkoCHPqcPailaxNX54hvOajeZDQCgtucw
7OyrpOpzvVUupnRlvGvucGw=
=KVoq
-----END PGP SIGNATURE-----
Index: bootstrap
===================================================================
RCS file: /sources/m4/m4/bootstrap,v
retrieving revision 1.34
diff -u -p -r1.34 bootstrap
--- bootstrap   17 Jul 2006 12:33:29 -0000      1.34
+++ bootstrap   9 Aug 2006 13:19:13 -0000
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-# bootstrap (GNU M4) version 2006-07-17
+# bootstrap (GNU M4) version 2006-08-09
 # Written by Gary V. Vaughan  <address@hidden>
 
 # Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -133,7 +133,7 @@ func_missing_arg ()
 func_usage ()
 {
     $SED '/^# Usage:/,/# -h/ {
-        s/^# //; s/^# *$//;
+       s/^# //; s/^# *$//;
        s/\$progname/'$progname'/;
        p;
     }; d' < "$progpath"
@@ -147,7 +147,7 @@ func_usage ()
 func_help ()
 {
     $SED '/^# Usage:/,/# Report bugs to/ {
-        s/^# //; s/^# *$//;
+       s/^# //; s/^# *$//;
        s/\$progname/'$progname'/;
        p;
      }; d' < "$progpath"
@@ -159,9 +159,9 @@ func_help ()
 func_version ()
 {
     $SED '/^# '$PROGRAM' (GNU /,/# warranty; / {
-        s/^# //; s/^# *$//;
-        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/;
-        p;
+       s/^# //; s/^# *$//;
+       s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/;
+       p;
      }; d' < "$progpath"
      exit $EXIT_SUCCESS
 }
@@ -181,7 +181,7 @@ func_version ()
     shift
     case $opt in
       -p|--download-po)
-                       test $# = 0 && func_missing_arg $opt && break
+                       test $# = 0 && func_missing_arg $opt && break
                        case $1 in
                          0|[Nn]*|[Ff]*) DOWNLOAD_PO=no ;;
                          [Oo]*)         DOWNLOAD_PO=only ;;
@@ -301,13 +301,6 @@ mv $config_macro_dir/regex.m4 $config_ma
 sed 's,lib/regex.c,gnu/regex.c,g' $config_macro_dir/regex-m4.old > 
$config_macro_dir/regex.m4 && \
   $RM $config_macro_dir/regex-m4.old
 
-func_echo "hiding gnulib jm_\* macros"
-cat >> $config_macro_dir/gnulib.m4 <<\EOF
-AC_DEFUN([gl_AC_HEADER_INTTYPES_H], [jm_AC_HEADER_INTTYPES_H])
-AC_DEFUN([gl_AC_HEADER_STDINT_H], [jm_AC_HEADER_STDINT_H])
-AC_DEFUN([gl_AC_TYPE_UINTMAX_T], [jm_AC_TYPE_UINTMAX_T])
-EOF
-
 
 ## --------------------------------- ##
 ## Copy additional src only modules. ##
Index: ltdl/m4/gnulib-cache.m4
===================================================================
RCS file: /sources/m4/m4/ltdl/m4/gnulib-cache.m4,v
retrieving revision 1.6
diff -u -p -r1.6 gnulib-cache.m4
--- ltdl/m4/gnulib-cache.m4     20 Jul 2006 15:45:43 -0000      1.6
+++ ltdl/m4/gnulib-cache.m4     9 Aug 2006 13:19:13 -0000
@@ -15,10 +15,10 @@
 
 
 # Specification in the form of a command-line invocation:
-#   gnulib-tool --import --dir=. --lib=libgnu --source-base=gnu 
--m4-base=ltdl/m4 --doc-base=doc --aux-dir=ltdl/config --libtool 
--macro-prefix=M4 --assume-autoconf=2.60 assert error exit fdl free gendocs 
gettext mkstemp obstack progname regex stdbool strtol xalloc xalloc-die 
xstrndup xvasprintf
+#   gnulib-tool --import --dir=. --lib=libgnu --source-base=gnu 
--m4-base=ltdl/m4 --doc-base=doc --aux-dir=ltdl/config --libtool 
--macro-prefix=M4 assert error exit fdl free gendocs gettext mkstemp obstack 
progname regex stdbool strtol verror xalloc xalloc-die xstrndup xvasprintf
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
-gl_MODULES([assert error exit fdl free gendocs gettext mkstemp obstack 
progname regex stdbool strtol xalloc xalloc-die xstrndup xvasprintf])
+gl_MODULES([assert error exit fdl free gendocs gettext mkstemp obstack 
progname regex stdbool strtol verror xalloc xalloc-die xstrndup xvasprintf])
 gl_AVOID([])
 gl_SOURCE_BASE([gnu])
 gl_M4_BASE([ltdl/m4])
@@ -27,4 +27,3 @@ gl_TESTS_BASE([tests])
 gl_LIB([libgnu])
 gl_LIBTOOL
 gl_MACRO_PREFIX([M4])
-gl_AUTOCONF_MINVERSION([2.60])
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.28
diff -u -p -r1.28 m4.texinfo
--- doc/m4.texinfo      19 Jul 2006 12:16:52 -0000      1.28
+++ doc/m4.texinfo      9 Aug 2006 13:19:14 -0000
@@ -1644,7 +1644,7 @@ warning about missing arguments is never
 ifelse(`some comments')
 @result{}
 ifelse(`foo', `bar')
address@hidden: input.m4: 2: Warning: ifelse: too few arguments: 2 < 3
address@hidden:input.m4:2: Warning: ifelse: too few arguments: 2 < 3
 @result{}
 @end example
 
@@ -2632,10 +2632,11 @@ The builtin macros @code{include} and @c
 only when given arguments.
 @end deffn
 
address@hidden status: 1
 @example
 include(`none')
 @result{}
address@hidden: input.m4: 1: Cannot open none: No such file or directory
address@hidden:input.m4:1: include: cannot open `none': No such file or 
directory
 sinclude(`none')
 @result{}
 @end example
@@ -3602,6 +3603,7 @@ The builtin macro @code{eval} is recogni
 
 Here are a few examples of use of @code{eval}.
 
address@hidden status: 1
 @example
 eval(`-3 * 5')
 @result{}-15
@@ -3616,7 +3618,7 @@ square(square(5)+1)
 define(`foo', `666')
 @result{}
 eval(`foo / 6')
address@hidden: input.m4: 7: Warning: eval: bad expression: foo / 6
address@hidden:input.m4:7: eval: bad expression: foo / 6
 @result{}
 eval(foo/6)
 @result{}111
Index: m4/debug.c
===================================================================
RCS file: /sources/m4/m4/m4/debug.c,v
retrieving revision 1.20
diff -u -p -r1.20 debug.c
--- m4/debug.c  1 May 2005 11:10:05 -0000       1.20
+++ m4/debug.c  9 Aug 2006 13:19:14 -0000
@@ -1,5 +1,5 @@
 /* GNU m4 -- A simple macro processor
-   Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1992, 1993, 1994, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -170,7 +170,7 @@ m4_debug_message_prefix (m4 *context)
   debug_file = m4_get_debug_file (context);
   fprintf (debug_file, "m4 debug: ");
   if (m4_is_debug_bit (context, M4_DEBUG_TRACE_FILE))
-    fprintf (debug_file, "%s: ", m4_current_file);
+    fprintf (debug_file, "%s: ", m4_get_current_file (context));
   if (m4_is_debug_bit (context, M4_DEBUG_TRACE_LINE))
-    fprintf (debug_file, "%d: ", m4_current_line);
+    fprintf (debug_file, "%d: ", m4_get_current_line (context));
 }
Index: m4/input.c
===================================================================
RCS file: /sources/m4/m4/m4/input.c,v
retrieving revision 1.41
diff -u -p -r1.41 input.c
--- m4/input.c  22 Jul 2006 19:23:04 -0000      1.41
+++ m4/input.c  9 Aug 2006 13:19:15 -0000
@@ -68,26 +68,26 @@
    input file.  */
 
 static int   file_peek                 (void);
-static int   file_read                 (void);
+static int   file_read                 (m4 *);
 static void  file_unget                (int ch);
 static void  file_clean                (m4 *context);
 static void  init_builtin_token        (m4 *context, m4_symbol_value *token);
 static int   builtin_peek              (void);
-static int   builtin_read              (void);
+static int   builtin_read              (m4 *);
 static int   match_input               (m4 *context, const unsigned char *s);
 static int   next_char                 (m4 *context);
 static void  pop_input                 (m4 *context);
 static int   single_peek               (void);
-static int   single_read               (void);
+static int   single_read               (m4 *);
 static int   string_peek               (void);
-static int   string_read               (void);
+static int   string_read               (m4 *);
 static void  string_unget              (int ch);
 static void  unget_input               (int ch);
 
 struct input_funcs
 {
   int (*peek_func) (void);     /* function to peek input */
-  int (*read_func) (void);     /* function to read input */
+  int (*read_func) (m4 *);     /* function to read input */
   void (*unget_func) (int);    /* function to unread input */
   void (*clean_func) (m4 *);   /* function to clean up */
 };
@@ -138,12 +138,6 @@ struct input_block
 typedef struct input_block input_block;
 
 
-/* Current input file name.  */
-const char *m4_current_file;
-
-/* Current input line number.  */
-int m4_current_line;
-
 /* Obstack for storing individual tokens.  */
 static m4_obstack token_stack;
 
@@ -168,7 +162,7 @@ static input_block *wsp;
 /* Aux. for handling split m4_push_string ().  */
 static input_block *next;
 
-/* Flag for next_char () to increment m4_current_line.  */
+/* Flag for next_char () to increment current_line.  */
 static bool start_of_input_line;
 
 
@@ -197,14 +191,14 @@ file_peek (void)
 }
 
 static int
-file_read (void)
+file_read (m4 *context)
 {
   int ch;
 
   if (start_of_input_line)
     {
       start_of_input_line = false;
-      m4_current_line++;
+      m4_set_current_line (context, m4_get_current_line (context) + 1);
     }
 
   ch = getc (isp->u.u_f.file);
@@ -233,8 +227,8 @@ file_clean (m4 *context)
                       isp->u.u_f.name, isp->u.u_f.lineno);
 
   fclose (isp->u.u_f.file);
-  m4_current_file = isp->u.u_f.name;
-  m4_current_line = isp->u.u_f.lineno;
+  m4_set_current_file (context, isp->u.u_f.name);
+  m4_set_current_line (context, isp->u.u_f.lineno);
   m4_output_current_line = isp->u.u_f.out_lineno;
   start_of_input_line = isp->u.u_f.advance_line;
   if (isp->prev != NULL)
@@ -264,13 +258,14 @@ m4_push_file (m4 *context, FILE *fp, con
   i->funcs = &file_funcs;
 
   i->u.u_f.file = fp;
-  i->u.u_f.name = m4_current_file;
-  i->u.u_f.lineno = m4_current_line;
+  i->u.u_f.name = m4_get_current_file (context);
+  i->u.u_f.lineno = m4_get_current_line (context);
   i->u.u_f.out_lineno = m4_output_current_line;
   i->u.u_f.advance_line = start_of_input_line;
 
-  m4_current_file = obstack_copy0 (current_input, title, strlen (title));
-  m4_current_line = 1;
+  m4_set_current_file (context, obstack_copy0 (current_input, title,
+                                              strlen (title)));
+  m4_set_current_line (context, 1);
   m4_output_current_line = -1;
 
   i->prev = isp;
@@ -290,7 +285,7 @@ builtin_peek (void)
 }
 
 static int
-builtin_read (void)
+builtin_read (m4 *context M4_GNUC_UNUSED)
 {
   if (isp->u.u_b.read == true)
     return CHAR_RETRY;
@@ -341,7 +336,7 @@ single_peek (void)
 }
 
 static int
-single_read (void)
+single_read (m4 *context M4_GNUC_UNUSED)
 {
   int ch = isp->u.u_c.ch;
 
@@ -388,7 +383,7 @@ string_peek (void)
 }
 
 static int
-string_read (void)
+string_read (m4 *context M4_GNUC_UNUSED)
 {
   int ch = *isp->u.u_s.current++;
 
@@ -414,13 +409,12 @@ m4_push_string_init (m4 *context)
 {
   if (next != NULL)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               "INTERNAL ERROR: Recursive m4_push_string!"));
+      assert (!"INTERNAL ERROR: recursive m4_push_string!");
       abort ();
     }
 
   next = (input_block *) obstack_alloc (current_input,
-                                       sizeof (struct input_block));
+                                       sizeof (struct input_block));
   next->funcs = &string_funcs;
 
   return current_input;
@@ -480,7 +474,7 @@ m4_push_wrapup (const char *s)
 
 
 /* The function pop_input () pops one level of input sources.  If the
-   popped input_block is a file, m4_current_file and m4_current_line are
+   popped input_block is a file, current_file and current_line are
    reset to the saved values before the memory for the input_block are
    released.  */
 static void
@@ -520,8 +514,7 @@ init_builtin_token (m4 *context, m4_symb
 {
   if (isp->funcs->read_func != builtin_read)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               "INTERNAL ERROR: Bad call to init_builtin_token ()"));
+      assert (!"INTERNAL ERROR: bad call to init_builtin_token ()");
       abort ();
     }
 
@@ -541,7 +534,7 @@ static int
 next_char (m4 *context)
 {
   int ch;
-  int (*f) (void);
+  int (*f) (m4 *);
 
   while (1)
     {
@@ -551,7 +544,7 @@ next_char (m4 *context)
       f = isp->funcs->read_func;
       if (f != NULL)
        {
-         while ((ch = (*f)()) != CHAR_RETRY)
+         while ((ch = f (context)) != CHAR_RETRY)
            {
              /* if (!IS_IGNORE(ch)) */
                return ch;
@@ -559,8 +552,7 @@ next_char (m4 *context)
        }
       else
        {
-         M4ERROR ((m4_get_warning_status_opt (context), 0,
-                   "INTERNAL ERROR: Input stack botch in next_char ()"));
+         assert (!"INTERNAL ERROR: input stack botch in next_char ()");
          abort ();
        }
 
@@ -593,8 +585,7 @@ m4_peek_input (m4 *context)
        }
       else
        {
-         M4ERROR ((m4_get_warning_status_opt (context), 0,
-                   "INTERNAL ERROR: Input stack botch in m4_peek_input ()"));
+         assert (!"INTERNAL ERROR: input stack botch in m4_peek_input ()");
          abort ();
        }
 
@@ -679,10 +670,14 @@ match_input (m4 *context, const unsigned
 
 /* Inititialise input stacks, and quote/comment characters.  */
 void
-m4_input_init (void)
+m4_input_init (m4 *context)
 {
-  m4_current_file = _("NONE");
-  m4_current_line = 0;
+  /* FIXME: The user should never be able to see the name "NONE", even
+     during m4wrap expansion.  If we fix that, we should be able to
+     use NULL instead of a string.  Hence, we don't translate this
+     string.  */
+  m4_set_current_file (context, "NONE");
+  m4_set_current_line (context, 0);
 
   obstack_init (&token_stack);
   obstack_init (&input_stack);
@@ -825,8 +820,8 @@ m4__next_token (m4 *context, m4_symbol_v
       }
     else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_LQUOTE))
       {                                        /* QUOTED STRING, SINGLE QUOTES 
*/
-       const char *current_file = m4_current_file;
-       int current_line = m4_current_line;
+       const char *current_file = m4_get_current_file (context);
+       int current_line = m4_get_current_line (context);
        quote_level = 1;
        while (1)
          {
@@ -855,8 +850,8 @@ m4__next_token (m4 *context, m4_symbol_v
     else if (!m4_is_syntax_single_quotes (M4SYNTAX)
             && MATCH (context, ch, context->syntax->lquote.string))
       {                                        /* QUOTED STRING, LONGER QUOTES 
*/
-       const char *current_file = m4_current_file;
-       int current_line = m4_current_line;
+       const char *current_file = m4_get_current_file (context);
+       int current_line = m4_get_current_line (context);
        quote_level = 1;
        while (1)
          {
Index: m4/m4module.h
===================================================================
RCS file: /sources/m4/m4/m4/m4module.h,v
retrieving revision 1.76
diff -u -p -r1.76 m4module.h
--- m4/m4module.h       28 Jul 2006 14:06:10 -0000      1.76
+++ m4/m4module.h       9 Aug 2006 13:19:15 -0000
@@ -92,11 +92,8 @@ extern void      m4_dump_args      (m4 *,
                                       bool);
 
 /* Error handling.  */
-#define M4ERROR(Arglist) (error Arglist)
-#define M4WARN(Arglist)                                M4_STMT_START { \
-       if (!m4_get_suppress_warnings_opt (context)) M4ERROR (Arglist); \
-                                                       } M4_STMT_END
-
+extern void m4_error (m4 *, int, int, const char *, ...) M4_GNUC_PRINTF (4, 5);
+extern void m4_warn  (m4 *, int, const char *, ...)      M4_GNUC_PRINTF (3, 4);
 
 
 /* --- CONTEXT MANAGEMENT --- */
@@ -111,9 +108,11 @@ extern void                m4_delete       (m4 *);
 #define m4_context_field_table                                         \
        M4FIELD(m4_symbol_table *, symbol_table,   symtab)              \
        M4FIELD(m4_syntax_table *, syntax_table,   syntax)              \
+       M4FIELD(const char *,      current_file,   current_file)        \
+       M4FIELD(int,               current_line,   current_line)        \
        M4FIELD(FILE *,            debug_file,     debug_file)          \
        M4FIELD(m4_obstack,        trace_messages, trace_messages)      \
-       M4FIELD(int,    warning_status_opt,        warning_status)      \
+       M4FIELD(int,               exit_status,    exit_status)         \
        M4FIELD(bool,   no_gnu_extensions_opt,     no_gnu_extensions)   \
        M4FIELD(int,    nesting_limit_opt,         nesting_limit)       \
        M4FIELD(int,    debug_level_opt,           debug_level)         \
@@ -128,6 +127,7 @@ extern void         m4_delete       (m4 *);
        M4OPT_BIT(M4_OPT_INTERACTIVE_BIT,       interactive_opt)        \
        M4OPT_BIT(M4_OPT_SYNC_OUTPUT_BIT,       sync_output_opt)        \
        M4OPT_BIT(M4_OPT_POSIXLY_CORRECT_BIT,   posixly_correct_opt)    \
+       M4OPT_BIT(M4_OPT_FATAL_WARN_BIT,        fatal_warnings_opt)     \
 
 
 #define M4FIELD(type, base, field)                                     \
@@ -344,13 +344,9 @@ extern int m4_set_syntax   (m4_syntax_tabl
 
 
 
-/* --- INPUT TOKENISATION --- */
-
-/* current input file, and line */
-extern const char *m4_current_file;
-extern int m4_current_line;
+/* --- INPUT TOKENIZATION --- */
 
-extern void    m4_input_init   (void);
+extern void    m4_input_init   (m4 *context);
 extern void    m4_input_exit   (void);
 extern int     m4_peek_input   (m4 *context);
 extern void    m4_skip_line    (m4 *context);
@@ -380,10 +376,10 @@ extern void       m4_shipout_string (m4 *, m4_
                                   int, bool);
 
 extern void    m4_make_diversion    (int);
-extern void    m4_insert_diversion  (int);
-extern void    m4_insert_file       (FILE *);
-extern void    m4_freeze_diversions (FILE *);
-extern void    m4_undivert_all      (void);
+extern void    m4_insert_diversion  (m4 *, int);
+extern void    m4_insert_file       (m4 *, FILE *);
+extern void    m4_freeze_diversions (m4 *, FILE *);
+extern void    m4_undivert_all      (m4 *);
 
 
 
Index: m4/m4private.h
===================================================================
RCS file: /sources/m4/m4/m4/m4private.h,v
retrieving revision 1.52
diff -u -p -r1.52 m4private.h
--- m4/m4private.h      28 Jul 2006 14:06:11 -0000      1.52
+++ m4/m4private.h      9 Aug 2006 13:19:15 -0000
@@ -26,13 +26,8 @@
 #  include <config.h>
 #endif
 
-#include <errno.h>
-
-#ifndef errno
-extern int errno;
-#endif
-
 #include <assert.h>
+#include <errno.h>
 
 #include "m4module.h"
 
@@ -56,11 +51,14 @@ struct m4 {
   m4_symbol_table *    symtab;
   m4_syntax_table *    syntax;
 
+  const char *         current_file;   /* Current input file.  */
+  int                  current_line;   /* Current input line.  */
+
   FILE *               debug_file;     /* File for debugging output.  */
   m4_obstack           trace_messages;
+  int                  exit_status;    /* Cumulative exit status.  */
 
   /* Option flags  (set in src/main.c).  */
-  int          warning_status;                 /* -E */
   bool         no_gnu_extensions;              /* -G */
   int          nesting_limit;                  /* -L */
   int          debug_level;                    /* -d */
@@ -78,6 +76,7 @@ struct m4 {
 #define M4_OPT_INTERACTIVE_BIT         (1 << 3) /* -e */
 #define M4_OPT_SYNC_OUTPUT_BIT         (1 << 4) /* -s */
 #define M4_OPT_POSIXLY_CORRECT_BIT     (1 << 5) /* POSIXLY_CORRECT */
+#define M4_OPT_FATAL_WARN_BIT          (1 << 6) /* -E */
 
 /* Fast macro versions of accessor functions for public fields of m4,
    that also have an identically named function exported in m4module.h.  */
@@ -86,12 +85,16 @@ struct m4 {
 #  define m4_set_symbol_table(C, V)            ((C)->symtab = (V))
 #  define m4_get_syntax_table(C)               ((C)->syntax)
 #  define m4_set_syntax_table(C, V)            ((C)->syntax = (V))
+#  define m4_get_current_file(C)               ((C)->current_file)
+#  define m4_set_current_file(C, V)            ((C)->current_file = (V))
+#  define m4_get_current_line(C)               ((C)->current_line)
+#  define m4_set_current_line(C, V)            ((C)->current_line = (V))
 #  define m4_get_debug_file(C)                 ((C)->debug_file)
 #  define m4_set_debug_file(C, V)              ((C)->debug_file = (V))
 #  define m4_get_trace_messages(C)             ((C)->trace_messages)
 #  define m4_set_trace_messages(C, V)          ((C)->trace_messages = (V))
-#  define m4_get_warning_status_opt(C)         ((C)->warning_status)
-#  define m4_set_warning_status_opt(C, V)      ((C)->warning_status = (V))
+#  define m4_get_exit_status(C)                        ((C)->exit_status)
+#  define m4_set_exit_status(C, V)             ((C)->exit_status = (V))
 #  define m4_get_no_gnu_extensions_opt(C)      ((C)->no_gnu_extensions)
 #  define m4_set_no_gnu_extensions_opt(C, V)   ((C)->no_gnu_extensions = (V))
 #  define m4_get_nesting_limit_opt(C)          ((C)->nesting_limit)
@@ -115,6 +118,8 @@ struct m4 {
                (BIT_TEST((C)->opt_flags, M4_OPT_SYNC_OUTPUT_BIT))
 #  define m4_get_posixly_correct_opt(C)                                        
\
                (BIT_TEST((C)->opt_flags, M4_OPT_POSIXLY_CORRECT_BIT))
+#  define m4_get_fatal_warnings_opt(C)                                 \
+               (BIT_TEST((C)->opt_flags, M4_OPT_FATAL_WARN_BIT))
 
 /* No fast opt bit set macros, as they would need to evaluate their
    arguments more than once, which would subtly change their semantics.  */
Index: m4/macro.c
===================================================================
RCS file: /sources/m4/m4/m4/macro.c,v
retrieving revision 1.46
diff -u -p -r1.46 macro.c
--- m4/macro.c  28 Jul 2006 14:06:11 -0000      1.46
+++ m4/macro.c  9 Aug 2006 13:19:15 -0000
@@ -119,8 +119,7 @@ expand_token (m4 *context, m4_obstack *o
       break;
 
     default:
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               "INTERNAL ERROR: Bad token type in expand_token ()"));
+      assert (!"INTERNAL ERROR: bad token type in expand_token ()");
       abort ();
     }
 
@@ -142,8 +141,8 @@ expand_argument (m4 *context, m4_obstack
   m4_symbol_value token;
   char *text;
   int paren_level = 0;
-  const char *current_file = m4_current_file;
-  int current_line = m4_current_line;
+  const char *current_file = m4_get_current_file (context);
+  int current_line = m4_get_current_line (context);
 
   argp->type = M4_SYMBOL_VOID;
 
@@ -200,8 +199,7 @@ expand_argument (m4 *context, m4_obstack
          break;
 
        default:
-         M4ERROR ((m4_get_warning_status_opt (context), 0,
-                   "INTERNAL ERROR: Bad token type in expand_argument ()"));
+         assert (!"INTERNAL ERROR: bad token type in expand_argument ()");
          abort ();
        }
 
@@ -231,9 +229,9 @@ expand_macro (m4 *context, const char *n
 
   expansion_level++;
   if (expansion_level > m4_get_nesting_limit_opt (context))
-    M4ERROR ((EXIT_FAILURE, 0, _("\
-ERROR: Recursion limit of %d exceeded, use -L<N> to change it"),
-             m4_get_nesting_limit_opt (context)));
+    m4_error (context, EXIT_FAILURE, 0, _("\
+recursion limit of %d exceeded, use -L<N> to change it"),
+             m4_get_nesting_limit_opt (context));
 
   macro_call_id++;
   my_call_id = macro_call_id;
@@ -331,14 +329,13 @@ m4_macro_call (m4 *context, m4_symbol *s
     }
   else if (m4_is_symbol_placeholder (symbol))
     {
-      M4WARN ((m4_get_warning_status_opt (context), 0, _("\
+      m4_warn (context, 0, _("\
 Warning: %s: builtin `%s' requested by frozen file not found"),
-              M4ARG (0), m4_get_symbol_placeholder (symbol)));
+              M4ARG (0), m4_get_symbol_placeholder (symbol));
     }
   else
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               "INTERNAL ERROR: Bad symbol type in call_macro ()"));
+      assert (!"INTERNAL ERROR: bad symbol type in call_macro ()");
       abort ();
     }
 }
@@ -407,8 +404,14 @@ process_macro (m4 *context, m4_symbol *s
              const char * endp;
              const char * key;
 
-             for (endp = ++text; *endp && m4_has_syntax (M4SYNTAX, *endp, 
M4_SYNTAX_OTHER|M4_SYNTAX_ALPHA|M4_SYNTAX_NUM); ++endp)
-               ++len;
+             for (endp = ++text;
+                  *endp && m4_has_syntax (M4SYNTAX, *endp,
+                                          (M4_SYNTAX_OTHER | M4_SYNTAX_ALPHA
+                                           | M4_SYNTAX_NUM));
+                  ++endp)
+               {
+                 ++len;
+               }
              key = xstrndup (text, len);
 
              if (*endp)
@@ -424,19 +427,20 @@ process_macro (m4 *context, m4_symbol *s
                      if (i < argc)
                        m4_shipout_string (context, obs, M4ARG (i), 0, false);
                      else
-                       M4ERROR ((EXIT_FAILURE, 0, "\
-INTERNAL ERROR: %s: out of range reference `%d' from argument %s",
-                             M4ARG (0), i, key));
+                       {
+                         assert (!"INTERNAL ERROR: out of range reference");
+                         abort ();
+                       }
                    }
                }
              else
                {
-                 M4ERROR ((m4_get_warning_status_opt (context), 0,
-                         _("Error: %s: unterminated parameter reference: %s"),
-                           M4ARG (0), key));
+                 m4_error (context, 0, 0,
+                           _("%s: unterminated parameter reference: %s"),
+                           M4ARG (0), key);
                }
 
-             text = *endp ? 1+ endp : endp;
+             text = *endp ? 1 + endp : endp;
 
              free ((char *) key);
              break;
@@ -532,9 +536,9 @@ trace_header (m4 *context, int id)
 {
   trace_format (context, "m4trace:");
   if (m4_is_debug_bit (context, M4_DEBUG_TRACE_FILE))
-    trace_format (context, "%s:", m4_current_file);
+    trace_format (context, "%s:", m4_get_current_file (context));
   if (m4_is_debug_bit (context, M4_DEBUG_TRACE_LINE))
-    trace_format (context, "%d:", m4_current_line);
+    trace_format (context, "%d:", m4_get_current_line (context));
   trace_format (context, " -%d- ", expansion_level);
   if (m4_is_debug_bit (context, M4_DEBUG_TRACE_CALLID))
     trace_format (context, "id %d: ", id);
@@ -594,8 +598,7 @@ trace_pre (m4 *context, const char *name
                                            m4_get_symbol_value_func(argv[i]));
              if (bp == NULL)
                {
-                 M4ERROR ((m4_get_warning_status_opt (context), 0, "\
-INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"));
+                 assert (!"INTERNAL ERROR: builtin not found in table!");
                  abort ();
                }
              trace_format (context, "<%s>", bp->name);
@@ -607,8 +610,7 @@ INTERNAL ERROR: Builtin not found in bui
            }
          else
            {
-             M4ERROR ((m4_get_warning_status_opt (context), 0,
-                       "INTERNAL ERROR: Bad token data type (trace_pre ())"));
+             assert (!"INTERNAL ERROR: bad token data type (trace_pre ())");
              abort ();
            }
        }
Index: m4/module.c
===================================================================
RCS file: /sources/m4/m4/m4/module.c,v
retrieving revision 1.38
diff -u -p -r1.38 module.c
--- m4/module.c 22 Jul 2006 19:23:04 -0000      1.38
+++ m4/module.c 9 Aug 2006 13:19:15 -0000
@@ -122,9 +122,8 @@ m4_module_import (m4 *context, const cha
       symbol_address = lt_dlsym (handle, symbol_name);
 
       if (!symbol_address)
-       M4ERROR ((m4_get_warning_status_opt (context), 0,
-                 _("Warning: cannot load symbol `%s' from module `%s'"),
-                   symbol_name, module_name));
+       m4_error (context, 0, 0, _("cannot load symbol `%s' from module `%s'"),
+                 symbol_name, module_name);
     }
 
   return (void *) symbol_address;
@@ -230,9 +229,8 @@ m4_module_load (m4 *context, const char 
          if (!name)
            name = MODULE_SELF_NAME;
 
-         M4ERROR ((m4_get_warning_status_opt (context), 0,
-                   _("Warning: cannot load module `%s': %s"),
-                   name, module_dlerror ()));
+         m4_error (context, 0, 0, _("cannot load module `%s': %s"),
+                   name, module_dlerror ());
        }
       else if (info->ref_count == 1)
        {
@@ -268,9 +266,9 @@ m4_module_unload (m4 *context, const cha
 
   if (errors)
     {
-      M4ERROR ((EXIT_FAILURE, 0,
+      m4_error (context, EXIT_FAILURE, 0,
                _("cannot unload module `%s': %s"),
-               name ? name : MODULE_SELF_NAME, module_dlerror ()));
+               name ? name : MODULE_SELF_NAME, module_dlerror ());
     }
 }
 
@@ -321,8 +319,7 @@ m4__module_init (m4 *context)
      module system has already been initialised.  */
   if (iface_id)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: multiple module loader initialisations")));
+      m4_error (context, 0, 0, _("multiple module loader initializations"));
       return;
     }
 
@@ -362,9 +359,9 @@ m4__module_init (m4 *context)
 
   /* Couldn't initialise the module system; diagnose and exit.  */
   if (errors)
-    M4ERROR ((EXIT_FAILURE, 0,
-             _("failed to initialise module loader: %s"),
-             module_dlerror ()));
+    m4_error (context, EXIT_FAILURE, 0,
+             _("failed to initialize module loader: %s"),
+             module_dlerror ());
 
 #ifdef DEBUG_MODULES
   M4_DEBUG_MESSAGE ("Module loader initialised.");
@@ -413,9 +410,8 @@ m4__module_open (m4 *context, const char
          && !lt_dlsym (handle, BUILTIN_SYMBOL)
          && !lt_dlsym (handle, MACRO_SYMBOL))
        {
-           M4ERROR ((EXIT_FAILURE, 0,
-                     _("module `%s' has no entry points"),
-                     name));
+         m4_error (context, EXIT_FAILURE, 0,
+                   _("module `%s' has no entry points"), name);
        }
 
 #ifdef DEBUG_MODULES
@@ -425,9 +421,8 @@ m4__module_open (m4 *context, const char
   else
     {
       /* Couldn't open the module; diagnose and exit. */
-      M4ERROR ((EXIT_FAILURE, 0,
-               _("cannot open module `%s': %s"),
-               name, module_dlerror ()));
+      m4_error (context, EXIT_FAILURE, 0, _("cannot open module `%s': %s"),
+               name, module_dlerror ());
     }
 
   return handle;
@@ -461,9 +456,8 @@ m4__module_exit (m4 *context)
 
   if (errors)
     {
-      M4ERROR ((EXIT_FAILURE, 0,
-               _("cannot unload all modules: %s"),
-               module_dlerror ()));
+      m4_error (context, EXIT_FAILURE, 0, _("cannot unload all modules: %s"),
+               module_dlerror ());
     }
 }
 
@@ -522,9 +516,8 @@ module_close (m4 *context, lt_dlhandle h
 
   if (errors)
     {
-      M4ERROR ((EXIT_FAILURE, 0,
-               _("cannot close module `%s': %s"),
-               name, module_dlerror ()));
+      m4_error (context, EXIT_FAILURE, 0, _("cannot close module `%s': %s"),
+               name, module_dlerror ());
     }
 
   free ((void *) name);
Index: m4/output.c
===================================================================
RCS file: /sources/m4/m4/m4/output.c,v
retrieving revision 1.25
diff -u -p -r1.25 output.c
--- m4/output.c 22 Jul 2006 19:23:04 -0000      1.25
+++ m4/output.c 9 Aug 2006 13:19:15 -0000
@@ -157,7 +157,7 @@ tmpfile (void)
    to be flushed to a newly created temporary file.  This flushed buffer
    might well be the current one.  */
 static void
-make_room_for (int length)
+make_room_for (m4 *context, int length)
 {
   int wanted_size;
 
@@ -204,8 +204,8 @@ make_room_for (int length)
 
       selected_diversion->file = tmpfile ();
       if (selected_diversion->file == NULL)
-       M4ERROR ((EXIT_FAILURE, errno,
-                 _("cannot create temporary file for diversion")));
+       m4_error (context, EXIT_FAILURE, errno,
+                 _("cannot create temporary file for diversion"));
 
       if (selected_diversion->used > 0)
        {
@@ -214,8 +214,8 @@ make_room_for (int length)
                          1,
                          selected_diversion->file);
          if (count != 1)
-           M4ERROR ((EXIT_FAILURE, errno,
-                     _("cannot flush diversion to temporary file")));
+           m4_error (context, EXIT_FAILURE, errno,
+                     _("cannot flush diversion to temporary file"));
        }
 
       /* Reclaim the buffer space for other diversions.  */
@@ -255,20 +255,21 @@ make_room_for (int length)
     }
 }
 
-/* Output one character CHAR, when it is known that it goes to a diversion
-   file or an in-memory diversion buffer.  */
-#define OUTPUT_CHARACTER(Char) \
+/* Output one character CHAR, when it is known that it goes to a
+   diversion file or an in-memory diversion buffer.  A variable m4
+   *context must be in scope.  */
+#define OUTPUT_CHARACTER(Char)                                          \
   if (output_file)                                                     \
     putc ((Char), output_file);                                                
\
   else if (output_unused == 0)                                         \
-    output_character_helper ((Char));                                  \
+    output_character_helper (context, (Char));                          \
   else                                                                 \
     (output_unused--, *output_cursor++ = (Char))
 
 static void
-output_character_helper (int character)
+output_character_helper (m4 *context, int character)
 {
-  make_room_for (1);
+  make_room_for (context, 1);
 
   if (output_file)
     putc (character, output_file);
@@ -282,18 +283,18 @@ output_character_helper (int character)
 /* Output one TEXT having LENGTH characters, when it is known that it goes
    to a diversion file or an in-memory diversion buffer.  */
 static void
-output_text (const char *text, int length)
+output_text (m4 *context, const char *text, int length)
 {
   int count;
 
   if (!output_file && length > output_unused)
-    make_room_for (length);
+    make_room_for (context, length);
 
   if (output_file)
     {
       count = fwrite (text, length, 1, output_file);
       if (count != 1)
-       M4ERROR ((EXIT_FAILURE, errno, _("copying inserted file")));
+       m4_error (context, EXIT_FAILURE, errno, _("copying inserted file"));
     }
   else
     {
@@ -355,7 +356,7 @@ m4_shipout_text (m4 *context, m4_obstack
        /* Optimize longer texts.  */
 
       default:
-       output_text (text, length);
+       output_text (context, text, length);
       }
   else
     for (; length-- > 0; text++)
@@ -374,21 +375,24 @@ m4_shipout_text (m4 *context, m4_obstack
               If output_current_line was previously given a negative
               value (invalidated), rather output `#line NUM "FILE"'.  */
 
-           if (m4_output_current_line != m4_current_line)
+           if (m4_output_current_line != m4_get_current_line (context))
              {
-               sprintf (line, "#line %d", m4_current_line);
+               sprintf (line, "#line %d", m4_get_current_line (context));
                for (cursor = line; *cursor; cursor++)
                  OUTPUT_CHARACTER (*cursor);
                if (m4_output_current_line < 1)
                  {
                    OUTPUT_CHARACTER (' ');
                    OUTPUT_CHARACTER ('"');
-                   for (cursor = m4_current_file; *cursor; cursor++)
-                     OUTPUT_CHARACTER (*cursor);
+                   for (cursor = m4_get_current_file (context);
+                        *cursor; cursor++)
+                     {
+                       OUTPUT_CHARACTER (*cursor);
+                     }
                    OUTPUT_CHARACTER ('"');
                  }
                OUTPUT_CHARACTER ('\n');
-               m4_output_current_line = m4_current_line;
+               m4_output_current_line = m4_get_current_line (context);
              }
          }
        OUTPUT_CHARACTER (*text);
@@ -484,7 +488,7 @@ m4_make_diversion (int divnum)
    diversions are handled.  This allows files to be included, without
    having them rescanned by m4.  */
 void
-m4_insert_file (FILE *file)
+m4_insert_file (m4 *context, FILE *file)
 {
   char buffer[COPY_BUFFER_SIZE];
   size_t length;
@@ -499,10 +503,10 @@ m4_insert_file (FILE *file)
     {
       length = fread (buffer, 1, COPY_BUFFER_SIZE, file);
       if (ferror (file))
-       M4ERROR ((EXIT_FAILURE, errno, _("reading inserted file")));
+       m4_error (context, EXIT_FAILURE, errno, _("reading inserted file"));
       if (length == 0)
        break;
-      output_text (buffer, length);
+      output_text (context, buffer, length);
     }
 }
 
@@ -510,7 +514,7 @@ m4_insert_file (FILE *file)
    diversion is NOT placed on the expansion obstack, because it must not
    be rescanned.  When the file is closed, it is deleted by the system.  */
 void
-m4_insert_diversion (int divnum)
+m4_insert_diversion (m4 *context, int divnum)
 {
   struct diversion *diversion;
 
@@ -532,10 +536,10 @@ m4_insert_diversion (int divnum)
       if (diversion->file)
        {
          rewind (diversion->file);
-         m4_insert_file (diversion->file);
+         m4_insert_file (context, diversion->file);
        }
       else if (diversion->buffer)
-       output_text (diversion->buffer, diversion->used);
+       output_text (context, diversion->buffer, diversion->used);
 
       m4_output_current_line = -1;
     }
@@ -559,17 +563,17 @@ m4_insert_diversion (int divnum)
 /* Get back all diversions.  This is done just before exiting from main (),
    and from m4_undivert (), if called without arguments.  */
 void
-m4_undivert_all ()
+m4_undivert_all (m4 *context)
 {
   int divnum;
 
   for (divnum = 1; divnum < diversions; divnum++)
-    m4_insert_diversion (divnum);
+    m4_insert_diversion (context, divnum);
 }
 
 /* Produce all diversion information in frozen format on FILE.  */
 void
-m4_freeze_diversions (FILE *file)
+m4_freeze_diversions (m4 *context, FILE *file)
 {
   int saved_number;
   int last_inserted;
@@ -591,17 +595,19 @@ m4_freeze_diversions (FILE *file)
            {
              fflush (diversion->file);
              if (fstat (fileno (diversion->file), &file_stat) < 0)
-               M4ERROR ((EXIT_FAILURE, errno, _("cannot stat diversion")));
+               m4_error (context, EXIT_FAILURE, errno,
+                         _("cannot stat diversion"));
              if (file_stat.st_size < 0
                  || file_stat.st_size != (unsigned long) file_stat.st_size)
-               M4ERROR ((EXIT_FAILURE, errno, _("diversion too large")));
+               m4_error (context, EXIT_FAILURE, errno,
+                         _("diversion too large"));
              fprintf (file, "D%d,%lu", divnum,
                       (unsigned long) file_stat.st_size);
            }
          else
            fprintf (file, "D%d,%d\n", divnum, diversion->used);
 
-         m4_insert_diversion (divnum);
+         m4_insert_diversion (context, divnum);
          putc ('\n', file);
 
          last_inserted = divnum;
Index: m4/utility.c
===================================================================
RCS file: /sources/m4/m4/m4/utility.c,v
retrieving revision 1.42
diff -u -p -r1.42 utility.c
--- m4/utility.c        10 Jun 2006 13:10:57 -0000      1.42
+++ m4/utility.c        9 Aug 2006 13:19:15 -0000
@@ -22,6 +22,7 @@
 #endif
 
 #include "m4private.h"
+#include "verror.h"
 
 
 static const char * skip_space (m4 *, const char *);
@@ -32,23 +33,22 @@ static const char * skip_space (m4 *, co
    inappropriate number of arguments.  ARGC/ARGV are the arguments,
    MIN is the minimum number of acceptable arguments, negative if not
    applicable, MAX is the maximum number, negative if not applicable.
-   ARGC, MIN, and MAX count ARGV[0], the name of the macro.  */
+   ARGC, MIN, and MAX count ARGV[0], the name of the macro.  Return
+   true if there are too few arguments, false otherwise.  */
 bool
 m4_bad_argc (m4 *context, int argc, m4_symbol_value **argv, int min, int max)
 {
   if (min > 0 && argc < min)
     {
-      M4WARN ((m4_get_warning_status_opt (context), 0,
-              _("Warning: %s: too few arguments: %d < %d"),
-              M4ARG (0), argc - 1, min - 1));
+      m4_warn (context, 0, _("Warning: %s: too few arguments: %d < %d"),
+              M4ARG (0), argc - 1, min - 1);
       return true;
     }
 
   if (max > 0 && argc > max)
     {
-      M4WARN ((m4_get_warning_status_opt (context), 0,
-              _("Warning: %s: too many arguments (ignored): %d > %d"),
-              M4ARG (0), argc - 1, max - 1));
+      m4_warn (context, 0, _("Warning: %s: extra arguments ignored: %d > %d"),
+              M4ARG (0), argc - 1, max - 1);
       /* Return false, otherwise it is not exactly `ignored'. */
       return false;
     }
@@ -79,9 +79,8 @@ m4_numeric_arg (m4 *context, int argc, m
       || (*valuep = strtol (skip_space (context, M4ARG (arg)), &endp, 10),
          *skip_space (context, endp) != 0))
     {
-      M4WARN ((m4_get_warning_status_opt (context), 0,
-              _("Warning: %s: argument %d non-numeric: %s"),
-              M4ARG (0), arg - 1, M4ARG (arg)));
+      m4_warn (context, 0, _("Warning: %s: argument %d non-numeric: %s"),
+              M4ARG (0), arg - 1, M4ARG (arg));
       return false;
     }
   return true;
@@ -105,3 +104,46 @@ m4_dump_args (m4 *context, m4_obstack *o
       m4_shipout_string (context, obs, M4ARG (i), 0, quoted);
     }
 }
+
+/* Issue an error.  The message is printf-style, based on FORMAT and
+   any other arguments, and the program name and location (if we are
+   currently parsing an input file) are automatically prepended.  If
+   ERRNUM is non-zero, include strerror output in the message.  If
+   STATUS is non-zero, or if errors are fatal, call exit immediately;
+   otherwise, remember that an error occurred so that m4 cannot exit
+   with success later on.*/
+void
+m4_error (m4 *context, int status, int errnum, const char *format, ...)
+{
+  va_list args;
+  int line = m4_get_current_line (context);
+  va_start (args, format);
+  if (status == EXIT_SUCCESS && m4_get_fatal_warnings_opt (context))
+    status = EXIT_FAILURE;
+  verror_at_line (status, errnum, line ? m4_get_current_file (context) : NULL,
+                 line, format, args);
+  m4_set_exit_status (context, EXIT_FAILURE);
+}
+
+/* Issue a warning, if they are not being suppressed.  The message is
+   printf-style, based on FORMAT and any other arguments, and the
+   program name and location (if we are currently parsing an input
+   file) are automatically prepended.  If ERRNUM is non-zero, include
+   strerror output in the message.  If warnings are fatal, call exit
+   immediately, otherwise exit status is unchanged.  */
+void
+m4_warn (m4 *context, int errnum, const char *format, ...)
+{
+  if (!m4_get_suppress_warnings_opt (context))
+    {
+      va_list args;
+      int status = EXIT_SUCCESS;
+      int line = m4_get_current_line (context);
+      va_start (args, format);
+      if (m4_get_fatal_warnings_opt (context))
+       status = EXIT_FAILURE;
+      verror_at_line (status, errnum,
+                     line ? m4_get_current_file (context) : NULL, line,
+                     format, args);
+    }
+}
Index: modules/evalparse.c
===================================================================
RCS file: /sources/m4/m4/modules/evalparse.c,v
retrieving revision 1.13
diff -u -p -r1.13 evalparse.c
--- modules/evalparse.c 16 Jun 2006 01:32:41 -0000      1.13
+++ modules/evalparse.c 9 Aug 2006 13:19:15 -0000
@@ -35,6 +35,7 @@
    both `eval' and `mpeval', but which is redefined appropriately when
    this file is #included into its clients.  */
 
+#include <assert.h>
 #include <ctype.h>
 
 typedef enum eval_token
@@ -518,8 +519,7 @@ cmp_term (m4 *context, eval_token et, nu
          break;
 
        default:
-         M4ERROR ((m4_get_warning_status_opt (context), 0,
-                   "INTERNAL ERROR: Bad comparison operator in cmp_term ()"));
+         assert (!"INTERNAL ERROR: bad comparison operator in cmp_term ()");
          abort ();
        }
     }
@@ -563,8 +563,7 @@ shift_term (m4 *context, eval_token et, 
          break;
 
        default:
-         M4ERROR ((m4_get_warning_status_opt (context), 0,
-                   "INTERNAL ERROR: Bad shift operator in shift_term ()"));
+         assert (!"INTERNAL ERROR: bad shift operator in shift_term ()");
          abort ();
        }
     }
@@ -665,8 +664,7 @@ mult_term (m4 *context, eval_token et, n
          break;
 
        default:
-         M4ERROR ((m4_get_warning_status_opt (context), 0,
-                   "INTERNAL ERROR: Bad operator in mult_term ()"));
+         assert (!"INTERNAL ERROR: bad operator in mult_term ()");
          abort ();
        }
     }
@@ -783,9 +781,8 @@ m4_evaluate (m4 *context, m4_obstack *ob
 
   if (radix <= 1 || radix > 36)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: %s: radix out of range: %d"),
-               M4ARG(0), radix));
+      m4_error (context, 0, 0, _("%s: radix out of range: %d"),
+               M4ARG(0), radix);
       return;
     }
 
@@ -794,9 +791,7 @@ m4_evaluate (m4 *context, m4_obstack *ob
 
   if (min <= 0)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: %s: negative width: %d"),
-               M4ARG(0), min));
+      m4_error (context, 0, 0, _("%s: negative width: %d"), M4ARG(0), min);
       return;
     }
 
@@ -816,44 +811,36 @@ m4_evaluate (m4 *context, m4_obstack *ob
       break;
 
     case MISSING_RIGHT:
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: %s: missing right parenthesis: %s"),
-               M4ARG (0), M4ARG (1)));
+      m4_error (context, 0, 0, _("%s: missing right parenthesis: %s"),
+               M4ARG (0), M4ARG (1));
       break;
 
     case SYNTAX_ERROR:
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: %s: bad expression: %s"),
-               M4ARG (0), M4ARG (1)));
+      m4_error (context, 0, 0, _("%s: bad expression: %s"),
+               M4ARG (0), M4ARG (1));
       break;
 
     case UNKNOWN_INPUT:
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: %s: bad input: %s"),
-               M4ARG (0), M4ARG (1)));
+      m4_error (context, 0, 0, _("%s: bad input: %s"), M4ARG (0), M4ARG (1));
       break;
 
     case EXCESS_INPUT:
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: %s: excess input: %s"),
-               M4ARG (0), M4ARG (1)));
+      m4_error (context, 0, 0, _("%s: excess input: %s"), M4ARG (0),
+               M4ARG (1));
       break;
 
     case DIVIDE_ZERO:
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: %s: divide by zero: %s"),
-               M4ARG (0), M4ARG (1)));
+      m4_error (context, 0, 0, _("%s: divide by zero: %s"), M4ARG (0),
+               M4ARG (1));
       break;
 
     case MODULO_ZERO:
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Warning: %s: modulo by zero: %s"),
-               M4ARG (0), M4ARG (1)));
+      m4_error (context, 0, 0, _("%s: modulo by zero: %s"), M4ARG (0),
+               M4ARG (1));
       break;
 
     default:
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               "INTERNAL ERROR: Bad error code in evaluate ()"));
+      assert (!"INTERNAL ERROR: bad error code in evaluate ()");
       abort ();
     }
 
Index: modules/gnu.c
===================================================================
RCS file: /sources/m4/m4/modules/gnu.c,v
retrieving revision 1.45
diff -u -p -r1.45 gnu.c
--- modules/gnu.c       14 Jul 2006 15:27:34 -0000      1.45
+++ modules/gnu.c       9 Aug 2006 13:19:15 -0000
@@ -138,9 +138,8 @@ m4_regexp_compile (m4 *context, const ch
 
   if (msg != NULL)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("%s: bad regular expression `%s': %s"),
-               caller, regexp, msg));
+      m4_error (context, 0, 0, _("%s: bad regular expression `%s': %s"),
+               caller, regexp, msg);
       return NULL;
     }
 
@@ -229,9 +228,9 @@ m4_regexp_substitute (m4 *context, m4_ob
             copied verbatim.  */
 
          if (matchpos == -2)
-           M4ERROR ((m4_get_warning_status_opt (context), 0,
+           m4_error (context, 0, 0,
                      _("%s: error matching regular expression `%s'"),
-                     caller, regexp));
+                     caller, regexp);
          else if (!ignore_duplicates && (offset < length))
            obstack_grow (obs, victim + offset, length - offset);
          break;
@@ -269,7 +268,7 @@ m4_regexp_substitute (m4 *context, m4_ob
  **/
 M4BUILTIN_HANDLER (__file__)
 {
-  m4_shipout_string (context, obs, m4_current_file, 0, true);
+  m4_shipout_string (context, obs, m4_get_current_file (context), 0, true);
 }
 
 
@@ -278,7 +277,7 @@ M4BUILTIN_HANDLER (__file__)
  **/
 M4BUILTIN_HANDLER (__line__)
 {
-  m4_shipout_int (obs, m4_current_line);
+  m4_shipout_int (obs, m4_get_current_line (context));
 }
 
 
@@ -297,8 +296,7 @@ M4BUILTIN_HANDLER (builtin)
   bp = m4_builtin_find_by_name (NULL, name);
 
   if (bp == NULL)
-    M4ERROR ((m4_get_warning_status_opt (context), 0,
-             _("Undefined name %s"), name));
+    m4_error (context, 0, 0, _("%s: undefined name `%s'"), M4ARG (0), name);
   else
     (*bp->func) (context, obs, argc - 1, argv + 1);
 }
@@ -313,11 +311,7 @@ m4_resyntax_encode_safe (m4 *context, co
   int resyntax = m4_regexp_syntax_encode (spec);
 
   if (resyntax < 0)
-    {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("%s: bad syntax-spec: `%s'"),
-               caller, spec));
-    }
+    m4_error (context, 0, 0, _("%s: bad syntax-spec: `%s'"), caller, spec);
 
   return resyntax;
 }
@@ -358,9 +352,8 @@ M4BUILTIN_HANDLER (changesyntax)
                              m4_expand_ranges (M4ARG (i)+1, obs)) < 0)
              && (key != '\0'))
            {
-             M4ERROR ((m4_get_warning_status_opt (context), 0,
-                       _("%s: undefined syntax code: `%c'"),
-                       M4ARG (0), key));
+             m4_error (context, 0, 0, _("%s: undefined syntax code: `%c'"),
+                       M4ARG (0), key);
            }
        }
     }
@@ -380,8 +373,8 @@ M4BUILTIN_HANDLER (debugfile)
   if (argc == 1)
     m4_debug_set_output (context, NULL);
   else if (!m4_debug_set_output (context, M4ARG (1)))
-    M4ERROR ((m4_get_warning_status_opt (context), errno,
-             _("Cannot set error file: %s"), M4ARG (1)));
+    m4_error (context, 0, errno, _("%s: cannot set error file: %s"),
+             M4ARG (0), M4ARG (1));
 }
 
 
@@ -414,8 +407,8 @@ M4BUILTIN_HANDLER (debugmode)
        }
 
       if (new_debug_level < 0)
-       M4ERROR ((m4_get_warning_status_opt (context), 0,
-                 _("Debugmode: bad debug flags: `%s'"), M4ARG (1)));
+       m4_error (context, 0, 0, _("%s: bad debug flags: `%s'"),
+                 M4ARG (0), M4ARG (1));
       else
        {
          switch (change_flag)
@@ -459,8 +452,9 @@ M4BUILTIN_HANDLER (esyscmd)
       pin = popen (M4ARG (1), "r");
       if (pin == NULL)
        {
-         M4ERROR ((m4_get_warning_status_opt (context), errno,
-                   _("Cannot open pipe to command `%s'"), M4ARG (1)));
+         m4_error (context, 0, errno,
+                   _("%s: cannot open pipe to command `%s'"),
+                   M4ARG (0), M4ARG (1));
          m4_set_sysval (0xffff);
        }
       else
@@ -502,8 +496,7 @@ M4BUILTIN_HANDLER (indir)
   m4_symbol *  symbol = m4_symbol_lookup (M4SYMTAB, name);
 
   if (symbol == NULL)
-    M4ERROR ((m4_get_warning_status_opt (context), 0,
-             _("Undefined name `%s'"), name));
+    m4_error (context, 0, 0, _("%s: undefined name `%s'"), M4ARG (0), name);
   else
     m4_macro_call (context, symbol, obs, argc - 1, argv + 1);
 }
@@ -599,9 +592,8 @@ M4BUILTIN_HANDLER (regexp)
 
   if (startpos  == -2)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("%s: error matching regular expression `%s'"),
-               me, M4ARG (2)));
+      m4_error (context, 0, 0, _("%s: error matching regular expression `%s'"),
+               me, M4ARG (2));
       return;
     }
 
Index: modules/load.c
===================================================================
RCS file: /sources/m4/m4/modules/load.c,v
retrieving revision 1.16
diff -u -p -r1.16 load.c
--- modules/load.c      27 Oct 2005 16:04:03 -0000      1.16
+++ modules/load.c      9 Aug 2006 13:19:15 -0000
@@ -1,5 +1,5 @@
 /* GNU m4 -- A simple macro processor
-   Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2005, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -71,13 +71,9 @@ m4_macro m4_macro_table[] =
    unload is in progress.  */
 M4INIT_HANDLER (load)
 {
-  if (handle)
-    if (lt_dlmakeresident (handle) != 0)
-      {
-       M4ERROR ((m4_get_warning_status_opt (context), 0,
-                 _("Warning: cannot make module `%s' resident: %s"),
-                 m4_get_module_name (handle), lt_dlerror ()));
-      }
+  if (handle && lt_dlmakeresident (handle) != 0)
+    m4_error (context, 0, 0, _("cannot make module `%s' resident: %s"),
+             m4_get_module_name (handle), lt_dlerror ());
 }
 
 
Index: modules/m4.c
===================================================================
RCS file: /sources/m4/m4/modules/m4.c,v
retrieving revision 1.63
diff -u -p -r1.63 m4.c
--- modules/m4.c        28 Jul 2006 14:06:11 -0000      1.63
+++ modules/m4.c        9 Aug 2006 13:19:15 -0000
@@ -146,13 +146,11 @@ m4_builtin m4_builtin_table[] =
    progress.  */
 M4INIT_HANDLER (m4)
 {
-  if (handle)
-    if (lt_dlmakeresident (handle) != 0)
-      {
-       M4ERROR ((m4_get_warning_status_opt (context), 0,
-                 _("Warning: cannot make module `%s' resident: %s"),
-                 m4_get_module_name (handle), lt_dlerror ()));
-      }
+  if (handle && lt_dlmakeresident (handle) != 0)
+    {
+      m4_error (context, 0, 0, _("cannot make module `%s' resident: %s"),
+               m4_get_module_name (handle), lt_dlerror ());
+    }
 }
 
 
@@ -188,8 +186,8 @@ M4BUILTIN_HANDLER (define)
 M4BUILTIN_HANDLER (undefine)
 {
   if (!m4_symbol_lookup (M4SYMTAB, M4ARG (1)))
-    M4WARN ((m4_get_warning_status_opt (context), 0,
-            _("Warning: %s: undefined name: %s"), M4ARG (0), M4ARG (1)));
+    m4_warn (context, 0,_("Warning: %s: undefined name: %s"), M4ARG (0),
+            M4ARG (1));
   else
     m4_symbol_delete (M4SYMTAB, M4ARG (1));
 }
@@ -212,8 +210,8 @@ M4BUILTIN_HANDLER (pushdef)
 M4BUILTIN_HANDLER (popdef)
 {
   if (!m4_symbol_lookup (M4SYMTAB, M4ARG (1)))
-    M4WARN ((m4_get_warning_status_opt (context), 0,
-            _("Warning: %s: undefined name: %s"), M4ARG (0), M4ARG (1)));
+    m4_warn (context, 0, _("Warning: %s: undefined name: %s"), M4ARG (0),
+            M4ARG (1));
   else
     m4_symbol_popdef (M4SYMTAB, M4ARG (1));
 }
@@ -341,9 +339,8 @@ m4_dump_symbols (m4 *context, m4_dump_sy
              dump_symbol_CB (NULL, M4ARG (i), symbol, data);
            }
          else if (complain)
-           M4WARN ((m4_get_warning_status_opt (context), 0,
-                    _("Warning: %s: undefined name: %s"),
-                    M4ARG (0), M4ARG (i)));
+           m4_warn (context, 0, _("Warning: %s: undefined name: %s"),
+                    M4ARG (0), M4ARG (i));
        }
     }
 
@@ -410,17 +407,16 @@ M4BUILTIN_HANDLER (defn)
       m4_symbol *symbol = m4_symbol_lookup (M4SYMTAB, name);
 
       if (!symbol)
-       M4WARN ((m4_get_warning_status_opt (context), 0,
-                _("Warning: %s: undefined name: %s"),
-                m4_get_symbol_value_text (argv[0]), name));
+       m4_warn (context, 0, _("Warning: %s: undefined name: %s"), M4ARG (0),
+                name);
       else if (m4_is_symbol_text (symbol))
        m4_shipout_string (context, obs, m4_get_symbol_text (symbol), 0, true);
       else if (m4_is_symbol_func (symbol))
        m4_push_builtin (m4_get_symbol_value (symbol));
       else if (m4_is_symbol_placeholder (symbol))
-       M4WARN ((m4_get_warning_status_opt (context), 0, _("\
+       m4_warn (context, 0, _("\
 Warning: %s: builtin `%s' requested by frozen file not found"),
-                name, m4_get_symbol_placeholder (symbol)));
+                name, m4_get_symbol_placeholder (symbol));
       else
        assert (!"Bad token data type in m4_defn");
     }
@@ -518,11 +514,11 @@ M4BUILTIN_HANDLER (undivert)
   int i = 0;
 
   if (argc == 1)
-    m4_undivert_all ();
+    m4_undivert_all (context);
   else
     {
       if (sscanf (M4ARG (1), "%d", &i) == 1)
-       m4_insert_diversion (i);
+       m4_insert_diversion (context, i);
       else if (m4_get_posixly_correct_opt (context))
        m4_numeric_arg (context, argc, argv, 1, &i);
       else
@@ -530,12 +526,12 @@ M4BUILTIN_HANDLER (undivert)
          FILE *fp = m4_path_search (context, M4ARG (1), (char **) NULL);
          if (fp != NULL)
            {
-             m4_insert_file (fp);
+             m4_insert_file (context, fp);
              fclose (fp);
            }
          else
-           M4ERROR ((m4_get_warning_status_opt (context), errno,
-                     _("Cannot undivert %s"), M4ARG (1)));
+           m4_error (context, 0, errno, _("%s: cannot undivert `%s'"),
+                     M4ARG (0), M4ARG (1));
        }
     }
 }
@@ -594,8 +590,8 @@ include (m4 *context, int argc, m4_symbo
   if (fp == NULL)
     {
       if (!silent)
-       M4ERROR ((m4_get_warning_status_opt (context), errno,
-                 _("Cannot open %s"), M4ARG (1)));
+       m4_error (context, 0, errno, _("%s: cannot open `%s'"), M4ARG (0),
+                 M4ARG (1));
       return;
     }
 
@@ -626,11 +622,11 @@ M4BUILTIN_HANDLER (maketemp)
   errno = 0;
   if ((fd = mkstemp (M4ARG(1))) < 0)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), errno,
-               "Cannot create tempfile %s", M4ARG (1)));
+      m4_error (context, 0, errno, _("%s: cannot create tempfile `%s'"),
+               M4ARG (0), M4ARG (1));
       return;
     }
-  close(fd);
+  close (fd);
   m4_shipout_string (context, obs, M4ARG (1), 0, false);
 }
 
@@ -705,8 +701,8 @@ M4BUILTIN_HANDLER (traceon)
        if (symbol != NULL)
          set_trace_CB (NULL, NULL, symbol, (char *) obs);
        else
-         M4WARN ((m4_get_warning_status_opt (context), 0,
-                  _("Warning: %s: undefined name: %s"), M4ARG (0), name));
+         m4_warn (context, 0, _("Warning: %s: undefined name: %s"),
+                  M4ARG (0), name);
       }
 }
 
@@ -725,8 +721,8 @@ M4BUILTIN_HANDLER (traceoff)
        if (symbol != NULL)
          set_trace_CB (NULL, NULL, symbol, NULL);
        else
-         M4WARN ((m4_get_warning_status_opt (context), 0,
-                  _("Warning: %s: undefined name: %s"), M4ARG (0), name));
+         m4_warn (context, 0, _("Warning: %s: undefined name: %s"),
+                  M4ARG (0), name);
       }
 }
 
@@ -806,9 +802,9 @@ m4_expand_ranges (const char *s, m4_obst
          to = *++s;
          if (to == '\0')
            {
-              /* trailing dash */
-              obstack_1grow (obs, '-');
-              break;
+             /* trailing dash */
+             obstack_1grow (obs, '-');
+             break;
            }
          else if (from <= to)
            {
Index: modules/mpeval.c
===================================================================
RCS file: /sources/m4/m4/modules/mpeval.c,v
retrieving revision 1.17
diff -u -p -r1.17 mpeval.c
--- modules/mpeval.c    16 Jun 2006 01:32:41 -0000      1.17
+++ modules/mpeval.c    9 Aug 2006 13:19:15 -0000
@@ -185,10 +185,7 @@ static void
 mpq2mpz (m4 *context, mpz_t z, const number q, const char *noisily)
 {
   if (noisily && mpz_cmp_si (mpq_denref (q), (long) 1) != 0)
-    {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Loss of precision in eval: %s"), noisily));
-    }
+    m4_error (context, 0, 0, _("loss of precision in eval: %s"), noisily);
 
   mpz_div (z, mpq_numref (q), mpq_denref (q));
 }
Index: src/freeze.c
===================================================================
RCS file: /sources/m4/m4/src/freeze.c,v
retrieving revision 1.47
diff -u -p -r1.47 freeze.c
--- src/freeze.c        28 Jul 2006 16:41:28 -0000      1.47
+++ src/freeze.c        9 Aug 2006 13:19:15 -0000
@@ -25,7 +25,7 @@
 #include "m4private.h"
 
 static int   decode_char           (FILE *);
-static void  issue_expect_message  (int);
+static void  issue_expect_message  (m4 *, int);
 static int   produce_char_dump     (char *, int);
 static void  produce_resyntax_dump (m4 *, FILE *);
 static void  produce_syntax_dump   (FILE *, m4_syntax_table *, char);
@@ -95,8 +95,8 @@ produce_resyntax_dump (m4 *context, FILE
       const char *resyntax = m4_regexp_syntax_decode (code);
 
       if (!resyntax)
-       M4ERROR ((EXIT_FAILURE, 0,
-                 _("Invalid regexp syntax code `%d'"), code));
+       m4_error (context, EXIT_FAILURE, 0,
+                 _("invalid regexp syntax code `%d'"), code);
 
       fprintf (file, "R%d\n%s\n", strlen(resyntax), resyntax);
     }
@@ -155,11 +155,7 @@ produce_symbol_dump (m4 *context, FILE *
 {
   const char *errormsg = m4_symtab_apply (symtab, dump_symbol_CB, file);
 
-  if (errormsg)
-    {
-      M4ERROR ((m4_get_warning_status_opt (context), 0, errormsg));
-      abort ();
-    }
+  assert (!errormsg);
 }
 
 static void *
@@ -191,7 +187,7 @@ dump_symbol_CB (m4_symbol_table *symtab,
                                                m4_get_symbol_func (symbol));
 
       if (bp == NULL)
-       return "INTERNAL ERROR: Builtin not found in builtin table!";
+       return "INTERNAL ERROR: builtin not found in builtin table!";
 
       fprintf (file, "F%lu,%lu",
               (unsigned long) strlen (symbol_name),
@@ -211,7 +207,7 @@ dump_symbol_CB (m4_symbol_table *symtab,
   else if (m4_is_symbol_placeholder (symbol))
     ; /* Nothing to do for a builtin we couldn't reload earlier.  */
   else
-    return "INTERNAL ERROR: Bad token data type in produce_symbol_dump ()";
+    return "INTERNAL ERROR: bad token data type in produce_symbol_dump ()";
 
   return NULL;
 }
@@ -227,9 +223,10 @@ produce_frozen_state (m4 *context, const
 # define FROZEN_WRITE "w"
 #endif
 
-  if (file = fopen (name, FROZEN_WRITE), !file)
+  file = fopen (name, FROZEN_WRITE);
+  if (!file)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), errno, name));
+      m4_error (context, 0, errno, _("cannot open `%s'"), name);
       return;
     }
 
@@ -297,7 +294,7 @@ produce_frozen_state (m4 *context, const
 
   /* Let diversions be issued from output.c module, its cleaner to have this
      piece of code there.  */
-  m4_freeze_diversions (file);
+  m4_freeze_diversions (context, file);
 
   /* All done.  */
 
@@ -307,13 +304,14 @@ produce_frozen_state (m4 *context, const
 
 /* Issue a message saying that some character is an EXPECTED character. */
 static void
-issue_expect_message (int expected)
+issue_expect_message (m4 *context, int expected)
 {
   if (expected == '\n')
-    M4ERROR ((EXIT_FAILURE, 0, _("Expecting line feed in frozen file")));
+    m4_error (context, EXIT_FAILURE, 0,
+             _("expecting line feed in frozen file"));
   else
-    M4ERROR ((EXIT_FAILURE, 0, _("Expecting character `%c' in frozen file"),
-             expected));
+    m4_error (context, EXIT_FAILURE, 0,
+             _("expecting character `%c' in frozen file"), expected);
 }
 
 /* Reload a frozen state from the given file NAME. */
@@ -392,8 +390,8 @@ reload_frozen_state (m4 *context, const 
       CHECK_ALLOCATION((Buf), (BufSize), (StrLen));            \
       if ((StrLen) > 0)                                                \
        if (!fread ((Buf), (size_t) (StrLen), 1, (File)))       \
-           M4ERROR ((EXIT_FAILURE, 0,                          \
-                     _("Premature end of frozen file")));      \
+         m4_error (context, EXIT_FAILURE, 0,                   \
+                   _("premature end of frozen file"));         \
       (Buf)[(StrLen)] = '\0';                                  \
     }                                                          \
   while (0)
@@ -402,7 +400,7 @@ reload_frozen_state (m4 *context, const 
   do                                                           \
     {                                                          \
       if (character != (Expected))                             \
-       issue_expect_message ((Expected));                      \
+       issue_expect_message (context, (Expected));             \
     }                                                          \
   while (0)
 
@@ -436,7 +434,7 @@ reload_frozen_state (m4 *context, const 
 
   file = m4_path_search (context, name, (char **)NULL);
   if (file == NULL)
-    M4ERROR ((EXIT_FAILURE, errno, _("Cannot open %s"), name));
+    m4_error (context, EXIT_FAILURE, errno, _("cannot open `%s'"), name);
 
   allocated[0] = 100;
   string[0] = xmalloc ((size_t) allocated[0]);
@@ -474,12 +472,12 @@ reload_frozen_state (m4 *context, const 
       break;
     default:
       if (version > 2)
-       M4ERROR ((EXIT_MISMATCH, 0,
-                 "frozen file version %d greater than max supported of 2",
-                 version));
+       m4_error (context, EXIT_MISMATCH, 0,
+                 _("frozen file version %d greater than max supported of 2"),
+                 version);
       else
-       M4ERROR ((EXIT_FAILURE, 0,
-                 "ill-formed frozen file, version directive expected"));
+       m4_error (context, EXIT_FAILURE, 0,
+                 _("ill-formed frozen file, version directive expected"));
     }
   VALIDATE ('\n');
 
@@ -489,9 +487,9 @@ reload_frozen_state (m4 *context, const 
       switch (character)
        {
        default:
-         M4ERROR ((EXIT_FAILURE, 0,
+         m4_error (context, EXIT_FAILURE, 0,
                    _("ill-formed frozen file, unknown directive %c"),
-                   character));
+                   character);
 
        case 'F':
          GET_CHARACTER;
@@ -515,8 +513,8 @@ reload_frozen_state (m4 *context, const 
              else
                /* 3 argument 'F' operations are invalid for format
                   version 1.  */
-               M4ERROR ((EXIT_FAILURE, 0, _("\
-ill-formed frozen file, version 2 directive encountered")));
+               m4_error (context, EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive `%c' encountered"), 'F');
            }
          else
            {
@@ -576,8 +574,8 @@ ill-formed frozen file, version 2 direct
          if (version < 2)
            {
              /* 'M' operator is not supported in format version 1. */
-             M4ERROR ((EXIT_FAILURE, 0, _("\
-ill-formed frozen file, version 2 directive encountered")));
+             m4_error (context, EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive `%c' encountered"), 'M');
            }
 
          GET_CHARACTER;
@@ -595,8 +593,8 @@ ill-formed frozen file, version 2 direct
          if (version < 2)
            {
              /* 'R' operator is not supported in format version 1. */
-             M4ERROR ((EXIT_FAILURE, 0, _("\
-ill-formed frozen file, version 2 directive encountered")));
+             m4_error (context, EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive `%c' encountered"), 'R');
            }
 
          GET_CHARACTER;
@@ -609,8 +607,8 @@ ill-formed frozen file, version 2 direct
                                    m4_regexp_syntax_encode (string[0]));
          if (m4_get_regexp_syntax_opt (context) < 0)
            {
-             M4ERROR ((EXIT_FAILURE, 0,
-                       _("Unknown regexp syntax code %s"), string[0]));
+             m4_error (context, EXIT_FAILURE, 0,
+                       _("unknown regexp syntax code `%s'"), string[0]);
            }
 
          break;
@@ -620,8 +618,8 @@ ill-formed frozen file, version 2 direct
          if (version < 2)
            {
              /* 'S' operator is not supported in format version 1. */
-             M4ERROR ((EXIT_FAILURE, 0, _("\
-ill-formed frozen file, version 2 directive encountered")));
+             m4_error (context, EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive `%c' encountered"), 'S');
            }
 
          GET_CHARACTER;
@@ -640,8 +638,8 @@ ill-formed frozen file, version 2 direct
                  int ch = decode_char (file);
 
                  if (ch < 0)
-                   M4ERROR ((EXIT_FAILURE, 0,
-                             _("Premature end of frozen file")));
+                   m4_error (context, EXIT_FAILURE, 0,
+                             _("premature end of frozen file"));
 
                  string[0][i] = (unsigned char) ch;
                }
@@ -651,8 +649,8 @@ ill-formed frozen file, version 2 direct
          if ((m4_set_syntax (context->syntax, syntax, string[0]) < 0)
              && (syntax != '\0'))
            {
-             M4ERROR ((m4_get_warning_status_opt (context), 0,
-                       _("Undefined syntax code %c"), syntax));
+             m4_error (context, 0, 0,
+                       _("undefined syntax code %c"), syntax);
            }
          break;
 
@@ -743,8 +741,8 @@ ill-formed frozen file, version 2 direct
                {
                  /* 3 argument 'T' operations are invalid for format
                     version 1.  */
-                 M4ERROR ((EXIT_FAILURE, 0, _("\
-ill-formed frozen file, version 2 directive encountered")));
+                 m4_error (context, EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive `%c' encountered"), 'T');
                }
            }
          else
Index: src/main.c
===================================================================
RCS file: /sources/m4/m4/src/main.c,v
retrieving revision 1.71
diff -u -p -r1.71 main.c
--- src/main.c  27 Jul 2006 22:34:55 -0000      1.71
+++ src/main.c  9 Aug 2006 13:19:15 -0000
@@ -27,8 +27,6 @@
 
 #define AUTHORS _("Rene' Seindal"), "Gary V. Vaughan"
 
-static void print_program_name_CB (void);
-
 
 /* Name of frozen file to digest after initialization.  */
 const char *frozen_file_to_read = NULL;
@@ -55,20 +53,6 @@ typedef struct macro_definition
 
 /* Error handling functions.  */
 
-/* Print program name, source file and line reference on standard
-   error, as a prefix for error messages.  Flush standard output first.  */
-static void
-print_program_name_CB (void)
-{
-  int e = errno;
-  fflush (stdout);
-  fprintf (stderr, "%s: ", program_name);
-  if (m4_current_line != 0)
-    fprintf (stderr, "%s: %d: ", m4_current_file, m4_current_line);
-  errno = e;
-}
-
-
 #ifdef USE_STACKOVF
 
 /* Tell user stack overflowed and abort.  */
@@ -79,8 +63,7 @@ stackovf_handler (void)
      since these functions invoke functions that are not signal-safe.  We
      are sort of justified by the fact that we will exit and never return,
      but this should really be fixed.  */
-  M4ERROR ((EXIT_FAILURE, 0,
-           _("Stack overflow.  (Infinite define recursion?)")));
+  error (EXIT_FAILURE, 0, _("stack overflow (infinite define recursion?)"));
 }
 
 #endif /* USE_STACKOV */
@@ -241,7 +224,6 @@ main (int argc, char *const *argv, char 
 
   /* Initialise gnulib error module.  */
   set_program_name (argv[0]);
-  error_print_progname = print_program_name_CB;
 
   setlocale (LC_ALL, "");
 #ifdef ENABLE_NLS
@@ -307,7 +289,7 @@ main (int argc, char *const *argv, char 
        break;
 
       case 'E':
-       m4_set_warning_status_opt (context, EXIT_FAILURE);
+       m4_set_fatal_warnings_opt (context, true);
        break;
 
       case 'F':
@@ -331,13 +313,13 @@ main (int argc, char *const *argv, char 
          {
            const char *dlerr = lt_dlerror();
            if (dlerr == NULL)
-             M4ERROR ((EXIT_FAILURE, 0,
+             m4_error (context, EXIT_FAILURE, 0,
                        _("failed to add search directory `%s'"),
-                       optarg));
+                       optarg);
            else
-             M4ERROR ((EXIT_FAILURE, 0,
+             m4_error (context, EXIT_FAILURE, 0,
                        _("failed to add search directory `%s': %s"),
-                       optarg, dlerr));
+                       optarg, dlerr);
          }
        break;
 
@@ -402,7 +384,7 @@ main (int argc, char *const *argv, char 
 
   /* Do the basic initialisations.  */
 
-  m4_input_init ();
+  m4_input_init (context);
   m4_output_init ();
   m4_include_env_init (context);
 
@@ -480,14 +462,13 @@ main (int argc, char *const *argv, char 
                                      m4_regexp_syntax_encode (optarg));
            if (m4_get_regexp_syntax_opt (context) < 0)
              {
-               M4ERROR ((EXIT_FAILURE, 0,
-                         _("Bad regexp syntax option: `%s'"), optarg));
+               m4_error (context, EXIT_FAILURE, 0,
+                         _("bad regexp syntax option: `%s'"), optarg);
              }
            break;
 
          default:
-           M4ERROR ((m4_get_warning_status_opt (context), 0,
-                     "INTERNAL ERROR: Bad code in deferred arguments"));
+           assert (!"INTERNAL ERROR: bad code in deferred arguments");
            abort ();
          }
 
@@ -547,7 +528,7 @@ main (int argc, char *const *argv, char 
   else
     {
       m4_make_diversion (0);
-      m4_undivert_all ();
+      m4_undivert_all (context);
     }
 
   /* The remaining cleanup functions systematically free all of the
@@ -560,6 +541,8 @@ main (int argc, char *const *argv, char 
   m4_output_exit ();
   m4_input_exit ();
 
+  if (exit_status == EXIT_SUCCESS)
+    exit_status = m4_get_exit_status (context);
   m4_delete (context);
 
   m4_hash_exit ();
Index: tests/builtins.at
===================================================================
RCS file: /sources/m4/m4/tests/builtins.at,v
retrieving revision 1.11
diff -u -p -r1.11 builtins.at
--- tests/builtins.at   10 Jul 2006 23:27:43 -0000      1.11
+++ tests/builtins.at   9 Aug 2006 13:19:15 -0000
@@ -42,15 +42,15 @@ AT_CHECK_M4([define.m4], 0,
 [[new value.
 hello, world.
 base value.
-]], [[m4: define.m4: 1: Warning: undefine: undefined name: macro
+]], [[m4:define.m4:1: Warning: undefine: undefined name: macro
 ]])
 
 AT_CHECK_M4([--traditional define.m4], 0,
 [[new value.
 macro.
 macro.
-]], [[m4: define.m4: 1: Warning: undefine: undefined name: macro
-m4: define.m4: 9: Warning: popdef: undefined name: macro
+]], [[m4:define.m4:1: Warning: undefine: undefined name: macro
+m4:define.m4:9: Warning: popdef: undefined name: macro
 ]])
 
 AT_CLEANUP
@@ -339,11 +339,11 @@ very late
 ]])
 
 AT_DATA([[experr]],
-[[m4: include.m4: 2: Cannot open NOFILE: No such file or directory
-m4: include.m4: 6: Cannot open NOFILE: No such file or directory
+[[m4:include.m4:2: include: cannot open `NOFILE': No such file or directory
+m4:include.m4:6: include: cannot open `NOFILE': No such file or directory
 ]])
 
-AT_CHECK_M4([include.m4], 0, expout, experr)
+AT_CHECK_M4([include.m4], 1, expout, experr)
 
 AT_CLEANUP
 
Index: tests/freeze.at
===================================================================
RCS file: /sources/m4/m4/tests/freeze.at,v
retrieving revision 1.4
diff -u -p -r1.4 freeze.at
--- tests/freeze.at     28 Jul 2006 16:41:29 -0000      1.4
+++ tests/freeze.at     9 Aug 2006 13:19:15 -0000
@@ -100,7 +100,7 @@ define 1
 my_define(bar, 4) 3
 bar
 ]],
-[[m4: input.m4: 5: Warning: popdef: undefined name: my_define
+[[m4:input.m4:5: Warning: popdef: undefined name: my_define
 ]])
 
 AT_CLEANUP
@@ -150,9 +150,9 @@ AT_CHECK_M4([-R frozen.m4f input.m4], 0,
 
 a
 ]],
-[[m4: input.m4: 4: Warning: a: builtin `b' requested by frozen file not found
-m4: input.m4: 6: Warning: a: builtin `b' requested by frozen file not found
-m4: input.m4: 8: Warning: a: builtin `b' requested by frozen file not found
+[[m4:input.m4:4: Warning: a: builtin `b' requested by frozen file not found
+m4:input.m4:6: Warning: a: builtin `b' requested by frozen file not found
+m4:input.m4:8: Warning: a: builtin `b' requested by frozen file not found
 a:     <placeholder for b>
 c:     `'
 ]])
Index: tests/macros.at
===================================================================
RCS file: /sources/m4/m4/tests/macros.at,v
retrieving revision 1.4
diff -u -p -r1.4 macros.at
--- tests/macros.at     7 Jul 2006 15:47:39 -0000       1.4
+++ tests/macros.at     9 Aug 2006 13:19:15 -0000
@@ -57,8 +57,8 @@ defun
 ]])
 
 AT_CHECK_M4([input.m4], 0, [expout],
-[[m4: input.m4: 5: Warning: define: too many arguments (ignored): 3 > 2
-m4: input.m4: 10: Warning: defun: too many arguments (ignored): 3 > 2
+[[m4:input.m4:5: Warning: define: extra arguments ignored: 3 > 2
+m4:input.m4:10: Warning: defun: extra arguments ignored: 3 > 2
 ]])
 
 AT_CLEANUP
@@ -93,7 +93,7 @@ AT_DATA([[expout]],
 ]])
 
 AT_CHECK_M4([--reload-state=frozen.m4f input.m4], 0, expout,
-[[m4: input.m4: 4: Warning: defun: too many arguments (ignored): 3 > 2
+[[m4:input.m4:4: Warning: defun: extra arguments ignored: 3 > 2
 ]])
 
 AT_CLEANUP(freezeme.m4 frozen.m4f)
@@ -137,9 +137,9 @@ hej:        `def 4.'
 hej:   `def 3.'
 hej:   `def 2.'
 hej:   `def 1.'
-m4: pushpop.m4: 18: Warning: dumpdef: undefined name: hej
-m4: pushpop.m4: 20: Warning: dumpdef: undefined name: mac2
-m4: pushpop.m4: 21: Warning: popdef: undefined name: mac2
+m4:pushpop.m4:18: Warning: dumpdef: undefined name: hej
+m4:pushpop.m4:20: Warning: dumpdef: undefined name: mac2
+m4:pushpop.m4:21: Warning: popdef: undefined name: mac2
 ]])
 
 AT_CLEANUP
Index: tests/modules.at
===================================================================
RCS file: /sources/m4/m4/tests/modules.at,v
retrieving revision 1.14
diff -u -p -r1.14 modules.at
--- tests/modules.at    7 Jul 2006 15:47:39 -0000       1.14
+++ tests/modules.at    9 Aug 2006 13:19:15 -0000
@@ -100,7 +100,7 @@ Dumpdef: .
 [[Test module loaded.
 test:  <test>
 Test module unloaded.
-m4: input.m4: 6: Warning: dumpdef: undefined name: test
+m4:input.m4:6: Warning: dumpdef: undefined name: test
 ]])
 
 AT_CLEANUP
@@ -375,8 +375,8 @@ Test module unloaded.
 Test module loaded.
 
 TRUE
-m4: input.m4: 6: Warning: cannot load symbol `no_such' from module `modtest'
-m4: input.m4: 7: cannot open module `no_such': no_such.so: cannot open shared 
object file: No such file or directory
+m4:input.m4:6: cannot load symbol `no_such' from module `modtest'
+m4:input.m4:7: cannot open module `no_such': no_such.so: cannot open shared 
object file: No such file or directory
 ]])
 
 AT_CHECK_M4([-m load input.m4], 1, expout, stderr)
@@ -389,7 +389,7 @@ AT_CHECK_M4([-m load input.m4], 1, expou
 rm -f expout
 mv experr expout
 
-AT_CHECK([sed '/^m4: input.m4: 7:/ {
+AT_CHECK([sed '/^m4:input.m4:7:/ {
     s,\(7:[[^:]]*:\).*$,\1 no_such.so: cannot open shared object file: No such 
file or directory,;q; }' stderr], 0, expout)
 
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]