* src/getargs.c (trace_types, trace_args): Accept trace_m4.
* src/output.c (output_skeleton): When set, pass -dV to m4.
Factor the handling of flags in m4.
* src/output.c (prepare): Rename the muscle names debug, defines,
error_verbose to debug_flag, defines_flag, error_verbose_flag.
* data/c.m4: Adjust.
(_b4_define_flag_if, b4_define_flag_if, b4_defines_if): New.
Use b4_define_flag_if to define other b4_FLAG_if macros.
(b4_location_if): As a consequence, rename as...
(b4_locations_if): this, for consistency.
Adjust all the skeletons.
+2006-05-14  Akim Demaille  <akim@lrde.epita.fr>
+
+       Implement --trace=m4.
+       * src/getargs.c (trace_types, trace_args): Accept trace_m4.
+       * src/output.c (output_skeleton): When set, pass -dV to m4.
+
+       Factor the handling of flags in m4.
+       * src/output.c (prepare): Rename the muscle names debug, defines,
+       error_verbose to debug_flag, defines_flag, error_verbose_flag.
+       * data/c.m4: Adjust.
+       (_b4_define_flag_if, b4_define_flag_if, b4_defines_if): New.
+       Use b4_define_flag_if to define other b4_FLAG_if macros.
+       (b4_location_if): As a consequence, rename as...
+       (b4_locations_if): this, for consistency.
+       Adjust all the skeletons.
+
 2006-05-14  Akim Demaille  <akim@lrde.epita.fr>
 
        * etc/bench.pm: Shorten bench names.
 
 [#]define YYSKELETON_NAME b4_skeleton
 
 /* Pure parsers.  */
-[#]define YYPURE b4_pure
+[#]define YYPURE b4_pure_flag
 
 /* Using locations.  */
 [#]define YYLSP_NEEDED b4_locations_flag
 ## Decoding options.  ##
 ## ------------------ ##
 
-
-# b4_error_verbose_if(IF-TRUE, IF-FALSE)
-# --------------------------------------
-# Expand IF-TRUE, if errors are verbose, IF-FALSE otherwise.
-m4_define([b4_error_verbose_if],
-[m4_if(b4_error_verbose, [1],
-       [$1],
-       [$2])])
-
-
-# b4_location_if(IF-TRUE, IF-FALSE)
-# ---------------------------------
-# Expand IF-TRUE, if locations are used, IF-FALSE otherwise.
-m4_define([b4_location_if],
-[m4_if(b4_locations_flag, [1],
-       [$1],
-       [$2])])
+# b4_flag_if(FLAG, IF-TRUE, IF-FALSE)
+# -----------------------------------
+# Run IF-TRUE if b4_FLAG_flag is 1, IF-FALSE if FLAG is 0, otherwise fail.
+m4_define([b4_flag_if],
+[m4_case(b4_$1_flag,
+         [0], [$3],
+        [1], [$2],
+        [m4_fatal([invalid $1 value: ]$1)])])
 
 
-# b4_pure_if(IF-TRUE, IF-FALSE)
+# b4_define_flag_if(FLAG)
+# -----------------------
+# Define "b4_FLAG_if(IF-TRUE, IF-FALSE)" that depends on the
+# value of the Boolean FLAG.
+m4_define([b4_define_flag_if],
+[_b4_define_flag_if($[1], $[2], [$1])])
+
+# _b4_define_flag_if($1, $2, FLAG)
+# --------------------------------
+# This macro works around the impossibility to define macros
+# inside macros, because issuing `[$1]' is not possible in M4 :(.
+# This sucks hard, GNU M4 should really provide M5 like $$1.
+m4_define([_b4_define_flag_if],
+[m4_if([$1$2], $[1]$[2], [],
+       [m4_fatal([$0: Invalid arguments: $@])])dnl
+m4_define([b4_$3_if], 
+          [b4_flag_if([$3], [$1], [$2])])])
+
+
+# b4_FLAG_if(IF-TRUE, IF-FALSE)
 # -----------------------------
-# Expand IF-TRUE, if %pure-parser, IF-FALSE otherwise.
-m4_define([b4_pure_if],
-[m4_if(b4_pure, [1],
-       [$1],
-       [$2])])
+# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
+b4_define_flag_if([defines])        # Whether headers are requested.
+b4_define_flag_if([error_verbose])  # Wheter error are verbose.
+b4_define_flag_if([locations])      # Whether locations are tracked.
+b4_define_flag_if([pure])           # Whether the interface is pure.
 
 
 
 # b4_syncline(LINE, FILE)
 # -----------------------
 m4_define([b4_syncline],
-[m4_if(b4_synclines_flag, 1,
-       [[#]line $1 $2])])
+[b4_flag_if([synclines], [[#]line $1 $2])])
 
 
 
     [[const char *yymsg],    [yymsg]],
     [[int yytype],           [yytype]],
     [[YYSTYPE *yyvaluep],    [yyvaluep]][]dnl
-b4_location_if(            [, [[YYLTYPE *yylocationp], [yylocationp]]])[]dnl
+b4_locations_if(            [, [[YYLTYPE *yylocationp], [yylocationp]]])[]dnl
 m4_ifset([b4_parse_param], [, b4_parse_param]))[
 {
   YYUSE (yyvaluep);
-]b4_location_if([  YYUSE (yylocationp);
+]b4_locations_if([  YYUSE (yylocationp);
 ])dnl
 b4_parse_param_use[]dnl
 [
               [[FILE *yyoutput],                       [yyoutput]],
               [[int yytype],                           [yytype]],
               [[const YYSTYPE * const yyvaluep],       [yyvaluep]][]dnl
-b4_location_if([, [[const YYLTYPE * const yylocationp], [yylocationp]]])[]dnl
+b4_locations_if([, [[const YYLTYPE * const yylocationp], [yylocationp]]])[]dnl
 m4_ifset([b4_parse_param], [, b4_parse_param]))[
 {
   if (!yyvaluep)
     return;
-]b4_location_if([  YYUSE (yylocationp);
+]b4_locations_if([  YYUSE (yylocationp);
 ])dnl
 b4_parse_param_use[]dnl
 [# ifdef YYPRINT
               [[FILE *yyoutput],                       [yyoutput]],
               [[int yytype],                           [yytype]],
               [[const YYSTYPE * const yyvaluep],       [yyvaluep]][]dnl
-b4_location_if([, [[const YYLTYPE * const yylocationp], [yylocationp]]])[]dnl
+b4_locations_if([, [[const YYLTYPE * const yylocationp], [yylocationp]]])[]dnl
 m4_ifset([b4_parse_param], [, b4_parse_param]))[
 {
   if (yytype < YYNTOKENS)
   else
     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
 
-]b4_location_if([  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+]b4_locations_if([  YY_LOCATION_PRINT (yyoutput, *yylocationp);
   YYFPRINTF (yyoutput, ": ");
 ])dnl
 [  yy_symbol_value_print (yyoutput, yytype, yyvaluep]dnl
-b4_location_if([, yylocationp])[]b4_user_args[);
+b4_locations_if([, yylocationp])[]b4_user_args[);
   YYFPRINTF (yyoutput, ")");
 }]dnl
 ])
 
 # Yes, this is quite ugly...
 m4_define([b4_lex_param],
 m4_dquote(b4_pure_if([[[[YYSTYPE *]], [[&yylval]]][]dnl
-b4_location_if([, [[YYLTYPE *], [&yylloc]]])])dnl
+b4_locations_if([, [[YYLTYPE *], [&yylloc]]])])dnl
 m4_ifdef([b4_lex_param], [, ]b4_lex_param)))
 
 
 # Optional effective arguments passed to yyerror: user args plus yylloc, and
 # a trailing comma.
 m4_define([b4_yyerror_args],
-[b4_pure_if([b4_location_if([yylocp, ])])dnl
+[b4_pure_if([b4_locations_if([yylocp, ])])dnl
 m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
 
 
 # ----------------
 # Same as above, but on the look-ahead, hence &yylloc instead of yylocp.
 m4_define([b4_lyyerror_args],
-[b4_pure_if([b4_location_if([&yylloc, ])])dnl
+[b4_pure_if([b4_locations_if([&yylloc, ])])dnl
 m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
 
 
 # ------------
 # Same as b4_yyerror_args, but with a leading comma.
 m4_define([b4_pure_args],
-[b4_pure_if([b4_location_if([, yylocp])])[]b4_user_args])
+[b4_pure_if([b4_locations_if([, yylocp])])[]b4_user_args])
 
 
 # b4_lpure_args
 # -------------
 # Same as above, but on the look-ahead, hence &yylloc instead of yylocp.
 m4_define([b4_lpure_args],
-[b4_pure_if([b4_location_if([, &yylloc])])[]b4_user_args])
+[b4_pure_if([b4_locations_if([, &yylloc])])[]b4_user_args])
 
 
 # b4_pure_formals
 # ---------------
 # Arguments passed to yyerror: user formals plus yylocp.
 m4_define([b4_pure_formals],
-[b4_pure_if([b4_location_if([, YYLTYPE *yylocp])])[]b4_user_formals])
+[b4_pure_if([b4_locations_if([, YYLTYPE *yylocp])])[]b4_user_formals])
 
 
 ## ----------------- ##
 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
 typedef struct YYLTYPE
 {
-]b4_location_if([
+]b4_locations_if([
   int first_line;
   int first_column;
   int last_line;
 #endif
 ]])
 
-m4_if(b4_defines_flag, 0,
-      [b4_shared_declarations],
-      [#include @output_header_name@])[
+b4_defines_if([#include @output_header_name@],
+              [b4_shared_declarations])[
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
-# define YYDEBUG ]b4_debug[
+# define YYDEBUG ]b4_debug_flag[
 #endif
 
 /* Enabling verbose error messages.  */
 # undef YYERROR_VERBOSE
 # define YYERROR_VERBOSE 1
 #else
-# define YYERROR_VERBOSE ]b4_error_verbose[
+# define YYERROR_VERBOSE ]b4_error_verbose_flag[
 #endif
 
 /* Enabling the token table.  */
 # endif
 #endif
 
-]b4_location_if([#define YYOPTIONAL_LOC(Name) Name],[
+]b4_locations_if([#define YYOPTIONAL_LOC(Name) Name],[
 #ifdef __cplusplus
 # define YYOPTIONAL_LOC(Name) /* empty */
 #else
    If N is 0, then set CURRENT to the empty location which ends
    the previous symbol: RHS[0] (always defined).  */
 
-]b4_location_if([[
+]b4_locations_if([[
 #define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
 #ifndef YYLLOC_DEFAULT
 # define YYLLOC_DEFAULT(Current, Rhs, N)                               \
     {                                                                      \
       YYFPRINTF (stderr, "%s ", Title);                                            \
       yy_symbol_print (stderr, Type,                                       \
-                      Value]b4_location_if([, Location])[]b4_user_args[);  \
+                      Value]b4_locations_if([, Location])[]b4_user_args[);  \
       YYFPRINTF (stderr, "\n");                                                    \
     }                                                                      \
 } while (YYID (0))
 
 #ifndef YYSTACKEXPANDABLE
 # if (! defined __cplusplus \
-      || (]b4_location_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+      || (]b4_locations_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
          && ]])[defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))
 #  define YYSTACKEXPANDABLE 1
 # else
 
 struct yyGLRStack {
   int yyerrState;
-]b4_location_if([[  /* To compute the location of the error token.  */
+]b4_locations_if([[  /* To compute the location of the error token.  */
   yyGLRStackItem yyerror_range[3];]])[
 ]b4_pure_if(
 [
   else
     *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;
   YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
-]b4_location_if([[  yystackp->yyerror_range[1].yystate.yyloc = *yylocp;
+]b4_locations_if([[  yystackp->yyerror_range[1].yystate.yyloc = *yylocp;
 ]])[
   switch (yyn)
     {
 {
   if (yys->yyresolved)
     yydestruct (yymsg, yystos[yys->yylrState],
-               &yys->yysemantics.yysval]b4_location_if([, &yys->yyloc])[]b4_user_args[);
+               &yys->yysemantics.yysval]b4_locations_if([, &yys->yyloc])[]b4_user_args[);
   else
     {
 #if YYDEBUG
          else
            YYFPRINTF (stderr, "%s incomplete ", yymsg);
          yy_symbol_print (stderr, yystos[yys->yylrState],
-                          NULL]b4_location_if([, &yys->yyloc])[]b4_user_args[);
+                          NULL]b4_locations_if([, &yys->yyloc])[]b4_user_args[);
          YYFPRINTF (stderr, "\n");
        }
 #endif
       yyGLRState* yys;
       yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
       yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
-       = yystackp->yytops.yystates[yyk];]b4_location_if([[
+       = yystackp->yytops.yystates[yyk];]b4_locations_if([[
       if (yynrhs == 0)
        /* Set default location.  */
        yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;]])[
       fprintf (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
                       &]b4_rhs_value(yynrhs, yyi + 1)[
-                      ]b4_location_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
+                      ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
                       b4_user_args[);
       fprintf (stderr, "\n");
     }
       return yyflag;
     }
 
-  yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;]b4_location_if([[
+  yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;]b4_locations_if([[
   if (yynrhs == 0)
     /* Set default location.  */
     yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yyopt->yystate->yyloc;]])[
                  {
                    yydestruct ("Cleanup: discarding incompletely merged value for",
                                yystos[yys->yylrState],
-                               &yysval]b4_location_if([, yylocp])[]b4_user_args[);
+                               &yysval]b4_locations_if([, yylocp])[]b4_user_args[);
                    break;
                  }
                yyuserMerge (yymerger[yyp->yyrule], &yysval, &yysval_other);
        if (yychar == YYEOF)
          yyFail (yystackp][]b4_lpure_args[, NULL);
        if (yychar != YYEMPTY)
-         {]b4_location_if([[
+         {]b4_locations_if([[
            /* We throw away the lookahead, but the error range
               of the shifted error token must take it into account.  */
            yyGLRState *yys = yystackp->yytops.yystates[0];
            YYLLOC_DEFAULT ((yys->yyloc), yyerror_range, 2);]])[
            yytoken = YYTRANSLATE (yychar);
            yydestruct ("Error: discarding",
-                       yytoken, &yylval]b4_location_if([, &yylloc])[]b4_user_args[);
+                       yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
          }
        YYDPRINTF ((stderr, "Reading a token: "));
        yychar = YYLEX;
              && yyisShiftAction (yytable[yyj]))
            {
              /* Shift the error token having adjusted its location.  */
-             YYLTYPE yyerrloc;]b4_location_if([[
+             YYLTYPE yyerrloc;]b4_locations_if([[
              yystackp->yyerror_range[2].yystate.yyloc = yylloc;
              YYLLOC_DEFAULT (yyerrloc, (yystackp->yyerror_range), 2);]])[
              YY_SYMBOL_PRINT ("Shifting", yystos[yytable[yyj]],
              break;
            }
        }
-]b4_location_if([[      yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[
+]b4_locations_if([[      yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[
       yydestroyGLRState ("Error: popping", yys]b4_user_args[);
       yystackp->yytops.yystates[0] = yys->yypred;
       yystackp->yynextFree -= 1;
 
   yychar = YYEMPTY;
   yylval = yyval_default;
-]b4_location_if([
+]b4_locations_if([
 #if YYLTYPE_IS_TRIVIAL
   yylloc.first_line   = yylloc.last_line   = 1;
   yylloc.first_column = yylloc.last_column = 0;
              yyrule = yydefaultAction (yystate);
              if (yyrule == 0)
                {
-]b4_location_if([[               yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
+]b4_locations_if([[              yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
                  yyreportSyntaxError (&yystack]b4_user_args[);
                  goto yyuser_error;
                }
                }
              else if (yyisErrorAction (yyaction))
                {
-]b4_location_if([[               yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
+]b4_locations_if([[              yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
                  yyreportSyntaxError (&yystack]b4_user_args[);
                  goto yyuser_error;
                }
                yyFail (&yystack][]b4_lpure_args[, YY_("syntax error"));
              YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
              YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
-]b4_location_if([[           yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
+]b4_locations_if([[          yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
              yyreportSyntaxError (&yystack]b4_user_args[);
              goto yyuser_error;
            }
   if (yychar != YYEOF && yychar != YYEMPTY)
     yydestruct ("Cleanup: discarding lookahead",
                YYTRANSLATE (yychar),
-               &yylval]b4_location_if([, &yylloc])[]b4_user_args[);
+               &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
 
   /* If the stack is well-formed, pop the stack until it is empty,
      destroying its entries as we go.  But free the stack regardless
                while (yystates[yyk])
                  {
                    yyGLRState *yys = yystates[yyk];
-]b4_location_if([[                 yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
+]b4_locations_if([[                yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
 )[                 yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
                    yystates[yyk] = yys->yypred;
                    yystack.yynextFree -= 1;
 ]
 
 b4_epilogue
-m4_if(b4_defines_flag, 0, [],
+b4_defines_if(
 [@output @output_header_name@
 b4_copyright([Skeleton interface for Bison GLR parsers in C],
   [2002, 2003, 2004, 2005, 2006])
 
 extern YYSTYPE b4_prefix[]lval;
 
-b4_location_if([b4_pure_if([],
+b4_locations_if([b4_pure_if([],
 [extern YYLTYPE b4_prefix[]lloc;])
 ])
 ])
 
 
 # We require a pure interface using locations.
 m4_define([b4_location_flag], [1])
-m4_define([b4_pure],          [1])
+m4_define([b4_pure_flag],     [1])
 
 m4_include(b4_pkgdatadir/[c++.m4])
 m4_include(b4_pkgdatadir/[location.cc])
     b4_parse_param)[
 {
 ]b4_parse_param_use[]dnl
-[  yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_location_if([, yylocationp])[);
+[  yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[);
 }
 ]])
 
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
-# define YYDEBUG ]b4_debug[
+# define YYDEBUG ]b4_debug_flag[
 #endif
 
 /* Enabling verbose error messages.  */
 # undef YYERROR_VERBOSE
 # define YYERROR_VERBOSE 1
 #else
-# define YYERROR_VERBOSE ]b4_error_verbose[
+# define YYERROR_VERBOSE ]b4_error_verbose_flag[
 #endif
 
 /* Enabling the token table.  */
 
 # We do want M4 expansion after # for CPP macros.
 m4_changecom()
 m4_divert(0)dnl
-m4_if(b4_defines_flag, 0, [],
+b4_defines_if(
 [@output @output_header_name@
 b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++],
   [2002, 2003, 2004, 2005, 2006])
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
-# define YYDEBUG ]b4_debug[
+# define YYDEBUG ]b4_debug_flag[
 #endif
 
 /* Enabling verbose error messages.  */
 # undef YYERROR_VERBOSE
 # define YYERROR_VERBOSE 1
 #else
-# define YYERROR_VERBOSE ]b4_error_verbose[
+# define YYERROR_VERBOSE ]b4_error_verbose_flag[
 #endif
 
 /* Enabling the token table.  */
 [
 // Take the name prefix into account.
 #define yylex   b4_prefix[]lex])
-m4_if(b4_defines_flag, 0, [],
-[
+b4_defines_if([
 #include @output_header_name@])[
 
 /* User implementation prologue.  */
        YYCDEBUG << "Reading a token: ";
        yychar = ]b4_c_function_call([yylex], [int],
                                     [[YYSTYPE*], [&yylval]][]dnl
-b4_location_if([, [[location*], [&yylloc]]])dnl
+b4_locations_if([, [[location*], [&yylloc]]])dnl
 m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
       }
 
 
 # ---------------
 # Arguments passed to yyerror: user args plus yylloc.
 m4_define([b4_yyerror_args],
-[b4_yacc_pure_if([b4_location_if([&yylloc, ])])dnl
+[b4_yacc_pure_if([b4_locations_if([&yylloc, ])])dnl
 m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
 
 
 # b4_lex_param arrives quoted twice, but we want to keep only one level.
 m4_define([b4_lex_param],
 m4_dquote(b4_pure_if([[[[YYSTYPE *]], [[&yylval]]][]dnl
-b4_location_if([, [[YYLTYPE *], [&yylloc]]])m4_ifdef([b4_lex_param], [, ])])dnl
+b4_locations_if([, [[YYLTYPE *], [&yylloc]]])m4_ifdef([b4_lex_param], [, ])])dnl
 m4_ifdef([b4_lex_param], b4_lex_param)))
 
 
 m4_changecom()
 m4_divert(0)dnl
 @output @output_parser_name@
-b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],
+b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl '
   [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006])[
 
 /* C LALR(1) parser skeleton written by Richard Stallman, by
 #define yychar  b4_prefix[]char
 #define yydebug b4_prefix[]debug
 #define yynerrs b4_prefix[]nerrs
-b4_location_if([#define yylloc b4_prefix[]lloc])])[
+b4_locations_if([#define yylloc b4_prefix[]lloc])])[
 
 ]b4_token_enums_defines(b4_tokens)[
 
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
-# define YYDEBUG ]b4_debug[
+# define YYDEBUG ]b4_debug_flag[
 #endif
 
 /* Enabling verbose error messages.  */
 # undef YYERROR_VERBOSE
 # define YYERROR_VERBOSE 1
 #else
-# define YYERROR_VERBOSE ]b4_error_verbose[
+# define YYERROR_VERBOSE ]b4_error_verbose_flag[
 #endif
 
 /* Enabling the token table.  */
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
-]b4_location_if([#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+]b4_locations_if([#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
 typedef struct YYLTYPE
 {
   int first_line;
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-        || (]b4_location_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+        || (]b4_locations_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
             && ]])[defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 {
   yytype_int16 yyss;
   YYSTYPE yyvs;
-  ]b4_location_if([  YYLTYPE yyls;
+  ]b4_locations_if([  YYLTYPE yyls;
 ])dnl
 [};
 
 
 /* The size of an array large to enough to hold all stacks, each with
    N elements.  */
-]b4_location_if(
+]b4_locations_if(
 [# define YYSTACK_BYTES(N) \
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
       + 2 * YYSTACK_GAP_MAXIMUM)],
 /* YYLEX -- calling `yylex' with the right arguments.  */
 
 #ifdef YYLEX_PARAM
-# define YYLEX yylex (]b4_pure_if([&yylval[]b4_location_if([, &yylloc]), ])[YYLEX_PARAM)
+# define YYLEX yylex (]b4_pure_if([&yylval[]b4_locations_if([, &yylloc]), ])[YYLEX_PARAM)
 #else
 # define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[
 #endif
     {                                                                    \
       YYFPRINTF (stderr, "%s ", Title);                                          \
       yy_symbol_print (stderr,                                           \
-                 Type, Value]b4_location_if([, Location])[]b4_user_args[); \
+                 Type, Value]b4_locations_if([, Location])[]b4_user_args[); \
       YYFPRINTF (stderr, "\n");                                                  \
     }                                                                    \
 } while (YYID (0))
 
 ]b4_c_function_def([yy_reduce_print], [static void],
                   [[YYSTYPE *yyvsp], [yyvsp]],
-    b4_location_if([[[YYLTYPE *yylsp], [yylsp]],])
+    b4_locations_if([[[YYLTYPE *yylsp], [yylsp]],])
                   [[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,])
                   b4_parse_param)[
 {
       fprintf (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
                       &]b4_rhs_value(yynrhs, yyi + 1)[
-                      ]b4_location_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
+                      ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
                       b4_user_args[);
       fprintf (stderr, "\n");
     }
 # define YY_REDUCE_PRINT(Rule)         \
 do {                                   \
   if (yydebug)                         \
-    yy_reduce_print (yyvsp, ]b4_location_if([yylsp, ])[Rule]b4_user_args[); \
+    yy_reduce_print (yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \
 } while (YYID (0))
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
 YYSTYPE yylval;
 
 /* Number of syntax errors so far.  */
-int yynerrs;b4_location_if([
+int yynerrs;b4_locations_if([
 /* Location data for the look-ahead symbol.  */
 YYLTYPE yylloc;])
 ])
   YYSTYPE *yyvs = yyvsa;
   YYSTYPE *yyvsp;
 
-]b4_location_if(
+]b4_locations_if(
 [[  /* The location stack.  */
   YYLTYPE yylsa[YYINITDEPTH];
   YYLTYPE *yyls = yylsa;
   /* The locations where the error started and ended.  */
   YYLTYPE yyerror_range[2];]])[
 
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N)]b4_location_if([, yylsp -= (N)])[)
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[)
 
   YYSIZE_T yystacksize = YYINITDEPTH;
 
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
-]b4_location_if([  YYLTYPE yyloc;])[
+]b4_locations_if([  YYLTYPE yyloc;])[
 
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
 
   yyssp = yyss;
   yyvsp = yyvs;
-]b4_location_if([[  yylsp = yyls;
+]b4_locations_if([[  yylsp = yyls;
 #if YYLTYPE_IS_TRIVIAL
   /* Initialize the default location before parsing starts.  */
   yylloc.first_line   = yylloc.last_line   = 1;
           memory.  */
        YYSTYPE *yyvs1 = yyvs;
        yytype_int16 *yyss1 = yyss;
-]b4_location_if([      YYLTYPE *yyls1 = yyls;])[
+]b4_locations_if([     YYLTYPE *yyls1 = yyls;])[
 
        /* Each stack pointer address is followed by the size of the
           data in use in that stack, in bytes.  This used to be a
        yyoverflow (YY_("memory exhausted"),
                    &yyss1, yysize * sizeof (*yyssp),
                    &yyvs1, yysize * sizeof (*yyvsp),
-]b4_location_if([                  &yyls1, yysize * sizeof (*yylsp),])[
+]b4_locations_if([                 &yyls1, yysize * sizeof (*yylsp),])[
                    &yystacksize);
-]b4_location_if([      yyls = yyls1;])[
+]b4_locations_if([     yyls = yyls1;])[
        yyss = yyss1;
        yyvs = yyvs1;
       }
          goto yyexhaustedlab;
        YYSTACK_RELOCATE (yyss);
        YYSTACK_RELOCATE (yyvs);
-]b4_location_if([      YYSTACK_RELOCATE (yyls);])[
+]b4_locations_if([     YYSTACK_RELOCATE (yyls);])[
 #  undef YYSTACK_RELOCATE
        if (yyss1 != yyssa)
          YYSTACK_FREE (yyss1);
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
-]b4_location_if([      yylsp = yyls + yysize - 1;])[
+]b4_locations_if([      yylsp = yyls + yysize - 1;])[
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
                  (unsigned long int) yystacksize));
 
   yystate = yyn;
   *++yyvsp = yylval;
-]b4_location_if([  *++yylsp = yylloc;])[
+]b4_locations_if([  *++yylsp = yylloc;])[
   goto yynewstate;
 
 
      GCC warning that YYVAL may be used uninitialized.  */
   yyval = yyvsp[1-yylen];
 
-]b4_location_if(
+]b4_locations_if(
 [[  /* Default location.  */
   YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);]])[
   YY_REDUCE_PRINT (yyn);
   YY_STACK_PRINT (yyss, yyssp);
 
   *++yyvsp = yyval;
-]b4_location_if([  *++yylsp = yyloc;])[
+]b4_locations_if([  *++yylsp = yyloc;])[
 
   /* Now `shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
 #endif
     }
 
-]b4_location_if([[  yyerror_range[0] = yylloc;]])[
+]b4_locations_if([[  yyerror_range[0] = yylloc;]])[
 
   if (yyerrstatus == 3)
     {
       else
        {
          yydestruct ("Error: discarding",
-                     yytoken, &yylval]b4_location_if([, &yylloc])[]b4_user_args[);
+                     yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
          yychar = YYEMPTY;
        }
     }
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-]b4_location_if([[  yyerror_range[0] = yylsp[1-yylen];
+]b4_locations_if([[  yyerror_range[0] = yylsp[1-yylen];
 ]])[  /* Do not reclaim the symbols of the rule which action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
       if (yyssp == yyss)
        YYABORT;
 
-]b4_location_if([[      yyerror_range[0] = *yylsp;]])[
+]b4_locations_if([[      yyerror_range[0] = *yylsp;]])[
       yydestruct ("Error: popping",
-                 yystos[yystate], yyvsp]b4_location_if([, yylsp])[]b4_user_args[);
+                 yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     YYACCEPT;
 
   *++yyvsp = yylval;
-]b4_location_if([[
+]b4_locations_if([[
   yyerror_range[1] = yylloc;
   /* Using YYLLOC is tempting, but would change the location of
      the look-ahead.  YYLOC is available though.  */
 yyreturn:
   if (yychar != YYEOF && yychar != YYEMPTY)
      yydestruct ("Cleanup: discarding lookahead",
-                yytoken, &yylval]b4_location_if([, &yylloc])[]b4_user_args[);
+                yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-                 yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[]b4_user_args[);
+                 yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
 
 
 b4_epilogue
-m4_if(b4_defines_flag, 0, [],
+b4_defines_if(
 [@output @output_header_name@
-b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],
+b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],dnl '
   [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006])
 
 b4_token_enums_defines(b4_tokens)
 b4_pure_if([],
 [extern YYSTYPE b4_prefix[]lval;])
 
-b4_location_if(
+b4_locations_if(
 [#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
 typedef struct YYLTYPE
 {
 # define YYLTYPE_IS_TRIVIAL 1
 #endif
 
-m4_if(b4_pure, [0],
-[extern YYLTYPE b4_prefix[]lloc;])
-])
-])
+b4_pure_if([],
+          [extern YYLTYPE b4_prefix[]lloc;])
+])dnl b4_locations_if
+])dnl b4_defines_if
 
   "grammar    - reading, reducing of the grammar",
   "resource   - memory consumption (where available)",
   "sets       - grammar sets: firsts, nullable etc.",
-  "tools      - m4 invocation and preserve the temporary file",
+  "tools      - m4 invocation",
+  "m4         - m4 traces",
   "skeleton   - skeleton postprocessing",
   "time       - time consumption",
   "all        - all of the above",
   trace_resource,
   trace_sets,
   trace_tools,
+  trace_m4,
   trace_skeleton,
   trace_time,
   trace_all
 
     trace_grammar   = 1 << 7,
     trace_time      = 1 << 8,
     trace_skeleton  = 1 << 9,
+    trace_m4        = 1 << 10,
     trace_all       = ~0
   };
 extern int trace_flag;
 
   FILE *in;
   FILE *out;
   int filter_fd[2];
-  char const *argv[5];
+  char const *argv[6];
   pid_t pid;
 
   /* Compute the names of the package data dir and skeleton file.
   argv[1] = full_m4sugar;
   argv[2] = "-";
   argv[3] = full_skeleton;
-  argv[4] = NULL;
+  argv[4] = trace_flag & trace_m4 ? "-dV" : NULL;
+  argv[5] = NULL;
 
   init_subpipe ();
   pid = create_subpipe (argv, filter_fd);
 prepare (void)
 {
   /* Flags. */
-  MUSCLE_INSERT_BOOL ("debug", debug_flag);
+  MUSCLE_INSERT_BOOL ("debug_flag", debug_flag);
   MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
-  MUSCLE_INSERT_BOOL ("error_verbose", error_verbose);
+  MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose);
   MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
-  MUSCLE_INSERT_BOOL ("pure", pure_parser);
+  MUSCLE_INSERT_BOOL ("pure_flag", pure_parser);
   MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
 
   /* File names.  */