[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
dumpdef a pushdef'd stack
From: |
Eric Blake |
Subject: |
dumpdef a pushdef'd stack |
Date: |
Tue, 26 Sep 2006 20:51:11 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
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.
(M4_DEBUG_TRACE_STACK): New enumerator.
(m4_is_debug_bit): Allow use without requiring m4private.h.
* m4/symtab.c (symbol_value_print, m4_symbol_print): New
functions.
* modules/m4.c (dump_symbol_CB, m4_dump_symbols): Speed up
callback.
(dumpdef): Allow printing pushdef'd stacks.
* m4/debug.c (m4_debug_decode): Add new 's' debug mode.
* src/main.c (usage): Document it.
* doc/m4.texinfo (Dumpdef, Debug Levels): Likewise.
* NEWS: Likewise.
Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.19
diff -u -r1.19 NEWS
--- NEWS 21 Sep 2006 04:12:55 -0000 1.19
+++ NEWS 26 Sep 2006 20:37:23 -0000
@@ -59,9 +59,10 @@
standard error are terminals.
* New `m' flag to `-d'/`--debug' option or `debugmode' macro traces
- actions related to module loading and unloading. Also, the `--debug'
- option now understands `-' and `+' modifiers, the way `debugmode' has
- always done.
+ actions related to module loading and unloading. New `s' flag shows the
+ entire stack of `pushdef' definitions during `dumpdef'. Also, the
+ `--debug' option now understands `-' and `+' modifiers, the way
+ `debugmode' has always done.
* The semantics of `traceon' and `traceoff' now match traditional
implementations: when called without arguments, they affect global state
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.51
diff -u -r1.51 m4.texinfo
--- doc/m4.texinfo 21 Sep 2006 16:40:03 -0000 1.51
+++ doc/m4.texinfo 26 Sep 2006 20:37:23 -0000
@@ -2638,9 +2638,23 @@
@result{}f1
@end example
address@hidden Levels}, for information on controlling the details of the
-display; in particular, the @samp{q} flag, implied by @option{-d} in the
-example command line, has an impact.
address@hidden 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.
+
address@hidden options: -ds
address@hidden
+$ @kbd{m4 -ds}
+pushdef(`foo', `1')
address@hidden
+pushdef(`foo', defn(`divnum'))
address@hidden
+pushdef(`foo', `3')
address@hidden
+dumpdef(`foo')
address@hidden:@tabchar{}3, <divnum>, 1
address@hidden
address@hidden example
@node Trace
@section Tracing macro calls
@@ -2900,6 +2914,10 @@
current quotes. This affects traced macros, as well as @code{dumpdef}
output.
address@hidden s
+Show the entire stack of definitions associated with a symbol via
address@hidden This affects @code{dumpdef} output.
+
@item t
Trace all macro calls made in this invocation of @code{m4}. This is
equivalent to using @code{traceon} without arguments.
Index: m4/debug.c
===================================================================
RCS file: /sources/m4/m4/m4/debug.c,v
retrieving revision 1.25
diff -u -r1.25 debug.c
--- m4/debug.c 19 Sep 2006 13:16:08 -0000 1.25
+++ m4/debug.c 26 Sep 2006 20:37:23 -0000
@@ -89,6 +89,10 @@
level |= M4_DEBUG_TRACE_MODULE;
break;
+ case 's':
+ level |= M4_DEBUG_TRACE_STACK;
+ break;
+
case 'V':
level |= M4_DEBUG_TRACE_VERBOSE;
break;
Index: m4/m4module.h
===================================================================
RCS file: /sources/m4/m4/m4/m4module.h,v
retrieving revision 1.86
diff -u -r1.86 m4module.h
--- m4/m4module.h 18 Sep 2006 13:16:44 -0000 1.86
+++ m4/m4module.h 26 Sep 2006 20:37:23 -0000
@@ -113,10 +113,10 @@
/* Error handling. */
extern void m4_error (m4 *, int, int, const char *, ...) M4_GNUC_PRINTF (4, 5);
extern void m4_error_at_line (m4 *, int, int, const char *, int,
- const char *, ...) M4_GNUC_PRINTF (6, 7);
-extern void m4_warn (m4 *, int, const char *, ...) M4_GNUC_PRINTF (3, 4);
+ const char *, ...) M4_GNUC_PRINTF (6, 7);
+extern void m4_warn (m4 *, int, const char *, ...) M4_GNUC_PRINTF (3, 4);
extern void m4_warn_at_line (m4 *, int, const char *, int,
- const char *, ...) M4_GNUC_PRINTF (5, 6);
+ const char *, ...) M4_GNUC_PRINTF (5, 6);
/* --- CONTEXT MANAGEMENT --- */
@@ -216,6 +216,8 @@
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);
#define m4_is_symbol_void(symbol) \
(m4_is_symbol_value_void (m4_get_symbol_value (symbol)))
@@ -294,16 +296,18 @@
M4_DEBUG_TRACE_CALLID = (1 << 9),
/* m: trace module actions */
M4_DEBUG_TRACE_MODULE = (1 << 10),
+ /* s: trace pushdef stacks */
+ M4_DEBUG_TRACE_STACK = (1 << 11),
/* V: very verbose -- print everything */
- M4_DEBUG_TRACE_VERBOSE = ((1 << 11) - 1)
+ M4_DEBUG_TRACE_VERBOSE = ((1 << 12) - 1)
};
/* default flags -- equiv: aeq */
#define M4_DEBUG_TRACE_DEFAULT \
- (M4_DEBUG_TRACE_ARGS|M4_DEBUG_TRACE_EXPANSION|M4_DEBUG_TRACE_QUOTE)
+ (M4_DEBUG_TRACE_ARGS | M4_DEBUG_TRACE_EXPANSION | M4_DEBUG_TRACE_QUOTE)
-#define m4_is_debug_bit(C,B) (BIT_TEST (m4_get_debug_level_opt (C), (B)))
+#define m4_is_debug_bit(C,B) ((m4_get_debug_level_opt (C) & (B)) != 0)
extern int m4_debug_decode (m4 *, int, const char *);
extern bool m4_debug_set_output (m4 *, const char *);
Index: m4/symtab.c
===================================================================
RCS file: /sources/m4/m4/m4/symtab.c,v
retrieving revision 1.60
diff -u -r1.60 symtab.c
--- m4/symtab.c 18 Sep 2006 13:16:44 -0000 1.60
+++ m4/symtab.c 26 Sep 2006 20:37:23 -0000
@@ -57,7 +57,8 @@
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 --
@@ -461,6 +462,76 @@
return result;
}
+/* 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)
+{
+ 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)));
+ }
+ 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, '>');
+ }
+ else if (m4_is_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, '>');
+ }
+ else
+ {
+ assert (!"invalid token in symbol_value_print");
+ abort ();
+ }
+}
+
+/* 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. */
+void
+m4_symbol_print (m4_symbol *symbol, m4_obstack *obs, bool quote,
+ const char *lquote, const char *rquote, bool stack)
+{
+ m4_symbol_value *value;
+
+ assert (symbol);
+ assert (obs);
+
+ value = m4_get_symbol_value (symbol);
+ symbol_value_print (value, obs, quote, lquote, rquote);
+ if (stack)
+ {
+ value = VALUE_NEXT (value);
+ while (value)
+ {
+ obstack_1grow (obs, ',');
+ obstack_1grow (obs, ' ');
+ symbol_value_print (value, obs, quote, lquote, rquote);
+ value = VALUE_NEXT (value);
+ }
+ }
+}
+
/* Define these functions at the end, so that calls in the file use the
faster macro version from m4module.h. */
Index: modules/m4.c
===================================================================
RCS file: /sources/m4/m4/modules/m4.c,v
retrieving revision 1.72
diff -u -r1.72 m4.c
--- modules/m4.c 26 Sep 2006 13:19:26 -0000 1.72
+++ modules/m4.c 26 Sep 2006 20:37:23 -0000
@@ -305,16 +305,22 @@
dump_symbol_CB (m4_symbol_table *ignored, const char *name, m4_symbol *symbol,
void *userdata)
{
+ m4_dump_symbol_data *symbol_data = (m4_dump_symbol_data *) userdata;
+
assert (name);
assert (symbol);
+ assert (!m4_is_symbol_value_void (m4_get_symbol_value (symbol)));
- if (!m4_is_symbol_value_void (m4_get_symbol_value (symbol)))
+ if (symbol_data->size == 0)
{
- m4_dump_symbol_data *symbol_data = (m4_dump_symbol_data *) userdata;
-
- obstack_blank (symbol_data->obs, sizeof (const char *));
- symbol_data->base = (const char **) obstack_base (symbol_data->obs);
- symbol_data->base[symbol_data->size++] = (const char *) name;
+ obstack_ptr_grow (symbol_data->obs, name);
+ symbol_data->size = (obstack_room (symbol_data->obs)
+ / sizeof (const char *));
+ }
+ else
+ {
+ obstack_ptr_grow_fast (symbol_data->obs, name);
+ symbol_data->size--;
}
return NULL;
@@ -326,8 +332,7 @@
m4_dump_symbols (m4 *context, m4_dump_symbol_data *data, int argc,
m4_symbol_value **argv, bool complain)
{
- data->base = (const char **) obstack_base (data->obs);
- data->size = 0;
+ data->size = obstack_room (data->obs) / sizeof (const char *);
if (argc == 1)
{
@@ -341,19 +346,17 @@
for (i = 1; i < argc; i++)
{
symbol = m4_symbol_lookup (M4SYMTAB, M4ARG (i));
- if (symbol != NULL
- && !m4_is_symbol_value_void (m4_get_symbol_value (symbol)))
- {
- dump_symbol_CB (NULL, M4ARG (i), symbol, data);
- }
+ if (symbol != NULL)
+ dump_symbol_CB (NULL, M4ARG (i), symbol, data);
else if (complain)
m4_warn (context, 0, _("%s: undefined macro `%s'"),
M4ARG (0), M4ARG (i));
}
}
- obstack_finish (data->obs);
- qsort ((void*) data->base, data->size, sizeof (const char*), dumpdef_cmp_CB);
+ data->size = obstack_object_size (data->obs) / sizeof (const char *);
+ data->base = (const char **) obstack_finish (data->obs);
+ qsort (data->base, data->size, sizeof (const char *), dumpdef_cmp_CB);
}
@@ -362,7 +365,10 @@
M4BUILTIN_HANDLER (dumpdef)
{
m4_dump_symbol_data data;
- const m4_builtin *bp;
+ 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);
data.obs = obs;
m4_dump_symbols (context, &data, argc, argv, true);
@@ -370,37 +376,18 @@
for (; data.size > 0; --data.size, data.base++)
{
m4_symbol *symbol = m4_symbol_lookup (M4SYMTAB, data.base[0]);
+ assert (symbol);
- fprintf (stderr, "%s:\t", data.base[0]);
-
- if (m4_is_symbol_text (symbol))
- {
- if (m4_get_debug_level_opt (context) & M4_DEBUG_TRACE_QUOTE)
- fprintf (stderr, "%s%s%s\n",
- m4_get_syntax_lquote (M4SYNTAX),
- m4_get_symbol_text (symbol),
- m4_get_syntax_rquote (M4SYNTAX));
- else
- fprintf (stderr, "%s\n", m4_get_symbol_text (symbol));
- }
- else if (m4_is_symbol_func (symbol))
- {
- bp = m4_builtin_find_by_func (NULL,
- m4_get_symbol_func (symbol));
- assert (bp);
- fprintf (stderr, "<%s>\n", bp->name);
- }
- else if (m4_is_symbol_placeholder (symbol))
- {
- fprintf (stderr, "<placeholder for %s>\n",
- m4_get_symbol_placeholder (symbol));
- }
- else
- {
- assert (!"invalid token in builtin_dumpdef");
- abort ();
- }
+ 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);
+ obstack_1grow (obs, '\n');
}
+
+ obstack_1grow (obs, '\0');
+ m4_sysval_flush (context);
+ fputs ((char *) obstack_finish (obs), stderr);
}
/* The macro "defn" returns the quoted definition of the macro named by
@@ -445,9 +432,9 @@
/* Helper macros for readability. */
#if UNIX || defined WEXITSTATUS
-# define M4_SYSVAL_EXITBITS(status) \
+# define M4_SYSVAL_EXITBITS(status) \
(WIFEXITED (status) ? WEXITSTATUS (status) : 0)
-# define M4_SYSVAL_TERMSIGBITS(status) \
+# define M4_SYSVAL_TERMSIGBITS(status) \
(WIFSIGNALED (status) ? WTERMSIG (status) << 8 : 0)
#else /* ! UNIX && ! defined WEXITSTATUS */
Index: src/main.c
===================================================================
RCS file: /sources/m4/m4/src/main.c,v
retrieving revision 1.87
diff -u -r1.87 main.c
--- src/main.c 21 Sep 2006 04:12:55 -0000 1.87
+++ src/main.c 26 Sep 2006 20:37:23 -0000
@@ -137,19 +137,20 @@
fputs (_("\
\n\
FLAGS is any of:\n\
- a show actual arguments\n\
- c show before collect, after collect and after call\n\
- e show expansion\n\
- f say current input file name\n\
- i show changes in input files\n\
- l say current input line number\n\
+ a show actual arguments in trace\n\
+ c show before collect, after collect and after call 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\
+ l include current input line number in trace and debug\n\
"), stdout);
fputs (_("\
- m show actions related to modules\n\
- p show results of path searches\n\
- q quote values as necessary, with a or e flag\n\
- t trace for all macro calls, not only traceon'ed\n\
- x add a unique macro call id, useful with c flag\n\
+ m show actions related to modules in debug\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\
+ s show full stack of pushdef values in dumpdef\n\
+ t trace all macro calls, regardless of traceon state\n\
+ x add a unique macro call id in trace, useful with c\n\
V shorthand for all of the above flags\n\
"), stdout);
fputs (_("\
- dumpdef a pushdef'd stack,
Eric Blake <=