[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: dumpdef a pushdef'd stack
From: |
Eric Blake |
Subject: |
Re: dumpdef a pushdef'd stack |
Date: |
Wed, 27 Sep 2006 07:20:19 -0600 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909 Thunderbird/1.5.0.7 Mnenhy/0.7.4.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
According to Eric Blake on 9/26/2006 2:51 PM:
> As mentioned in the second half of: http://lists.gnu.org/archive/html/m4-
> patches/2006-09/msg00027.html
>
> 2006-09-26 Eric Blake <address@hidden>
>
> * m4/m4module.h (m4_symbol_print): New prototype.
And in followup, I noticed that macro.c was doing some code duplication.
Even worse, our testsuite did not have ANY coverage of the -l/--arglength
option. The patch below tweaks the semantics of -l slightly, and adds
tests accordingly.
I would like to do a followup to this patch, which does three things.
First, --arglength currently does not validate its numeric argument, so
'm4 -loops' is equivalent to 'm4 -l0'; I'd like to see the first case at
least warn on the invalid argument. Second, I'd like to simplify
trace_format in macro.c - using non-standard format modifiers like %l for
optional left quote and %S for length-limited string just looks weird.
The current patch removed one of these uses (debugmode(a)), but not the
other (debugmode(e)).
Third, now that --arglength can affect dumpdef output as well as trace
output, we should be able to tweak it on the fly. I'm thinking a macro
named debuglen is the best fit here (fitting in with the naming of other
debug* builtins), but I could also be persuaded to name the macro
arglength to match the command-line option. Or maybe name it debuglen,
deprecate --arglength (as that name isn't quite descriptive of what is
really being length-limited), and introduce --debuglen as a synonym to -l.
Thoughts?
2006-09-27 Eric Blake <address@hidden>
* ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
strnlen.
* m4/symtab.c (symbol_value_print): Rename to...
(m4_symbol_value_print): ...this, and...
(m4_symbol_print): Update to allow -L length truncation. Now
truncation also affects dumpdef output and builtin names.
* m4/m4private.h (nesting_limit, max_debug_argument_length):
Switch to size_t.
* m4/m4module.h (m4_symbol_print): Add parameter.
(m4_symbol_value_print): New function.
* modules/m4.c (dumpdef): Allow length truncation.
* m4/macro.c (trace_pre): Use m4_symbol_print, rather than
repeating code.
* doc/m4.texinfo (Invoking m4): Document -l better.
(Dumpdef, Debug Levels): Document the effect of -l.
* NEWS: Document this change.
- --
Life is short - so eat dessert first!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFFGnqS84KuGfSFAYARAsJBAJ933m7giRteAB2HheebIy6th8SsqwCgj/AL
mQT+zK5jNYFeKQ43MO6Znlw=
=ygUs
-----END PGP SIGNATURE-----
? ltdl/m4/double-slash-root.m4
Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.20
diff -u -p -r1.20 NEWS
--- NEWS 26 Sep 2006 21:21:50 -0000 1.20
+++ NEWS 27 Sep 2006 13:06:27 -0000
@@ -94,6 +94,9 @@ promoted to 2.0.
either be blind (ie. be unrecognized without arguments), or begin with
the prefix `m4' or `__'.
+* The `-l'/`--arglength' command line argument now affects dumpdef
+ output as well as trace output.
+
* FIXME: `m4wrap' semantics need an update to FIFO.
* FIXME: include the (long) list of changes in 1.4.x that were not already
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.52
diff -u -p -r1.52 m4.texinfo
--- doc/m4.texinfo 26 Sep 2006 21:21:50 -0000 1.52
+++ doc/m4.texinfo 27 Sep 2006 13:06:29 -0000
@@ -692,9 +692,13 @@ future release.
@item -l @var{NUM}
@itemx address@hidden
-Restrict the size of the output generated by macro tracing to @var{NUM}
-characters per trace line. If unspecified or zero, output is
-unlimited. @xref{Debug Levels}, for more details.
+Restrict the size of the output generated by macro tracing or by
address@hidden to @var{NUM} characters per string. If unspecified or
+zero, output is unlimited. @xref{Debug Levels}, for more details.
address@hidden FIXME - should we add a debuglen macro that can alter this
address@hidden setting on the fly? Also, should we add an option that
address@hidden controls whether output strings are sanitized with escape
address@hidden sequences, so that dumpdef is truly one line per macro?
@item -t @var{NAME}
@itemx address@hidden
@@ -2640,19 +2644,22 @@ f(popdef(`f')dumpdef(`f'))
@xref{Debug Levels}, for information on how the @samp{q} and @samp{s}
flags affect the details of the display. Remember, the @samp{q} flag is
-implied when @option{-d} is used in the command line without arguments.
+implied when the @option{--debug} option (@option{-d}, @pxref{Invoking
+m4}) is used in the command line without arguments. Also, the
address@hidden option (@option{-l}) can affect output, by
+truncating longer strings.
address@hidden options: -ds
address@hidden options: -ds -l3
@example
-$ @kbd{m4 -ds}
-pushdef(`foo', `1')
+$ @kbd{m4 -ds -l 3}
+pushdef(`foo', `1 long string')
@result{}
pushdef(`foo', defn(`divnum'))
@result{}
pushdef(`foo', `3')
@result{}
dumpdef(`foo')
address@hidden:@tabchar{}3, <divnum>, 1
address@hidden:@tabchar{}3, <div...>, 1 l...
@result{}
@end example
@@ -2883,7 +2890,9 @@ following:
@table @code
@item a
In trace output, show the actual arguments that were collected before
-invoking the macro.
+invoking the macro. Arguments are subject to length truncation
+specified by the command line option @option{--arglength}
+(@option{-l}).
@item c
In trace output, show several trace lines for each macro call. A line
@@ -2893,7 +2902,8 @@ after the call has completed.
@item e
In trace output, show the expansion of each macro call, if it is not
-void.
+void. The expansion is subject to length truncation specified by the
+command line option @option{--arglength} (@option{-l}).
@item f
In debug and trace output, include the name of the current input file in
@@ -2948,6 +2958,26 @@ If no flags are specified with the @opti
@samp{aeq}. Many examples in this manual show their output using
default flags.
address@hidden FIXME - add a new macro debuglen (or some other spelling) that
address@hidden allows changing the -l/--arglength option on the fly? If so,
address@hidden add a new node here describing it.
+Also, the option @option{--arglength} (@option{-l}) can affect trace
+and dumpdef output. If the option is specified to a non-zero value,
+then strings longer than that length are truncated, and @samp{...}
+included in the output to show that truncation took place. This allows
+reducing the size of the debug output in the face of arbitrarily long
+macro arguments or definitions.
+
address@hidden options: -l4 -techo
address@hidden
+$ @kbd{m4 -d -l 4 -t echo}
+define(`echo', `$@')
address@hidden
+echo(`long string')
address@hidden: -1- echo(`long...') -> ``lon...'
address@hidden string
address@hidden example
+
@cindex @acronym{GNU} extensions
There is a builtin macro @code{debugmode}, which allows on-the-fly control of
the debugging output format:
Index: ltdl/m4/gnulib-cache.m4
===================================================================
RCS file: /sources/m4/m4/ltdl/m4/gnulib-cache.m4,v
retrieving revision 1.10
diff -u -p -r1.10 gnulib-cache.m4
--- ltdl/m4/gnulib-cache.m4 1 Sep 2006 23:11:05 -0000 1.10
+++ ltdl/m4/gnulib-cache.m4 27 Sep 2006 13:06:29 -0000
@@ -15,11 +15,11 @@
# Specification in the form of a command-line invocation:
-# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnu
--m4-base=ltdl/m4 --doc-base=doc --aux-dir=ltdl/config --libtool
--macro-prefix=M4 assert binary-io cloexec close-stream dirname error exit fdl
filenamecat fopen-safer free gendocs gettext gnupload mkstemp obstack progname
regex regexprops-generic stdbool stdlib-safer strtol unlocked-io verror xalloc
xalloc-die xstrndup xvasprintf
+# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnu
--m4-base=ltdl/m4 --doc-base=doc --aux-dir=ltdl/config --libtool
--macro-prefix=M4 assert binary-io cloexec close-stream dirname error exit fdl
filenamecat fopen-safer free gendocs gettext gnupload mkstemp obstack progname
regex regexprops-generic stdbool stdlib-safer strnlen strtol unlocked-io verror
xalloc xalloc-die xstrndup xvasprintf
# Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([])
-gl_MODULES([assert binary-io cloexec close-stream dirname error exit fdl
filenamecat fopen-safer free gendocs gettext gnupload mkstemp obstack progname
regex regexprops-generic stdbool stdlib-safer strtol unlocked-io verror xalloc
xalloc-die xstrndup xvasprintf])
+gl_MODULES([assert binary-io cloexec close-stream dirname error exit fdl
filenamecat fopen-safer free gendocs gettext gnupload mkstemp obstack progname
regex regexprops-generic stdbool stdlib-safer strnlen strtol unlocked-io verror
xalloc xalloc-die xstrndup xvasprintf])
gl_AVOID([])
gl_SOURCE_BASE([gnu])
gl_M4_BASE([ltdl/m4])
Index: m4/m4module.h
===================================================================
RCS file: /sources/m4/m4/m4/m4module.h,v
retrieving revision 1.87
diff -u -p -r1.87 m4module.h
--- m4/m4module.h 26 Sep 2006 21:21:50 -0000 1.87
+++ m4/m4module.h 27 Sep 2006 13:06:29 -0000
@@ -137,9 +137,9 @@ extern void m4_delete (m4 *);
M4FIELD(m4_obstack, trace_messages, trace_messages) \
M4FIELD(int, exit_status, exit_status) \
M4FIELD(bool, no_gnu_extensions_opt, no_gnu_extensions) \
- M4FIELD(int, nesting_limit_opt, nesting_limit) \
+ M4FIELD(size_t, nesting_limit_opt, nesting_limit) \
M4FIELD(int, debug_level_opt, debug_level) \
- M4FIELD(int, max_debug_arg_length_opt, max_debug_arg_length)\
+ M4FIELD(size_t, max_debug_arg_length_opt, max_debug_arg_length)\
M4FIELD(int, regexp_syntax_opt, regexp_syntax) \
@@ -216,8 +216,11 @@ extern m4_symbol_value *m4_get_symbol_va
extern bool m4_get_symbol_traced (m4_symbol*);
extern bool m4_set_symbol_name_traced (m4_symbol_table*,
const char *, bool);
-extern void m4_symbol_print (m4_symbol *, m4_obstack *, bool,
- const char *, const char *, bool);
+extern void m4_symbol_value_print (m4_symbol_value *, m4_obstack *, bool,
+ const char *, const char *, size_t);
+extern void m4_symbol_print (m4_symbol *, m4_obstack *, bool,
+ const char *, const char *, bool,
+ size_t);
#define m4_is_symbol_void(symbol) \
(m4_is_symbol_value_void (m4_get_symbol_value (symbol)))
Index: m4/m4private.h
===================================================================
RCS file: /sources/m4/m4/m4/m4private.h,v
retrieving revision 1.63
diff -u -p -r1.63 m4private.h
--- m4/m4private.h 26 Sep 2006 13:19:26 -0000 1.63
+++ m4/m4private.h 27 Sep 2006 13:06:29 -0000
@@ -63,9 +63,9 @@ struct m4 {
/* Option flags (set in src/main.c). */
bool no_gnu_extensions; /* -G */
- int nesting_limit; /* -L */
+ size_t nesting_limit; /* -L */
int debug_level; /* -d */
- int max_debug_arg_length; /* -l */
+ size_t max_debug_arg_length; /* -l */
int regexp_syntax; /* -r */
int opt_flags;
Index: m4/macro.c
===================================================================
RCS file: /sources/m4/m4/m4/macro.c,v
retrieving revision 1.54
diff -u -p -r1.54 macro.c
--- m4/macro.c 27 Sep 2006 12:24:53 -0000 1.54
+++ m4/macro.c 27 Sep 2006 13:06:29 -0000
@@ -188,8 +188,8 @@ expand_argument (m4 *context, m4_obstack
break;
case M4_TOKEN_EOF:
- m4_error_at_line (context, EXIT_FAILURE, 0, file, line,
- _("end of file in argument list"));
+ m4_error_at_line (context, EXIT_FAILURE, 0, file, line,
+ _("end of file in argument list"));
break;
case M4_TOKEN_WORD:
@@ -608,45 +608,25 @@ trace_pre (m4 *context, const char *name
int argc, m4_symbol_value **argv)
{
int i;
- const m4_builtin *bp;
trace_header (context, id);
trace_format (context, "%s", name);
if ((argc > 1) && m4_is_debug_bit (context, M4_DEBUG_TRACE_ARGS))
{
- trace_format (context, "(");
+ bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
+ const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
+ const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
+ size_t arg_length = m4_get_max_debug_arg_length_opt (context);
+ trace_format (context, "(");
for (i = 1; i < argc; i++)
{
if (i != 1)
trace_format (context, ", ");
- if (m4_is_symbol_value_text (argv[i]))
- {
- trace_format (context, "%l%S%r", M4ARG (i));
- }
- else if (m4_is_symbol_value_func (argv[i]))
- {
- bp = m4_builtin_find_by_func (NULL,
- m4_get_symbol_value_func(argv[i]));
- if (bp == NULL)
- {
- assert (!"INTERNAL ERROR: builtin not found in table!");
- abort ();
- }
- trace_format (context, "<%s>", bp->name);
- }
- else if (m4_is_symbol_value_placeholder (argv[i]))
- {
- trace_format (context, "<placeholder for %s>",
- m4_get_symbol_value_placeholder (argv[i]));
- }
- else
- {
- assert (!"INTERNAL ERROR: bad token data type (trace_pre ())");
- abort ();
- }
+ m4_symbol_value_print (argv[i], &context->trace_messages,
+ quote, lquote, rquote, arg_length);
}
trace_format (context, ")");
}
Index: m4/symtab.c
===================================================================
RCS file: /sources/m4/m4/m4/symtab.c,v
retrieving revision 1.61
diff -u -p -r1.61 symtab.c
--- m4/symtab.c 26 Sep 2006 21:21:50 -0000 1.61
+++ m4/symtab.c 27 Sep 2006 13:06:29 -0000
@@ -20,6 +20,8 @@
#include "m4private.h"
+#include "strnlen.h"
+
/* Define this to see runtime debug info. Implied by DEBUG. */
/*#define DEBUG_SYM */
@@ -57,8 +59,6 @@ static void * arg_destroy_CB (m4_hash
void *arg, void *ignored);
static void * arg_copy_CB (m4_hash *src, const void *name,
void *arg, m4_hash *dest);
-static void symbol_value_print (m4_symbol_value *, m4_obstack *, bool,
- const char *, const char *);
/* -- SYMBOL TABLE MANAGEMENT --
@@ -463,54 +463,63 @@ m4_set_symbol_name_traced (m4_symbol_tab
}
/* Grow OBS with a text representation of VALUE. If QUOTE, then
- surround a text definition by LQUOTE and RQUOTE. */
-static void
-symbol_value_print (m4_symbol_value *value, m4_obstack *obs, bool quote,
- const char *lquote, const char *rquote)
+ surround a text definition by LQUOTE and RQUOTE. If ARG_LENGTH is
+ non-zero, then truncate text definitions to that length. */
+void
+m4_symbol_value_print (m4_symbol_value *value, m4_obstack *obs, bool quote,
+ const char *lquote, const char *rquote,
+ size_t arg_length)
{
+ const char *text;
+ size_t len;
+
if (m4_is_symbol_value_text (value))
{
- if (quote)
- {
- obstack_grow (obs, lquote, strlen (lquote));
- obstack_grow (obs, m4_get_symbol_value_text (value),
- strlen (m4_get_symbol_value_text (value)));
- obstack_grow (obs, rquote, strlen (rquote));
- }
- else
- obstack_grow (obs, m4_get_symbol_value_text (value),
- strlen (m4_get_symbol_value_text (value)));
+ text = m4_get_symbol_value_text (value);
}
else if (m4_is_symbol_value_func (value))
{
const m4_builtin *bp;
bp = m4_builtin_find_by_func (NULL, m4_get_symbol_value_func (value));
assert (bp);
- obstack_1grow (obs, '<');
- obstack_grow (obs, bp->name, strlen (bp->name));
- obstack_1grow (obs, '>');
+ text = bp->name;
+ lquote = "<";
+ rquote = ">";
+ quote = true;
}
else if (m4_is_symbol_value_placeholder (value))
{
+ text = m4_get_symbol_value_placeholder (value);
/* FIXME - is it worth translating "placeholder for "? */
- obstack_grow (obs, "<placeholder for ", strlen ("<placeholder for "));
- obstack_grow (obs, m4_get_symbol_value_placeholder (value),
- strlen (m4_get_symbol_value_placeholder (value)));
- obstack_1grow (obs, '>');
+ lquote = "<placeholder for ";
+ rquote = ">";
+ quote = true;
}
else
{
assert (!"invalid token in symbol_value_print");
abort ();
}
+
+ len = arg_length ? strnlen (text, arg_length) : strlen (text);
+ if (quote)
+ obstack_grow (obs, lquote, strlen (lquote));
+ obstack_grow (obs, text, len);
+ if (len == arg_length && text[len] != '\0')
+ obstack_grow (obs, "...", 3);
+ if (quote)
+ obstack_grow (obs, rquote, strlen (rquote));
}
/* Grow OBS with a text representation of SYMBOL. If QUOTE, then
- surround each definition by LQUOTE and RQUOTE. If STACK, then
- append all pushdef'd values, rather than just the top. */
+ surround each text definition by LQUOTE and RQUOTE. If STACK, then
+ append all pushdef'd values, rather than just the top. If
+ ARG_LENGTH is non-zero, then truncate text definitions to that
+ length. */
void
m4_symbol_print (m4_symbol *symbol, m4_obstack *obs, bool quote,
- const char *lquote, const char *rquote, bool stack)
+ const char *lquote, const char *rquote, bool stack,
+ size_t arg_length)
{
m4_symbol_value *value;
@@ -518,7 +527,7 @@ m4_symbol_print (m4_symbol *symbol, m4_o
assert (obs);
value = m4_get_symbol_value (symbol);
- symbol_value_print (value, obs, quote, lquote, rquote);
+ m4_symbol_value_print (value, obs, quote, lquote, rquote, arg_length);
if (stack)
{
value = VALUE_NEXT (value);
@@ -526,7 +535,8 @@ m4_symbol_print (m4_symbol *symbol, m4_o
{
obstack_1grow (obs, ',');
obstack_1grow (obs, ' ');
- symbol_value_print (value, obs, quote, lquote, rquote);
+ m4_symbol_value_print (value, obs, quote, lquote, rquote,
+ arg_length);
value = VALUE_NEXT (value);
}
}
Index: modules/m4.c
===================================================================
RCS file: /sources/m4/m4/modules/m4.c,v
retrieving revision 1.74
diff -u -p -r1.74 m4.c
--- modules/m4.c 27 Sep 2006 12:24:53 -0000 1.74
+++ modules/m4.c 27 Sep 2006 13:06:29 -0000
@@ -367,9 +367,10 @@ M4BUILTIN_HANDLER (dumpdef)
{
m4_dump_symbol_data data;
bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
- bool stack = m4_is_debug_bit (context, M4_DEBUG_TRACE_STACK);
const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
+ bool stack = m4_is_debug_bit (context, M4_DEBUG_TRACE_STACK);
+ size_t arg_length = m4_get_max_debug_arg_length_opt (context);
data.obs = obs;
m4_dump_symbols (context, &data, argc, argv, true);
@@ -382,7 +383,7 @@ M4BUILTIN_HANDLER (dumpdef)
obstack_grow (obs, data.base[0], strlen (data.base[0]));
obstack_1grow (obs, ':');
obstack_1grow (obs, '\t');
- m4_symbol_print (symbol, obs, quote, lquote, rquote, stack);
+ m4_symbol_print (symbol, obs, quote, lquote, rquote, stack, arg_length);
obstack_1grow (obs, '\n');
}