Re: popdef(undefined), __m4_version__

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

 



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

According to Eric Blake on 8/3/2008 5:39 PM:
> |
> | That's not to say the default mode need necessarily be compatible, but
> | at least detecting that we are running inside autoconf and setting the
> | right options to work without patching would be the kindest thing to
> | do.
> 
> You are doing a good job of convincing me that the inability of m4 1.6 to
> work with unpatched autoconf 2.62 is bad.  Here's my current idea:
> 
> In m4, add a new debugmode() letter (perhaps 'd' for dereference), then
> condition all warnings related to dereferencing undefined macros on that
> option being set.  Right now, if you don't use m4 -d, you default to a
> debugmode of ""; we could change this to default to a debugmode of "d", so
> that a vanilla user of m4 gets the warning.  Likewise, 'm4 -d' was
> equivalent to 'm4 -daeq'; it would now be equivalent to 'm4 -dadeq'.

Here's what I'm planning on committing to m4; it adds debugmode(d) as a
new flag that controls whether dereferencing undefined macros warns, then
enables the flag by default unless an explicit -d specifies other flags or
if -E is in effect.  Both conditions for disabling the debugmode(d) flag
were necessary, so that branch-1.6 of m4.git can once again handle
autoconf 2.62 out of the box.

By committing this series, I now need a followup patch to autoconf;
m4sugar now needs to explicitly request m4_debugmode([+d]) when it detects
__m4_version__, before it can rely on native defn/popdef/undefine for speed.

I am also working on an autom4te patch that detects status 63 when loading
a frozen file, and falls back to retrying the load without the use of a
frozen file; which, if I then make m4 1.6 use frozen file format 2, will
allow the user to install autoconf with m4 1.6, then downgrade to m4 1.4.x
without being penalized by quadratic performance.

- --
Don't work too hard, make some time for fun as well!

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

iEYEARECAAYFAkiyrokACgkQ84KuGfSFAYA4VwCeM+wrCY82PDzbfZS4ZKYWJyuL
95MAoKG7EGXRMx7G04FpCHPCUplTnETH
=I2oY
-----END PGP SIGNATURE-----
>From 8912baaae894abfe31716a003126b680351be33c Mon Sep 17 00:00:00 2001
From: Eric Blake <ebb9@xxxxxxx>
Date: Mon, 18 Aug 2008 06:29:31 -0600
Subject: [PATCH] Allow + and - in --debug, and add --debugmode.

* src/builtin.c (m4_debugmode): Move +- handling...
* src/debug.c (debug_decode): ...here.
* src/m4.c (main): Adjust caller.
(long_options): Add alternate spelling for --debug.
(usage): Mention it.
* doc/m4.texinfo (Debugging options): Document additional
semantics.
* NEWS: Likewise.

Signed-off-by: Eric Blake <ebb9@xxxxxxx>
(cherry picked from commit c2e093a955214b8aaf4da8dd44bd595b06fea235)
---
 ChangeLog      |   12 ++++++++++++
 NEWS           |    7 +++++++
 doc/m4.texinfo |   39 ++++++++++++++++++++++++++++++---------
 src/builtin.c  |   37 ++-----------------------------------
 src/debug.c    |   35 ++++++++++++++++++++++++++++++-----
 src/m4.c       |   12 +++++-------
 6 files changed, 86 insertions(+), 56 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0e06082..bb719cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-08-22  Eric Blake  <ebb9@xxxxxxx>
+
+	Allow + and - in --debug, and add --debugmode.
+	* src/builtin.c (m4_debugmode): Move +- handling...
+	* src/debug.c (debug_decode): ...here.
+	* src/m4.c (main): Adjust caller.
+	(long_options): Add alternate spelling for --debug.
+	(usage): Mention it.
+	* doc/m4.texinfo (Debugging options): Document additional
+	semantics.
+	* NEWS: Likewise.
+
 2008-08-21  Eric Blake  <ebb9@xxxxxxx>
 
 	Fix crash with traced defn(undef), regression from 2007-08-09.
diff --git a/NEWS b/NEWS
index 109c80a..0099383 100644
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,13 @@ Foundation, Inc.
    then apply this patch:
      http://git.sv.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=56d42fa71
 
