head -dV option

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

$ m4 -dV
m4: bad debug flags: `V'

Whoops - especially since --help said -dV is shorthand for -dacefilpqtx.

So, I added a test.  While I was at it, I was annoyed that debugmode
allowed adding and subtracting flags, but getopt always wiped earlier
occurrences out.  In testing, I also found and fixed a slight output
formatting bug in 1.4.x, but I did not feel like porting the -d
improvements back to the branch.

branch-1_4
2006-08-22  Eric Blake  <[email protected]>

	* src/input.c (pop_input): Avoid empty filename with -di option.
	* src/debug.c (debug_message_prefix): Put space before message.

head
2006-08-22  Eric Blake  <[email protected]>

	* tests/options.at (debug-flags): New test.
	* m4/m4module.h (M4_DEBUG_TRACE_VERBOSE): Make sure this value is
	not negative, to distinguish failure in m4_debug_decode.
	(m4_debug_decode): Add new parameter.
	* modules/gnu.c (regexp): Slight cleanup.
	(renamesyms): Ignore excess arguments.
	(syncoutput): Make case-insensitive, warn on bad argument.
	(debugmode): Factor -+ handling out to...
	* m4/debug.c (m4_debug_decode): ...here.
	(m4_debug_message_prefix): Fix spacing.
	* src/main.c (main): Let -d option adjust flags.
	* m4/input.c (file_clean): Avoid printing empty file name.
	* doc/m4.texinfo (Syncoutput): Document new range of input.
	(Invoking m4): Document use of multiple -d flags.

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

Eric Blake             [email protected]

-----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

iD8DBQFE681z84KuGfSFAYARArB2AKCWU2YLMdFF7iYqFubURcXY9iz5WwCgr9Jr
tolOyd/J5LmFZoAdsmcYUNA=
=inSC
-----END PGP SIGNATURE-----

_______________________________________________
M4-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/m4-patches
m4.patch130 (text/plain, 1.4 KB)
Index: src/debug.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/debug.c,v
retrieving revision 1.1.1.1.2.8
diff -u -p -r1.1.1.1.2.8 debug.c
--- src/debug.c	18 Aug 2006 23:11:36 -0000	1.1.1.1.2.8
+++ src/debug.c	23 Aug 2006 00:45:06 -0000
@@ -219,8 +219,10 @@ debug_message_prefix (void)
     if (debug_level & DEBUG_TRACE_FILE)
       fprintf (debug, "%s:", current_file);
     if (debug_level & DEBUG_TRACE_LINE)
-      fprintf (debug, "%d:", current_line);
+      fprintf (debug, "%d: ", current_line);
   }
+  else
+    putc (' ', debug);
 }
 
 /* The rest of this file contains the functions for macro tracing output.
Index: src/input.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/input.c,v
retrieving revision 1.1.1.1.2.20
diff -u -p -r1.1.1.1.2.20 input.c
--- src/input.c	18 Aug 2006 16:28:22 -0000	1.1.1.1.2.20
+++ src/input.c	23 Aug 2006 00:45:06 -0000
@@ -311,8 +311,13 @@ pop_input (void)
 
     case INPUT_FILE:
       if (debug_level & DEBUG_TRACE_INPUT)
-	DEBUG_MESSAGE2 ("input reverted to %s, line %d",
-			isp->u.u_f.name, isp->u.u_f.lineno);
+	{
+	  if (isp->u.u_f.lineno)
+	    DEBUG_MESSAGE2 ("input reverted to %s, line %d",
+			    isp->u.u_f.name, isp->u.u_f.lineno);
+	  else
+	    DEBUG_MESSAGE ("input exhausted");
+	}
 
       if (ferror (isp->u.u_f.file))
 	{
m4.patch131 (text/plain, 10 KB)
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.31
diff -u -p -r1.31 m4.texinfo
--- doc/m4.texinfo	22 Aug 2006 13:44:22 -0000	1.31
+++ doc/m4.texinfo	23 Aug 2006 03:35:47 -0000
@@ -623,7 +623,10 @@ scripts.
 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}.  When the option is presented multiple times, if later
+@var{FLAGS} starts with @samp{-} or @samp{+}, they are cumulative,
+otherwise the later flags override all earlier occurrences.
 
 @item -l @var{NUM}
 @itemx --arglength=@var{NUM}
@@ -4006,15 +4009,15 @@ If you need to toggle sync lines on and 
 to insure that they are off or on, you may do so using
 @code{syncoutput}.
 
-@code{syncoutput(1)}, @code{syncoutput(on)}, and @code{syncoutput(yes)}
-causes @code{m4} to emit sync lines of the form: @code{#line <number>
-["<filename>"]}.
+If @var{truth} matches the extended regular expression
+@samp{^[1yY]|^([oO][nN])}, it causes @code{m4} to emit sync lines of the
+form: @code{#line <number> ["<file>"]}.
 
-@code{syncoutput(0)}, @code{syncoutput(off)}, and @code{syncoutput(no)}
-turn them off.
+If @var{truth} is empty, or matches the extended regular expression
+@samp{^[0nN]|^([oO][fF])}, it causes @code{m4} to turn sync lines off.
 
-All other arguments are ignored as is @code{syncoutput} without
-parenthesis.
+All other arguments are ignored and issue a warning.  The macro
+@code{syncoutput} is only recognized with arguments.
 @end deffn
 
 @node Frozen files
Index: m4/debug.c
===================================================================
RCS file: /sources/m4/m4/m4/debug.c,v
retrieving revision 1.22
diff -u -p -r1.22 debug.c
--- m4/debug.c	22 Aug 2006 22:36:28 -0000	1.22
+++ m4/debug.c	23 Aug 2006 03:35:47 -0000
@@ -29,14 +29,17 @@ static void set_debug_file (m4 *, FILE *
 /* Function to decode the debugging flags OPTS.  Used by main while
    processing option -d, and by the builtin debugmode ().  */
 int
-m4_debug_decode (m4 *context, const char *opts)
+m4_debug_decode (m4 *context, int previous, const char *opts)
 {
   int level;
+  char mode = '\0';
 
   if (opts == NULL || *opts == '\0')
     level = M4_DEBUG_TRACE_DEFAULT;
   else
     {
+      if (*opts == '-' || *opts == '+')
+	mode = *opts++;
       for (level = 0; *opts; opts++)
 	{
 	  switch (*opts)
@@ -97,6 +100,26 @@ m4_debug_decode (m4 *context, const char
   obstack_free (&context->trace_messages,
 		obstack_finish (&context->trace_messages));
 
+  switch (mode)
+    {
+    case '\0':
+      /* Replace old level.  */
+      break;
+
+    case '-':
+      /* Subtract flags.  */
+      level = previous & ~level;
+      break;
+
+    case '+':
+      /* Add flags.  */
+      level |= previous;
+      break;
+
+    default:
+      assert (!"INTERNAL ERROR: impossible mode from flags");
+    }
+
   return level;
 }
 
@@ -179,4 +202,5 @@ m4_debug_message_prefix (m4 *context)
       if (m4_is_debug_bit (context, M4_DEBUG_TRACE_LINE))
 	fprintf (debug_file, "%d:", m4_get_current_line (context));
     }
+  putc (' ', debug_file);
 }
Index: m4/input.c
===================================================================
RCS file: /sources/m4/m4/m4/input.c,v
retrieving revision 1.43
diff -u -p -r1.43 input.c
--- m4/input.c	16 Aug 2006 12:23:04 -0000	1.43
+++ m4/input.c	23 Aug 2006 03:35:48 -0000
@@ -223,8 +223,13 @@ static void
 file_clean (m4 *context)
 {
   if (m4_is_debug_bit (context, M4_DEBUG_TRACE_INPUT))
-    M4_DEBUG_MESSAGE2 (context, _("input reverted to %s, line %d"),
-		       isp->u.u_f.name, isp->u.u_f.lineno);
+    {
+      if (isp->u.u_f.lineno)
+	M4_DEBUG_MESSAGE2 (context, _("input reverted to %s, line %d"),
+			   isp->u.u_f.name, isp->u.u_f.lineno);
+      else
+	M4_DEBUG_MESSAGE (context, _("input exhausted"));
+    }
 
   fclose (isp->u.u_f.file);
   m4_set_current_file (context, isp->u.u_f.name);
Index: m4/m4module.h
===================================================================
RCS file: /sources/m4/m4/m4/m4module.h,v
retrieving revision 1.77
diff -u -p -r1.77 m4module.h
--- m4/m4module.h	9 Aug 2006 21:33:24 -0000	1.77
+++ m4/m4module.h	23 Aug 2006 03:35:48 -0000
@@ -268,7 +268,7 @@ enum {
   M4_DEBUG_TRACE_CALLID		= (1 << 9),
 
   /* V: very verbose --  print everything */
-  M4_DEBUG_TRACE_VERBOSE	= (~0)
+  M4_DEBUG_TRACE_VERBOSE	= ((1 << 10) - 1)
 };
 
 /* default flags -- equiv: aeq */
@@ -277,7 +277,7 @@ enum {
 
 #define m4_is_debug_bit(C,B)	(BIT_TEST (m4_get_debug_level_opt (C), (B)))
 
-extern int	m4_debug_decode		(m4 *, const char *);
+extern int	m4_debug_decode		(m4 *, int, const char *);
 extern bool	m4_debug_set_output	(m4 *, const char *);
 extern void	m4_debug_message_prefix (m4 *);
 
Index: modules/gnu.c
===================================================================
RCS file: /sources/m4/m4/modules/gnu.c,v
retrieving revision 1.49
diff -u -p -r1.49 gnu.c
--- modules/gnu.c	21 Aug 2006 12:46:24 -0000	1.49
+++ modules/gnu.c	23 Aug 2006 03:35:48 -0000
@@ -410,43 +410,17 @@ M4BUILTIN_HANDLER (debugmode)
 {
   int debug_level = m4_get_debug_level_opt (context);
   int new_debug_level;
-  int change_flag;
 
   if (argc == 1)
     m4_set_debug_level_opt (context, 0);
   else
     {
-      if (M4ARG (1)[0] == '+' || M4ARG (1)[0] == '-')
-	{
-	  change_flag = M4ARG (1)[0];
-	  new_debug_level = m4_debug_decode (context, M4ARG (1) + 1);
-	}
-      else
-	{
-	  change_flag = 0;
-	  new_debug_level = m4_debug_decode (context, M4ARG (1));
-	}
-
+      new_debug_level = m4_debug_decode (context, debug_level, M4ARG (1));
       if (new_debug_level < 0)
 	m4_error (context, 0, 0, _("%s: bad debug flags: `%s'"),
 		  M4ARG (0), M4ARG (1));
       else
