prelim patches before argv_ref

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
Some trivial cleanup patches for branch-1_4, to make it more like the master 
branch, before I start applying the argv_ref patches to both branch and head.  
One makes dnl's warning message include the macro name, the next improves the 
bad_argc calling conventions, and the final makes all messages consistently 
mention the macro name.

I plan on rebasing the argv_ref branch on top of these patches.

Subject: [PATCH] Make dnl diagnostic print macro name.
* src/m4.h (skip_line): Adjust prototype.
* src/input.c (skip_line): Report error on behalf of caller.
* src/builtin.c (m4_dnl): Adjust caller.
(dump_args, m4_dumpdef, m4_changequote, m4_changecom)
(m4_changeword, m4_traceon, m4_traceoff, expand_user_macro): Use
ARG macro instead of open-coding.
* doc/m4.texinfo (Dnl): Adjust test.

Subject: [PATCH] Make argument checking a bit more sane.
* src/builtin.c (bad_argc): Adjust signature, and don't force
callers to add 1.  Adjust all callers.
(numeric_arg): Adjust signature.  Adjust all callers.

Subject: [PATCH] Consistently report macro name first in messages.
* src/m4.h (evaluate): Adjust prototype.
* src/builtin.c (bad_argc, numeric_arg, m4_placeholder): Alter
wording to match head.
(mkstemp_helper, substitute): Adjust signature.  All callers
changed.
(m4_dumpdef, m4_builtin, m4_indir, m4_defn, m4_esyscmd, m4_eval)
(m4_undivert, m4_maketemp, m4_m4exit, m4_debugmode)
(m4_debugfile, m4_regexp, m4_patsubst): Mention macro name in
message.
(m4_format): Adjust call.
* src/format.c (format): No longer skip argv[0].
* src/eval.c (evaluate): Mention macro name in message.
(logical_or_term, logical_and_term, or_term, xor_term, and_term)
(equality_term, cmp_term, shift_term, add_term, mult_term)
(exp_term, unary_term, simple_term): Adjust signature.
* src/macro.c (warn_builtin_concat): Likewise.
(expand_argument): Adjust caller.
* doc/m4.texinfo (Macro Arguments, Ifdef, Ifelse, Debug Output)
(Dnl, Improved fatal_error, Defn, Builtin, Index macro, Regexp)
(Substr, Translit, Patsubst, Format, Eval, Dumpdef, Include)
(Improved forloop, Indir, Trace, Incr): Adjust tests to match.


---
From 19de46ef3e90aec72901b225c702b5ac1749c1a1 Mon Sep 17 00:00:00 2001
From: Eric Blake <[email protected]>
Date: Wed, 21 Nov 2007 14:17:36 -0700
Subject: [PATCH] Make dnl diagnostic print macro name.

* src/m4.h (skip_line): Adjust prototype.
* src/input.c (skip_line): Report error on behalf of caller.
* src/builtin.c (m4_dnl): Adjust caller.
(dump_args, m4_dumpdef, m4_changequote, m4_changecom)
(m4_changeword, m4_traceon, m4_traceoff, expand_user_macro): Use
ARG macro instead of open-coding.
* doc/m4.texinfo (Dnl): Adjust test.

Signed-off-by: Eric Blake <[email protected]>
---
 ChangeLog      |   11 +++++++++++
 doc/m4.texinfo |    2 +-
 src/builtin.c  |   26 ++++++++++++--------------
 src/input.c    |    4 ++--
 src/m4.h       |    2 +-
 5 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ae487a0..22776fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-11-21  Eric Blake  <[email protected]>
+
+	Make dnl diagnostic print macro name.
+	* src/m4.h (skip_line): Adjust prototype.
+	* src/input.c (skip_line): Report error on behalf of caller.
+	* src/builtin.c (m4_dnl): Adjust caller.
+	(dump_args, m4_dumpdef, m4_changequote, m4_changecom)
+	(m4_changeword, m4_traceon, m4_traceoff, expand_user_macro): Use
+	ARG macro instead of open-coding.
+	* doc/m4.texinfo (Dnl): Adjust test.
+
 2007-11-14  Eric Blake  <[email protected]>
 
 	Avoid builtin concatenation in macro arguments.
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 6caa7c3..c573e76 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -3491,7 +3491,7 @@ m4wrap(`m4wrap(`2 hi
 define(`hi', `HI')
 @result{}
 ^D
-@error{}m4:stdin:1: Warning: end of file treated as newline
+@error{}m4:stdin:1: Warning: dnl: end of file treated as newline
 @result{}0 HI 2 HI
 @end example
 
diff --git a/src/builtin.c b/src/builtin.c
index 280344f..88649da 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -634,8 +634,7 @@ dump_args (struct obstack *obs, int argc, token_data **argv,
 	obstack_grow (obs, sep, len);
       if (quoted)
 	obstack_grow (obs, lquote.string, lquote.length);
-      obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
-		    strlen (TOKEN_DATA_TEXT (argv[i])));
+      obstack_grow (obs, ARG (i), strlen (ARG (i)));
       if (quoted)
 	obstack_grow (obs, rquote.string, rquote.length);
     }
@@ -866,12 +865,12 @@ m4_dumpdef (struct obstack *obs, int argc, token_data 
**argv)
     {
       for (i = 1; i < argc; i++)
 	{
-	  s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
+	  s = lookup_symbol (ARG (i), SYMBOL_LOOKUP);
 	  if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
 	    dump_symbol (s, &data);
 	  else
 	    M4ERROR ((warning_status, 0,
-		      "undefined macro `%s'", TOKEN_DATA_TEXT (argv[i])));
+		      "undefined macro `%s'", ARG (i)));
 	}
     }
 
@@ -1334,7 +1333,7 @@ m4_dnl (struct obstack *obs, int argc, token_data **argv)
   if (bad_argc (argv[0], argc, 1, 1))
     return;
 
-  skip_line ();
+  skip_line (ARG (0));
 }
 
 /*-------------------------------------------------------------------------.
@@ -1361,8 +1360,8 @@ m4_changequote (struct obstack *obs, int argc, token_data 
**argv)
     return;
 
   /* Explicit NULL distinguishes between empty and missing argument.  */
-  set_quotes ((argc >= 2) ? TOKEN_DATA_TEXT (argv[1]) : NULL,
-	     (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
+  set_quotes ((argc >= 2) ? ARG (1) : NULL,
+	     (argc >= 3) ? ARG (2) : NULL);
 }
 
 /*--------------------------------------------------------------------.
@@ -1377,8 +1376,8 @@ m4_changecom (struct obstack *obs, int argc, token_data 
**argv)
     return;
 
   /* Explicit NULL distinguishes between empty and missing argument.  */
-  set_comment ((argc >= 2) ? TOKEN_DATA_TEXT (argv[1]) : NULL,
-	       (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
+  set_comment ((argc >= 2) ? ARG (1) : NULL,
+	       (argc >= 3) ? ARG (2) : NULL);
 }
 
 #ifdef ENABLE_CHANGEWORD
@@ -1394,7 +1393,7 @@ m4_changeword (struct obstack *obs, int argc, token_data 
**argv)
   if (bad_argc (argv[0], argc, 2, 2))
     return;
 
-  set_word_regexp (TOKEN_DATA_TEXT (argv[1]));
+  set_word_regexp (ARG (1));
 }
 
 #endif /* ENABLE_CHANGEWORD */
@@ -1670,7 +1669,7 @@ m4_traceon (struct obstack *obs, int argc, token_data 
**argv)
   else
     for (i = 1; i < argc; i++)
       {
-	s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_INSERT);
+	s = lookup_symbol (ARG (i), SYMBOL_INSERT);
 	set_trace (s, obs);
       }
 }
@@ -1690,7 +1689,7 @@ m4_traceoff (struct obstack *obs, int argc, token_data 
**argv)
   else
     for (i = 1; i < argc; i++)
       {
-	s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
+	s = lookup_symbol (ARG (i), SYMBOL_LOOKUP);
 	if (s != NULL)
 	  set_trace (s, NULL);
       }
@@ -2295,8 +2294,7 @@ expand_user_macro (struct obstack *obs, symbol *sym,
 		i = i*10 + (*text - '0');
 	    }
 	  if (i < argc)
-	    obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
-			  strlen (TOKEN_DATA_TEXT (argv[i])));
+	    obstack_grow (obs, ARG (i), strlen (ARG (i)));
 	  break;
 
 	case '#':		/* number of arguments */
diff --git a/src/input.c b/src/input.c
index 091d108..58f24be 100644
--- a/src/input.c
+++ b/src/input.c
@@ -564,7 +564,7 @@ next_char_1 (void)
 `-------------------------------------------------------------------*/
 
 void
-skip_line (void)
+skip_line (const char *name)
 {
   int ch;
   const char *file = current_file;
@@ -576,7 +576,7 @@ skip_line (void)
     /* current_file changed to "" if we see CHAR_EOF, use the
        previous value we stored earlier.  */
     M4ERROR_AT_LINE ((warning_status, 0, file, line,
-		      "Warning: end of file treated as newline"));
+		      "Warning: %s: end of file treated as newline", name));
   /* On the rare occasion that dnl crosses include file boundaries
      (either the input file did not end in a newline, or changeword
      was used), calling next_char can update current_file and
diff --git a/src/m4.h b/src/m4.h
index f1ff0c8..a85bf41 100644
--- a/src/m4.h
+++ b/src/m4.h
@@ -288,7 +288,7 @@ typedef enum token_data_type token_data_type;
 void input_init (void);
 token_type peek_token (void);
 token_type next_token (token_data *, int *, const char *);
-void skip_line (void);
+void skip_line (const char *);
 
 /* push back input */
 void push_file (FILE *, const char *, bool);
-- 
1.5.3.5


From e60e8abd21366b0a14103a96eca8ad1c1e979de3 Mon Sep 17 00:00:00 2001
From: Eric Blake <[email protected]>
Date: Wed, 21 Nov 2007 14:55:44 -0700
Subject: [PATCH] Make argument checking a bit more sane.

* src/builtin.c (bad_argc): Adjust signature, and don't force
callers to add 1.  Adjust all callers.
(numeric_arg): Adjust signature.  Adjust all callers.

Signed-off-by: Eric Blake <[email protected]>
---
 ChangeLog     |    5 ++
 src/builtin.c |  203 +++++++++++++++++++++++++++-----------------------------
 2 files changed, 103 insertions(+), 105 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 22776fb..4cb7b46 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2007-11-21  Eric Blake  <[email protected]>
 
+	Make argument checking a bit more sane.
+	* src/builtin.c (bad_argc): Adjust signature, and don't force
+	callers to add 1.  Adjust all callers.
+	(numeric_arg): Adjust signature.  Adjust all callers.
+
 	Make dnl diagnostic print macro name.
 	* src/m4.h (skip_line): Adjust prototype.
 	* src/input.c (skip_line): Report error on behalf of caller.
diff --git a/src/builtin.c b/src/builtin.c
index 88649da..4e6f5dc 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -491,43 +491,39 @@ builtin_init (void)
       }
 }
 
-/*------------------------------------------------------------------------.
-| Give friendly warnings if a builtin macro is passed an inappropriate	  |
-| number of arguments.  NAME is macro name for messages, ARGC is actual
	  |
-| number of arguments, MIN is the minimum number of acceptable arguments, |
-| negative if not applicable, MAX is the maximum number, negative if not  |
-| applicable.								  |
-`------------------------------------------------------------------------*/
+/*------------------------------------------------------------------.
+| Give friendly warnings if a builtin macro is passed an            |
+| inappropriate number of arguments.  NAME is macro name for        |
+| messages.  ARGC is one more than the number of arguments.  MIN is |
+| the 0-based minimum number of acceptable arguments.  MAX is the   |
+| 0-based maximum number of arguments, UINT_MAX if not applicable.  |
+| Return true if there are not enough arguments.                    |
+`------------------------------------------------------------------*/
 
 static bool
