m4-commit
[Top][All Lists]
Advanced

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

[SCM] GNU M4 source repository branch, branch-1_4, updated. branch-cvs-r


From: Eric Blake
Subject: [SCM] GNU M4 source repository branch, branch-1_4, updated. branch-cvs-readonly-17-ged2e087
Date: Wed, 21 Nov 2007 23:11:38 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU M4 source repository".

http://git.sv.gnu.org/gitweb/?p=m4.git;a=commitdiff;h=ed2e087c61541a94a3af378fe963cd1ae271d935

The branch, branch-1_4 has been updated
       via  ed2e087c61541a94a3af378fe963cd1ae271d935 (commit)
       via  902fc6fad4ed4194fa1305b94613abe7dc6cabd7 (commit)
       via  bfe28c9acd9691ecbb00a8d0a594c728a58267d3 (commit)
      from  4149c1c87008e2e0d451d8a4f43f5a187cb9c755 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ed2e087c61541a94a3af378fe963cd1ae271d935
Author: Eric Blake <address@hidden>
Date:   Wed Nov 21 16:05:23 2007 -0700

    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>

commit 902fc6fad4ed4194fa1305b94613abe7dc6cabd7
Author: Eric Blake <address@hidden>
Date:   Wed Nov 21 14:55:44 2007 -0700

    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>

commit bfe28c9acd9691ecbb00a8d0a594c728a58267d3
Author: Eric Blake <address@hidden>
Date:   Wed Nov 21 14:17:36 2007 -0700

    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>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog      |   39 +++++++
 doc/m4.texinfo |  116 ++++++++++----------
 src/builtin.c  |  334 +++++++++++++++++++++++++++++---------------------------
 src/eval.c     |  126 +++++++++++-----------
 src/format.c   |    7 +-
 src/input.c    |    4 +-
 src/m4.h       |    4 +-
 src/macro.c    |   12 +-
 8 files changed, 346 insertions(+), 296 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index acf9452..4179e81 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+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.
+       (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.
+       * 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-20  Ralf Wildenhues  <address@hidden>
 
        * Makefile.am (EXTRA_DIST): gendocs.sh is gone here.
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 6caa7c3..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
@@ -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
 
@@ -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 280344f..48df3d6 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -491,52 +491,48 @@ 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: %s: too few arguments: %d < %d",
+                 name, argc - 1, min));
+      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: %s: extra arguments ignored: %d > %d",
+             name, argc - 1, max));
+  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;
 
   if (*arg == '\0')
     {
       *valuep = 0;
-      M4ERROR ((warning_status, 0,
-               "empty string treated as 0 in builtin `%s'",
-               TOKEN_DATA_TEXT (macro)));
+      M4ERROR ((warning_status, 0, "%s: empty string treated as 0", name));
     }
   else
     {
@@ -545,18 +541,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)));
+                   "%s: non-numeric argument `%s'", name, arg));
          return false;
        }
       if (isspace (to_uchar (*arg)))
        M4ERROR ((warning_status, 0,
-                 "leading whitespace ignored in builtin `%s'",
-                 TOKEN_DATA_TEXT (macro)));
+                 "%s: leading whitespace ignored", name));
       else if (errno == ERANGE)
        M4ERROR ((warning_status, 0,
-                 "numeric overflow detected in builtin `%s'",
-                 TOKEN_DATA_TEXT (macro)));
+                 "%s: numeric overflow detected", name));
     }
   return true;
 }
@@ -634,8 +627,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);
     }
@@ -665,14 +657,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;
     }
 
@@ -712,7 +705,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);
@@ -728,7 +721,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);
@@ -744,7 +737,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);
 
@@ -763,18 +756,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--;
 
@@ -849,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;
@@ -866,12 +860,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])));
+                     "%s: undefined macro `%s'", me, ARG (i)));
        }
     }
 
@@ -923,15 +917,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;
     }
 
@@ -939,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;
@@ -964,15 +959,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;
     }
 
@@ -980,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;
@@ -1004,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 (argv[0], argc, 2, -1))
+  if (bad_argc (me, argc, 1, -1))
     return;
 
   for (i = 1; i < argc; i++)
@@ -1029,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;
@@ -1085,7 +1082,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;
@@ -1109,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 (argv[0], argc, 2, 2))
+  if (bad_argc (me, argc, 1, 1))
     {
       /* The empty command is successful.  */
       sysval = 0;
@@ -1125,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
@@ -1152,38 +1150,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)));
+               "%s: radix %d out of range", me, radix));
       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)));
