+
+ /* Parse the skeleton file and output the needed parsers. */
+ muscle_insert ("skeleton", skeleton);
+
+ /* Store the definition of all the muscles. */
+ {
+ FILE *muscles_m4 = xfopen ("/tmp/muscles.m4", "w");
+ /* There are no comments, especially not `#': we do want M4 expansion
+ after `#': think of CPP macros! */
+ fprintf (muscles_m4, "m4_changecom()\n");
+ fprintf (muscles_m4, "m4_init()\n");
+
+ fprintf (muscles_m4, "m4_define([b4_actions], \n[[");
+ actions_output (muscles_m4);
+ fprintf (muscles_m4, "]])\n\n");
+
+ fprintf (muscles_m4, "m4_define([b4_guards], \n[[");
+ guards_output (muscles_m4);
+ fprintf (muscles_m4, "]])\n\n");
+
+ fprintf (muscles_m4, "m4_define([b4_tokendef], \n[[");
+ token_definitions_output (muscles_m4);
+ fprintf (muscles_m4, "]])\n\n");
+
+ muscles_m4_output (muscles_m4);
+
+ fprintf (muscles_m4, "m4_wrap([m4_divert_pop(0)])\n");
+ fprintf (muscles_m4, "m4_divert_push(0)dnl\n");
+ xfclose (muscles_m4);
+ }
+
+ /* Invoke m4 on the definition of the muscles, and the skeleton. */
+ {
+ const char *bison_pkgdatadir = getenv ("BISON_PKGDATADIR");
+ if (!bison_pkgdatadir)
+ bison_pkgdatadir = PKGDATADIR;
+ skel_in = readpipe ("m4",
+ "-I",
+ bison_pkgdatadir,
+ "m4sugar/m4sugar.m4",
+ "/tmp/muscles.m4",
+ skeleton,
+ NULL);
+ if (!skel_in)
+ error (EXIT_FAILURE, errno, "cannot run m4");
+ skel_lex ();
+ }