-bad_argc (token_data *name, int argc, int min, int max)
+bad_argc (const char *name, int argc, unsigned int min, unsigned int max)
 {
-  bool isbad = false;
-
-  if (min > 0 && argc < min)
+  if (argc - 1 < min)
     {
       if (!suppress_warnings)
 	M4ERROR ((warning_status, 0,
-		  "Warning: too few arguments to builtin `%s'",
-		  TOKEN_DATA_TEXT (name)));
-      isbad = true;
+		  "Warning: too few arguments to builtin `%s'", name));
+      return true;
     }
-  else if (max > 0 && argc > max && !suppress_warnings)
+  if (argc - 1 > max && !suppress_warnings)
     M4ERROR ((warning_status, 0,
-	      "Warning: excess arguments to builtin `%s' ignored",
-	      TOKEN_DATA_TEXT (name)));
-
-  return isbad;
+	      "Warning: excess arguments to builtin `%s' ignored", name));
+  return false;
 }
 
-/*--------------------------------------------------------------------------.
-| The function numeric_arg () converts ARG to an int pointed to by VALUEP.  |
-| If the conversion fails, print error message for macro MACRO.  Return
	    |
-| true iff conversion succeeds.					
	    |
-`--------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------.
+| The function numeric_arg () converts ARG to an int pointed to by   |
+| VALUEP.  If the conversion fails, print error message on behalf of |
+| NAME.  Return true iff conversion succeeds.                        |
+`-------------------------------------------------------------------*/
 
 static bool
-numeric_arg (token_data *macro, const char *arg, int *valuep)
+numeric_arg (const char *name, const char *arg, int *valuep)
 {
   char *endp;
 
@@ -535,8 +531,7 @@ numeric_arg (token_data *macro, const char *arg, int 
*valuep)
     {
       *valuep = 0;
       M4ERROR ((warning_status, 0,
-		"empty string treated as 0 in builtin `%s'",
-		TOKEN_DATA_TEXT (macro)));
+		"empty string treated as 0 in builtin `%s'", name));
     }
   else
     {
@@ -545,18 +540,15 @@ numeric_arg (token_data *macro, const char *arg, int 
*valuep)
       if (*endp != '\0')
 	{
 	  M4ERROR ((warning_status, 0,
-		    "non-numeric argument to builtin `%s'",
-		    TOKEN_DATA_TEXT (macro)));
+		    "non-numeric argument to builtin `%s'", name));
 	  return false;
 	}
       if (isspace (to_uchar (*arg)))
 	M4ERROR ((warning_status, 0,
-		  "leading whitespace ignored in builtin `%s'",
-		  TOKEN_DATA_TEXT (macro)));
+		  "leading whitespace ignored in builtin `%s'", name));
       else if (errno == ERANGE)
 	M4ERROR ((warning_status, 0,
-		  "numeric overflow detected in builtin `%s'",
-		  TOKEN_DATA_TEXT (macro)));
+		  "numeric overflow detected in builtin `%s'", name));
     }
   return true;
 }
@@ -664,14 +656,15 @@ static void
 define_macro (int argc, token_data **argv, symbol_lookup mode)
 {
   const builtin *bp;
+  const char *me = ARG (0);
 
-  if (bad_argc (argv[0], argc, 2, 3))
+  if (bad_argc (me, argc, 1, 2))
     return;
 
   if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
     {
       M4ERROR ((warning_status, 0,
-		"Warning: %s: invalid macro name ignored", ARG (0)));
+		"Warning: %s: invalid macro name ignored", me));
       return;
     }
 
@@ -711,7 +704,7 @@ static void
 m4_undefine (struct obstack *obs, int argc, token_data **argv)
 {
   int i;
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (ARG (0), argc, 1, -1))
     return;
   for (i = 1; i < argc; i++)
     lookup_symbol (ARG (i), SYMBOL_DELETE);
@@ -727,7 +720,7 @@ static void
 m4_popdef (struct obstack *obs, int argc, token_data **argv)
 {
   int i;
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (ARG (0), argc, 1, -1))
     return;
   for (i = 1; i < argc; i++)
     lookup_symbol (ARG (i), SYMBOL_POPDEF);
@@ -743,7 +736,7 @@ m4_ifdef (struct obstack *obs, int argc, token_data **argv)
   symbol *s;
   const char *result;
 
-  if (bad_argc (argv[0], argc, 3, 4))
+  if (bad_argc (ARG (0), argc, 2, 3))
     return;
   s = lookup_symbol (ARG (1), SYMBOL_LOOKUP);
 
@@ -762,18 +755,18 @@ static void
 m4_ifelse (struct obstack *obs, int argc, token_data **argv)
 {
   const char *result;
-  token_data *argv0;
+  const char *me;
 
   if (argc == 2)
     return;
 
-  if (bad_argc (argv[0], argc, 4, -1))
+  me = ARG (0);
+  if (bad_argc (me, argc, 3, -1))
     return;
-  else
+  else if (argc % 3 == 0)
     /* Diagnose excess arguments if 5, 8, 11, etc., actual arguments.  */
-    bad_argc (argv[0], (argc + 2) % 3, -1, 1);
+    bad_argc (me, argc, 0, argc - 2);
 
-  argv0 = argv[0];
   argv++;
   argc--;
 
@@ -922,15 +915,16 @@ m4_dumpdef (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_builtin (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   const builtin *bp;
   const char *name;
 
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (me, argc, 1, -1))
     return;
   if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
     {
       M4ERROR ((warning_status, 0,
-		"Warning: %s: invalid macro name ignored", ARG (0)));
+		"Warning: %s: invalid macro name ignored", me));
       return;
     }
 
@@ -963,15 +957,16 @@ m4_builtin (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_indir (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   symbol *s;
   const char *name;
 
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (me, argc, 1, -1))
     return;
   if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
     {
       M4ERROR ((warning_status, 0,
-		"Warning: %s: invalid macro name ignored", ARG (0)));
+		"Warning: %s: invalid macro name ignored", me));
       return;
     }
 
@@ -1007,7 +1002,7 @@ m4_defn (struct obstack *obs, int argc, token_data **argv)
   builtin_func *b;
   int i;
 
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (ARG (0), argc, 1, -1))
     return;
 
   for (i = 1; i < argc; i++)
@@ -1084,7 +1079,7 @@ static int sysval;
 static void
 m4_syscmd (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (ARG (0), argc, 1, 1))
     {
       /* The empty command is successful.  */
       sysval = 0;
@@ -1111,7 +1106,7 @@ m4_esyscmd (struct obstack *obs, int argc, token_data 
**argv)
   FILE *pin;
   int ch;
 
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (ARG (0), argc, 1, 1))
     {
       /* The empty command is successful.  */
       sysval = 0;
@@ -1151,37 +1146,37 @@ m4_sysval (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_eval (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   int32_t value = 0;
   int radix = 10;
   int min = 1;
   const char *s;
 
-  if (bad_argc (argv[0], argc, 2, 4))
+  if (bad_argc (me, argc, 1, 3))
     return;
 
-  if (*ARG (2) && !numeric_arg (argv[0], ARG (2), &radix))
+  if (*ARG (2) && !numeric_arg (me, ARG (2), &radix))
     return;
 
   if (radix < 1 || radix > (int) strlen (digits))
     {
       M4ERROR ((warning_status, 0,
-		"radix %d in builtin `%s' out of range",
-		radix, ARG (0)));
+		"radix %d in builtin `%s' out of range", radix, me));
       return;
     }
 
-  if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &min))
+  if (argc >= 4 && !numeric_arg (me, ARG (3), &min))
     return;
   if (min < 0)
     {
       M4ERROR ((warning_status, 0,
-		"negative width to builtin `%s'", ARG (0)));
+		"negative width to builtin `%s'", me));
       return;
     }
 
   if (!*ARG (1))
     M4ERROR ((warning_status, 0,
-	      "empty string treated as 0 in builtin `%s'", ARG (0)));
+	      "empty string treated as 0 in builtin `%s'", me));
   else if (evaluate (ARG (1), &value))
     return;
 