-	{
-	  switch (change_flag)
-	    {
-	    case 0:
-	      m4_set_debug_level_opt (context, new_debug_level);
-	      break;
-
-	    case '+':
-	      m4_set_debug_level_opt (context, debug_level | new_debug_level);
-	      break;
-
-	    case '-':
-	      m4_set_debug_level_opt (context, debug_level & ~new_debug_level);
-	      break;
-	    }
-	}
+	m4_set_debug_level_opt (context, new_debug_level);
     }
 }
 
@@ -610,11 +584,11 @@ M4BUILTIN_HANDLER (regexp)
       if (resyntax < 0)
 	return;
     }
-  /*
-    else
-      regexp(VICTIM, REGEXP)  */
+  else
+    /* regexp(VICTIM, REGEXP)  */
+    replace = NULL;
 
-  buf = m4_regexp_compile (context, me, M4ARG (2), resyntax, argc == 3);
+  buf = m4_regexp_compile (context, me, M4ARG (2), resyntax, replace == NULL);
   if (!buf)
     return;
 
@@ -628,7 +602,7 @@ M4BUILTIN_HANDLER (regexp)
       return;
     }
 
-  if ((argc == 3) || (replace == NULL))
+  if (replace == NULL)
     m4_shipout_int (obs, startpos);
   else if (startpos >= 0)
     substitute (context, obs, me, M4ARG (1), replace, buf);