+      M4ERROR ((warning_status, 0, "%s: negative width", me));
       return;
     }
 
   if (!*ARG (1))
     M4ERROR ((warning_status, 0,
-             "empty string treated as 0 in builtin `%s'", ARG (0)));
-  else if (evaluate (ARG (1), &value))
+             "%s: empty string treated as 0", me));
+  else if (evaluate (me, ARG (1), &value))
     return;
 
   if (radix == 1)
@@ -1218,12 +1215,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);
@@ -1232,12 +1230,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);
@@ -1254,12 +1253,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);
@@ -1272,8 +1270,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);
 }
 
@@ -1287,7 +1284,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;
 
@@ -1296,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'", ARG (0)));
+                   "%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));
          }
       }
 }
@@ -1331,10 +1331,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 ();
+  bad_argc (me, argc, 0, 0);
+  skip_line (me);
 }
 
 /*-------------------------------------------------------------------------.
@@ -1345,7 +1345,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);
 }
@@ -1357,12 +1357,11 @@ 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) ? 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);
 }
 
 /*--------------------------------------------------------------------.
@@ -1373,12 +1372,11 @@ 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) ? 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
@@ -1391,10 +1389,10 @@ 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 (TOKEN_DATA_TEXT (argv[1]));
+  set_word_regexp (ARG (1));
 }
 
 #endif /* ENABLE_CHANGEWORD */
@@ -1411,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 (argv[0], argc, 2, 2))
+  if (bad_argc (me, argc, 1, 1))
     return;
 
   fp = m4_path_search (ARG (1), &name);
@@ -1422,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;
@@ -1455,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;
@@ -1483,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
@@ -1493,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 (argv[0], argc, 2, 2))
+  const char *me = ARG (0);
+
+  if (bad_argc (me, argc, 1, 1))
     return;
   if (no_gnu_extensions)
     {
@@ -1513,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;
@@ -1530,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 (argv[0], argc, 2, 2))
+  const char *me = ARG (0);
+
+  if (bad_argc (me, argc, 1, 1))
     return;
-  mkstemp_helper (obs, ARG (1));
+  mkstemp_helper (obs, me, ARG (1));
 }
 
 /*----------------------------------------.
@@ -1548,7 +1552,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');
@@ -1560,8 +1564,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);
@@ -1570,16 +1573,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);
@@ -1597,16 +1598,17 @@ 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)
     {
       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
@@ -1630,7 +1632,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)));
@@ -1670,7 +1672,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 +1692,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);
       }
@@ -1705,30 +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;
 
-  if (bad_argc (argv[0], argc, 1, 2))
-    return;
+  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)
@@ -1757,14 +1760,15 @@ 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;
+  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",
@@ -1778,7 +1782,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)));
 }
@@ -1796,7 +1800,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)
@@ -1831,10 +1835,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)
@@ -1843,10 +1849,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)
@@ -1920,7 +1926,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)
@@ -1978,9 +1984,9 @@ 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);
+  format (obs, argc, argv);
 }
 
 /*-------------------------------------------------------------------------.
@@ -1995,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;
 
@@ -2015,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.  */
@@ -2031,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]);
@@ -2039,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:
@@ -2077,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 */
@@ -2087,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 (argv[0], argc, 3, 4))
+  if (bad_argc (me, argc, 2, 3))
     {
       /* builtin(`regexp') is blank, but regexp(`abc') is 0.  */
       if (argc == 2)
@@ -2105,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;
     }
 
@@ -2119,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;
     }
 
@@ -2130,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);
 }
 
 /*------------------------------------------------------------------.
@@ -2148,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;
@@ -2159,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 (argv[0], argc, 3, 4))
+  if (bad_argc (me, argc, 2, 3))
     {
       /* builtin(`patsubst') is blank, but patsubst(`abc') is abc.  */
       if (argc == 2)
@@ -2188,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;
     }
 
@@ -2209,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;
@@ -2222,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
@@ -2254,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)));
 }
 
 /*-------------------------------------------------------------------------.
@@ -2295,8 +2304,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/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/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..c372ffd 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);
@@ -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;


hooks/post-receive
--
GNU M4 source repository




reply via email to

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