+** The `-d'/`--debug' command-line option now understands `-' and `+'
+   modifiers, the way the builtin `debugmode' has always done; this allows
+   `-d-V' to disable prior debug settings from the command line, similar to
+   using the builtin `debugmode' without arguments.  The option
+   `--debugmode' is added as an alias for `-d'.  When given the empty
+   string, the mode is treated as `+aeq' instead of `aeq'.
+
 ** New `-g'/`--gnu' command-line option overrides `-G'/`--traditional'.
    For now, the environment variable POSIXLY_CORRECT has no effect on M4
    behavior; but a future release of M4 will behave as though --traditional
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 7540b2e..f47fd3c 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -838,12 +838,34 @@ Debugging options
 scripts.
 
 @table @code
-@item -d@r{[}@var{FLAGS}@r{]}
-@itemx --debug@r{[}=@var{FLAGS}@r{]}
+@item -d@r{[}@r{[}-@r{|}+@r{]}@var{FLAGS}@r{]}
+@itemx --debug@r{[}=@r{[}-@r{|}+@r{]}@var{FLAGS}@r{]}
+@itemx --debugmode@r{[}=@r{[}-@r{|}+@r{]}@var{FLAGS}@r{]}
 Set the debug-level according to the flags @var{FLAGS}.  The debug-level
 controls the format and amount of information presented by the debugging
 functions.  @xref{Debug Levels}, for more details on the format and
-meaning of @var{FLAGS}.  If omitted, @var{FLAGS} defaults to @samp{aeq}.
+meaning of @var{FLAGS}.  If omitted, @var{FLAGS} defaults to
+@samp{+aeq}.  If the option occurs multiple times, @var{FLAGS} starting
+with @samp{-} or @samp{+} are cumulative, while @var{FLAGS} starting
+with a letter override all earlier settings.  Therefore, to disable all
+previously set flags, specify an explicit @var{FLAGS} of @samp{-V}.  The
+spelling @option{--debug} is recognized as an unambiguous option for
+compatibility with earlier versions of @acronym{GNU} M4, but for
+consistency with the builtin name, you can also use the spelling
+@option{--debugmode}.
+
+The cumulative effect of the various options in this example is
+equivalent to a single invocation of @code{debugmode(`alqx')}:
+
+@comment options: -d-V -d+lx --debug --debugmode=-e
+@example
+$ @kbd{m4 -d+lx --debug --debugmode=-e}
+traceon(`len')
+@result{}
+len(`123')
+@error{}m4trace:2: -1- id 2: len(`123')
+@result{}3
+@end example
 
 @item --debugfile=@var{FILE}
 @itemx -o @var{FILE}
@@ -2483,6 +2505,7 @@ Pushdef
 @option{-Q} (@option{--quiet}, @pxref{Operation modes, , Invoking m4}).
 
 @example
+$ @kbd{m4}
 define(`a', `1')
 @result{}
 popdef
@@ -3646,10 +3669,10 @@ Dumpdef
 If you want to see what a name expands into, you can use the builtin
 @code{dumpdef}:
 
-@deffn Builtin dumpdef (@ovar{names@dots{}})
+@deffn Builtin dumpdef (@ovar{name@dots{}})
 Accepts any number of arguments.  If called without any arguments,
 it displays the definitions of all known names, otherwise it displays
-the definitions of the @var{names} given.  The output is printed to the
+the definitions of each @var{name} given.  The output is printed to the
 current debug file (usually standard error), and is sorted by name.  If
 an unknown name is encountered, a warning is printed.
 
@@ -3741,8 +3764,7 @@ Trace
 @option{-t}) can be used to invoke @code{traceon(@var{name})} before
 parsing input.
 
-@comment The explicit -dp neutralizes the testsuite default of -d.
-@comment options: -dp -L3 -tifelse
+@comment options: -d-V -L3 -tifelse
 @comment status: 1
 @example
 $ @kbd{m4 -L 3 -t ifelse}
@@ -3992,8 +4014,7 @@ Debug Levels
 The expansion of @code{debugmode} is void.
 @end deffn
 
-@comment The explicit -dp neutralizes the testsuite default of -d.
-@comment options: -dp
+@comment options: -d-V
 @example
 $ @kbd{m4}
 define(`foo', `FOO')
diff --git a/src/builtin.c b/src/builtin.c
index b8449a0..34387b9 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -1759,46 +1759,13 @@ m4_debugmode (struct obstack *obs, int argc, macro_arguments *argv)
 {
   const call_info *me = arg_info (argv);
   const char *str = ARG (1);
-  int new_debug_level;
-  int change_flag;
 
   bad_argc (me, argc, 0, 1);
 
   if (argc == 1)
     debug_level = 0;
-  else
-    {
-      if (*str == '+' || *str == '-')
-	{
-	  change_flag = *str;
-	  new_debug_level = debug_decode (str + 1);
-	}
-      else
-	{
-	  change_flag = 0;
-	  new_debug_level = debug_decode (str);
-	}
-
-      if (new_debug_level < 0)
-	m4_warn (0, me, _("bad debug flags: `%s'"), str);
-      else
-	{
-	  switch (change_flag)
-	    {
-	    case 0:
-	      debug_level = new_debug_level;
-	      break;
-
-	    case '+':
-	      debug_level |= new_debug_level;
-	      break;
-
-	    case '-':
-	      debug_level &= ~new_debug_level;
-	      break;
-	    }
-	}
-    }
+  else if (debug_decode (str) < 0)
+    m4_warn (0, me, _("bad debug flags: `%s'"), str);
 }
 
 /*-------------------------------------------------------------------------.
diff --git a/src/debug.c b/src/debug.c
index c3f85bd..579960b 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -43,20 +43,24 @@ debug_init (void)
   obstack_init (&trace);
 }
 
-/*-----------------------------------------------------------------.
-| Function to decode the debugging flags OPTS.  Used by main while |
-| processing option -d, and by the builtin debugmode ().	   |
-`-----------------------------------------------------------------*/
+/*------------------------------------------------------------------.
+| Function to decode the debugging flags OPTS.  Used by main while  |
+| processing option -d, and by the builtin debugmode ().  Return -1 |
+| if the parse failed, otherwise change the debug level.	    |
+`------------------------------------------------------------------*/
 
 int
 debug_decode (const char *opts)
 {
   int level;
+  char mode = '\0';
 
   if (opts == NULL || *opts == '\0')
-    level = DEBUG_TRACE_DEFAULT;
+    level = DEBUG_TRACE_DEFAULT | debug_level;
   else
     {
+      if (*opts == '-' || *opts == '+')
+	mode = *opts++;
       for (level = 0; *opts; opts++)
 	{
 	  switch (*opts)
@@ -110,6 +114,27 @@ debug_decode (const char *opts)
 	    }
 	}
     }
+  switch (mode)
+    {
+    case '\0':
+      /* Replace old level.  */
+      break;
+
+    case '-':
+      /* Subtract flags.  */
+      level = debug_level & ~level;
+      break;
+
+    case '+':
+      /* Add flags.  */
+      level |= debug_level;
+      break;
+
+    default:
+      assert (!"debug_decode");
+      abort ();
+    }
+  debug_level = level;
   return level;
 }
 