@@ -666,7 +640,7 @@ M4BUILTIN_HANDLER (renamesyms)
       replace = M4ARG (2);
 
       resyntax = m4_get_regexp_syntax_opt (context);
-      if (argc == 4)
+      if (argc >= 4)
 	{
 	  resyntax = m4_resyntax_encode_safe (context, me, M4ARG (3));
 	  if (resyntax < 0)
@@ -746,15 +720,22 @@ M4BUILTIN_HANDLER (symbols)
  **/
 M4BUILTIN_HANDLER (syncoutput)
 {
-  if (m4_is_symbol_value_text (argv[1]))
-    {
-      if (   M4ARG (1)[0] == '0'
-	  || M4ARG (1)[0] == 'n'
-	  || (M4ARG (1)[0] == 'o' && M4ARG (1)[1] == 'f'))
-	m4_set_sync_output_opt (context, false);
-      else if (   M4ARG (1)[0] == '1'
-	       || M4ARG (1)[0] == 'y'
-	       || (M4ARG (1)[0] == 'o' && M4ARG (1)[1] == 'n'))
-	m4_set_sync_output_opt (context, true);
-    }
+  const char *arg = M4ARG (1);
+
+  if (arg[0] == '\0'
+      || arg[0] == '0'
+      || arg[0] == 'n'
+      || arg[0] == 'N'
+      || ((arg[0] == 'o' || arg[0] == 'O')
+	  && (arg[1] == 'f' || arg[1] == 'F')))
+    m4_set_sync_output_opt (context, false);
+  else if (arg[0] == '1'
+	   || arg[0] == 'y'
+	   || arg[0] == 'Y'
+	   || ((arg[0] == 'o' || arg[0] == 'O')
+	       && (arg[1] == 'n' || arg[1] == 'N')))
+    m4_set_sync_output_opt (context, true);
+  else
+    m4_warn (context, 0, _("Warning: %s: unknown directive `%s'"),
+	     M4ARG (0), arg);
 }
Index: src/main.c
===================================================================
RCS file: /sources/m4/m4/src/main.c,v
retrieving revision 1.75
diff -u -p -r1.75 main.c
--- src/main.c	22 Aug 2006 16:16:48 -0000	1.75
+++ src/main.c	23 Aug 2006 03:35:48 -0000
@@ -345,7 +345,11 @@ main (int argc, char *const *argv, char 
 	break;
 
       case 'd':
-	m4_set_debug_level_opt (context, m4_debug_decode (context, optarg));
+	{
+	  int old = m4_get_debug_level_opt (context);
+	  m4_set_debug_level_opt (context, m4_debug_decode (context, old,
+							    optarg));
+	}
 	if (m4_get_debug_level_opt (context) < 0)
 	  {
 	    error (0, 0, _("bad debug flags: `%s'"), optarg);
Index: tests/options.at
===================================================================
RCS file: /sources/m4/m4/tests/options.at,v
retrieving revision 1.3
diff -u -p -r1.3 options.at
--- tests/options.at	22 Aug 2006 16:16:48 -0000	1.3
+++ tests/options.at	23 Aug 2006 03:35:48 -0000
@@ -73,3 +73,43 @@ OVERRIDE=It is changed.
 ]])
 
 AT_CLEANUP