@@ -1217,12 +1212,13 @@ m4_eval (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_incr (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   int value;
 
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (me, argc, 1, 1))
     return;
 
-  if (!numeric_arg (argv[0], ARG (1), &value))
+  if (!numeric_arg (me, ARG (1), &value))
     return;
 
   shipout_int (obs, value + 1);
@@ -1231,12 +1227,13 @@ m4_incr (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_decr (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   int value;
 
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (me, argc, 1, 1))
     return;
 
-  if (!numeric_arg (argv[0], ARG (1), &value))
+  if (!numeric_arg (me, ARG (1), &value))
     return;
 
   shipout_int (obs, value - 1);
@@ -1253,12 +1250,11 @@ m4_decr (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_divert (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   int i = 0;
 
-  if (bad_argc (argv[0], argc, 1, 2))
-    return;
-
-  if (argc >= 2 && !numeric_arg (argv[0], ARG (1), &i))
+  bad_argc (me, argc, 0, 1);
+  if (argc >= 2 && !numeric_arg (me, ARG (1), &i))
     return;
 
   make_diversion (i);
@@ -1271,8 +1267,7 @@ m4_divert (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_divnum (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 1, 1))
-    return;
+  bad_argc (ARG (0), argc, 0, 0);
   shipout_int (obs, current_diversion);
 }
 
@@ -1286,7 +1281,9 @@ m4_divnum (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_undivert (struct obstack *obs, int argc, token_data **argv)
 {
-  int i, file;
+  const char *me = ARG (0);
+  int i;
+  int file;
   FILE *fp;
   char *endp;
 
@@ -1300,7 +1297,7 @@ m4_undivert (struct obstack *obs, int argc, token_data 
**argv)
 	  insert_diversion (file);
 	else if (no_gnu_extensions)
 	  M4ERROR ((warning_status, 0,
-		    "non-numeric argument to builtin `%s'", ARG (0)));
+		    "non-numeric argument to builtin `%s'", me));
 	else
 	  {
 	    fp = m4_path_search (ARG (i), NULL);
@@ -1330,10 +1327,10 @@ m4_undivert (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_dnl (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 1, 1))
-    return;
+  const char *me = ARG (0);
 
-  skip_line (ARG (0));
+  bad_argc (me, argc, 0, 0);
+  skip_line (me);
 }
 
 /*-------------------------------------------------------------------------.
@@ -1344,7 +1341,7 @@ m4_dnl (struct obstack *obs, int argc, token_data **argv)
 static void
 m4_shift (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (ARG (0), argc, 1, -1))
     return;
   dump_args (obs, argc - 1, argv + 1, ",", true);
 }
@@ -1356,8 +1353,7 @@ m4_shift (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_changequote (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 1, 3))
-    return;
+  bad_argc (ARG (0), argc, 0, 2);
 
   /* Explicit NULL distinguishes between empty and missing argument.  */
   set_quotes ((argc >= 2) ? ARG (1) : NULL,
@@ -1372,8 +1368,7 @@ m4_changequote (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_changecom (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 1, 3))
-    return;
+  bad_argc (ARG (0), argc, 0, 2);
 
   /* Explicit NULL distinguishes between empty and missing argument.  */
   set_comment ((argc >= 2) ? ARG (1) : NULL,
@@ -1390,7 +1385,7 @@ m4_changecom (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_changeword (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (ARG (0), argc, 1, 1))
     return;
 
   set_word_regexp (ARG (1));
@@ -1413,7 +1408,7 @@ include (int argc, token_data **argv, bool silent)
   FILE *fp;
   char *name;
 
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (ARG (0), argc, 1, 1))
     return;
 
   fp = m4_path_search (ARG (1), &name);
@@ -1492,7 +1487,7 @@ mkstemp_helper (struct obstack *obs, const char *name)
 static void
 m4_maketemp (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (ARG (0), argc, 1, 1))
     return;
   if (no_gnu_extensions)
     {
@@ -1535,7 +1530,7 @@ m4_maketemp (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_mkstemp (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (ARG (0), argc, 1, 1))
     return;
   mkstemp_helper (obs, ARG (1));
 }
@@ -1547,7 +1542,7 @@ m4_mkstemp (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_errprint (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (ARG (0), argc, 1, -1))
     return;
   dump_args (obs, argc, argv, " ", false);
   obstack_1grow (obs, '\0');
@@ -1559,8 +1554,7 @@ m4_errprint (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4___file__ (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 1, 1))
-    return;
+  bad_argc (ARG (0), argc, 0, 0);
   obstack_grow (obs, lquote.string, lquote.length);
   obstack_grow (obs, current_file, strlen (current_file));
   obstack_grow (obs, rquote.string, rquote.length);
@@ -1569,16 +1563,14 @@ m4___file__ (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4___line__ (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 1, 1))
-    return;
+  bad_argc (ARG (0), argc, 0, 0);
   shipout_int (obs, current_line);
 }
 
 static void
 m4___program__ (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 1, 1))
-    return;
+  bad_argc (ARG (0), argc, 0, 0);
   obstack_grow (obs, lquote.string, lquote.length);
   obstack_grow (obs, program_name, strlen (program_name));
   obstack_grow (obs, rquote.string, rquote.length);
@@ -1596,11 +1588,12 @@ m4___program__ (struct obstack *obs, int argc, 
token_data **argv)
 static void
 m4_m4exit (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   int exit_code = EXIT_SUCCESS;
 
   /* Warn on bad arguments, but still exit.  */
-  bad_argc (argv[0], argc, 1, 2);
-  if (argc >= 2 && !numeric_arg (argv[0], ARG (1), &exit_code))
+  bad_argc (me, argc, 0, 1);
+  if (argc >= 2 && !numeric_arg (me, ARG (1), &exit_code))
     exit_code = EXIT_FAILURE;
   if (exit_code < 0 || exit_code > 255)
     {
@@ -1629,7 +1622,7 @@ m4_m4exit (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_m4wrap (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (ARG (0), argc, 1, -1))
     return;
   if (no_gnu_extensions)
     obstack_grow (obs, ARG (1), strlen (ARG (1)));
@@ -1707,8 +1700,7 @@ m4_debugmode (struct obstack *obs, int argc, token_data 
**argv)
   int new_debug_level;
   int change_flag;
 
-  if (bad_argc (argv[0], argc, 1, 2))
-    return;
+  bad_argc (ARG (0), argc, 0, 1);
 
   if (argc == 1)
     debug_level = 0;
@@ -1756,8 +1748,7 @@ m4_debugmode (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_debugfile (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 1, 2))
-    return;
+  bad_argc (ARG (0), argc, 0, 1);
 
   if (argc == 1)
     debug_set_output (NULL);
@@ -1777,7 +1768,7 @@ m4_debugfile (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_len (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, 2))
+  if (bad_argc (ARG (0), argc, 1, 1))
     return;
   shipout_int (obs, strlen (ARG (1)));
 }
@@ -1795,7 +1786,7 @@ m4_index (struct obstack *obs, int argc, token_data 
**argv)
   const char *result = NULL;
   int retval = -1;
 
-  if (bad_argc (argv[0], argc, 3, 3))
+  if (bad_argc (ARG (0), argc, 2, 2))
     {
       /* builtin(`index') is blank, but index(`abc') is 0.  */
       if (argc == 2)
@@ -1830,10 +1821,12 @@ m4_index (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_substr (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   int start = 0;
-  int length, avail;
+  int length;
+  int avail;
 
-  if (bad_argc (argv[0], argc, 3, 4))
+  if (bad_argc (me, argc, 2, 3))
     {
       /* builtin(`substr') is blank, but substr(`abc') is abc.  */
       if (argc == 2)
@@ -1842,10 +1835,10 @@ m4_substr (struct obstack *obs, int argc, token_data 
**argv)
     }
 
   length = avail = strlen (ARG (1));
-  if (!numeric_arg (argv[0], ARG (2), &start))
+  if (!numeric_arg (me, ARG (2), &start))
     return;
 
-  if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &length))
+  if (argc >= 4 && !numeric_arg (me, ARG (3), &length))
     return;
 
   if (start < 0 || length <= 0 || start >= avail)
@@ -1919,7 +1912,7 @@ m4_translit (struct obstack *obs, int argc, token_data 
**argv)
   char found[256] = {0};
   unsigned char ch;
 
-  if (bad_argc (argv[0], argc, 3, 4))
+  if (bad_argc (ARG (0), argc, 2, 3))
     {
       /* builtin(`translit') is blank, but translit(`abc') is abc.  */
       if (argc == 2)
@@ -1977,7 +1970,7 @@ m4_translit (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_format (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (argv[0], argc, 2, -1))
+  if (bad_argc (ARG (0), argc, 1, -1))
     return;
   format (obs, argc - 1, argv + 1);
 }
@@ -2086,7 +2079,7 @@ m4_regexp (struct obstack *obs, int argc, token_data 
**argv)
   int startpos;			/* start position of match */
   int length;			/* length of first argument */
 
-  if (bad_argc (argv[0], argc, 3, 4))
+  if (bad_argc (ARG (0), argc, 2, 3))
     {
       /* builtin(`regexp') is blank, but regexp(`abc') is 0.  */
       if (argc == 2)
@@ -2158,7 +2151,7 @@ m4_patsubst (struct obstack *obs, int argc, token_data 
**argv)
   int offset;			/* current match offset */
   int length;			/* length of first argument */
 
-  if (bad_argc (argv[0], argc, 3, 4))
+  if (bad_argc (ARG (0), argc, 2, 3))
     {
       /* builtin(`patsubst') is blank, but patsubst(`abc') is abc.  */
       if (argc == 2)
-- 
1.5.3.5


From 8bc2bf7c3c8554cc055e440bee3554683d8f02f6 Mon Sep 17 00:00:00 2001
From: Eric Blake <[email protected]>
Date: Wed, 21 Nov 2007 16:05:23 -0700
Subject: [PATCH] Consistently report macro name first in messages.

* src/m4.h (evaluate): Adjust prototype.
* src/builtin.c (bad_argc, numeric_arg, m4_placeholder): Alter
wording to match head.
(mkstemp_helper, substitute): Adjust signature.  All callers
changed.
(m4_dumpdef, m4_builtin, m4_indir, m4_defn, m4_esyscmd, m4_eval)
(m4_undivert, m4_maketemp, m4_m4exit, m4_debugmode)
(m4_debugfile, m4_regexp, m4_patsubst): Mention macro name in
message.
(m4_format): Adjust call.
* src/format.c (format): No longer skip argv[0].
* src/eval.c (evaluate): Mention macro name in message.
(logical_or_term, logical_and_term, or_term, xor_term, and_term)
(equality_term, cmp_term, shift_term, add_term, mult_term)
(exp_term, unary_term, simple_term): Adjust signature.
* src/macro.c (warn_builtin_concat): Likewise.
(expand_argument): Adjust caller.
* doc/m4.texinfo (Macro Arguments, Ifdef, Ifelse, Debug Output)
(Dnl, Improved fatal_error, Defn, Builtin, Index macro, Regexp)
(Substr, Translit, Patsubst, Format, Eval, Dumpdef, Include)
(Improved forloop, Indir, Trace, Incr): Adjust tests to match.

Signed-off-by: Eric Blake <[email protected]>
---
 ChangeLog      |   23 +++++++++
 doc/m4.texinfo |  114 ++++++++++++++++++++++----------------------
 src/builtin.c  |  147 +++++++++++++++++++++++++++++++-------------------------
 src/eval.c     |  126 ++++++++++++++++++++++++------------------------
 src/format.c   |    7 ++-
 src/m4.h       |    2 +-
 src/macro.c    |   12 ++--
 7 files changed, 237 insertions(+), 194 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4cb7b46..4602b6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
 2007-11-21  Eric Blake  <[email protected]>
 
+	Consistently report macro name first in messages.
+	* src/m4.h (evaluate): Adjust prototype.
+	* src/builtin.c (bad_argc, numeric_arg, m4_placeholder): Alter
+	wording to match head.
+	(mkstemp_helper, substitute): Adjust signature.  All callers
+	changed.
+	(m4_dumpdef, m4_builtin, m4_indir, m4_defn, m4_esyscmd, m4_eval)
+	(m4_undivert, m4_maketemp, m4_m4exit, m4_debugmode)
+	(m4_debugfile, m4_regexp, m4_patsubst): Mention macro name in
+	message.
+	(m4_format): Adjust call.
+	* src/format.c (format): No longer skip argv[0].
+	* src/eval.c (evaluate): Mention macro name in message.
+	(logical_or_term, logical_and_term, or_term, xor_term, and_term)
+	(equality_term, cmp_term, shift_term, add_term, mult_term)
+	(exp_term, unary_term, simple_term): Adjust signature.
+	* src/macro.c (warn_builtin_concat): Likewise.
+	(expand_argument): Adjust caller.
+	* doc/m4.texinfo (Macro Arguments, Ifdef, Ifelse, Debug Output)
+	(Dnl, Improved fatal_error, Defn, Builtin, Index macro, Regexp)
+	(Substr, Translit, Patsubst, Format, Eval, Dumpdef, Include)
+	(Improved forloop, Indir, Trace, Incr): Adjust tests to match.
+
 	Make argument checking a bit more sane.
 	* src/builtin.c (bad_argc): Adjust signature, and don't force
 	callers to add 1.  Adjust all callers.
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index c573e76..6ae09f7 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -1450,12 +1450,12 @@ defined macros, there is no check of the number of 
arguments given.
 @example
 $ @kbd{m4}
 index(`abc')
-@error{}m4:stdin:1: Warning: too few arguments to builtin `index'
+@error{}m4:stdin:1: Warning: index: too few arguments: 1 < 2
 @result{}0
 index(`abc',)
 @result{}0
 index(`abc', `b', `ignored')
-@error{}m4:stdin:3: Warning: excess arguments to builtin `index' ignored
+@error{}m4:stdin:3: Warning: index: extra arguments ignored: 3 > 2
 @result{}1
 @end example
 
@@ -2203,21 +2203,21 @@ version of @acronym{GNU} M4 may lift these restrictions.
 define(`a', `A')define(`AA', `b')
 @result{}
 defn(`a', `divnum', `a')
-@error{}m4:stdin:2: Warning: cannot concatenate builtin `divnum'
+@error{}m4:stdin:2: Warning: defn: cannot concatenate builtin `divnum'
 @result{}AA
 define(`mydivnum', defn(`divnum', `divnum'))mydivnum
-@error{}m4:stdin:3: Warning: cannot concatenate builtin `divnum'
-@error{}m4:stdin:3: Warning: cannot concatenate builtin `divnum'
+@error{}m4:stdin:3: Warning: defn: cannot concatenate builtin `divnum'
+@error{}m4:stdin:3: Warning: defn: cannot concatenate builtin `divnum'
 @result{}
 define(`mydivnum', defn(`divnum')defn(`divnum'))mydivnum
-@error{}m4:stdin:4: Warning: cannot concatenate builtin `divnum'
-@error{}m4:stdin:4: Warning: cannot concatenate builtin `divnum'
+@error{}m4:stdin:4: Warning: define: cannot concatenate builtin `divnum'
+@error{}m4:stdin:4: Warning: define: cannot concatenate builtin `divnum'
 @result{}
 define(`mydivnum', defn(`divnum')`a')mydivnum
-@error{}m4:stdin:5: Warning: cannot concatenate builtin `divnum'
+@error{}m4:stdin:5: Warning: define: cannot concatenate builtin `divnum'
 @result{}A
 define(`mydivnum', `a'defn(`divnum'))mydivnum
-@error{}m4:stdin:6: Warning: cannot concatenate builtin `divnum'
+@error{}m4:stdin:6: Warning: define: cannot concatenate builtin `divnum'
 @result{}A
 @end example
 
@@ -2367,7 +2367,7 @@ f(define(`f', `2'))
 indir(`f', define(`f', `3'))
 @result{}3
 indir(`f', undefine(`f'))
-@error{}m4:stdin:4: undefined macro `f'
+@error{}m4:stdin:4: indir: undefined macro `f'
 @result{}
 @end example
 
@@ -2389,7 +2389,7 @@ indir(`define', `foo', defn(`divnum'))
 foo
 @result{}0
 indir(`divert', defn(`foo'))
-@error{}m4:stdin:5: empty string treated as 0 in builtin `divert'
+@error{}m4:stdin:5: divert: empty string treated as 0
 @result{}
 @end example
 
@@ -2452,10 +2452,10 @@ $ @kbd{m4 -P}
 m4_builtin(`divnum')
 @result{}0
 m4_builtin(`m4_divnum')
-@error{}m4:stdin:2: undefined builtin `m4_divnum'
+@error{}m4:stdin:2: m4_builtin: undefined builtin `m4_divnum'
 @result{}
 m4_indir(`divnum')
-@error{}m4:stdin:3: undefined macro `divnum'
+@error{}m4:stdin:3: m4_indir: undefined macro `divnum'
 @result{}
 m4_indir(`m4_divnum')
 @result{}0
@@ -2469,13 +2469,13 @@ recognized; but it will provoke a warning, and result 
in a void expansion.
 builtin
 @result{}builtin
 builtin()
-@error{}m4:stdin:2: undefined builtin `'
+@error{}m4:stdin:2: builtin: undefined builtin `'
 @result{}
 builtin(`builtin')
-@error{}m4:stdin:3: Warning: too few arguments to builtin `builtin'
+@error{}m4:stdin:3: Warning: builtin: too few arguments: 0 < 1
 @result{}
 builtin(`builtin',)
-@error{}m4:stdin:4: undefined builtin `'
+@error{}m4:stdin:4: builtin: undefined builtin `'
 @result{}
 @end example
 
@@ -2531,7 +2531,7 @@ define(`foo', `')
 ifdef(`foo', ``foo' is defined', ``foo' is not defined')
 @result{}foo is defined
 ifdef(`no_such_macro', `yes', `no', `extra argument')
-@error{}m4:stdin:4: Warning: excess arguments to builtin `ifdef' ignored
+@error{}m4:stdin:4: Warning: ifdef: extra arguments ignored: 4 > 3
 @result{}no
 @end example
 
@@ -2575,7 +2575,7 @@ case, the warning about missing arguments is never 
triggered.
 ifelse(`some comments')
 @result{}
 ifelse(`foo', `bar')
-@error{}m4:stdin:2: Warning: too few arguments to builtin `ifelse'
+@error{}m4:stdin:2: Warning: ifelse: too few arguments: 2 < 3
 @result{}
 @end example
 
@@ -2624,14 +2624,14 @@ calls for an example:
 
 @example
 ifelse(`foo', `bar', `third', `gnu', `gnats')
-@error{}m4:stdin:1: Warning: excess arguments to builtin `ifelse' ignored
+@error{}m4:stdin:1: Warning: ifelse: extra arguments ignored: 5 > 4
 @result{}gnu
 ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth')
 @result{}
 ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth', `seventh')
 @result{}seventh
 ifelse(`foo', `bar', `3', `gnu', `gnats', `6', `7', `8')
-@error{}m4:stdin:4: Warning: excess arguments to builtin `ifelse' ignored
+@error{}m4:stdin:4: Warning: ifelse: extra arguments ignored: 8 > 7
 @result{}7
 @end example
 
@@ -3133,7 +3133,7 @@ f(popdef(`f')dumpdef(`f'))
 @error{}f:@tabchar{}``$0'1'
 @result{}f2
 f(popdef(`f')dumpdef(`f'))
-@error{}m4:stdin:3: undefined macro `f'
+@error{}m4:stdin:3: dumpdef: undefined macro `f'
 @result{}f1
 @end example
 
@@ -3231,7 +3231,7 @@ undefine(`foo')
 ifdef(`foo', `yes', `no')
 @result{}no
 indir(`foo')
-@error{}m4:stdin:8: undefined macro `foo'
+@error{}m4:stdin:8: indir: undefined macro `foo'
 @result{}
 define(`foo', `blah')
 @result{}
@@ -3407,13 +3407,13 @@ $ @kbd{m4}
 traceon(`divnum')
 @result{}
 divnum(`extra')
-@error{}m4:stdin:2: Warning: excess arguments to builtin `divnum' ignored
+@error{}m4:stdin:2: Warning: divnum: extra arguments ignored: 1 > 0
 @error{}m4trace: -1- divnum(`extra') -> `0'
 @result{}0
 debugfile()
 @result{}
 divnum(`extra')
-@error{}m4:stdin:4: Warning: excess arguments to builtin `divnum' ignored
+@error{}m4:stdin:4: Warning: divnum: extra arguments ignored: 1 > 0
 @result{}0
 debugfile
 @result{}
@@ -3476,7 +3476,7 @@ next newline, on whatever line containing it, will still 
be discarded.
 @example
 dnl(`args are ignored, but side effects occur',
 define(`foo', `like this')) while this text is ignored: undefine(`foo')
-@error{}m4:stdin:1: Warning: excess arguments to builtin `dnl' ignored
+@error{}m4:stdin:1: Warning: dnl: extra arguments ignored: 2 > 0
 See how `foo' was defined, foo?
 @result{}See how foo was defined, like this?
 @end example
@@ -4240,13 +4240,13 @@ parameters.
 
 @comment status: 1
 @example
-include(`none')
-@error{}m4:stdin:1: cannot open `none': No such file or directory
+include(`n')
+@error{}m4:stdin:1: include: cannot open `n': No such file or directory
 @result{}
 include()
-@error{}m4:stdin:2: cannot open `': No such file or directory
+@error{}m4:stdin:2: include: cannot open `': No such file or directory
 @result{}
-sinclude(`none')
+sinclude(`n')
 @result{}
 sinclude()
 @result{}
@@ -4797,7 +4797,7 @@ contrast this with an empty @var{substring}.
 
 @example
 index(`abc')
-@error{}m4:stdin:1: Warning: too few arguments to builtin `index'
+@error{}m4:stdin:1: Warning: index: too few arguments: 1 < 2
 @result{}0
 index(`abc', `')
 @result{}0
@@ -4865,13 +4865,13 @@ Here are some more examples on the handling of 
backslash:
 regexp(`abc', `\(b\)', `\\\10\a')
 @result{}\b0a
 regexp(`abc', `b', `\1\')
-@error{}m4:stdin:2: Warning: sub-expression 1 not present
-@error{}m4:stdin:2: Warning: trailing \ ignored in replacement
+@error{}m4:stdin:2: Warning: regexp: sub-expression 1 not present
+@error{}m4:stdin:2: Warning: regexp: trailing \ ignored in replacement
 @result{}
 regexp(`abc', `\(\(d\)?\)\(c\)', `\1\2\3\4\5\6')
-@error{}m4:stdin:3: Warning: sub-expression 4 not present
-@error{}m4:stdin:3: Warning: sub-expression 5 not present
-@error{}m4:stdin:3: Warning: sub-expression 6 not present
+@error{}m4:stdin:3: Warning: regexp: sub-expression 4 not present
+@error{}m4:stdin:3: Warning: regexp: sub-expression 5 not present
+@error{}m4:stdin:3: Warning: regexp: sub-expression 6 not present
 @result{}c
 @end example
 
@@ -4880,7 +4880,7 @@ contrast this with an empty @var{regexp} argument.
 
 @example
 regexp(`abc')
-@error{}m4:stdin:1: Warning: too few arguments to builtin `regexp'
+@error{}m4:stdin:1: Warning: regexp: too few arguments: 1 < 2
 @result{}0
 regexp(`abc', `')
 @result{}0
@@ -4917,10 +4917,10 @@ Omitting @var{from} evokes a warning, but still 
produces output.
 
 @example
 substr(`abc')
-@error{}m4:stdin:1: Warning: too few arguments to builtin `substr'
+@error{}m4:stdin:1: Warning: substr: too few arguments: 1 < 2
 @result{}abc
 substr(`abc',)
-@error{}m4:stdin:2: empty string treated as 0 in builtin `substr'
+@error{}m4:stdin:2: substr: empty string treated as 0
 @result{}abc
 @end example
 
@@ -4997,7 +4997,7 @@ Omitting @var{chars} evokes a warning, but still produces 
output.
 
 @example
 translit(`abc')
-@error{}m4:stdin:1: Warning: too few arguments to builtin `translit'
+@error{}m4:stdin:1: Warning: translit: too few arguments: 1 < 2
 @result{}abc
 @end example
 
@@ -5051,7 +5051,7 @@ patsubst(`GNUs not Unix', `\w+', `(\&)')
 patsubst(`GNUs not Unix', `[A-Z][a-z]+')
 @result{}GN not@w{ }
 patsubst(`GNUs not Unix', `not', `NOT\')
-@error{}m4:stdin:6: Warning: trailing \ ignored in replacement
+@error{}m4:stdin:6: Warning: patsubst: trailing \ ignored in replacement
 @result{}GNUs NOT Unix
 @end example
 
@@ -5128,7 +5128,7 @@ contrast this with an empty @var{regexp} argument.
 
 @example
 patsubst(`abc')
-@error{}m4:stdin:1: Warning: too few arguments to builtin `patsubst'
+@error{}m4:stdin:1: Warning: patsubst: too few arguments: 1 < 2
 @result{}abc
 patsubst(`abc', `')
 @result{}abc
@@ -5224,7 +5224,7 @@ encountered.  Likewise, escape sequences are not yet 
recognized.
 
 @example
 format(`%p', `0')
-@error{}m4:stdin:1: Warning: unrecognized specifier in `%p'
+@error{}m4:stdin:1: Warning: format: unrecognized specifier in `%p'
 @result{}
 @end example
 
@@ -5266,10 +5266,10 @@ incr(`4')
 decr(`7')
 @result{}6
 incr()
-@error{}m4:stdin:3: empty string treated as 0 in builtin `incr'
+@error{}m4:stdin:3: incr: empty string treated as 0
 @result{}1
 decr()
-@error{}m4:stdin:4: empty string treated as 0 in builtin `decr'
+@error{}m4:stdin:4: decr: empty string treated as 0
 @result{}-1
 @end example
 
@@ -5339,13 +5339,13 @@ extension when @acronym{POSIX} mode is not requested, 
and that using
 @comment status: 1
 @example
 eval(`2 = 2')
-@error{}m4:stdin:1: Warning: recommend ==, not =, for equality operator
+@error{}m4:stdin:1: Warning: eval: recommend ==, not =, for equality
 @result{}1
 eval(`++0')
-@error{}m4:stdin:2: invalid operator in eval: ++0
+@error{}m4:stdin:2: eval: invalid operator: ++0
 @result{}
 eval(`0 |= 1')
-@error{}m4:stdin:3: invalid operator in eval: 0 |= 1
+@error{}m4:stdin:3: eval: invalid operator: 0 |= 1
 @result{}
 @end example
 
@@ -5388,12 +5388,12 @@ eval(`+ + - ~ ! ~ 0')
 eval(`2 || 1 / 0')
 @result{}1
 eval(`0 || 1 / 0')
-@error{}m4:stdin:9: divide by zero in eval: 0 || 1 / 0
+@error{}m4:stdin:9: eval: divide by zero: 0 || 1 / 0
 @result{}
 eval(`0 && 1 % 0')
 @result{}0
 eval(`2 && 1 % 0')
-@error{}m4:stdin:11: modulo by zero in eval: 2 && 1 % 0
+@error{}m4:stdin:11: eval: modulo by zero: 2 && 1 % 0
 @result{}
 @end example
 
@@ -5414,9 +5414,9 @@ eval(`2 ** 0')
 @result{}1
 eval(`0 ** 0')
 @result{}
-@error{}m4:stdin:5: divide by zero in eval: 0 ** 0
+@error{}m4:stdin:5: eval: divide by zero: 0 ** 0
 eval(`4 ** -2')
-@error{}m4:stdin:6: negative exponent in eval: 4 ** -2
+@error{}m4:stdin:6: eval: negative exponent: 4 ** -2
 @result{}
 @end example
 
@@ -5461,7 +5461,7 @@ square(square(`5')` + 1')
 define(`foo', `666')
 @result{}
 eval(`foo / 6')
-@error{}m4:stdin:11: bad expression in eval: foo / 6
+@error{}m4:stdin:11: eval: bad expression: foo / 6
 @result{}
 eval(foo / 6)
 @result{}111
@@ -5529,13 +5529,13 @@ eval(`10', `', `0')
 eval(`10', `16')
 @result{}a
 eval(`1', `37')
-@error{}m4:stdin:9: radix 37 in builtin `eval' out of range
+@error{}m4:stdin:9: eval: radix 37 out of range
 @result{}
 eval(`1', , `-1')
-@error{}m4:stdin:10: negative width to builtin `eval'
+@error{}m4:stdin:10: eval: negative width
 @result{}
 eval()
-@error{}m4:stdin:11: empty string treated as 0 in builtin `eval'
+@error{}m4:stdin:11: eval: empty string treated as 0
 @result{}0
 @end example
 
@@ -6769,7 +6769,7 @@ forloop(`', `1', `2', ` odd iterator name')
 forloop(`i', `5 + 5', `0xc', ` 0x`'eval(i, `16')')
 @result{} 0xa 0xb 0xc
 forloop(`i', `a', `b', `non-numeric bounds')
-@error{}m4:stdin:6: bad expression in eval (bad input): (b) >= (a)
+@error{}m4:stdin:6: eval: bad expression (bad input): (b) >= (a)
 @result{}
 @end example
 
@@ -7211,7 +7211,7 @@ m4wrap(`divnum(`demo of internal message')
 fatal_error(`inside wrapped text')')
 @result{}
 ^D
-@error{}m4:stdin:6: Warning: excess arguments to builtin `divnum' ignored
+@error{}m4:stdin:6: Warning: divnum: extra arguments ignored: 1 > 0
 @result{}0
 @error{}m4:stdin:6: fatal error: inside wrapped text
 @end example
diff --git a/src/builtin.c b/src/builtin.c
index 4e6f5dc..48df3d6 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -507,12 +507,14 @@ bad_argc (const char *name, int argc, unsigned int min, 
unsigned int max)
     {
       if (!suppress_warnings)
 	M4ERROR ((warning_status, 0,
-		  "Warning: too few arguments to builtin `%s'", name));
+		  "Warning: %s: too few arguments: %d < %d",
+		  name, argc - 1, min));
       return true;
     }
   if (argc - 1 > max && !suppress_warnings)
     M4ERROR ((warning_status, 0,
-	      "Warning: excess arguments to builtin `%s' ignored", name));
+	      "Warning: %s: extra arguments ignored: %d > %d",
+	      name, argc - 1, max));
   return false;
 }
 
@@ -530,8 +532,7 @@ numeric_arg (const char *name, const char *arg, int *valuep)
   if (*arg == '\0')
     {
       *valuep = 0;
-      M4ERROR ((warning_status, 0,
-		"empty string treated as 0 in builtin `%s'", name));
+      M4ERROR ((warning_status, 0, "%s: empty string treated as 0", name));
     }
   else
     {
@@ -540,15 +541,15 @@ numeric_arg (const char *name, const char *arg, int 
*valuep)
       if (*endp != '\0')
 	{
 	  M4ERROR ((warning_status, 0,
-		    "non-numeric argument to builtin `%s'", name));
+		    "%s: non-numeric argument `%s'", name, arg));
 	  return false;
 	}
       if (isspace (to_uchar (*arg)))
 	M4ERROR ((warning_status, 0,
-		  "leading whitespace ignored in builtin `%s'", name));
+		  "%s: leading whitespace ignored", name));
       else if (errno == ERANGE)
 	M4ERROR ((warning_status, 0,
-		  "numeric overflow detected in builtin `%s'", name));
+		  "%s: numeric overflow detected", name));
     }
   return true;
 }
@@ -841,6 +842,7 @@ dumpdef_cmp (const void *s1, const void *s2)
 static void
 m4_dumpdef (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   symbol *s;
   int i;
   struct dump_symbol_data data;
@@ -863,7 +865,7 @@ m4_dumpdef (struct obstack *obs, int argc, token_data 
**argv)
 	    dump_symbol (s, &data);
 	  else
 	    M4ERROR ((warning_status, 0,
-		      "undefined macro `%s'", ARG (i)));
+		      "%s: undefined macro `%s'", me, ARG (i)));
 	}
     }
 
@@ -932,7 +934,7 @@ m4_builtin (struct obstack *obs, int argc, token_data 
**argv)
   bp = find_builtin_by_name (name);
   if (bp->func == m4_placeholder)
     M4ERROR ((warning_status, 0,
-	      "undefined builtin `%s'", name));
+	      "%s: undefined builtin `%s'", me, name));
   else
     {
       int i;
@@ -974,7 +976,7 @@ m4_indir (struct obstack *obs, int argc, token_data **argv)
   s = lookup_symbol (name, SYMBOL_LOOKUP);
   if (s == NULL || SYMBOL_TYPE (s) == TOKEN_VOID)
     M4ERROR ((warning_status, 0,
-	      "undefined macro `%s'", name));
+	      "%s: undefined macro `%s'", me, name));
   else
     {
       int i;
@@ -998,11 +1000,12 @@ m4_indir (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_defn (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   symbol *s;
   builtin_func *b;
   int i;
 
-  if (bad_argc (ARG (0), argc, 1, -1))
+  if (bad_argc (me, argc, 1, -1))
     return;
 
   for (i = 1; i < argc; i++)
@@ -1023,11 +1026,11 @@ m4_defn (struct obstack *obs, int argc, token_data 
**argv)
 	  b = SYMBOL_FUNC (s);
 	  if (b == m4_placeholder)
 	    M4ERROR ((warning_status, 0, "\
-builtin `%s' requested by frozen file is not supported", ARG (i)));
+Warning: %s: builtin `%s' requested by frozen file not found", me, ARG (i)));
 	  else if (argc != 2)
 	    M4ERROR ((warning_status, 0,
-		      "Warning: cannot concatenate builtin `%s'",
-		      ARG (i)));
+		      "Warning: %s: cannot concatenate builtin `%s'",
+		      me, ARG (i)));
 	  else
 	    push_macro (b);
 	  break;
@@ -1103,10 +1106,11 @@ m4_syscmd (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_esyscmd (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   FILE *pin;
   int ch;
 
-  if (bad_argc (ARG (0), argc, 1, 1))
+  if (bad_argc (me, argc, 1, 1))
     {
       /* The empty command is successful.  */
       sysval = 0;
@@ -1119,7 +1123,7 @@ m4_esyscmd (struct obstack *obs, int argc, token_data 
**argv)
   if (pin == NULL)
     {
       M4ERROR ((warning_status, errno,
-		"cannot open pipe to command `%s'", ARG (1)));
+		"%s: cannot open pipe to command `%s'", me, ARG (1)));
       sysval = -1;
     }
   else
@@ -1161,7 +1165,7 @@ m4_eval (struct obstack *obs, int argc, token_data **argv)
   if (radix < 1 || radix > (int) strlen (digits))
     {
       M4ERROR ((warning_status, 0,
-		"radix %d in builtin `%s' out of range", radix, me));
+		"%s: radix %d out of range", me, radix));
       return;
     }
 
@@ -1169,15 +1173,14 @@ m4_eval (struct obstack *obs, int argc, token_data 
**argv)
     return;
   if (min < 0)
     {
-      M4ERROR ((warning_status, 0,
-		"negative width to builtin `%s'", me));
+      M4ERROR ((warning_status, 0, "%s: negative width", me));
       return;
     }
 
   if (!*ARG (1))
     M4ERROR ((warning_status, 0,
-	      "empty string treated as 0 in builtin `%s'", me));
-  else if (evaluate (ARG (1), &value))
+	      "%s: empty string treated as 0", me));
+  else if (evaluate (me, ARG (1), &value))
     return;
 
   if (radix == 1)
@@ -1292,25 +1295,26 @@ m4_undivert (struct obstack *obs, int argc, token_data 
**argv)
   else
     for (i = 1; i < argc; i++)
       {
-	file = strtol (ARG (i), &endp, 10);
-	if (*endp == '\0' && !isspace (to_uchar (*ARG (i))))
+	const char *str = ARG (i);
+	file = strtol (str, &endp, 10);
+	if (*endp == '\0' && !isspace (to_uchar (*str)))
 	  insert_diversion (file);
 	else if (no_gnu_extensions)
 	  M4ERROR ((warning_status, 0,
-		    "non-numeric argument to builtin `%s'", me));
+		    "%s: non-numeric argument `%s'", me, str));
 	else
 	  {
-	    fp = m4_path_search (ARG (i), NULL);
+	    fp = m4_path_search (str, NULL);
 	    if (fp != NULL)
 	      {
 		insert_file (fp);
 		if (fclose (fp) == EOF)
 		  M4ERROR ((warning_status, errno,
-			    "error undiverting `%s'", ARG (i)));
+			    "%s: error undiverting `%s'", me, str));
 	      }
 	    else
 	      M4ERROR ((warning_status, errno,
-			"cannot undivert `%s'", ARG (i)));
+			"%s: cannot undivert `%s'", me, str));
 	  }
       }
 }
@@ -1405,10 +1409,11 @@ m4_changeword (struct obstack *obs, int argc, 
token_data **argv)
 static void
 include (int argc, token_data **argv, bool silent)
 {
+  const char *me = ARG (0);
   FILE *fp;
   char *name;
 
-  if (bad_argc (ARG (0), argc, 1, 1))
+  if (bad_argc (me, argc, 1, 1))
     return;
 
   fp = m4_path_search (ARG (1), &name);
@@ -1416,7 +1421,8 @@ include (int argc, token_data **argv, bool silent)
     {
       if (!silent)
 	{
-	  M4ERROR ((warning_status, errno, "cannot open `%s'", ARG (1)));
+	  M4ERROR ((warning_status, errno, "%s: cannot open `%s'",
+		    me, ARG (1)));
 	  retcode = EXIT_FAILURE;
 	}
       return;
@@ -1449,14 +1455,14 @@ m4_sinclude (struct obstack *obs, int argc, token_data 
**argv)
 /* More miscellaneous builtins -- "maketemp", "errprint", "__file__",
    "__line__", and "__program__".  The last three are GNU specific.  */
 
-/*------------------------------------------------------------------.
-| Use the first argument as at template for a temporary file name.  |
-`------------------------------------------------------------------*/
+/*-----------------------------------------------------------------.
+| Use the first argument as a template for a temporary file name.  |
+`-----------------------------------------------------------------*/
 
 /* Add trailing 'X' to NAME if necessary, securely create the file,
-   and place the new file name on OBS.  */
+   and place the new file name on OBS.  Report errors on behalf of ME.  */
 static void
-mkstemp_helper (struct obstack *obs, const char *name)
+mkstemp_helper (struct obstack *obs, const char *me, const char *name)
 {
   int fd;
   int len;
@@ -1477,7 +1483,7 @@ mkstemp_helper (struct obstack *obs, const char *name)
   fd = mkstemp ((char *) obstack_base (obs));
   if (fd < 0)
     {
-      M4ERROR ((0, errno, "cannot create tempfile `%s'", name));
+      M4ERROR ((0, errno, "%s: cannot create tempfile `%s'", me, name));
       obstack_free (obs, obstack_finish (obs));
     }
   else
@@ -1487,7 +1493,9 @@ mkstemp_helper (struct obstack *obs, const char *name)
 static void
 m4_maketemp (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (ARG (0), argc, 1, 1))
+  const char *me = ARG (0);
+
+  if (bad_argc (me, argc, 1, 1))
     return;
   if (no_gnu_extensions)
     {
@@ -1507,7 +1515,7 @@ m4_maketemp (struct obstack *obs, int argc, token_data 
**argv)
       int i;
       int len2;
 
-      M4ERROR ((warning_status, 0, "recommend using mkstemp instead"));
+      M4ERROR ((warning_status, 0, "%s: recommend using mkstemp instead", me));
       for (i = len; i > 1; i--)
 	if (str[i - 1] != 'X')
 	  break;
@@ -1524,15 +1532,17 @@ m4_maketemp (struct obstack *obs, int argc, token_data 
**argv)
 	}
     }
   else
-    mkstemp_helper (obs, ARG (1));
+    mkstemp_helper (obs, me, ARG (1));
 }
 
 static void
 m4_mkstemp (struct obstack *obs, int argc, token_data **argv)
 {
-  if (bad_argc (ARG (0), argc, 1, 1))
+  const char *me = ARG (0);
+
+  if (bad_argc (me, argc, 1, 1))
     return;
-  mkstemp_helper (obs, ARG (1));
+  mkstemp_helper (obs, me, ARG (1));
 }
 
 /*----------------------------------------.
@@ -1598,7 +1608,7 @@ m4_m4exit (struct obstack *obs, int argc, token_data 
**argv)
   if (exit_code < 0 || exit_code > 255)
     {
       M4ERROR ((warning_status, 0,
-		"exit status out of range: `%d'", exit_code));
+		"%s: exit status out of range: `%d'", me, exit_code));
       exit_code = EXIT_FAILURE;
     }
   /* Change debug stream back to stderr, to force flushing debug stream and
@@ -1697,29 +1707,31 @@ m4_traceoff (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_debugmode (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
+  const char *str = ARG (1);
   int new_debug_level;
   int change_flag;
 
-  bad_argc (ARG (0), argc, 0, 1);
+  bad_argc (me, argc, 0, 1);
 
   if (argc == 1)
     debug_level = 0;
   else
     {
-      if (ARG (1)[0] == '+' || ARG (1)[0] == '-')
+      if (*str == '+' || *str == '-')
 	{
-	  change_flag = ARG (1)[0];
-	  new_debug_level = debug_decode (ARG (1) + 1);
+	  change_flag = *str;
+	  new_debug_level = debug_decode (str + 1);
 	}
       else
 	{
 	  change_flag = 0;
-	  new_debug_level = debug_decode (ARG (1));
+	  new_debug_level = debug_decode (str);
 	}
 
       if (new_debug_level < 0)
 	M4ERROR ((warning_status, 0,
-		  "Debugmode: bad debug flags: `%s'", ARG (1)));
+		  "%s: bad debug flags: `%s'", me, str));
       else
 	{
 	  switch (change_flag)
@@ -1748,13 +1760,15 @@ m4_debugmode (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_debugfile (struct obstack *obs, int argc, token_data **argv)
 {
-  bad_argc (ARG (0), argc, 0, 1);
+  const char *me = ARG (0);
+
+  bad_argc (me, argc, 0, 1);
 
   if (argc == 1)
     debug_set_output (NULL);
   else if (!debug_set_output (ARG (1)))
     M4ERROR ((warning_status, errno,
-	      "cannot set error file: `%s'", ARG (1)));
+	      "%s: cannot set error file: `%s'", me, ARG (1)));
 }
 
 /* This section contains text processing macros: "len", "index",
@@ -1972,7 +1986,7 @@ m4_format (struct obstack *obs, int argc, token_data 
**argv)
 {
   if (bad_argc (ARG (0), argc, 1, -1))
     return;
-  format (obs, argc - 1, argv + 1);
+  format (obs, argc, argv);
 }
 
 /*-------------------------------------------------------------------------.
@@ -1987,8 +2001,8 @@ m4_format (struct obstack *obs, int argc, token_data 
**argv)
 static int substitute_warned = 0;
 
 static void
-substitute (struct obstack *obs, const char *victim, const char *repl,
-	    struct re_registers *regs)
+substitute (struct obstack *obs, const char *me, const char *victim,
+	    const char *repl, struct re_registers *regs)
 {
   int ch;
 
@@ -2007,7 +2021,7 @@ substitute (struct obstack *obs, const char *victim, 
const char *repl,
 	  if (!substitute_warned)
 	    {
 	      M4ERROR ((warning_status, 0, "\
-Warning: \\0 will disappear, use \\& instead in replacements"));
+Warning: %s: \\0 will disappear, use \\& instead in replacements", me));
 	      substitute_warned = 1;
 	    }
 	  /* Fall through.  */
@@ -2023,7 +2037,7 @@ Warning: \\0 will disappear, use \\& instead in 
replacements"));
 	  ch -= '0';
 	  if (!regs || regs->num_regs - 1 <= ch)
 	    M4ERROR ((warning_status, 0,
-		      "Warning: sub-expression %d not present", ch));
+		      "Warning: %s: sub-expression %d not present", me, ch));
 	  else if (regs->end[ch] > 0)
 	    obstack_grow (obs, victim + regs->start[ch],
 			  regs->end[ch] - regs->start[ch]);
@@ -2031,7 +2045,7 @@ Warning: \\0 will disappear, use \\& instead in 
replacements"));
 
 	case '\0':
 	  M4ERROR ((warning_status, 0,
-		    "Warning: trailing \\ ignored in replacement"));
+		    "Warning: %s: trailing \\ ignored in replacement", me));
 	  return;
 
 	default:
@@ -2069,6 +2083,7 @@ init_pattern_buffer (struct re_pattern_buffer *buf, 
struct re_registers *regs)
 static void
 m4_regexp (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   const char *victim;		/* first argument */
   const char *regexp;		/* regular expression */
   const char *repl;		/* replacement string */
@@ -2079,7 +2094,7 @@ m4_regexp (struct obstack *obs, int argc, token_data 
**argv)
   int startpos;			/* start position of match */
   int length;			/* length of first argument */
 
-  if (bad_argc (ARG (0), argc, 2, 3))
+  if (bad_argc (me, argc, 2, 3))
     {
       /* builtin(`regexp') is blank, but regexp(`abc') is 0.  */
       if (argc == 2)
@@ -2097,7 +2112,7 @@ m4_regexp (struct obstack *obs, int argc, token_data 
**argv)
       if (argc == 3)
 	shipout_int (obs, 0);
       else
-	substitute (obs, victim, repl, NULL);
+	substitute (obs, me, victim, repl, NULL);
       return;
     }
 
@@ -2111,7 +2126,7 @@ m4_regexp (struct obstack *obs, int argc, token_data 
**argv)
   if (msg != NULL)
     {
       M4ERROR ((warning_status, 0,
-		"bad regular expression: `%s': %s", regexp, msg));
+		"%s: bad regular expression: `%s': %s", me, regexp, msg));
       return;
     }
 
@@ -2122,11 +2137,11 @@ m4_regexp (struct obstack *obs, int argc, token_data 
**argv)
 
   if (startpos == -2)
     M4ERROR ((warning_status, 0,
-	       "error matching regular expression `%s'", regexp));
+	      "%s: error matching regular expression `%s'", me, regexp));
   else if (argc == 3)
     shipout_int (obs, startpos);
   else if (startpos >= 0)
-    substitute (obs, victim, repl, regs);
+    substitute (obs, me, victim, repl, regs);
 }
 
 /*------------------------------------------------------------------.
@@ -2140,6 +2155,7 @@ m4_regexp (struct obstack *obs, int argc, token_data 
**argv)
 static void
 m4_patsubst (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = ARG (0);
   const char *victim;		/* first argument */
   const char *regexp;		/* regular expression */
   const char *repl;
@@ -2151,7 +2167,7 @@ m4_patsubst (struct obstack *obs, int argc, token_data 
**argv)
   int offset;			/* current match offset */
   int length;			/* length of first argument */
 
-  if (bad_argc (ARG (0), argc, 2, 3))
+  if (bad_argc (me, argc, 2, 3))
     {
       /* builtin(`patsubst') is blank, but patsubst(`abc') is abc.  */
       if (argc == 2)
@@ -2180,7 +2196,7 @@ m4_patsubst (struct obstack *obs, int argc, token_data 
**argv)
   if (msg != NULL)
     {
       M4ERROR ((warning_status, 0,
-		"bad regular expression `%s': %s", regexp, msg));
+		"%s: bad regular expression `%s': %s", me, regexp, msg));
       return;
     }
 
@@ -2201,7 +2217,8 @@ m4_patsubst (struct obstack *obs, int argc, token_data 
**argv)
 
 	  if (matchpos == -2)
 	    M4ERROR ((warning_status, 0,
-		      "error matching regular expression `%s'", regexp));
+		      "%s: error matching regular expression `%s'",
+		      me, regexp));
 	  else if (offset < length)
 	    obstack_grow (obs, victim + offset, length - offset);
 	  break;