diff --git a/src/m4.c b/src/m4.c
index 73ccce1..c368021 100644
--- a/src/m4.c
+++ b/src/m4.c
@@ -256,7 +256,8 @@ Frozen state files:\n\
       puts ("");
       fputs (_("\
 Debugging:\n\
-  -d, --debug[=FLAGS]          set debug level (no FLAGS implies `aeq')\n\
+  -d, --debug[=[-|+]FLAGS], --debugmode[=[-|+]FLAGS]\n\
+                               set debug level (no FLAGS implies `+aeq')\n\
       --debugfile=FILE         redirect debug and trace output\n\
   -l, --arglength=NUM          restrict macro tracing size\n\
   -t, --trace=NAME             trace NAME when it is defined\n\
@@ -318,6 +319,7 @@ static const struct option long_options[] =
 {
   {"arglength", required_argument, NULL, 'l'},
   {"debug", optional_argument, NULL, 'd'},
+  {"debugmode", optional_argument, NULL, 'd'},
   {"define", required_argument, NULL, 'D'},
   {"error-output", required_argument, NULL, 'o'}, /* FIXME: deprecate in 2.0 */
   {"fatal-warnings", no_argument, NULL, 'E'},
@@ -521,12 +523,8 @@ main (int argc, char *const *argv, char *const *envp)
 #endif
 
       case 'd':
-	debug_level = debug_decode (optarg);
-	if (debug_level < 0)
-	  {
-	    error (0, 0, "bad debug flags: `%s'", optarg);
-	    debug_level = 0;
-	  }
+	if (debug_decode (optarg) < 0)
+	  error (0, 0, "bad debug flags: `%s'", optarg);
 	break;
 
       case 'e':
-- 
1.6.0


>From cb3bbd28fa8a04d3eddc08261169b5c3e98c252f Mon Sep 17 00:00:00 2001
From: Eric Blake <ebb9@xxxxxxx>
Date: Mon, 18 Aug 2008 07:17:35 -0600
Subject: [PATCH] Interleave -d handling with files.

* src/m4.c (main): Defer -d handling when appropriate.
* doc/m4.texinfo (Debugging options): Mention it.
(Command line files): Test it.
* NEWS: Mention it.

Signed-off-by: Eric Blake <ebb9@xxxxxxx>
---
 ChangeLog      |    6 ++++++
 NEWS           |    4 +++-
 doc/m4.texinfo |   18 +++++++++++++++++-
 src/m4.c       |   13 +++++++++++--
 4 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bb719cf..07fced3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2008-08-22  Eric Blake  <ebb9@xxxxxxx>
 
+	Interleave -d handling with files.
+	* src/m4.c (main): Defer -d handling when appropriate.
+	* doc/m4.texinfo (Debugging options): Mention it.
+	(Command line files): Test it.
+	* NEWS: Mention it.
+
 	Allow + and - in --debug, and add --debugmode.
 	* src/builtin.c (m4_debugmode): Move +- handling...
 	* src/debug.c (debug_decode): ...here.
diff --git a/NEWS b/NEWS
index 0099383..9e69a3b 100644
--- a/NEWS
+++ b/NEWS
@@ -47,7 +47,9 @@ Foundation, Inc.
    `-d-V' to disable prior debug settings from the command line, similar to
    using the builtin `debugmode' without arguments.  The option
    `--debugmode' is added as an alias for `-d'.  When given the empty
-   string, the mode is treated as `+aeq' instead of `aeq'.
+   string, the mode is treated as `+aeq' instead of `aeq'.  Also, the
+   position of `-d' with respect to files on the command line is now
+   significant.
 
 ** New `-g'/`--gnu' command-line option overrides `-G'/`--traditional'.
    For now, the environment variable POSIXLY_CORRECT has no effect on M4
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index f47fd3c..5cfdb1a 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -852,7 +852,7 @@ Debugging options
 spelling @option{--debug} is recognized as an unambiguous option for
 compatibility with earlier versions of @acronym{GNU} M4, but for
 consistency with the builtin name, you can also use the spelling
-@option{--debugmode}.
+@option{--debugmode}.  Order is significant with respect to file names.
 
 The cumulative effect of the various options in this example is
 equivalent to a single invocation of @code{debugmode(`alqx')}:
@@ -926,6 +926,7 @@ Command line files
 The text @samp{bar} can then be redefined over multiple uses of
 @file{foo}:
 
+@comment examples
 @comment options: -Dbar=hello foo -Dbar=world foo
 @example
 $ @kbd{m4 -Dbar=hello foo -Dbar=world foo}
@@ -933,6 +934,21 @@ Command line files
 @result{}world
 @end example
 
+@ignore
+@comment Not worth putting the manual, but worth testing.
+
+@comment examples
+@comment options: -Dbar=hello -d foo -t bar foo -d-V foo
+@example
+$ @kbd{m4 -Dbar=hello -d foo -t bar foo -d-V foo
+@result{}hello
+@error{}m4trace: -1- bar -> `hello'
+@result{}hello
+@error{}m4trace: -1- bar
+@result{}hello
+@end example
+@end ignore
+
 If none of the input files invoked @code{m4exit} (@pxref{M4exit}), the
 exit status of @code{m4} will be 0 for success, 1 for general failure
 (such as problems with reading an input file), and 63 for version
diff --git a/src/m4.c b/src/m4.c
index c368021..22586fc 100644
--- a/src/m4.c
+++ b/src/m4.c
@@ -455,11 +455,14 @@ main (int argc, char *const *argv, char *const *envp)
 	       optchar);
 	break;
 
+      case '\1':
+	seen_file = true;
+	/* fall through */
       case 'D':
       case 'U':
       case 's':
       case 't':
-      case '\1':
+      defer:
 	/* Arguments that cannot be handled until later are accumulated.  */
 
 	defn = (macro_definition *) xmalloc (sizeof (macro_definition));
@@ -523,6 +526,8 @@ main (int argc, char *const *argv, char *const *envp)
 #endif
 
       case 'd':
+	if (seen_file)
+	  goto defer;
 	if (debug_decode (optarg) < 0)
 	  error (0, 0, "bad debug flags: `%s'", optarg);
 	break;
@@ -621,6 +626,11 @@ main (int argc, char *const *argv, char *const *envp)
 	  lookup_symbol (defines->arg, strlen (defines->arg), SYMBOL_DELETE);
 	  break;
 
+	case 'd':
+	  if (debug_decode (defines->arg) < 0)
+	    error (0, 0, "bad debug flags: `%s'", defines->arg);
+	  break;
+
 	case 't':
 	  sym = lookup_symbol (defines->arg, strlen (defines->arg),
 			       SYMBOL_INSERT);
@@ -632,7 +642,6 @@ main (int argc, char *const *argv, char *const *envp)
 	  break;
 
 	case '\1':
-	  seen_file = true;
 	  process_file (defines->arg);
 	  break;
 
-- 
1.6.0


>From d918ca5f34a4653ed4120d5732c8b46738f78bb3 Mon Sep 17 00:00:00 2001
From: Eric Blake <ebb9@xxxxxxx>
Date: Fri, 22 Aug 2008 17:26:01 -0600
Subject: [PATCH] Allow debugmode control over whether defn(undef) warns.

* src/m4.h (DEBUG_TRACE_DEREF): New define.
(DEBUG_TRACE_VERBOSE, DEBUG_TRACE_DEFAULT): Adjust.
* src/m4.c (debug_level): Start with debugmode = d.
(usage): Mention this.
(main): Let -E impact debug mode.
* src/builtin.c (m4_undefine, m4_popdef, m4_dumpdef, m4_builtin)
(m4_indir, m4_defn): Squelch undefined warning if debug flag is
clear.
* src/debug.c (debug_decode): Parse new mode.
* doc/m4.texinfo (Debugging options): Mention change in the
default behavior.
(Debug Levels): Mention new flag d.
(Operation modes): Mention interaction with -E.
(Undefine, Defn, Pushdef, Indir, Builtin, Dumpdef): Document and
test its effect.
* NEWS: Document this.
Reported by Ralf Wildenhues; without this patch, M4 1.6 would be
incompatible with Autoconf 2.62.

Signed-off-by: Eric Blake <ebb9@xxxxxxx>
---
 ChangeLog      |   22 +++++++
 NEWS           |   32 ++++------
 doc/m4.texinfo |  186 ++++++++++++++++++++++++++++++++++++++-----------------
 src/builtin.c  |   29 ++++++---
 src/debug.c    |    4 +
 src/m4.c       |    6 +-
 src/m4.h       |    8 ++-
 7 files changed, 195 insertions(+), 92 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 07fced3..1b9bbaa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2008-08-23  Eric Blake  <ebb9@xxxxxxx>
+
+	Allow debugmode control over whether defn(undef) warns.
+	* src/m4.h (DEBUG_TRACE_DEREF): New define.
+	(DEBUG_TRACE_VERBOSE, DEBUG_TRACE_DEFAULT): Adjust.
+	* src/m4.c (debug_level): Start with debugmode = d.
+	(usage): Mention this.
+	(main): Let -E impact debug mode.
+	* src/builtin.c (m4_undefine, m4_popdef, m4_dumpdef, m4_builtin)
+	(m4_indir, m4_defn): Squelch undefined warning if debug flag is
+	clear.
+	* src/debug.c (debug_decode): Parse new mode.
+	* doc/m4.texinfo (Debugging options): Mention change in the
+	default behavior.
+	(Debug Levels): Mention new flag d.
+	(Operation modes): Mention interaction with -E.
+	(Undefine, Defn, Pushdef, Indir, Builtin, Dumpdef): Document and
+	test its effect.
+	* NEWS: Document this.
+	Reported by Ralf Wildenhues; without this patch, M4 1.6 would be
+	incompatible with Autoconf 2.62.
+
 2008-08-22  Eric Blake  <ebb9@xxxxxxx>
 
 	Interleave -d handling with files.
diff --git a/NEWS b/NEWS
index 9e69a3b..5a3ecb3 100644
--- a/NEWS
+++ b/NEWS
@@ -46,10 +46,12 @@ Foundation, Inc.
    modifiers, the way the builtin `debugmode' has always done; this allows
    `-d-V' to disable prior debug settings from the command line, similar to
    using the builtin `debugmode' without arguments.  The option
-   `--debugmode' is added as an alias for `-d'.  When given the empty
-   string, the mode is treated as `+aeq' instead of `aeq'.  Also, the
-   position of `-d' with respect to files on the command line is now
-   significant.
+   `--debugmode' is added as an alias for `-d'.  The new flag `d' is added
+   to control whether dereferncing an undefined macro causes a warning;
+   this flag is enabled by default if neither `-d' nor `-E' are specified.
+   When given the empty string, the mode is treated as `+adeq' instead of
+   `aeq'.  Also, the position of `-d' with respect to files on the command
+   line is now significant.
 
 ** New `-g'/`--gnu' command-line option overrides `-G'/`--traditional'.
    For now, the environment variable POSIXLY_CORRECT has no effect on M4
@@ -69,21 +71,13 @@ Foundation, Inc.
    be used, via `defn', to determine whether the version of m4 processing
    your file is adequate.
 
-** The `defn', `popdef', and `undefine' builtins now warn when operating
-   on an undefined macro name, similar to what was already done in the
-   `indir' and `dumpdef' builtins.  To simulate 1.4.x behavior, use:
-     pushdef(`defn', `ifelse(`$#', `0', ``defn'',
-                             `ifdef(`$1', `builtin(`defn', `$1')')')')
-     pushdef(`popdef', `ifelse(`$#', `0', ``popdef'', `_$0($@)')')
-     define(`_popdef', `ifdef(`$1', `builtin(`popdef', `$1')')ifelse(`$#',
-                `1', `', `$0(shift($@))')')
-     pushdef(`undefine', `ifelse(`$#', `0', ``undefine'', `_$0($@)')')
-     define(`_undefine', `ifdef(`$1', `builtin(`undefine', `$1')')ifelse(`$#',
-                `1', `', `$0(shift($@))')')
-
-   Additionally, if you want to install Autoconf 2.62 or earlier, then
-   apply this patch:
-     http://git.sv.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=c4a32a009
+** The `defn', `popdef', and `undefine' builtins gained a new warning when
+   operating on an undefined macro name, to match the warning already
+   present in `builtin', `indir', and `dumpdef'.  For backwards
+   compatibility, the warning can be disabled by using `debugmode(`-d')'
+   (or the command line option `--debug=-d').  The flag is also cleared by
+   the command line option `-E'/`--fatal-warnings', so that scripts written
+   for 1.4.x do not cause the script to fail because of new warnings.
 
 ** Enhance the `indir' builtin to trace indirect macros, where the trace
    is requested via `traceon' or the command-line option `-t'.  Previously,
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 5cfdb1a..e537c79 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -598,6 +598,56 @@ Operation modes
 1.4.9; for behavior consistent with earlier versions, you should specify
 @option{-E} twice.
 
+For backwards compatibility reasons, using @option{-E} behaves as if an
+implicit @option{--debug=-d} option is also present.  This is so that
+scripts written for older M4 versions will not fail if they used
+constructs that were previously silently allowed, but would now trigger
+a warning.
+
+@example
+$ @kbd{m4}
+defn(`oops')
+@error{}m4:stdin:1: Warning: defn: undefined macro `oops'
+@result{}
+^D
+@end example
+
+@comment ignore
+@example
+$ @kbd{echo $?}
+@result{}0
+@end example
+
+@comment options: -E
+@example
+$ @kbd{m4 -E}
+defn(`oops')
+@result{}
+^D
+@end example
+
+@comment ignore
+@example
+$ @kbd{echo $?}
+@result{}0
+@end example
+
+@comment options: -E -d
+@comment status: 1
+@example
+$ @kbd{m4 -E -d}
+defn(`oops')
+@error{}m4:stdin:1: Warning: defn: undefined macro `oops'
+@result{}
+^D
+@end example
+
+@comment ignore
+@example
+$ @kbd{echo $?}
+@result{}1
+@end example
+
 @item -i
 @itemx --interactive
 @itemx -e
@@ -845,17 +895,20 @@ Debugging options
 controls the format and amount of information presented by the debugging
 functions.  @xref{Debug Levels}, for more details on the format and
 meaning of @var{FLAGS}.  If omitted, @var{FLAGS} defaults to
-@samp{+aeq}.  If the option occurs multiple times, @var{FLAGS} starting
+@samp{+adeq}.  If the option occurs multiple times, @var{FLAGS} starting
 with @samp{-} or @samp{+} are cumulative, while @var{FLAGS} starting
-with a letter override all earlier settings.  Therefore, to disable all
-previously set flags, specify an explicit @var{FLAGS} of @samp{-V}.  The
-spelling @option{--debug} is recognized as an unambiguous option for
+with a letter override all earlier settings.  The debug-level starts
+with @samp{d} enabled and all other flags disabled.  To disable all
+previously set flags, specify an explicit @var{FLAGS} of @samp{-V}.  For
+backward compatibility reasons, the option @option{--fatal-warnings}
+implies @samp{--debug=-d} as part of its effects.  The spelling
+@option{--debug} is recognized as an unambiguous option for
 compatibility with earlier versions of @acronym{GNU} M4, but for
 consistency with the builtin name, you can also use the spelling
 @option{--debugmode}.  Order is significant with respect to file names.
 
 The cumulative effect of the various options in this example is
-equivalent to a single invocation of @code{debugmode(`alqx')}:
+equivalent to a single invocation of @code{debugmode(`adlqx')}:
 
 @comment options: -d-V -d+lx --debug --debugmode=-e
 @example
@@ -2130,7 +2183,8 @@ Undefine
 @deffn Builtin undefine (@var{name}@dots{})
 For each argument, remove the macro @var{name}.  The macro names must
 necessarily be quoted, since they will be expanded otherwise.  If an
-argument is not a defined macro, a warning is issued.
+argument is not a defined macro, then the @samp{d} debug level controls
+whether a warning is issued (@pxref{Debug Levels}).
 
 The expansion of @code{undefine} is void.
 The macro @code{undefine} is recognized only with parameters.
@@ -2165,30 +2219,19 @@ Undefine
 @result{}f(bye)
 @end example
 
-As of M4 1.6, @code{undefine} will warn if @var{name} is not a macro.
-The following example shows how to recover earlier behavior that
-silently ignores undefined names, using concepts that will be explained
-later in the manual.  Or, you could use the command line option
-@option{-Q} (@option{--quiet}, @pxref{Operation modes, , Invoking m4}).
+As of M4 1.6, @code{undefine} can warn if @var{name} is not a macro, by
+using @code{debugmode} (@pxref{Debug Levels}) or the command line option
+@option{-d} (@option{--debugmode}, @pxref{Debugging options, , Invoking
+m4}).
 
 @example
-define(`a', `1')
-@result{}
-undefine
-@result{}undefine
-undefine(`a', `a')
-@error{}m4:stdin:3: Warning: undefine: undefined macro `a'
-@result{}
-define(`a', `1')
-@result{}
-pushdef(`undefine', `ifelse(`$#', `0', ``undefine'', `_$0($@@)')')
+$ @kbd{m4}
+undefine(`a')
+@error{}m4:stdin:1: Warning: undefine: undefined macro `a'
 @result{}
-define(`_undefine', `ifdef(`$1', `builtin(`undefine',
-  `$1')')ifelse(`$#', `1', `', `$0(shift($@@))')')
+debugmode(`-d')
 @result{}
-undefine
-@result{}undefine
-undefine(`a', `a')
+undefine(`a')
 @result{}
 @end example
 
@@ -2205,7 +2248,8 @@ Defn
 @deffn Builtin defn (@var{name}@dots{})
 Expands to the @emph{quoted definition} of each @var{name}.  If an
 argument is not a defined macro, the expansion for that argument is
-empty and triggers a warning.
+empty, and the @samp{d} debug level controls whether a warning is issued
+(@pxref{Debug Levels}).
 
 If @var{name} is a user-defined macro, the quoted definition is simply
 the quoted expansion text.  If, instead, @var{name} is a builtin, the
@@ -2371,9 +2415,11 @@ Defn
 @result{}0
 @end example
 
-A warning is issued if @var{name} is undefined.  Also note that as of M4
-1.6, @code{defn} with multiple arguments can join text with builtin
-tokens.  However, when defining a macro via @code{define} or
+As of M4 1.6, @code{defn} can warn if @var{name} is not a macro, by
+using @code{debugmode} (@pxref{Debug Levels}) or the command line option
+@option{-d} (@option{--debugmode}, @pxref{Debugging options, , Invoking
+m4}).  Also, @code{defn} with multiple arguments can join text with
+builtin tokens.  However, when defining a macro via @code{define} or
 @code{pushdef}, a warning is issued and the builtin token ignored if the
 builtin token does not occur in isolation.  A future version of
 @acronym{GNU} M4 may lift this restriction.
@@ -2383,6 +2429,10 @@ Defn
 defn(`foo')
 @error{}m4:stdin:1: Warning: defn: undefined macro `foo'
 @result{}
+debugmode(`-d')
+@result{}
+defn(`foo')
+@result{}
 define(`a', `A')define(`AA', `b')
 @result{}
 traceon(`defn', `define')
@@ -2392,25 +2442,25 @@ Defn
 @result{}AA
 define(`mydivnum', defn(`divnum', `divnum'))mydivnum
 @error{}m4trace: -2- defn(`divnum', `divnum') -> `<divnum><divnum>'
-@error{}m4:stdin:5: Warning: define: cannot concatenate builtins
+@error{}m4:stdin:7: Warning: define: cannot concatenate builtins
 @error{}m4trace: -1- define(`mydivnum', `<divnum><divnum>') -> `'
 @result{}
 traceoff(`defn', `define')dumpdef(`mydivnum')
 @error{}mydivnum:@tabchar{}`'
 @result{}
 define(`mydivnum', defn(`divnum')defn(`divnum'))mydivnum
-@error{}m4:stdin:7: Warning: define: cannot concatenate builtins
+@error{}m4:stdin:9: Warning: define: cannot concatenate builtins
 @result{}
 define(`mydivnum', defn(`divnum')`a')mydivnum
-@error{}m4:stdin:8: Warning: define: cannot concatenate builtins
+@error{}m4:stdin:10: Warning: define: cannot concatenate builtins
 @result{}A
 define(`mydivnum', `a'defn(`divnum'))mydivnum
-@error{}m4:stdin:9: Warning: define: cannot concatenate builtins
+@error{}m4:stdin:11: Warning: define: cannot concatenate builtins
 @result{}A
 define(`q', ``$@@'')
 @result{}
 define(`foo', q(`a', defn(`divnum')))foo
-@error{}m4:stdin:11: Warning: define: cannot concatenate builtins
+@error{}m4:stdin:13: Warning: define: cannot concatenate builtins
 @result{}a,
 ifdef(`foo', `yes', `no')
 @result{}yes
@@ -2441,7 +2491,8 @@ Pushdef
 If a macro has several definitions (of which only one is accessible),
 the topmost definition can be removed with @code{popdef}.  If there is
 no previous definition, @code{popdef} behaves like @code{undefine}, and
-if there is no definition at all, @code{popdef} issues a warning.
+if there is no definition at all, the @samp{d} debug level controls
+whether a warning is issued (@pxref{Debug Levels}).
 
 The expansion of both @code{pushdef} and @code{popdef} is void.
 The macros @code{pushdef} and @code{popdef} are recognized only with
@@ -2514,11 +2565,10 @@ Pushdef
 It is possible to temporarily redefine a builtin with @code{pushdef}
 and @code{defn}.
 
-As of M4 1.6, @code{popdef} will warn if @var{name} is not a macro.
-The following example shows how to recover earlier behavior that
-silently ignores undefined names, using concepts that will be explained
-later in the manual.  Or, you could use the command line option
-@option{-Q} (@option{--quiet}, @pxref{Operation modes, , Invoking m4}).
+As of M4 1.6, @code{popdef} can warn if @var{name} is not a macro, by
+using @code{debugmode} (@pxref{Debug Levels}) or the command line option
+@option{-d} (@option{--debugmode}, @pxref{Debugging options, , Invoking
+m4}).
 
 @example
 $ @kbd{m4}
@@ -2529,16 +2579,9 @@ Pushdef
 popdef(`a', `a')
 @error{}m4:stdin:3: Warning: popdef: undefined macro `a'
 @result{}
-define(`a', `1')
-@result{}
-pushdef(`popdef', `ifelse(`$#', `0', ``popdef'', `_$0($@@)')')
-@result{}
-define(`_popdef', `ifdef(`$1', `builtin(`popdef',
-  `$1')')ifelse(`$#', `1', `', `$0(shift($@@))')')
+debugmode(`-d')
 @result{}
-popdef
-@result{}popdef
-popdef(`a', `a')
+popdef(`a')
 @result{}
 @end example
 
@@ -2552,9 +2595,10 @@ Indir
 Any macro can be called indirectly with @code{indir}:
 
 @deffn Builtin indir (@var{name}, @ovar{args@dots{}})
-Results in a call to the macro @var{name}, which is passed the
-rest of the arguments @var{args}.  If @var{name} is not defined, an
-error message is printed, and the expansion is void.
+Results in a call to the macro @var{name}, which is passed the rest of
+the arguments @var{args}.  If @var{name} is not defined, the expansion
+is void, and the @samp{d} debug level controls whether a warning is
+issued (@pxref{Debug Levels}).
 
 The macro @code{indir} is recognized only with parameters.
 @end deffn
@@ -2593,6 +2637,10 @@ Indir
 indir(`f', undefine(`f'))
 @error{}m4:stdin:4: Warning: indir: undefined macro `f'
 @result{}
+debugmode(`-d')
+@result{}
+indir(`f')
+@result{}
 @end example
 
 When handed the result of @code{defn} (@pxref{Defn}) as one of its
@@ -2643,7 +2691,8 @@ Builtin
 @deffn Builtin builtin (@var{name}, @ovar{args@dots{}})
 Results in a call to the builtin @var{name}, which is passed the
 rest of the arguments @var{args}.  If @var{name} does not name a
-builtin, an error message is printed, and the expansion is void.
+builtin, the expansion is void, and the @samp{d} debug level controls
+whether a warning is issued (@pxref{Debug Levels}).
 
 The macro @code{builtin} is recognized only with parameters.
 @end deffn
@@ -2697,6 +2746,10 @@ Builtin
 @result{}
 m4_indir(`m4_divnum')
 @result{}0
+m4_debugmode(`-d')
+@result{}
+m4_builtin(`m4_divnum')
+@result{}
 @end example
 
 Note that @code{indir} and @code{builtin} can be used to invoke builtins
@@ -3690,7 +3743,8 @@ Dumpdef
 it displays the definitions of all known names, otherwise it displays
 the definitions of each @var{name} given.  The output is printed to the
 current debug file (usually standard error), and is sorted by name.  If
-an unknown name is encountered, a warning is printed.
+a @var{name} is undefined, the @samp{d} debug level controls whether a
+warning is issued (@pxref{Debug Levels}).
 
 The expansion of @code{dumpdef} is void.
 @end deffn
@@ -3722,6 +3776,10 @@ Dumpdef
 f(popdef(`f')dumpdef(`f'))
 @error{}m4:stdin:3: Warning: dumpdef: undefined macro `f'
 @result{}f1
+debugmode(`-d')
+@result{}
+dumpdef(`f')
+@result{}
 @end example
 
 @xref{Debug Levels}, for information on controlling the details of the
@@ -3966,6 +4024,18 @@ Debug Levels
 only one line is printed, after all arguments are collected and the
 expansion determined.  This is often used with the @samp{x} flag.
 
+@item d
+Output a warning on any attempt to dereference an undefined macro via
+@code{builtin}, @code{defn}, @code{dumpdef}, @code{indir},
+@code{popdef}, or @code{undefine}.  Note that @code{indef},
+@code{traceon}, and @code{traceoff} do not dereference undefined macros.
+Like any other warning, the warnings enabled by this flag go to standard
+error regardless of the current @code{debugfile} setting, and will
+change exit status if the command line option @option{--fatal-warnings}
+was specified.  This flag is useful in diagnosing spelling mistakes in
+macro names.  It is enabled by default when neither @option{--debug} nor
+@option{--fatal-warnings} are specified on the command line.
+
 @item e
 In trace output, show the expansion of each macro call, if it is not
 void.  This applies to all macro calls if the @samp{t} flag is used,
@@ -4012,7 +4082,7 @@ Debug Levels
 @end table
 
 If no flags are specified with the @option{-d} option, the default is
-@samp{aeq}.  The examples throughout this manual assume the default
+@samp{+adeq}.  The examples throughout this manual assume the default
 flags.
 
 @cindex @acronym{GNU} extensions
@@ -4024,8 +4094,8 @@ Debug Levels
 As special cases, if the argument starts with a @samp{+}, the flags are
 added to the current debug flags, and if it starts with a @samp{-}, they
 are removed.  If no argument is present, all debugging flags are cleared
-(as if no @option{-d} was given), and with an empty argument the flags
-are reset to the default of @samp{aeq}.
+(as if by @samp{-V}), and with an empty argument the flags are reset to
+the default of @samp{+adeq}.
 
 The expansion of @code{debugmode} is void.
 @end deffn
diff --git a/src/builtin.c b/src/builtin.c
index 34387b9..a4e5bee 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -724,7 +724,8 @@ m4_undefine (struct obstack *obs, int argc, macro_arguments *argv)
   for (i = 1; i < argc; i++)
     if (arg_type (argv, i) != TOKEN_TEXT)
       m4_warn (0, me, _("invalid macro name ignored"));
-    else if (!lookup_symbol (ARG (i), ARG_LEN (i), SYMBOL_DELETE))
+    else if (!lookup_symbol (ARG (i), ARG_LEN (i), SYMBOL_DELETE)
+	     && (debug_level & DEBUG_TRACE_DEREF))
       m4_warn (0, me, _("undefined macro %s"),
 	       quotearg_style_mem (locale_quoting_style, ARG (i),
 				   ARG_LEN (i)));
@@ -746,7 +747,8 @@ m4_popdef (struct obstack *obs, int argc, macro_arguments *argv)
   for (i = 1; i < argc; i++)
     if (arg_type (argv, i) != TOKEN_TEXT)
       m4_warn (0, me, _("invalid macro name ignored"));
-    else if (!lookup_symbol (ARG (i), ARG_LEN (i), SYMBOL_POPDEF))
+    else if (!lookup_symbol (ARG (i), ARG_LEN (i), SYMBOL_POPDEF)
+	     && (debug_level & DEBUG_TRACE_DEREF))
       m4_warn (0, me, _("undefined macro %s"),
 	       quotearg_style_mem (locale_quoting_style, ARG (i),
 				   ARG_LEN (i)));
@@ -896,7 +898,7 @@ m4_dumpdef (struct obstack *obs, int argc, macro_arguments *argv)
 	  s = lookup_symbol (ARG (i), ARG_LEN (i), SYMBOL_LOOKUP);
 	  if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
 	    dump_symbol (s, &data);
-	  else
+	  else if (debug_level & DEBUG_TRACE_DEREF)
 	    m4_warn (0, me, _("undefined macro %s"),
 		     quotearg_style_mem (locale_quoting_style, ARG (i),
 					 ARG_LEN (i)));
@@ -970,8 +972,11 @@ m4_builtin (struct obstack *obs, int argc, macro_arguments *argv)
   name = ARG (1);
   bp = find_builtin_by_name (name);
   if (bp->func == m4_placeholder)
-    m4_warn (0, me, _("undefined builtin %s"),
-	     quotearg_style_mem (locale_quoting_style, name, ARG_LEN (1)));
+    {
+      if (debug_level & DEBUG_TRACE_DEREF)
+	m4_warn (0, me, _("undefined builtin %s"),
+		 quotearg_style_mem (locale_quoting_style, name, ARG_LEN (1)));
+    }
   else
     {
       macro_arguments *new_argv = make_argv_ref (argv, name, ARG_LEN (1),
@@ -1007,8 +1012,11 @@ m4_indir (struct obstack *obs, int argc, macro_arguments *argv)
   len = ARG_LEN (1);
   s = lookup_symbol (name, len, SYMBOL_LOOKUP);
   if (s == NULL || SYMBOL_TYPE (s) == TOKEN_VOID)
-    m4_warn (0, me, _("undefined macro %s"),
-	     quotearg_style_mem (locale_quoting_style, name, len));
+    {
+      if (debug_level & DEBUG_TRACE_DEREF)
+	m4_warn (0, me, _("undefined macro %s"),
+		 quotearg_style_mem (locale_quoting_style, name, len));
+    }
   else
     {
       macro_arguments *new_argv = make_argv_ref (argv, name, len,
@@ -1046,9 +1054,10 @@ m4_defn (struct obstack *obs, int argc, macro_arguments *argv)
       s = lookup_symbol (ARG (i), ARG_LEN (i), SYMBOL_LOOKUP);
       if (s == NULL || SYMBOL_TYPE (s) == TOKEN_VOID)
 	{
-	  m4_warn (0, me, _("undefined macro %s"),
-		   quotearg_style_mem (locale_quoting_style, ARG (i),
-				       ARG_LEN (i)));
+	  if (debug_level & DEBUG_TRACE_DEREF)
+	    m4_warn (0, me, _("undefined macro %s"),
+		     quotearg_style_mem (locale_quoting_style, ARG (i),
+					 ARG_LEN (i)));
 	  continue;
 	}
 
diff --git a/src/debug.c b/src/debug.c
index 579960b..babaf87 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -105,6 +105,10 @@ debug_decode (const char *opts)
 	      level |= DEBUG_TRACE_CALLID;
 	      break;
 
+	    case 'd':
+	      level |= DEBUG_TRACE_DEREF;
+	      break;
+
 	    case 'V':
 	      level |= DEBUG_TRACE_VERBOSE;
 	      break;
diff --git a/src/m4.c b/src/m4.c
index 22586fc..93beb40 100644
--- a/src/m4.c
+++ b/src/m4.c
@@ -36,7 +36,7 @@ static void usage (int);
 int sync_output = 0;
 
 /* Debug (-d[flags]).  */
-int debug_level = 0;
+int debug_level = DEBUG_TRACE_DEREF;
 
 /* Disable GNU extensions (-G).  */
 int no_gnu_extensions = 0;
@@ -257,7 +257,7 @@ Frozen state files:\n\
       fputs (_("\
 Debugging:\n\
   -d, --debug[=[-|+]FLAGS], --debugmode[=[-|+]FLAGS]\n\
-                               set debug level (no FLAGS implies `+aeq')\n\
+                               set debug level (no FLAGS implies `+adeq')\n\
       --debugfile=FILE         redirect debug and trace output\n\
   -l, --arglength=NUM          restrict macro tracing size\n\
   -t, --trace=NAME             trace NAME when it is defined\n\
@@ -267,6 +267,7 @@ Debugging:\n\
 FLAGS is any of:\n\
   a   show actual arguments in trace\n\
   c   show collection line in trace\n\
+  d   warn when dereferencing undefined macros (default on unless -E)\n\
   e   show expansion in trace\n\
   f   include current input file name in trace and debug\n\
   i   show changes in input files in debug\n\
@@ -479,6 +480,7 @@ main (int argc, char *const *argv, char *const *envp)
 	break;
 
       case 'E':
+	debug_decode ("-d");
 	if (!fatal_warnings)
 	  fatal_warnings = true;
 	else
diff --git a/src/m4.h b/src/m4.h
index 8da7d3c..27c0fa7 100644
--- a/src/m4.h
+++ b/src/m4.h
@@ -192,11 +192,13 @@ extern FILE *debug;
 #define DEBUG_TRACE_INPUT 0x100
 /* x: add call id to trace output */
 #define DEBUG_TRACE_CALLID 0x200
+/* d: warn if dereferencing undefined macro */
+#define DEBUG_TRACE_DEREF 0x400
 
 /* V: very verbose --  print everything */
-#define DEBUG_TRACE_VERBOSE 0x3FF
-/* default flags -- equiv: aeq */
-#define DEBUG_TRACE_DEFAULT 0x007
+#define DEBUG_TRACE_VERBOSE 0x7FF
+/* default flags -- equiv: adeq */
+#define DEBUG_TRACE_DEFAULT 0x407
 
 void debug_init (void);
 int debug_decode (const char *);
-- 
1.6.0

_______________________________________________
Autoconf mailing list
Autoconf@xxxxxxx
http://lists.gnu.org/mailman/listinfo/autoconf

[Index of Archives]     [GCC Help]     [Kernel Discussion]     [RPM Discussion]     [Red Hat Development]     [Yosemite News]     [Linux USB]     [Samba]

  Powered by Linux