split -E functionality

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
Based on Ralf's complaint[1], I decided that the 1.4.8 meaning of -E does two 
independently useful things - turns warnings into errors, and quits execution 
on the first warning.  This patch makes that distinction explicit in 1.4.9 - 
you must use -EE instead of -E to get the old behavior, and the new behavior 
of -E is friendlier to detecting non-portable macro definitions via --warn-
syntax.

[1] http://lists.gnu.org/archive/html/autoconf-patches/2007-01/msg00136.html

2007-02-01  Eric Blake  <[email protected]>

	* src/m4.c (fatal_warnings): New variable.
	(usage): Document new -E behavior.
	(main): Make -E an additive option.
	(m4_error, m4_error_at_line): Change exit status when required.
	* NEWS: Document this change.
	* doc/m4.texinfo (Operation modes): Likewise.
	Reported by Ralf Wildenhues.

Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.1.1.1.2.91
diff -u -r1.1.1.1.2.91 NEWS
--- NEWS	28 Jan 2007 01:54:36 -0000	1.1.1.1.2.91
+++ NEWS	1 Feb 2007 19:14:18 -0000
@@ -15,6 +15,11 @@
   of variable assignment as an extension.
 * The `include' builtin now affects exit status on failure, as required by
   POSIX.  Use `sinclude' if you need a successful exit status.
+* The `-E'/`--fatal-warnings' command-line option now has two levels.  When
+  specified only once, warnings affect exit status, but execution
+  continues, so that you can see all warnings instead of fixing them one
+  at a time.  To acheive 1.4.8 behavior, where the first warning
+  immediately exits, specify -E twice on the command line.
 * A new `--warn-syntax' command-line option allows detection of
   non-portable syntax that might be broken when upgrading to M4 2.0.  For
   example, POSIX requires a macro definition containing `$11' to expand to
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.1.1.1.2.109
diff -u -r1.1.1.1.2.109 m4.texinfo
--- doc/m4.texinfo	28 Jan 2007 01:54:43 -0000	1.1.1.1.2.109
+++ doc/m4.texinfo	1 Feb 2007 19:14:18 -0000
@@ -551,8 +551,14 @@
 
 @item -E
 @itemx --fatal-warnings
-Stop execution and exit @code{m4} once the first warning or error has
-been issued, considering all of them to be fatal.
+Controls the effect of warnings.  If unspecified, then execution
+continues and exit status is unaffected when a warning is printed.  If
+specified exactly once, warnings become fatal; when one is issued,
+execution continues, but the exit status will be non-zero.  If specified
+multiple times, then execution halts with non-zero status the first time
+a warning is issued.  The introduction of behavior levels is new to M4
+1.4.9; for behavior consistent with earlier versions, you should specify
+@option{-E} twice.
 
 @item -i
 @itemx --interactive
Index: src/m4.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/m4.c,v
retrieving revision 1.1.1.1.2.42
diff -u -r1.1.1.1.2.42 m4.c
--- src/m4.c	28 Jan 2007 01:54:44 -0000	1.1.1.1.2.42
+++ src/m4.c	1 Feb 2007 19:14:18 -0000
@@ -52,6 +52,9 @@
 /* Suppress warnings about missing arguments.  */
 int suppress_warnings = 0;
 
+/* If true, then warnings affect exit status.  */
+static bool fatal_warnings = false;
+
 /* If not zero, then value of exit status for warning diagnostics.  */
 int warning_status = 0;
 
@@ -69,6 +72,10 @@
 /* The name this program was run with. */
 const char *program_name;
 
+/* Global catchall for any errors that should affect final error status, but
+   where we try to continue execution in the meantime.  */
+int retcode;
+
 struct macro_definition
 {
   struct macro_definition *next;
@@ -90,6 +97,8 @@
   va_start (args, format);
   verror_at_line (status, errnum, current_line ? current_file : NULL,
 		  current_line, format, args);
+  if (fatal_warnings && ! retcode)
+    retcode = EXIT_FAILURE;
 }
 
 /*-------------------------------.
@@ -103,6 +112,8 @@
   va_list args;
   va_start (args, format);
   verror_at_line (status, errnum, line ? file : NULL, line, format, args);
+  if (fatal_warnings && ! retcode)
+    retcode = EXIT_FAILURE;
 }
 
 #ifdef USE_STACKOVF
@@ -147,7 +158,8 @@
       --version                output version information and exit\n\
 ", stdout);
       fputs ("\
-  -E, --fatal-warnings         stop execution after first warning\n\
+  -E, --fatal-warnings         once: warnings become errors, twice: stop\n\
+                               execution at first error\n\
   -i, --interactive            unbuffer output, ignore interrupts\n\
   -P, --prefix-builtins        force a `m4_' prefix to all builtins\n\
   -Q, --quiet, --silent        suppress some warnings for builtins\n\
@@ -265,10 +277,6 @@
   { NULL, 0, NULL, 0 },
 };
 
-/* Global catchall for any errors that should affect final error status, but
-   where we try to continue execution in the meantime.  */
-int retcode;
-
 /* Process a command line file NAME, and return true only if it was
    stdin.  */
 static bool
@@ -388,7 +396,10 @@
 	break;
 
       case 'E':
-	warning_status = EXIT_FAILURE;
+	if (! fatal_warnings)
+	  fatal_warnings = true;
+	else
+	  warning_status = EXIT_FAILURE;
 	break;
 
       case 'F':
@@ -543,8 +554,7 @@
 	  break;
 
 	default:
-	  M4ERROR ((warning_status, 0,
-		    "INTERNAL ERROR: bad code in deferred arguments"));
+	  M4ERROR ((0, 0, "INTERNAL ERROR: bad code in deferred arguments"));
 	  abort ();
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.