m4-patches
[Top][All Lists]
Advanced

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

prelim patches before argv_ref


From: Eric Blake
Subject: prelim patches before argv_ref
Date: Wed, 21 Nov 2007 23:08:53 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

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 <address@hidden>
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 <address@hidden>
---
 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  <address@hidden>
+
+       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  <address@hidden>
 
        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
address@hidden:stdin:1: Warning: end of file treated as newline
address@hidden: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 <address@hidden>
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 <address@hidden>
---
 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  <address@hidden>
 
+       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 <address@hidden>
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 <address@hidden>
---
 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  <address@hidden>
 
+       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')
address@hidden:stdin:1: Warning: too few arguments to builtin `index'
address@hidden:stdin:1: Warning: index: too few arguments: 1 < 2
 @result{}0
 index(`abc',)
 @result{}0
 index(`abc', `b', `ignored')
address@hidden:stdin:3: Warning: excess arguments to builtin `index' ignored
address@hidden: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')
address@hidden:stdin:2: Warning: cannot concatenate builtin `divnum'
address@hidden:stdin:2: Warning: defn: cannot concatenate builtin `divnum'
 @result{}AA
 define(`mydivnum', defn(`divnum', `divnum'))mydivnum
address@hidden:stdin:3: Warning: cannot concatenate builtin `divnum'
address@hidden:stdin:3: Warning: cannot concatenate builtin `divnum'
address@hidden:stdin:3: Warning: defn: cannot concatenate builtin `divnum'
address@hidden:stdin:3: Warning: defn: cannot concatenate builtin `divnum'
 @result{}
 define(`mydivnum', defn(`divnum')defn(`divnum'))mydivnum
address@hidden:stdin:4: Warning: cannot concatenate builtin `divnum'
address@hidden:stdin:4: Warning: cannot concatenate builtin `divnum'
address@hidden:stdin:4: Warning: define: cannot concatenate builtin `divnum'
address@hidden:stdin:4: Warning: define: cannot concatenate builtin `divnum'
 @result{}
 define(`mydivnum', defn(`divnum')`a')mydivnum
address@hidden:stdin:5: Warning: cannot concatenate builtin `divnum'
address@hidden:stdin:5: Warning: define: cannot concatenate builtin `divnum'
 @result{}A
 define(`mydivnum', `a'defn(`divnum'))mydivnum
address@hidden:stdin:6: Warning: cannot concatenate builtin `divnum'
address@hidden: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'))
address@hidden:stdin:4: undefined macro `f'
address@hidden: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'))
address@hidden:stdin:5: empty string treated as 0 in builtin `divert'
address@hidden: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')
address@hidden:stdin:2: undefined builtin `m4_divnum'
address@hidden:stdin:2: m4_builtin: undefined builtin `m4_divnum'
 @result{}
 m4_indir(`divnum')
address@hidden:stdin:3: undefined macro `divnum'
address@hidden: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()
address@hidden:stdin:2: undefined builtin `'
address@hidden:stdin:2: builtin: undefined builtin `'
 @result{}
 builtin(`builtin')
address@hidden:stdin:3: Warning: too few arguments to builtin `builtin'
address@hidden:stdin:3: Warning: builtin: too few arguments: 0 < 1
 @result{}
 builtin(`builtin',)
address@hidden:stdin:4: undefined builtin `'
address@hidden: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')
address@hidden:stdin:4: Warning: excess arguments to builtin `ifdef' ignored
address@hidden: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')
address@hidden:stdin:2: Warning: too few arguments to builtin `ifelse'
address@hidden: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')
address@hidden:stdin:1: Warning: excess arguments to builtin `ifelse' ignored
address@hidden: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')
address@hidden:stdin:4: Warning: excess arguments to builtin `ifelse' ignored
address@hidden: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'))
address@hidden:stdin:3: undefined macro `f'
address@hidden:stdin:3: dumpdef: undefined macro `f'
 @result{}f1
 @end example
 
@@ -3231,7 +3231,7 @@ undefine(`foo')
 ifdef(`foo', `yes', `no')
 @result{}no
 indir(`foo')
address@hidden:stdin:8: undefined macro `foo'
address@hidden:stdin:8: indir: undefined macro `foo'
 @result{}
 define(`foo', `blah')
 @result{}
@@ -3407,13 +3407,13 @@ $ @kbd{m4}
 traceon(`divnum')
 @result{}
 divnum(`extra')
address@hidden:stdin:2: Warning: excess arguments to builtin `divnum' ignored
address@hidden:stdin:2: Warning: divnum: extra arguments ignored: 1 > 0
 @error{}m4trace: -1- divnum(`extra') -> `0'
 @result{}0
 debugfile()
 @result{}
 divnum(`extra')
address@hidden:stdin:4: Warning: excess arguments to builtin `divnum' ignored
address@hidden: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')
address@hidden:stdin:1: Warning: excess arguments to builtin `dnl' ignored
address@hidden: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')
address@hidden:stdin:1: cannot open `none': No such file or directory
+include(`n')
address@hidden:stdin:1: include: cannot open `n': No such file or directory
 @result{}
 include()
address@hidden:stdin:2: cannot open `': No such file or directory
address@hidden: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')
address@hidden:stdin:1: Warning: too few arguments to builtin `index'
address@hidden: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\')
address@hidden:stdin:2: Warning: sub-expression 1 not present
address@hidden:stdin:2: Warning: trailing \ ignored in replacement
address@hidden:stdin:2: Warning: regexp: sub-expression 1 not present
address@hidden:stdin:2: Warning: regexp: trailing \ ignored in replacement
 @result{}
 regexp(`abc', `\(\(d\)?\)\(c\)', `\1\2\3\4\5\6')
address@hidden:stdin:3: Warning: sub-expression 4 not present
address@hidden:stdin:3: Warning: sub-expression 5 not present
address@hidden:stdin:3: Warning: sub-expression 6 not present
address@hidden:stdin:3: Warning: regexp: sub-expression 4 not present
address@hidden:stdin:3: Warning: regexp: sub-expression 5 not present
address@hidden: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')
address@hidden:stdin:1: Warning: too few arguments to builtin `regexp'
address@hidden: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')
address@hidden:stdin:1: Warning: too few arguments to builtin `substr'
address@hidden:stdin:1: Warning: substr: too few arguments: 1 < 2
 @result{}abc
 substr(`abc',)
address@hidden:stdin:2: empty string treated as 0 in builtin `substr'
address@hidden: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')
address@hidden:stdin:1: Warning: too few arguments to builtin `translit'
address@hidden: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 address@hidden }
 patsubst(`GNUs not Unix', `not', `NOT\')
address@hidden:stdin:6: Warning: trailing \ ignored in replacement
address@hidden: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')
address@hidden:stdin:1: Warning: too few arguments to builtin `patsubst'
address@hidden: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')
address@hidden:stdin:1: Warning: unrecognized specifier in `%p'
address@hidden:stdin:1: Warning: format: unrecognized specifier in `%p'
 @result{}
 @end example
 
@@ -5266,10 +5266,10 @@ incr(`4')
 decr(`7')
 @result{}6
 incr()
address@hidden:stdin:3: empty string treated as 0 in builtin `incr'
address@hidden:stdin:3: incr: empty string treated as 0
 @result{}1
 decr()
address@hidden:stdin:4: empty string treated as 0 in builtin `decr'
address@hidden: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')
address@hidden:stdin:1: Warning: recommend ==, not =, for equality operator
address@hidden:stdin:1: Warning: eval: recommend ==, not =, for equality
 @result{}1
 eval(`++0')
address@hidden:stdin:2: invalid operator in eval: ++0
address@hidden:stdin:2: eval: invalid operator: ++0
 @result{}
 eval(`0 |= 1')
address@hidden:stdin:3: invalid operator in eval: 0 |= 1
address@hidden: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')
address@hidden:stdin:9: divide by zero in eval: 0 || 1 / 0
address@hidden:stdin:9: eval: divide by zero: 0 || 1 / 0
 @result{}
 eval(`0 && 1 % 0')
 @result{}0
 eval(`2 && 1 % 0')
address@hidden:stdin:11: modulo by zero in eval: 2 && 1 % 0
address@hidden: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{}
address@hidden:stdin:5: divide by zero in eval: 0 ** 0
address@hidden:stdin:5: eval: divide by zero: 0 ** 0
 eval(`4 ** -2')
address@hidden:stdin:6: negative exponent in eval: 4 ** -2
address@hidden: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')
address@hidden:stdin:11: bad expression in eval: foo / 6
address@hidden: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')
address@hidden:stdin:9: radix 37 in builtin `eval' out of range
address@hidden:stdin:9: eval: radix 37 out of range
 @result{}
 eval(`1', , `-1')
address@hidden:stdin:10: negative width to builtin `eval'
address@hidden:stdin:10: eval: negative width
 @result{}
 eval()
address@hidden:stdin:11: empty string treated as 0 in builtin `eval'
address@hidden: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')
address@hidden:stdin:6: bad expression in eval (bad input): (b) >= (a)
address@hidden: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
address@hidden:stdin:6: Warning: excess arguments to builtin `divnum' ignored
address@hidden: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







reply via email to

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