m4-patches
[Top][All Lists]
Advanced

[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 (_("\






reply via email to

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