@@ -2214,7 +2231,7 @@ m4_patsubst (struct obstack *obs, int argc, token_data 
**argv)
 
       /* Handle the part of the string that was covered by the match.  */
 
-      substitute (obs, victim, repl, regs);
+      substitute (obs, me, victim, repl, regs);
 
       /* Update the offset to the end of the match.  If the regexp
 	 matched a null string, advance offset one more, to avoid
@@ -2246,7 +2263,7 @@ void
 m4_placeholder (struct obstack *obs, int argc, token_data **argv)
 {
   M4ERROR ((warning_status, 0, "\
-builtin `%s' requested by frozen file is not supported", ARG (0)));
+builtin `%s' requested by frozen file not found", ARG (0)));
 }
 
 /*-------------------------------------------------------------------------.
diff --git a/src/eval.c b/src/eval.c
index 7abc7ab..1af596e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -62,19 +62,19 @@ typedef enum eval_error
   }
 eval_error;
 
-static eval_error logical_or_term (eval_token, int32_t *);
-static eval_error logical_and_term (eval_token, int32_t *);
-static eval_error or_term (eval_token, int32_t *);
-static eval_error xor_term (eval_token, int32_t *);
-static eval_error and_term (eval_token, int32_t *);
-static eval_error equality_term (eval_token, int32_t *);
-static eval_error cmp_term (eval_token, int32_t *);
-static eval_error shift_term (eval_token, int32_t *);
-static eval_error add_term (eval_token, int32_t *);
-static eval_error mult_term (eval_token, int32_t *);
-static eval_error exp_term (eval_token, int32_t *);
-static eval_error unary_term (eval_token, int32_t *);
-static eval_error simple_term (eval_token, int32_t *);
+static eval_error logical_or_term (const char *, eval_token, int32_t *);
+static eval_error logical_and_term (const char *, eval_token, int32_t *);
+static eval_error or_term (const char *, eval_token, int32_t *);
+static eval_error xor_term (const char *, eval_token, int32_t *);
+static eval_error and_term (const char *, eval_token, int32_t *);
+static eval_error equality_term (const char *, eval_token, int32_t *);
+static eval_error cmp_term (const char *, eval_token, int32_t *);
+static eval_error shift_term (const char *, eval_token, int32_t *);
+static eval_error add_term (const char *, eval_token, int32_t *);
+static eval_error mult_term (const char *, eval_token, int32_t *);
+static eval_error exp_term (const char *, eval_token, int32_t *);
+static eval_error unary_term (const char *, eval_token, int32_t *);
+static eval_error simple_term (const char *, eval_token, int32_t *);
 
 /*--------------------.
 | Lexical functions.  |
@@ -287,14 +287,14 @@ eval_lex (int32_t *val)
 `---------------------------------------*/
 
 bool