+
+
+## ----------- ##
+## debug-flags ##
+## ----------- ##
+
+AT_SETUP([debug-flags])
+
+AT_DATA([[in]],
+[[divnum
+len(`abc')
+]])
+
+dnl AT_CHECK_M4 starts life with -d.  Make sure it looks like -daeq.
+AT_CHECK_M4([-tlen in], 0, [[0
+3
+]], [[m4trace: -1- len(`abc') -> `3'
+]])
+
+dnl Test all flags.
+AT_CHECK_M4([-dV in], 0, [[0
+3
+]], [[m4debug: input read from in
+m4trace:in:1: -1- id 1: divnum ...
+m4trace:in:1: -1- id 1: divnum -> ???
+m4trace:in:1: -1- id 1: divnum -> `0'
+m4trace:in:2: -1- id 2: len ...
+m4trace:in:2: -1- id 2: len(`abc') -> ???
+m4trace:in:2: -1- id 2: len(...) -> `3'
+m4debug:in:3: input exhausted
+]])
+
+dnl Test addition and subtraction of flags.
+AT_CHECK_M4([-d-e -d+xt in], 0, [[0
+3
+]], [[m4trace: -1- id 1: divnum
+m4trace: -1- id 2: len(`abc')
+]])
+
+AT_CLEANUP
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.