static void output_skeleton (void) { int filter_fd[2]; pid_t pid; /* Compute the names of the package data dir and skeleton files. */ char const *m4 = (m4 = getenv ("M4")) ? m4 : M4; char const *datadir = pkgdatadir (); char *m4sugar = xconcatenated_filename (datadir, "m4sugar/m4sugar.m4", NULL); char *m4bison = xconcatenated_filename (datadir, "bison.m4", NULL); char *skel = (IS_PATH_WITH_DIR (skeleton) ? xstrdup (skeleton) : xconcatenated_filename (datadir, skeleton, NULL)); /* Test whether m4sugar.m4 is readable, to check for proper installation. A faulty installation can cause deadlock, so a cheap sanity check is worthwhile. */ xfclose (xfopen (m4sugar, "r")); /* Create an m4 subprocess connected to us via two pipes. */ if (trace_flag & trace_tools) fprintf (stderr, "running: %s %s - %s %s\n", m4, m4sugar, m4bison, skel); /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a position-dependent manner. Keep it as the first argument so that all files are traced. See the thread starting at <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html> for details. */ { char const *argv[10]; int i = 0; argv[i++] = m4; /* When POSIXLY_CORRECT is set, GNU M4 1.6 and later disable GNU extensions, which Bison's skeletons depend on. With older M4, it has no effect. M4 1.4.12 added a -g/--gnu command-line option to make it explicit that a program wants GNU M4 extensions even when POSIXLY_CORRECT is set. See the thread starting at <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html> for details. */ if (*M4_GNU_OPTION) argv[i++] = M4_GNU_OPTION; argv[i++] = "-I"; argv[i++] = datadir; if (trace_flag & trace_m4) argv[i++] = "-dV"; argv[i++] = m4sugar; argv[i++] = "-"; argv[i++] = m4bison; argv[i++] = skel; argv[i++] = NULL; aver (i <= ARRAY_CARDINALITY (argv)); /* The ugly cast is because gnulib gets the const-ness wrong. */ pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true, true, filter_fd); } free (m4sugar); free (m4bison); free (skel); if (trace_flag & trace_muscles) muscles_output (stderr); { FILE *out = xfdopen (filter_fd[1], "w"); muscles_output (out); xfclose (out); } /* Read and process m4's output. */ timevar_push (TV_M4); { FILE *in = xfdopen (filter_fd[0], "r"); scan_skel (in); /* scan_skel should have read all of M4's output. Otherwise, when we close the pipe, we risk letting M4 report a broken-pipe to the Bison user. */ aver (feof (in)); xfclose (in); } wait_subprocess (pid, "m4", false, false, true, true, NULL); timevar_pop (TV_M4); }
static void output_skeleton (void) { FILE *m4_in = NULL; FILE *m4_out = NULL; char m4_in_file_name[] = "~m4_in_temp_file_XXXXXX"; char m4_out_file_name[] = "~m4_out_temp_file_XXXXXX"; // FILE *in; // int filter_fd[2]; char const *argv[10]; // pid_t pid; /* Compute the names of the package data dir and skeleton files. */ char const m4sugar[] = "m4sugar/m4sugar.m4"; char const m4bison[] = "bison.m4"; char *full_m4sugar; char *full_m4bison; char *full_skeleton; char const *p; char const *m4 = (p = getenv ("M4")) ? p : "M4"; int i = 0; char const *pkgdatadir = compute_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)); strncpy (full_skeleton, pkgdatadir, pkgdatadirlen); full_skeleton[pkgdatadirlen] = '/'; strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar); full_m4sugar = xstrdup (full_skeleton); strcpy (full_skeleton + pkgdatadirlen + 1, m4bison); full_m4bison = xstrdup (full_skeleton); if (_mbschr (skeleton, '/')) strcpy (full_skeleton, skeleton); else strcpy (full_skeleton + pkgdatadirlen + 1, skeleton); /* Test whether m4sugar.m4 is readable, to check for proper installation. A faulty installation can cause deadlock, so a cheap sanity check is worthwhile. */ 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 %s\n", m4, full_m4sugar, full_m4bison, full_skeleton); /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a position-dependent manner. Keep it as the first argument so that all files are traced. See the thread starting at <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html> for details. */ { argv[i++] = m4; /* When POSIXLY_CORRECT is set, GNU M4 1.6 and later disable GNU extensions, which Bison's skeletons depend on. With older M4, it has no effect. M4 1.4.12 added a -g/--gnu command-line option to make it explicit that a program wants GNU M4 extensions even when POSIXLY_CORRECT is set. See the thread starting at <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html> for details. */ // if (*M4_GNU_OPTION) // argv[i++] = M4_GNU_OPTION; argv[i++] = "-I"; argv[i++] = pkgdatadir; if (trace_flag & trace_m4) argv[i++] = "-dV"; argv[i++] = full_m4sugar; argv[i++] = "-"; argv[i++] = full_m4bison; argv[i++] = full_skeleton; argv[i++] = NULL; aver (i <= ARRAY_CARDINALITY (argv)); /* The ugly cast is because gnulib gets the const-ness wrong. */ // pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true, // true, filter_fd); } if (trace_flag & trace_muscles) muscles_output (stderr); { m4_in = mkstempFILE(m4_in_file_name, "w+"); if (!m4_in) error (EXIT_FAILURE, get_errno (), "fopen"); muscles_output (m4_in); fflush(m4_in); if (fseek(m4_in, 0, SEEK_SET)) error (EXIT_FAILURE, get_errno (), "fseek"); } /* Read and process m4's output. */ { m4_out = mkstempFILE(m4_out_file_name, "w+"); if (!m4_out) error (EXIT_FAILURE, get_errno (), "fopen"); } if (main_m4(i-1, argv, m4_in, m4_out)) error (EXIT_FAILURE, get_errno (), "m4 failed"); free (full_m4sugar); free (full_m4bison); free (full_skeleton); fflush(m4_out); if (fseek(m4_out, 0, SEEK_SET)) error (EXIT_FAILURE, get_errno (), "fseek"); timevar_push (TV_M4); // in = fdopen (filter_fd[0], "r"); // if (! in) // error (EXIT_FAILURE, get_errno (), // "fdopen"); scan_skel (m4_out); /* scan_skel should have read all of M4's output. Otherwise, when we close the pipe, we risk letting M4 report a broken-pipe to the Bison user. */ aver (feof (m4_out)); xfclose (m4_in); xfclose (m4_out); _unlink (m4_in_file_name); _unlink (m4_out_file_name); // wait_subprocess (pid, "m4", false, false, true, true, NULL); timevar_pop (TV_M4); }