-evaluate (const char *expr, int32_t *val)
+evaluate (const char *me, const char *expr, int32_t *val)
 {
   eval_token et;
   eval_error err;
 
   eval_init_lex (expr);
   et = eval_lex (val);
-  err = logical_or_term (et, val);
+  err = logical_or_term (me, et, val);
 
   if (err == NO_ERROR && *eval_text != '\0')
     {
@@ -311,44 +311,44 @@ evaluate (const char *expr, int32_t *val)
 
     case MISSING_RIGHT:
       M4ERROR ((warning_status, 0,
-		"bad expression in eval (missing right parenthesis): %s",
-		expr));
+		"%s: bad expression (missing right parenthesis): %s",
+		me, expr));
       break;
 
     case SYNTAX_ERROR:
       M4ERROR ((warning_status, 0,
-		"bad expression in eval: %s", expr));
+		"%s: bad expression: %s", me, expr));
       break;
 
     case UNKNOWN_INPUT:
       M4ERROR ((warning_status, 0,
-		"bad expression in eval (bad input): %s", expr));
+		"%s: bad expression (bad input): %s", me, expr));
       break;
 
     case EXCESS_INPUT:
       M4ERROR ((warning_status, 0,
-		"bad expression in eval (excess input): %s", expr));
+		"%s: bad expression (excess input): %s", me, expr));
       break;
 
     case INVALID_OPERATOR:
       M4ERROR ((warning_status, 0,
-		"invalid operator in eval: %s", expr));
+		"%s: invalid operator: %s", me, expr));
       retcode = EXIT_FAILURE;
       break;
 
     case DIVIDE_ZERO:
       M4ERROR ((warning_status, 0,
-		"divide by zero in eval: %s", expr));
+		"%s: divide by zero: %s", me, expr));
       break;
 
     case MODULO_ZERO:
       M4ERROR ((warning_status, 0,
-		"modulo by zero in eval: %s", expr));
+		"%s: modulo by zero: %s", me, expr));
       break;
 
     case NEGATIVE_EXPONENT:
       M4ERROR ((warning_status, 0,
-		"negative exponent in eval: %s", expr));
+		"%s: negative exponent: %s", me, expr));
       break;
 
     default:
