[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[SCM] GNU M4 source repository branch, master, updated. cvs-readonly-110
From: |
Eric Blake |
Subject: |
[SCM] GNU M4 source repository branch, master, updated. cvs-readonly-110-gb9738ad |
Date: |
Fri, 09 May 2008 03:12:23 +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=b9738adbaaf9c8f02c97c6179b9e595a0d28121c
The branch, master has been updated
via b9738adbaaf9c8f02c97c6179b9e595a0d28121c (commit)
from d74cecd6377345903ba25c9d9b82729324fbbcf8 (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 b9738adbaaf9c8f02c97c6179b9e595a0d28121c
Author: Eric Blake <address@hidden>
Date: Thu May 8 20:39:16 2008 -0600
Stage 23: allow tracing of indirect macro calls.
* m4/m4module.h (m4_input_block): Remove.
(m4_call_info): New opaque type.
(m4_trace_prepare, m4_arg_info): New prototypes.
(m4_macro_call, m4_push_string_finish, m4_input_print): Change
prototypes.
* m4/m4private.h (struct m4_macro_args): Add info field.
(struct m4_call_info): New structure.
(m4_arg_info): New accessor.
* m4/input.c (m4_input_block): Make typedef local.
(m4_push_string_init): Initialize length.
(m4_push_string_finish, m4_input_print): Change signature, so that
printing can be done before finalization.
(struct input_funcs): Add parameter to print_func.
(file_print, string_print, composite_print): Adjust accordingly.
* m4/macro.c (trace_header, trace_flush, trace_pre, trace_post):
Change signatures for stacked trace messages, and for using call
context.
(trace_prepre): Export and rename...
(m4_trace_prepare): ...to this, for use by indir. Alter signature
to use call context.
(collect_arguments): Alter signature, to manage new field.
(expand_macro): Change call context management. Move tracing...
(m4_macro_call): ...here. Remove redundant parameter.
(m4_arg_argc): New function.
(m4_make_argv_ref): Replace unused skip parameter with new trace
parameter; manage new field.
* modules/gnu.c (builtin, indir): Adjust callers.
* src/main.c (usage): Update debugmode flag summary.
* tests/null.m4: Enhance test.
* tests/null.err: Update expected output.
* tests/macros.at (Tracing Hanoi Towers): Likewise.
* doc/m4.texinfo (Trace): Mention more about trace formatting.
(Debugmode): Enhance description of 'c' and 'x'. Enhance test to
cover line numbering details in traces.
(Debuglen): Enhance test to cover indir tracing.
* NEWS: Mention these changes.
Signed-off-by: Eric Blake <address@hidden>
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 45 +++++++++
NEWS | 19 +++-
doc/m4.texinfo | 97 +++++++++++++++----
m4/input.c | 83 ++++++++--------
m4/m4module.h | 20 ++--
m4/m4private.h | 19 ++++
m4/macro.c | 288 +++++++++++++++++++++++++++++--------------------------
modules/gnu.c | 10 +-
src/main.c | 6 +-
tests/macros.at | 2 +-
tests/null.err | Bin 18 -> 51 bytes
tests/null.m4 | Bin 6607 -> 6605 bytes
12 files changed, 373 insertions(+), 216 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2f39b0e..c20ac6e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+2008-05-08 Eric Blake <address@hidden>
+
+ Stage 23: allow tracing of indirect macro calls.
+ Track all trace information as part of the argv struct, rather
+ than temporarily resetting global state. Teach indir to trace
+ macros that it invokes.
+ Memory impact: slight penalty, due to larger argv struct.
+ Speed impact: none noticed.
+ * m4/m4module.h (m4_input_block): Remove.
+ (m4_call_info): New opaque type.
+ (m4_trace_prepare, m4_arg_info): New prototypes.
+ (m4_macro_call, m4_push_string_finish, m4_input_print): Change
+ prototypes.
+ * m4/m4private.h (struct m4_macro_args): Add info field.
+ (struct m4_call_info): New structure.
+ (m4_arg_info): New accessor.
+ * m4/input.c (m4_input_block): Make typedef local.
+ (m4_push_string_init): Initialize length.
+ (m4_push_string_finish, m4_input_print): Change signature, so that
+ printing can be done before finalization.
+ (struct input_funcs): Add parameter to print_func.
+ (file_print, string_print, composite_print): Adjust accordingly.
+ * m4/macro.c (trace_header, trace_flush, trace_pre, trace_post):
+ Change signatures for stacked trace messages, and for using call
+ context.
+ (trace_prepre): Export and rename...
+ (m4_trace_prepare): ...to this, for use by indir. Alter signature
+ to use call context.
+ (collect_arguments): Alter signature, to manage new field.
+ (expand_macro): Change call context management. Move tracing...
+ (m4_macro_call): ...here. Remove redundant parameter.
+ (m4_arg_argc): New function.
+ (m4_make_argv_ref): Replace unused skip parameter with new trace
+ parameter; manage new field.
+ * modules/gnu.c (builtin, indir): Adjust callers.
+ * src/main.c (usage): Update debugmode flag summary.
+ * tests/null.m4: Enhance test.
+ * tests/null.err: Update expected output.
+ * tests/macros.at (Tracing Hanoi Towers): Likewise.
+ * doc/m4.texinfo (Trace): Mention more about trace formatting.
+ (Debugmode): Enhance description of 'c' and 'x'. Enhance test to
+ cover line numbering details in traces.
+ (Debuglen): Enhance test to cover indir tracing.
+ * NEWS: Mention these changes.
+
2008-05-07 Eric Blake <address@hidden>
Test for traceon regression just fixed in branch-1.6.
diff --git a/NEWS b/NEWS
index fd3bb09..ea0385b 100644
--- a/NEWS
+++ b/NEWS
@@ -158,10 +158,8 @@ promoted to 2.0.
builtin traces actions related to module loading and unloading, and
affects `dumpdef' and trace output to show where builtins come from.
New `s' flag shows the entire stack of `pushdef' definitions during
- `dumpdef'. The `c' flag has been updated to output two lines instead
- of three (since the last two had always been paired), and to add
- information to the first line to show the definition of the macro being
- expanded. The 'e' flag has been updated to output non-text expansions.
+ `dumpdef'. The `c' flag has been updated to add information to the
+ first line to show the definition of the macro being expanded.
*** The `divert' builtin now accepts an optional second argument of text
that is immediately placed on the new diversion, regardless of whether
@@ -248,6 +246,19 @@ promoted to 2.0.
To simulate 1.4.x behavior, use:
pushdef(`defn', `ifdef(`$1', `builtin(`defn', `$1')')')
+** Enhance the `indir' builtin to trace indirect macros, where the trace
+ is requested via `traceon' or the command-line option `-t'. Previously,
+ it was impossible to trace macro names such as `foo-bar' which could
+ only be invoked indirectly, without relying on global tracing (such as
+ with `debugmode(`t')') or the experimental `changeword'.
+
+** Aspects of tracing output that were previously undocumented have been
+ slightly altered, and the effect of the builtin `debugmode' on trace
+ output is more fully documented. As POSIX does not specify trace output
+ format, parsing such output is inherently fragile in the first place.
+ The intent is that future M4 versions will not change documented trace
+ output without adding additional `debugmode' flags.
+
** Enhance the `ifdef', `ifelse', and `shift' builtins, as well as all
user macros, to transparently handle builtin tokens generated by `defn'.
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 7bdfa66..8c4c237 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -3958,7 +3958,7 @@ foo # untraced
@result{}bar # untraced
@end example
-However, @acronym{GNU} M4 1.4.7 and earlier had slightly different
+However, @acronym{GNU} M4 prior to 2.0 had slightly different
semantics, where @code{traceon} without arguments only affected symbols
that were defined at that moment, and @code{traceoff} without arguments
stopped all tracing, even when tracing was requested by macro name. The
@@ -4006,7 +4006,56 @@ a b
@end example
@xref{Debugmode}, for information on controlling the details of the
-display.
+display. The format of the trace output is not specified by
address@hidden, and varies between implementations of @code{m4}.
+
+Starting with M4 1.6, tracing also works via @code{indir}
+(@pxref{Indir}). However, since tracing is an attribute tracked by
+macro names, and @code{builtin} bypasses macro names (@pxref{Builtin}),
+it is not possible for @code{builtin} to trace which subsidiary builtin
+it invokes. If you are worried about tracking all invocations of a
+given builtin, you should also trace @code{builtin}, or enable global
+tracing (the @samp{t} debug level, @pxref{Debugmode}).
+
address@hidden
+$ @kbd{m4 -d}
+define(`my_defn', defn(`defn'))undefine(`defn')
address@hidden
+define(`foo', `bar')traceon(`foo', `defn', `my_defn')
address@hidden
+foo
address@hidden: -1- foo -> `bar'
address@hidden
+indir(`foo')
address@hidden: -1- foo -> `bar'
address@hidden
+my_defn(`foo')
address@hidden: -1- my_defn(`foo') -> ``bar''
address@hidden
+indir(`my_defn', `foo')
address@hidden: -1- my_defn(`foo') -> ``bar''
address@hidden
+builtin(`defn', `foo')
address@hidden
+debugmode(`+cxt')
address@hidden
+builtin(`defn', builtin(`shift', `', `foo'))
address@hidden: -1- id 12: builtin ... = <builtin>
address@hidden: -2- id 13: builtin ... = <builtin>
address@hidden: -2- id 13: builtin(`shift', `', `foo') -> ``foo''
address@hidden: -1- id 12: builtin(`defn', `foo') -> ``bar''
address@hidden
+indir(`my_defn', indir(`shift', `', `foo'))
address@hidden: -1- id 14: indir ... = <indir>
address@hidden: -2- id 15: indir ... = <indir>
address@hidden: -2- id 15: shift ... = <shift>
address@hidden: -2- id 15: shift(`', `foo') -> ``foo''
address@hidden: -2- id 15: indir(`shift', `', `foo') -> ``foo''
address@hidden: -1- id 14: my_defn ... = <defn>
address@hidden: -1- id 14: my_defn(`foo') -> ``bar''
address@hidden: -1- id 14: indir(`my_defn', `foo') -> ``bar''
address@hidden
address@hidden example
@node Debugmode
@section Controlling debugging options
@@ -4033,10 +4082,13 @@ invoking the macro. Arguments are subject to length
truncation
specified by @code{debuglen} (@pxref{Debuglen}).
@item c
-In trace output, show an additional line for each macro call, prior to
-the arguments being collected, that shows the definition of the macro
-that will be used for the expansion. The definition is subject to
-length truncation specified by @code{debuglen} (@pxref{Debuglen}).
+In trace output, show an additional line for each macro call, when the
+macro is seen, but before the arguments are collected, and show the
+definition of the macro that will be used for the expansion. By
+default, only one line is printed, after all arguments are collected and
+the expansion determined. The definition is subject to length
+truncation specified by @code{debuglen} (@pxref{Debuglen}). This is
+often used with the @samp{x} flag.
@item e
In trace output, show the expansion of each macro call. The expansion
@@ -4082,7 +4134,11 @@ arguments.
@item x
In trace output, add a unique `macro call id' to each line of the trace
-output. This is useful in connection with the @samp{c} flag above.
+output. This is useful in connection with the @samp{c} flag above, to
+match where a macro is first recognized with where it is finally
+expanded, in spite of intermediate expansions that occur while
+collecting arguments. It can also be used in isolation to determine how
+many macros have been expanded.
@item V
A shorthand for all of the above flags.
@@ -4128,15 +4184,18 @@ debugmode()
foo
@error{}m4trace: -1- foo -> `FOO'
@result{}FOO
-debugmode(`V')
address@hidden
-foo(`BAR')
address@hidden:stdin:6: -1- id 6: foo ... = `FOO$1'
address@hidden:stdin:6: -1- id 6: foo(`BAR') -> `FOOBAR'
+debugmode(`V')debugmode(`-q')
address@hidden:stdin:5: -1- id 6: debugmode ... = <debugmode>@address@hidden
address@hidden:stdin:5: -1- id 6: debugmode(`-q') -> `'
address@hidden
+foo(
+`BAR')
address@hidden:stdin:6: -1- id 7: foo ... = FOO$1
address@hidden:stdin:6: -1- id 7: foo(BAR) -> FOOBAR
@result{}FOOBAR
debugmode
address@hidden:stdin:7: -1- id 7: debugmode ... = <debugmode>@address@hidden
address@hidden:stdin:7: -1- id 7: debugmode ->@w{ }
address@hidden:stdin:8: -1- id 8: debugmode ... = <debugmode>@address@hidden
address@hidden:stdin:8: -1- id 8: debugmode ->@w{ }
@result{}
foo
@error{}m4trace: -1- foo
@@ -4144,10 +4203,10 @@ foo
debugmode(`+clmx')
@result{}
foo(divnum)
address@hidden:10: -1- id 10: foo ... = FOO$1
address@hidden:10: -2- id 11: divnum ... = <divnum>@address@hidden
address@hidden:10: -2- id 11: divnum
address@hidden:10: -1- id 10: foo
address@hidden:11: -1- id 11: foo ... = FOO$1
address@hidden:11: -2- id 12: divnum ... = <divnum>@address@hidden
address@hidden:11: -2- id 12: divnum
address@hidden:11: -1- id 11: foo
@result{}FOO0
debugmode(`-m')
@result{}
@@ -4224,7 +4283,7 @@ define(`echo', `$@@')
echo(`1', `long string')
@error{}m4trace: -1- echo(`1', `long s...') -> ``1',`l...'
@result{}1,long string
-echo(defn(`changequote'))
+indir(`echo', defn(`changequote'))
@error{}m4trace: -2- defn(`change...') -> `<changequote>'
@error{}m4trace: -1- echo(<changequote>) -> ``<changequote>''
@result{}
diff --git a/m4/input.c b/m4/input.c
index 1f89916..a021e70 100644
--- a/m4/input.c
+++ b/m4/input.c
@@ -92,23 +92,28 @@
maintains its own notion of the current file and line, so swapping
between input blocks must update the context accordingly. */
+typedef struct m4_input_block m4_input_block;
+
static int file_peek (m4_input_block *, m4 *, bool);
static int file_read (m4_input_block *, m4 *, bool, bool,
bool);
static void file_unget (m4_input_block *, int);
static bool file_clean (m4_input_block *, m4 *, bool);
-static void file_print (m4_input_block *, m4 *, m4_obstack *);
+static void file_print (m4_input_block *, m4 *, m4_obstack *,
+ int);
static int string_peek (m4_input_block *, m4 *, bool);
static int string_read (m4_input_block *, m4 *, bool, bool,
bool);
static void string_unget (m4_input_block *, int);
-static void string_print (m4_input_block *, m4 *, m4_obstack *);
+static void string_print (m4_input_block *, m4 *, m4_obstack *,
+ int);
static int composite_peek (m4_input_block *, m4 *, bool);
static int composite_read (m4_input_block *, m4 *, bool, bool,
bool);
static void composite_unget (m4_input_block *, int);
static bool composite_clean (m4_input_block *, m4 *, bool);
-static void composite_print (m4_input_block *, m4 *, m4_obstack *);
+static void composite_print (m4_input_block *, m4 *, m4_obstack *,
+ int);
static int eof_peek (m4_input_block *, m4 *, bool);
static int eof_read (m4_input_block *, m4 *, bool, bool,
bool);
@@ -159,7 +164,7 @@ struct input_funcs
/* Add a representation of the input block to the obstack, for use
in trace expansion output. */
- void (*print_func) (m4_input_block *, m4 *, m4_obstack *);
+ void (*print_func) (m4_input_block *, m4 *, m4_obstack *, int);
};
/* A block of input to be scanned. */
@@ -337,9 +342,11 @@ file_clean (m4_input_block *me, m4 *context, bool cleanup)
}
static void
-file_print (m4_input_block *me, m4 *context, m4_obstack *obs)
+file_print (m4_input_block *me, m4 *context M4_GNUC_UNUSED, m4_obstack *obs,
+ int debug_level M4_GNUC_UNUSED)
{
const char *text = me->file;
+ assert (obstack_object_size (current_input) == 0);
obstack_grow (obs, "<file: ", strlen ("<file: "));
obstack_grow (obs, text, strlen (text));
obstack_1grow (obs, '>');
@@ -417,12 +424,15 @@ string_unget (m4_input_block *me, int ch)
}
static void
-string_print (m4_input_block *me, m4 *context, m4_obstack *obs)
+string_print (m4_input_block *me, m4 *context, m4_obstack *obs,
+ int debug_level)
{
- bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
+ bool quote = (debug_level & M4_DEBUG_TRACE_QUOTE) != 0;
size_t arg_length = m4_get_max_debug_arg_length_opt (context);
- m4_shipout_string_trunc (obs, me->u.u_s.str, me->u.u_s.len,
+ assert (!me->u.u_s.len);
+ m4_shipout_string_trunc (obs, (char *) obstack_base (current_input),
+ obstack_object_size (current_input),
quote ? m4_get_syntax_quotes (M4SYNTAX) : NULL,
&arg_length);
}
@@ -442,6 +452,7 @@ m4_push_string_init (m4 *context)
next->funcs = &string_funcs;
next->file = m4_get_current_file (context);
next->line = m4_get_current_line (context);
+ next->u.u_s.len = 0;
return current_input;
}
@@ -610,24 +621,19 @@ m4__push_symbol (m4 *context, m4_symbol_value *value,
size_t level, bool inuse)
}
/* Last half of m4_push_string (). If next is now NULL, a call to
- m4_push_file () or m4_push_builtin () has pushed a different input
- block to the top of the stack. If the new object is void, we do
- not push it. The function m4_push_string_finish () returns the
- opaque finished object, whether that is still a string or has been
- replaced by a file or builtin; this object can then be used in
- m4_input_print () during tracing. This pointer is only for
- temporary use, since reading the next token might release the
- memory used for the object. */
-m4_input_block *
+ m4_push_file () has pushed a different input block to the top of
+ the stack. Otherwise, all unfinished text on the obstack returned
+ from push_string_init is collected into the input stack. If the
+ new object is empty, we do not push it. */
+void
m4_push_string_finish (void)
{
- m4_input_block *ret = NULL;
size_t len = obstack_object_size (current_input);
if (next == NULL)
{
assert (!len);
- return isp;
+ return;
}
if (len || next->funcs == &composite_funcs)
@@ -641,13 +647,12 @@ m4_push_string_finish (void)
m4__make_text_link (current_input, &next->u.u_c.chain,
&next->u.u_c.end);
next->prev = isp;
- ret = isp = next;
+ isp = next;
input_change = true;
}
else
obstack_free (current_input, next);
next = NULL;
- return ret;
}
@@ -846,14 +851,16 @@ composite_clean (m4_input_block *me, m4 *context, bool
cleanup)
}
static void
-composite_print (m4_input_block *me, m4 *context, m4_obstack *obs)
+composite_print (m4_input_block *me, m4 *context, m4_obstack *obs,
+ int debug_level)
{
- bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
+ bool quote = (debug_level & M4_DEBUG_TRACE_QUOTE) != 0;
size_t maxlen = m4_get_max_debug_arg_length_opt (context);
m4__symbol_chain *chain = me->u.u_c.chain;
const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
- bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
+ bool module = (debug_level & M4_DEBUG_TRACE_MODULE) != 0;
bool done = false;
+ size_t len = obstack_object_size (current_input);
if (quote)
m4_shipout_string (context, obs, quotes->str1, quotes->len1, false);
@@ -885,6 +892,9 @@ composite_print (m4_input_block *me, m4 *context,
m4_obstack *obs)
}
chain = chain->next;
}
+ if (len)
+ m4_shipout_string_trunc (obs, (char *) obstack_base (current_input), len,
+ NULL, &maxlen);
if (quote)
m4_shipout_string (context, obs, quotes->str2, quotes->len2, false);
}
@@ -988,25 +998,16 @@ eof_unget (m4_input_block *me M4_GNUC_UNUSED, int ch)
/* When tracing, print a summary of the contents of the input block
- created by push_string_init/push_string_finish to OBS. */
+ created by push_string_init/push_string_finish to OBS. Use
+ DEBUG_LEVEL to determine whether to add quotes or module
+ designations. */
void
-m4_input_print (m4 *context, m4_obstack *obs, m4_input_block *input)
+m4_input_print (m4 *context, m4_obstack *obs, int debug_level)
{
- assert (context && obs);
- if (input == NULL)
- {
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE))
- {
- const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
- obstack_grow (obs, quotes->str1, quotes->len1);
- obstack_grow (obs, quotes->str2, quotes->len2);
- }
- }
- else
- {
- assert (input->funcs->print_func);
- input->funcs->print_func (input, context, obs);
- }
+ m4_input_block *block = next ? next : isp;
+ assert (context && obs && (debug_level & M4_DEBUG_TRACE_EXPANSION));
+ assert (block->funcs->print_func);
+ block->funcs->print_func (block, context, obs, debug_level);
}
/* Return an obstack ready for direct expansion of wrapup text, and
diff --git a/m4/m4module.h b/m4/m4module.h
index 21a8339..96b76ea 100644
--- a/m4/m4module.h
+++ b/m4/m4module.h
@@ -32,15 +32,14 @@ BEGIN_C_DECLS
typedef struct m4 m4;
typedef struct m4_builtin m4_builtin;
+typedef struct m4_call_info m4_call_info;
typedef struct m4_macro m4_macro;
-typedef struct m4_symbol m4_symbol;
-typedef struct m4_symbol_value m4_symbol_value;
-typedef struct m4_input_block m4_input_block;
-typedef struct m4_module m4_module;
typedef struct m4_macro_args m4_macro_args;
-typedef struct m4_string_pair m4_string_pair;
-
+typedef struct m4_module m4_module;
typedef struct obstack m4_obstack;
+typedef struct m4_string_pair m4_string_pair;
+typedef struct m4_symbol m4_symbol;
+typedef struct m4_symbol_value m4_symbol_value;
typedef void m4_builtin_func (m4 *, m4_obstack *, size_t, m4_macro_args *);
@@ -347,8 +346,9 @@ extern m4_symbol_value *m4_builtin_find_by_func
(m4_module *,
extern void m4_macro_expand_input (m4 *);
extern void m4_macro_call (m4 *, m4_symbol_value *, m4_obstack *,
- size_t, m4_macro_args *);
+ m4_macro_args *);
extern size_t m4_arg_argc (m4_macro_args *);
+extern const m4_call_info *m4_arg_info (m4_macro_args *);
extern m4_symbol_value *m4_arg_symbol (m4_macro_args *, size_t);
extern bool m4_is_arg_text (m4_macro_args *, size_t);
extern bool m4_is_arg_func (m4_macro_args *, size_t);
@@ -414,6 +414,8 @@ extern void m4_debug_message_prefix (m4 *);
extern void m4_debug_message (m4 *, int, const char *, ...)
M4_GNUC_PRINTF (3, 4);
+extern void m4_trace_prepare (m4 *, const m4_call_info *,
+ m4_symbol_value *);
/* --- REGEXP SYNTAX --- */
@@ -496,9 +498,9 @@ extern void m4_skip_line (m4 *context, const
char *);
extern void m4_push_file (m4 *, FILE *, const char *, bool);
extern void m4_push_builtin (m4 *, m4_obstack *, m4_symbol_value *);
extern m4_obstack *m4_push_string_init (m4 *);
-extern m4_input_block *m4_push_string_finish (void);
+extern void m4_push_string_finish (void);
extern bool m4_pop_wrapup (m4 *);
-extern void m4_input_print (m4 *, m4_obstack *, m4_input_block *);
+extern void m4_input_print (m4 *, m4_obstack *, int);
diff --git a/m4/m4private.h b/m4/m4private.h
index 7e1f7a8..526a0ef 100644
--- a/m4/m4private.h
+++ b/m4/m4private.h
@@ -313,6 +313,9 @@ struct m4_macro_args
during parsing or any token is potentially unsafe and requires a
rescan. */
unsigned int quote_age;
+ /* The context of the macro call during expansion, and NULL in a
+ back-reference. */
+ m4_call_info *info;
size_t level; /* Which obstack owns this argv. */
size_t arraylen; /* True length of allocated elements in array. */
/* Used as a variable-length array, storing information about each
@@ -332,6 +335,21 @@ struct m4__macro_arg_stacks
void *argv_base; /* Location for clearing the argv obstack. */
};
+/* Opaque structure for managing call context information. Contains
+ the context used in tracing and error messages that was valid at
+ the start of the macro expansion, even if argument collection
+ changes global context in the meantime. */
+struct m4_call_info
+{
+ const char *file; /* The file containing the macro invocation. */
+ int line; /* The line the macro was called on. */
+ int call_id; /* The unique sequence call id of the macro. */
+ int trace : 1; /* True to trace this macro. */
+ int debug_level : 31; /* The debug level for tracing the macro call.
*/
+ const char *name; /* The macro name. */
+ size_t name_len; /* The length of name. */
+};
+
extern size_t m4__adjust_refcount (m4 *, size_t, bool);
extern bool m4__arg_adjust_refcount (m4 *, m4_macro_args *, bool);
extern void m4__push_arg_quote (m4 *, m4_obstack *, m4_macro_args *,
@@ -553,6 +571,7 @@ extern bool m4__next_token_is_open (m4 *);
that also have an identically named function exported in m4module.h. */
#ifdef NDEBUG
# define m4_arg_argc(A) (A)->argc
+# define m4_arg_info(A) (A)->info
# define m4_arg_scratch(C) \
((C)->arg_stacks[(C)->expansion_level - 1].argv)
#endif /* NDEBUG */
diff --git a/m4/macro.c b/m4/macro.c
index f5bec18..1e88299 100644
--- a/m4/macro.c
+++ b/m4/macro.c
@@ -122,9 +122,8 @@
memory left on the obstack while waiting for refcounts to drop.
*/
-static m4_macro_args *collect_arguments (m4 *, const char *, size_t,
- m4_symbol *, m4_obstack *,
- m4_obstack *);
+static m4_macro_args *collect_arguments (m4 *, m4_call_info *, m4_symbol *,
+ m4_obstack *, m4_obstack *);
static void expand_macro (m4 *, const char *, size_t, m4_symbol *);
static bool expand_token (m4 *, m4_obstack *, m4__token_type,
m4_symbol_value *, int, bool);
@@ -133,16 +132,13 @@ static bool expand_argument (m4 *, m4_obstack *,
m4_symbol_value *,
static void process_macro (m4 *, m4_symbol_value *, m4_obstack *, int,
m4_macro_args *);
-static void trace_prepre (m4 *, const char *, size_t,
- m4_symbol_value *);
-static void trace_pre (m4 *, size_t, m4_macro_args *);
-static void trace_post (m4 *, size_t, m4_macro_args *,
- m4_input_block *, bool);
+static unsigned int trace_pre (m4 *, m4_macro_args *);
+static void trace_post (m4 *, unsigned int, const m4_call_info *);
static void trace_format (m4 *, const char *, ...)
M4_GNUC_PRINTF (2, 3);
-static void trace_header (m4 *, size_t);
-static void trace_flush (m4 *);
+static unsigned int trace_header (m4 *, const m4_call_info *);
+static void trace_flush (m4 *, unsigned int);
/* The number of the current call of expand_macro (). */
@@ -443,22 +439,12 @@ expand_macro (m4 *context, const char *name, size_t len,
m4_symbol *symbol)
void *argv_base; /* Base of stack->argv on entry. */
m4_macro_args *argv; /* Arguments to the called macro. */
m4_obstack *expansion; /* Collects the macro's expansion. */
- m4_input_block *expanded; /* The resulting expansion, for tracing. */
- bool traced; /* True if this macro is traced. */
- bool trace_expansion = false; /* True if trace and debugmode(`e'). */
- size_t my_call_id; /* Sequence id for this macro. */
m4_symbol_value *value; /* Original value of this macro. */
size_t level; /* Expansion level of this macro. */
m4__macro_arg_stacks *stack; /* Storage for this macro. */
+ m4_call_info info; /* Context of this macro call. */
- /* Report errors at the location where the open parenthesis (if any)
- was found, but after expansion, restore global state back to the
- location of the close parenthesis. This is safe since we
- guarantee that macro expansion does not alter the state of
- current_file/current_line (dnl, include, and sinclude are special
- cased in the input engine to ensure this fact). */
- const char *loc_open_file = m4_get_current_file (context);
- int loc_open_line = m4_get_current_line (context);
+ /* TODO - use m4_call_info to avoid temporary munging of global state. */
const char *loc_close_file;
int loc_close_line;
@@ -496,10 +482,14 @@ expand_macro (m4 *context, const char *name, size_t len,
m4_symbol *symbol)
collecting arguments. Likewise, grab any state needed during
tracing. */
value = m4_get_symbol_value (symbol);
- traced = (m4_is_debug_bit (context, M4_DEBUG_TRACE_ALL)
- || m4_get_symbol_traced (symbol));
- if (traced)
- trace_expansion = m4_is_debug_bit (context, M4_DEBUG_TRACE_EXPANSION);
+ info.file = m4_get_current_file (context);
+ info.line = m4_get_current_line (context);
+ info.call_id = ++macro_call_id;
+ info.trace = (m4_is_debug_bit (context, M4_DEBUG_TRACE_ALL)
+ || m4_get_symbol_traced (symbol));
+ info.debug_level = m4_get_debug_level_opt (context);
+ info.name = name;
+ info.name_len = len;
/* Prepare for macro expansion. */
VALUE_PENDING (value)++;
@@ -507,13 +497,9 @@ expand_macro (m4 *context, const char *name, size_t len,
m4_symbol *symbol)
m4_error (context, EXIT_FAILURE, 0, NULL, _("\
recursion limit of %zu exceeded, use -L<N> to change it"),
m4_get_nesting_limit_opt (context));
- my_call_id = ++macro_call_id;
- if (traced && m4_is_debug_bit (context, M4_DEBUG_TRACE_CALL))
- trace_prepre (context, name, my_call_id, value);
-
- argv = collect_arguments (context, name, len, symbol, stack->args,
- stack->argv);
+ m4_trace_prepare (context, &info, value);
+ argv = collect_arguments (context, &info, symbol, stack->args, stack->argv);
/* Since collect_arguments can invalidate stack by reallocating
context->arg_stacks during a recursive expand_macro call, we must
reset it here. */
@@ -523,22 +509,16 @@ recursion limit of %zu exceeded, use -L<N> to change it"),
/* The actual macro call. */
loc_close_file = m4_get_current_file (context);
loc_close_line = m4_get_current_line (context);
- m4_set_current_file (context, loc_open_file);
- m4_set_current_line (context, loc_open_line);
-
- if (traced)
- trace_pre (context, my_call_id, argv);
-
+ m4_set_current_file (context, info.file);
+ m4_set_current_line (context, info.line);
expansion = m4_push_string_init (context);
- m4_macro_call (context, value, expansion, argv->argc, argv);
- expanded = m4_push_string_finish ();
-
- if (traced)
- trace_post (context, my_call_id, argv, expanded, trace_expansion);
+ m4_macro_call (context, value, expansion, argv);
+ m4_push_string_finish ();
/* Cleanup. */
m4_set_current_file (context, loc_close_file);
m4_set_current_line (context, loc_close_line);
+ argv->info = NULL;
--context->expansion_level;
--VALUE_PENDING (value);
@@ -558,8 +538,8 @@ recursion limit of %zu exceeded, use -L<N> to change it"),
obstack_free (stack->args, args_scratch);
if (debug_macro_level & PRINT_ARGCOUNT_CHANGES)
xfprintf (stderr, "m4debug: -%d- `%s' in use, level=%d, "
- "refcount=%zu, argcount=%zu\n", my_call_id, argv->argv0,
- level, stack->refcount, stack->argcount);
+ "refcount=%zu, argcount=%zu\n", info.call_id,
+ argv->argv0, level, stack->refcount, stack->argcount);
}
else
{
@@ -570,15 +550,13 @@ recursion limit of %zu exceeded, use -L<N> to change it"),
}
}
-/* Collect all the arguments to a call of the macro SYMBOL (called
- NAME, with length LEN). The arguments are stored on the obstack
- ARGUMENTS and a table of pointers to the arguments on the obstack
- argv_stack. Return the object describing all of the macro
- arguments. */
+/* Collect all the arguments to a call of the macro SYMBOL, with call
+ context INFO. The arguments are stored on the obstack ARGUMENTS
+ and a table of pointers to the arguments on ARGV_STACK. Return the
+ object describing all of the macro arguments. */
static m4_macro_args *
-collect_arguments (m4 *context, const char *name, size_t len,
- m4_symbol *symbol, m4_obstack *arguments,
- m4_obstack *argv_stack)
+collect_arguments (m4 *context, m4_call_info *info, m4_symbol *symbol,
+ m4_obstack *arguments, m4_obstack *argv_stack)
{
m4_symbol_value token;
m4_symbol_value *tokenp;
@@ -594,23 +572,24 @@ collect_arguments (m4 *context, const char *name, size_t
len,
args.has_func = false;
/* Must copy here, since we are consuming tokens, and since symbol
table can be changed during argument collection. */
- args.argv0 = (char *) obstack_copy0 (arguments, name, len);
- args.argv0_len = len;
+ args.argv0 = (char *) obstack_copy0 (arguments, info->name, info->name_len);
+ args.argv0_len = info->name_len;
args.quote_age = m4__quote_age (M4SYNTAX);
+ args.info = info;
args.level = context->expansion_level - 1;
args.arraylen = 0;
obstack_grow (argv_stack, &args, offsetof (m4_macro_args, array));
- name = args.argv0;
+ info->name = args.argv0;
if (m4__next_token_is_open (context))
{
/* Gobble parenthesis, then collect arguments. */
- m4__next_token (context, &token, NULL, NULL, false, name);
+ m4__next_token (context, &token, NULL, NULL, false, info->name);
do
{
tokenp = (m4_symbol_value *) obstack_alloc (arguments,
sizeof *tokenp);
- more_args = expand_argument (context, arguments, tokenp, name);
+ more_args = expand_argument (context, arguments, tokenp, info->name);
if ((m4_is_symbol_value_text (tokenp)
&& !m4_get_symbol_value_len (tokenp))
@@ -669,33 +648,41 @@ collect_arguments (m4 *context, const char *name, size_t
len,
/* The actual call of a macro is handled by m4_macro_call ().
- m4_macro_call () is passed a SYMBOL, whose type is used to
+ m4_macro_call () is passed a symbol VALUE, whose type is used to
call either a builtin function, or the user macro expansion
- function process_macro (). There are ARGC arguments to
- the call, stored in the ARGV table. The expansion is left on
- the obstack EXPANSION. Macro tracing is also handled here. */
+ function process_macro (). The arguments are provided by the ARGV
+ table. The expansion is left on the obstack EXPANSION. Macro
+ tracing is also handled here. */
void
m4_macro_call (m4 *context, m4_symbol_value *value, m4_obstack *expansion,
- size_t argc, m4_macro_args *argv)
+ m4_macro_args *argv)
{
- if (m4_bad_argc (context, argc, argv->argv0,
- VALUE_MIN_ARGS (value), VALUE_MAX_ARGS (value),
- BIT_TEST (VALUE_FLAGS (value),
- VALUE_SIDE_EFFECT_ARGS_BIT)))
- return;
- if (m4_is_symbol_value_text (value))
- process_macro (context, value, expansion, argc, argv);
- else if (m4_is_symbol_value_func (value))
- m4_get_symbol_value_func (value) (context, expansion, argc, argv);
- else if (m4_is_symbol_value_placeholder (value))
- m4_warn (context, 0, M4ARG (0),
- _("builtin `%s' requested by frozen file not found"),
- m4_get_symbol_value_placeholder (value));
- else
+ unsigned int trace_start = 0;
+
+ if (argv->info->trace)
+ trace_start = trace_pre (context, argv);
+ if (!m4_bad_argc (context, argv->argc, argv->argv0,
+ VALUE_MIN_ARGS (value), VALUE_MAX_ARGS (value),
+ BIT_TEST (VALUE_FLAGS (value),
+ VALUE_SIDE_EFFECT_ARGS_BIT)))
{
- assert (!"m4_macro_call");
- abort ();
+ if (m4_is_symbol_value_text (value))
+ process_macro (context, value, expansion, argv->argc, argv);
+ else if (m4_is_symbol_value_func (value))
+ m4_get_symbol_value_func (value) (context, expansion, argv->argc,
+ argv);
+ else if (m4_is_symbol_value_placeholder (value))
+ m4_warn (context, 0, M4ARG (0),
+ _("builtin `%s' requested by frozen file not found"),
+ m4_get_symbol_value_placeholder (value));
+ else
+ {
+ assert (!"m4_macro_call");
+ abort ();
+ }
}
+ if (argv->info->trace)
+ trace_post (context, trace_start, argv->info);
}
/* This function handles all expansion of user defined and predefined
@@ -881,91 +868,106 @@ trace_format (m4 *context, const char *fmt, ...)
va_end (args);
}
-/* Format the standard header attached to all tracing output lines. */
-static void
-trace_header (m4 *context, size_t id)
+/* Format the standard header attached to all tracing output lines,
+ using the context in INFO as appropriate. Return the offset into
+ the trace obstack where this particular trace begins. */
+static unsigned int
+trace_header (m4 *context, const m4_call_info *info)
{
+ unsigned int result = obstack_object_size (&context->trace_messages);
trace_format (context, "m4trace:");
- if (m4_get_current_line (context))
- {
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_FILE))
- trace_format (context, "%s:", m4_get_current_file (context));
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_LINE))
- trace_format (context, "%d:", m4_get_current_line (context));
- }
+ if (info->debug_level & M4_DEBUG_TRACE_FILE)
+ trace_format (context, "%s:", info->file);
+ if (info->debug_level & M4_DEBUG_TRACE_LINE)
+ trace_format (context, "%d:", info->line);
trace_format (context, " -%zu- ", context->expansion_level);
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_CALLID))
- trace_format (context, "id %zu: ", id);
+ if (info->debug_level & M4_DEBUG_TRACE_CALLID)
+ trace_format (context, "id %zu: ", info->call_id);
+ return result;
}
-/* Print current tracing line, and clear the obstack. */
+/* Print current tracing line starting at offset START, as returned
+ from an earlier trace_header(), then clear the obstack. */
static void
-trace_flush (m4 *context)
+trace_flush (m4 *context, unsigned int start)
{
- char *line;
-
- obstack_1grow (&context->trace_messages, '\n');
- obstack_1grow (&context->trace_messages, '\0');
- line = obstack_finish (&context->trace_messages);
- if (m4_get_debug_file (context))
- fputs (line, m4_get_debug_file (context));
- obstack_free (&context->trace_messages, line);
+ char *str;
+ FILE *file = m4_get_debug_file (context);
+
+ if (file)
+ {
+ obstack_1grow (&context->trace_messages, '\0');
+ str = (char *) obstack_base (&context->trace_messages);
+ fprintf (file, "%s\n", &str[start]);
+ }
+ start -= obstack_object_size (&context->trace_messages);
+ obstack_blank (&context->trace_messages, start);
}
-/* Do pre-argument-collection tracing for macro NAME. Used from
- expand_macro (). */
-static void
-trace_prepre (m4 *context, const char *name, size_t id, m4_symbol_value *value)
+/* Do pre-argument-collection tracing for the macro described in INFO.
+ Should be called prior to m4_macro_call(). */
+void
+m4_trace_prepare (m4 *context, const m4_call_info *info,
+ m4_symbol_value *value)
{
const m4_string_pair *quotes = NULL;
size_t arg_length = m4_get_max_debug_arg_length_opt (context);
- bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
+ bool module = (info->debug_level & M4_DEBUG_TRACE_MODULE) != 0;
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE))
+ if (info->debug_level & M4_DEBUG_TRACE_QUOTE)
quotes = m4_get_syntax_quotes (M4SYNTAX);
- trace_header (context, id);
- trace_format (context, "%s ... = ", name);
- m4__symbol_value_print (context, value, &context->trace_messages, quotes,
- false, NULL, &arg_length, module);
- trace_flush (context);
+ if (info->trace && (info->debug_level & M4_DEBUG_TRACE_CALL))
+ {
+ unsigned int start = trace_header (context, info);
+ trace_format (context, "%s ... = ", info->name);
+ m4__symbol_value_print (context, value, &context->trace_messages, quotes,
+ false, NULL, &arg_length, module);
+ trace_flush (context, start);
+ }
}
-/* Format the parts of a trace line, that can be made before the macro is
- actually expanded. Used from expand_macro (). */
-static void
-trace_pre (m4 *context, size_t id, m4_macro_args *argv)
+/* Format the parts of a trace line that are known via ARGV before the
+ macro is actually expanded. Used from m4_macro_call(). Return the
+ start of the current trace, in case other traces are printed before
+ this trace completes trace_post. */
+static unsigned int
+trace_pre (m4 *context, m4_macro_args *argv)
{
- trace_header (context, id);
+ int trace_level = argv->info->debug_level;
+ unsigned int start = trace_header (context, argv->info);
+
+ assert (argv->info->trace);
trace_format (context, "%s", M4ARG (0));
- if (1 < m4_arg_argc (argv) && m4_is_debug_bit (context, M4_DEBUG_TRACE_ARGS))
+ if (1 < m4_arg_argc (argv) && (trace_level & M4_DEBUG_TRACE_ARGS))
{
const m4_string_pair *quotes = NULL;
size_t arg_length = m4_get_max_debug_arg_length_opt (context);
- bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
+ bool module = (trace_level & M4_DEBUG_TRACE_MODULE) != 0;
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE))
+ if (trace_level & M4_DEBUG_TRACE_QUOTE)
quotes = m4_get_syntax_quotes (M4SYNTAX);
trace_format (context, "(");
m4__arg_print (context, &context->trace_messages, argv, 1, quotes, false,
NULL, ", ", &arg_length, true, module);
trace_format (context, ")");
}
+ return start;
}
-/* Format the final part of a trace line and print it all. Used from
- expand_macro (). */
+/* If requested by the trace state in INFO, format the final part of a
+ trace line. Then print all collected information from START,
+ returned from a prior trace_pre(). Used from m4_macro_call (). */
static void
-trace_post (m4 *context, size_t id, m4_macro_args *argv,
- m4_input_block *expanded, bool trace_expansion)
+trace_post (m4 *context, unsigned int start, const m4_call_info *info)
{
- if (trace_expansion)
+ assert (info->trace);
+ if (info->debug_level & M4_DEBUG_TRACE_EXPANSION)
{
trace_format (context, " -> ");
- m4_input_print (context, &context->trace_messages, expanded);
+ m4_input_print (context, &context->trace_messages, info->debug_level);
}
-
- trace_flush (context);
+ trace_flush (context, start);
}
@@ -1586,23 +1588,24 @@ m4__arg_print (m4 *context, m4_obstack *obs,
m4_macro_args *argv, size_t arg,
/* Create a new argument object using the same obstack as ARGV; thus,
the new object will automatically be freed when the original is
freed. Explicitly set the macro name (argv[0]) from ARGV0 with
- length ARGV0_LEN. If SKIP, set argv[1] of the new object to
- argv[2] of the old, otherwise the objects share all arguments. If
+ length ARGV0_LEN, and discard argv[1] of the wrapped ARGV. If
FLATTEN, any builtins in ARGV are flattened to an empty string when
- referenced through the new object. */
+ referenced through the new object. If TRACE, then trace the macro
+ regardless of global trace state. */
m4_macro_args *
m4_make_argv_ref (m4 *context, m4_macro_args *argv, const char *argv0,
- size_t argv0_len, bool skip, bool flatten)
+ size_t argv0_len, bool flatten, bool trace)
{
m4_macro_args *new_argv;
m4_symbol_value *value;
m4_symbol_value *new_value;
- size_t arg = skip ? 2 : 1;
m4_obstack *obs = m4_arg_scratch (context);
+ m4_call_info *info;
+ info = (m4_call_info *) obstack_copy (obs, argv->info, sizeof *info);
new_value = (m4_symbol_value *) obstack_alloc (obs, sizeof *value);
value = make_argv_ref (context, new_value, obs, context->expansion_level - 1,
- argv, arg, flatten, NULL);
+ argv, 2, flatten, NULL);
if (!value)
{
obstack_free (obs, new_value);
@@ -1626,11 +1629,15 @@ m4_make_argv_ref (m4 *context, m4_macro_args *argv,
const char *argv0,
new_argv->flatten = flatten;
new_argv->has_func = argv->has_func;
}
- new_argv->argc = argv->argc - (arg - 1);
+ new_argv->argc = argv->argc - 1;
new_argv->inuse = false;
new_argv->argv0 = argv0;
new_argv->argv0_len = argv0_len;
new_argv->quote_age = argv->quote_age;
+ new_argv->info = info;
+ info->trace = (argv->info->debug_level & M4_DEBUG_TRACE_ALL) || trace;
+ info->name = argv0;
+ info->name_len = argv0_len;
new_argv->level = argv->level;
return new_argv;
}
@@ -1780,6 +1787,17 @@ m4_arg_argc (m4_macro_args *argv)
return argv->argc;
}
+/* Given ARGV, return the call context in effect when argument
+ collection began. Only safe to call while the macro is being
+ expanded. */
+#undef m4_arg_info
+const m4_call_info *
+m4_arg_info (m4_macro_args *argv)
+{
+ assert (argv->info);
+ return argv->info;
+}
+
/* Return an obstack useful for scratch calculations, and which will
not interfere with macro expansion. The obstack will be reset when
expand_macro completes. */
diff --git a/modules/gnu.c b/modules/gnu.c
index f0d3a44..c28a100 100644
--- a/modules/gnu.c
+++ b/modules/gnu.c
@@ -447,7 +447,7 @@ M4BUILTIN_HANDLER (builtin)
m4_macro_args *new_argv;
bool flatten = (bp->flags & M4_BUILTIN_FLATTEN_ARGS) != 0;
new_argv = m4_make_argv_ref (context, argv, name, M4ARGLEN (1),
- true, flatten);
+ flatten, false);
bp->func (context, obs, argc - 1, new_argv);
}
free (value);
@@ -680,10 +680,12 @@ M4BUILTIN_HANDLER (indir)
else
{
m4_macro_args *new_argv;
+ m4_symbol_value *value = m4_get_symbol_value (symbol);
new_argv = m4_make_argv_ref (context, argv, name, M4ARGLEN (1),
- true, m4_symbol_flatten_args (symbol));
- m4_macro_call (context, m4_get_symbol_value (symbol), obs,
- argc - 1, new_argv);
+ m4_symbol_flatten_args (symbol),
+ m4_get_symbol_traced (symbol));
+ m4_trace_prepare (context, m4_arg_info (new_argv), value);
+ m4_macro_call (context, value, obs, new_argv);
}
}
}
diff --git a/src/main.c b/src/main.c
index 7c3b9cc..e500046 100644
--- a/src/main.c
+++ b/src/main.c
@@ -156,7 +156,7 @@ Debugging:\n\
fputs (_("\
FLAGS is any of:\n\
a show actual arguments in trace\n\
- c show definition line in trace\n\
+ c show collection line in trace\n\
e show expansion in trace\n\
f include current input file name in trace and debug\n\
i show changes in input files in debug\n\
@@ -165,9 +165,9 @@ FLAGS is any of:\n\
fputs (_("\
m show module information in trace, debug, and dumpdef\n\
p show results of path searches in debug\n\
- q quote values as necessary in dumpdef and trace, useful with a or e\n\
+ q quote values in dumpdef and trace, useful with a or e\n\
s show full stack of pushdef values in dumpdef\n\
- t trace all macro calls, regardless of named traceon state\n\
+ t trace all macro calls, regardless of per-macro traceon state\n\
x include unique macro call id in trace, useful with c\n\
V shorthand for all of the above flags\n\
"), stdout);
diff --git a/tests/macros.at b/tests/macros.at
index c4db9e6..fe42518 100644
--- a/tests/macros.at
+++ b/tests/macros.at
@@ -356,7 +356,7 @@ m4trace: -2- eval(`1<=1') -> `1'
m4trace: -1- ifelse(`1', `1', `move(auxilliary, destination)',
`_hanoi(decr(1), auxilliary, source, destination)move(auxilliary,
destination)_hanoi(decr(1), source, destination, auxilliary)') ->
`move(auxilliary, destination)'
m4trace: -1- move(`auxilliary', `destination') -> `Move one disk from
`auxilliary' to `destination'.
'
-m4trace: -1- debugmode -> @&t@
+m4trace: -1- debugmode -> `'
m4trace: -1- _hanoi(2, source, destination, auxilliary) ->
ifelse(eval(`2'<=1), 1, `move(source, destination)',
`_hanoi(decr(2), source, auxilliary, destination)move(source,
destination)_hanoi(decr(2), auxilliary, destination, source)')
m4trace: -1- _hanoi(1, source, auxilliary, destination) ->
ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
diff --git a/tests/null.err b/tests/null.err
index 61518e8..d825818 100644
Binary files a/tests/null.err and b/tests/null.err differ
diff --git a/tests/null.m4 b/tests/null.m4
index 90e339f..851d665 100644
Binary files a/tests/null.m4 and b/tests/null.m4 differ
hooks/post-receive
--
GNU M4 source repository
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] GNU M4 source repository branch, master, updated. cvs-readonly-110-gb9738ad,
Eric Blake <=