static void muscles_output (FILE *out) { fputs ("m4_init()\n", out); merger_output (out); symbol_numbers_output (out); type_names_output (out); user_actions_output (out); /* Must be last. */ muscles_m4_output (out); }
static void output_skeleton (void) { FILE *in; FILE *out; int filter_fd[2]; char const *argv[6]; pid_t pid; /* Compute the names of the package data dir and skeleton file. Test whether m4sugar.m4 is readable, to check for proper installation. A faulty installation can cause deadlock, so a cheap sanity check is worthwhile. */ char const m4sugar[] = "m4sugar/m4sugar.m4"; char *full_m4sugar; char *full_skeleton; char const *p; char const *m4 = (p = getenv ("M4")) ? p : M4; char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR; size_t skeleton_size = strlen (skeleton) + 1; size_t pkgdatadirlen = strlen (pkgdatadir); while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/') pkgdatadirlen--; full_skeleton = xmalloc (pkgdatadirlen + 1 + (skeleton_size < sizeof m4sugar ? sizeof m4sugar : skeleton_size)); strcpy (full_skeleton, pkgdatadir); full_skeleton[pkgdatadirlen] = '/'; strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar); full_m4sugar = xstrdup (full_skeleton); strcpy (full_skeleton + pkgdatadirlen + 1, skeleton); xfclose (xfopen (full_m4sugar, "r")); /* Create an m4 subprocess connected to us via two pipes. */ if (trace_flag & trace_tools) fprintf (stderr, "running: %s %s - %s\n", m4, full_m4sugar, full_skeleton); argv[0] = m4; argv[1] = full_m4sugar; argv[2] = "-"; argv[3] = full_skeleton; argv[4] = trace_flag & trace_m4 ? "-dV" : NULL; argv[5] = NULL; init_subpipe (); pid = create_subpipe (argv, filter_fd); free (full_m4sugar); free (full_skeleton); out = fdopen (filter_fd[0], "w"); if (! out) error (EXIT_FAILURE, get_errno (), "fdopen"); /* Output the definitions of all the muscles. */ fputs ("m4_init()\n", out); user_actions_output (out); merger_output (out); token_definitions_output (out); symbol_destructors_output (out); symbol_printers_output (out); muscles_m4_output (out); fputs ("m4_wrap([m4_divert_pop(0)])\n", out); fputs ("m4_divert_push(0)dnl\n", out); xfclose (out); /* Read and process m4's output. */ timevar_push (TV_M4); end_of_output_subpipe (pid, filter_fd); in = fdopen (filter_fd[1], "r"); if (! in) error (EXIT_FAILURE, get_errno (), "fdopen"); scan_skel (in); xfclose (in); reap_subpipe (pid, m4); timevar_pop (TV_M4); }