@@ -364,12 +364,12 @@ evaluate (const char *expr, int32_t *val)
 `---------------------------*/
 
 static eval_error
-logical_or_term (eval_token et, int32_t *v1)
+logical_or_term (const char *me, eval_token et, int32_t *v1)
 {
   int32_t v2;
   eval_error er;
 
-  if ((er = logical_and_term (et, v1)) != NO_ERROR)
+  if ((er = logical_and_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((et = eval_lex (&v2)) == LOR)
@@ -379,7 +379,7 @@ logical_or_term (eval_token et, int32_t *v1)
 	return UNKNOWN_INPUT;
 
       /* Implement short-circuiting of valid syntax.  */
-      er = logical_and_term (et, &v2);
+      er = logical_and_term (me, et, &v2);
       if (er == NO_ERROR)
 	*v1 = *v1 || v2;
       else if (*v1 != 0 && er < SYNTAX_ERROR)
@@ -395,12 +395,12 @@ logical_or_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-logical_and_term (eval_token et, int32_t *v1)
+logical_and_term (const char *me, eval_token et, int32_t *v1)
 {
   int32_t v2;
   eval_error er;
 
-  if ((er = or_term (et, v1)) != NO_ERROR)
+  if ((er = or_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((et = eval_lex (&v2)) == LAND)
@@ -410,7 +410,7 @@ logical_and_term (eval_token et, int32_t *v1)
 	return UNKNOWN_INPUT;
 
       /* Implement short-circuiting of valid syntax.  */
-      er = or_term (et, &v2);
+      er = or_term (me, et, &v2);
       if (er == NO_ERROR)
 	*v1 = *v1 && v2;
       else if (*v1 == 0 && er < SYNTAX_ERROR)
@@ -426,12 +426,12 @@ logical_and_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-or_term (eval_token et, int32_t *v1)
+or_term (const char *me, eval_token et, int32_t *v1)
 {
   int32_t v2;
   eval_error er;
 
-  if ((er = xor_term (et, v1)) != NO_ERROR)
+  if ((er = xor_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((et = eval_lex (&v2)) == OR)
@@ -440,7 +440,7 @@ or_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = xor_term (et, &v2)) != NO_ERROR)
+      if ((er = xor_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       *v1 |= v2;
@@ -453,12 +453,12 @@ or_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-xor_term (eval_token et, int32_t *v1)
+xor_term (const char *me, eval_token et, int32_t *v1)
 {
   int32_t v2;
   eval_error er;
 
-  if ((er = and_term (et, v1)) != NO_ERROR)
+  if ((er = and_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((et = eval_lex (&v2)) == XOR)
@@ -467,7 +467,7 @@ xor_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = and_term (et, &v2)) != NO_ERROR)
+      if ((er = and_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       *v1 ^= v2;
@@ -480,12 +480,12 @@ xor_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-and_term (eval_token et, int32_t *v1)
+and_term (const char *me, eval_token et, int32_t *v1)
 {
   int32_t v2;
   eval_error er;
 
-  if ((er = equality_term (et, v1)) != NO_ERROR)
+  if ((er = equality_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((et = eval_lex (&v2)) == AND)
@@ -494,7 +494,7 @@ and_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = equality_term (et, &v2)) != NO_ERROR)
+      if ((er = equality_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       *v1 &= v2;
@@ -507,13 +507,13 @@ and_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-equality_term (eval_token et, int32_t *v1)
+equality_term (const char *me, eval_token et, int32_t *v1)
 {
   eval_token op;
   int32_t v2;
   eval_error er;
 
-  if ((er = cmp_term (et, v1)) != NO_ERROR)
+  if ((er = cmp_term (me, et, v1)) != NO_ERROR)
     return er;
 
   /* In the 1.4.x series, we maintain the traditional behavior that
@@ -525,13 +525,13 @@ equality_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = cmp_term (et, &v2)) != NO_ERROR)
+      if ((er = cmp_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       if (op == ASSIGN)
       {
 	M4ERROR ((warning_status, 0, "\
-Warning: recommend ==, not =, for equality operator"));
+Warning: %s: recommend ==, not =, for equality", me));
 	op = EQ;
       }
       *v1 = (op == EQ) == (*v1 == v2);
@@ -544,13 +544,13 @@ Warning: recommend ==, not =, for equality operator"));
 }
 
 static eval_error
-cmp_term (eval_token et, int32_t *v1)
+cmp_term (const char *me, eval_token et, int32_t *v1)
 {
   eval_token op;
   int32_t v2;
   eval_error er;
 
-  if ((er = shift_term (et, v1)) != NO_ERROR)
+  if ((er = shift_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((op = eval_lex (&v2)) == GT || op == GTEQ
@@ -561,7 +561,7 @@ cmp_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = shift_term (et, &v2)) != NO_ERROR)
+      if ((er = shift_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       switch (op)
@@ -595,14 +595,14 @@ cmp_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-shift_term (eval_token et, int32_t *v1)
+shift_term (const char *me, eval_token et, int32_t *v1)
 {
   eval_token op;
   int32_t v2;
   uint32_t u1;
   eval_error er;
 
-  if ((er = add_term (et, v1)) != NO_ERROR)
+  if ((er = add_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((op = eval_lex (&v2)) == LSHIFT || op == RSHIFT)
@@ -612,7 +612,7 @@ shift_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = add_term (et, &v2)) != NO_ERROR)
+      if ((er = add_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       /* Minimize undefined C behavior (shifting by a negative number,
@@ -648,13 +648,13 @@ shift_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-add_term (eval_token et, int32_t *v1)
+add_term (const char *me, eval_token et, int32_t *v1)
 {
   eval_token op;
   int32_t v2;
   eval_error er;
 
-  if ((er = mult_term (et, v1)) != NO_ERROR)
+  if ((er = mult_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((op = eval_lex (&v2)) == PLUS || op == MINUS)
@@ -663,7 +663,7 @@ add_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = mult_term (et, &v2)) != NO_ERROR)
+      if ((er = mult_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       /* Minimize undefined C behavior on overflow.  This code assumes
@@ -683,13 +683,13 @@ add_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-mult_term (eval_token et, int32_t *v1)
+mult_term (const char *me, eval_token et, int32_t *v1)
 {
   eval_token op;
   int32_t v2;
   eval_error er;
 
-  if ((er = exp_term (et, v1)) != NO_ERROR)
+  if ((er = exp_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((op = eval_lex (&v2)) == TIMES || op == DIVIDE || op == MODULO)
@@ -698,7 +698,7 @@ mult_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = exp_term (et, &v2)) != NO_ERROR)
+      if ((er = exp_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       /* Minimize undefined C behavior on overflow.  This code assumes
@@ -744,13 +744,13 @@ mult_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-exp_term (eval_token et, int32_t *v1)
+exp_term (const char *me, eval_token et, int32_t *v1)
 {
   uint32_t result;
   int32_t v2;
   eval_error er;
 
-  if ((er = unary_term (et, v1)) != NO_ERROR)
+  if ((er = unary_term (me, et, v1)) != NO_ERROR)
     return er;
 
   while ((et = eval_lex (&v2)) == EXPONENT)
@@ -759,7 +759,7 @@ exp_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = exp_term (et, &v2)) != NO_ERROR)
+      if ((er = exp_term (me, et, &v2)) != NO_ERROR)
 	return er;
 
       /* Minimize undefined C behavior on overflow.  This code assumes
@@ -783,7 +783,7 @@ exp_term (eval_token et, int32_t *v1)
 }
 
 static eval_error
-unary_term (eval_token et, int32_t *v1)
+unary_term (const char *me, eval_token et, int32_t *v1)
 {
   eval_token et2 = et;
   eval_error er;
@@ -794,7 +794,7 @@ unary_term (eval_token et, int32_t *v1)
       if (et2 == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = unary_term (et2, v1)) != NO_ERROR)
+      if ((er = unary_term (me, et2, v1)) != NO_ERROR)
 	return er;
 
       /* Minimize undefined C behavior on overflow.  This code assumes
@@ -808,14 +808,14 @@ unary_term (eval_token et, int32_t *v1)
       else if (et == LNOT)
 	*v1 = *v1 == 0 ? 1 : 0;
     }
-  else if ((er = simple_term (et, v1)) != NO_ERROR)
+  else if ((er = simple_term (me, et, v1)) != NO_ERROR)
     return er;
 
   return NO_ERROR;
 }
 
 static eval_error
-simple_term (eval_token et, int32_t *v1)
+simple_term (const char *me, eval_token et, int32_t *v1)
 {
   int32_t v2;
   eval_error er;
@@ -827,7 +827,7 @@ simple_term (eval_token et, int32_t *v1)
       if (et == ERROR)
 	return UNKNOWN_INPUT;
 
-      if ((er = logical_or_term (et, v1)) != NO_ERROR)
+      if ((er = logical_or_term (me, et, v1)) != NO_ERROR)
 	return er;
 
       et = eval_lex (&v2);
diff --git a/src/format.c b/src/format.c
index 0cc283a..a9e7150 100644
--- a/src/format.c
+++ b/src/format.c
@@ -55,6 +55,7 @@
 void
 format (struct obstack *obs, int argc, token_data **argv)
 {
+  const char *me = TOKEN_DATA_TEXT (argv[0]);
   const char *f;			/* format control string */
   const char *fmt;			/* position within f */
   char fstart[] = "%'+- 0#*.*hhd";	/* current format spec */
@@ -87,6 +88,8 @@ format (struct obstack *obs, int argc, token_data **argv)
   char *str;			/* malloc'd buffer of formatted text */
   enum {CHAR, INT, LONG, DOUBLE, STR} datatype;
 
+  argv++;
+  argc--;
   f = fmt = ARG_STR (argc, argv);
   memset (ok, 0, sizeof ok);
   for (;;)
@@ -231,7 +234,7 @@ format (struct obstack *obs, int argc, token_data **argv)
       if (c > sizeof ok || !ok[c])
 	{
 	  M4ERROR ((warning_status, 0,
-		    "Warning: unrecognized specifier in `%s'", f));
+		    "Warning: %s: unrecognized specifier in `%s'", me, f));
 	  if (c == '\0')
 	    fmt--;
 	  continue;
@@ -306,7 +309,7 @@ format (struct obstack *obs, int argc, token_data **argv)
       if (str == NULL)
 	{
 	  M4ERROR ((warning_status, 0,
-		    "Warning: unable to format output for `%s'", f));
+		    "Warning: %s: unable to format output for `%s'", me, f));
 	  continue;
 	}
 
diff --git a/src/m4.h b/src/m4.h
index a85bf41..c372ffd 100644
--- a/src/m4.h
+++ b/src/m4.h
@@ -438,7 +438,7 @@ FILE *m4_path_search (const char *, char **);
 
 /* File: eval.c  --- expression evaluation.  */
 
-bool evaluate (const char *, int32_t *);
+bool evaluate (const char *, const char *, int32_t *);
 
 /* File: format.c  --- printf like formatting.  */
 
diff --git a/src/macro.c b/src/macro.c
index 9a3123a..6781cd9 100644
--- a/src/macro.c
+++ b/src/macro.c
@@ -130,12 +130,12 @@ expand_token (struct obstack *obs, token_type t, 
token_data *td, int line)
 | text.                                                          |
 `---------------------------------------------------------------*/
 static void
-warn_builtin_concat (builtin_func *func)
+warn_builtin_concat (const char *caller, builtin_func *func)
 {
   const builtin *bp = find_builtin_by_addr (func);
   assert (bp);
-  M4ERROR ((warning_status, 0, "Warning: cannot concatenate builtin `%s'",
-	    bp->name));
+  M4ERROR ((warning_status, 0, "Warning: %s: cannot concatenate builtin `%s'",
+	    caller, bp->name));
 }
 
 /*-------------------------------------------------------------------.
@@ -182,7 +182,7 @@ expand_argument (struct obstack *obs, token_data *argp, 
const char *caller)
 		{
 		  if (obstack_object_size (obs) == 0)
 		    return t == TOKEN_COMMA;
-		  warn_builtin_concat (TOKEN_DATA_FUNC (argp));
+		  warn_builtin_concat (caller, TOKEN_DATA_FUNC (argp));
 		}
 	      obstack_1grow (obs, '\0');
 	      TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
@@ -221,8 +221,8 @@ expand_argument (struct obstack *obs, token_data *argp, 
const char *caller)
 	  else
 	    {
 	      if (TOKEN_DATA_TYPE (argp) == TOKEN_FUNC)
-		warn_builtin_concat (TOKEN_DATA_FUNC (argp));
-	      warn_builtin_concat (TOKEN_DATA_FUNC (&td));
+		warn_builtin_concat (caller, TOKEN_DATA_FUNC (argp));
+	      warn_builtin_concat (caller, TOKEN_DATA_FUNC (&td));
 	      TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
 	    }
 	  break;
-- 
1.5.3.5
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.