bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

new readpipe patch (corrected)


From: Florian Krohm
Subject: new readpipe patch (corrected)
Date: Sun, 12 May 2002 15:37:55 -0400 (EDT)

Please disregard the patch I sent earlier. I used an account that
you cannot reply to. Sorry for that.  Here it goes again.

Florian

=============================================================

Here is the new readpipe patch. It incorporates Paul's suggestions
and eliminates the temporary file by running m4 as a filter.

I will be ging on vacation this Friday and will be out of touch for
three weeks. If the patch needs adjustment, please let me know soon
so I can fix it before I leave. Otherwise, it will have to wait 
until I'm back.

Florian

================= begin new file readpipe.h =======================

/*  Copyright (C) 2002 Free Software Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#ifndef READPIPE_H
# define READPIPE_H 1

# if HAVE_CONFIG_H
#  include <config.h>
# endif

# if HAVE_UNISTD_H
#  include <sys/types.h>
#  include <unistd.h>
# else
#  define pid_t int
# endif

# ifndef PARAMS
#  if defined PROTOTYPES || (defined __STDC__ && __STDC__)
#   define PARAMS(proto) proto
#  else
#   define PARAMS(proto) ()
#  endif
# endif

pid_t open_filter PARAMS ((const char **argv, int *from, int *to));

#endif /* !READPIPE_H */
================= end new file readpipe.h =======================

Index: bison/ChangeLog
===================================================================
RCS file: /cvsroot/bison/bison/ChangeLog,v
retrieving revision 1.677
diff -u -r1.677 ChangeLog
--- bison/ChangeLog     7 May 2002 08:13:00 -0000       1.677
+++ bison/ChangeLog     12 May 2002 17:11:01 -0000
@@ -1,3 +1,14 @@
+2002-05-12  Florian Krohm  <address@hidden>
+
+       * configure.in (AC_FUNC_FORK, AC_TYPE_PID): Added
+       * lib/readpipe.c (open_filter): New function
+       * lib/readpipe.h: New
+       * src/muscle_tab.c (muscles_m4_output): Use obstack not FILE.
+       * src/muscle_tab.h (muscles_m4_output): Use obstack not FILE.
+       * src/output.h (actions_output, token_definitions_output): Remove
+       * src/output.c (output_skeleton): Adapted to use open_filter.
+       Eliminated temporary file. Use obstacks. More trace output.
+
 2002-05-07  Akim Demaille  <address@hidden>
 
        * tests/synclines.at: Be sure to prototype yylex and yyerror to
Index: bison/configure.in
===================================================================
RCS file: /cvsroot/bison/bison/configure.in,v
retrieving revision 1.64
diff -u -r1.64 configure.in
--- bison/configure.in  3 May 2002 15:52:53 -0000       1.64
+++ bison/configure.in  12 May 2002 17:11:03 -0000
@@ -91,6 +91,7 @@
 AC_FUNC_OBSTACK
 AC_FUNC_ERROR_AT_LINE
 AC_FUNC_STRNLEN
+AC_FUNC_FORK
 UTILS_FUNC_MKSTEMP
 AC_CHECK_FUNCS(setlocale)
 AC_CHECK_DECLS([free, stpcpy, strchr, strspn, strnlen,
@@ -101,6 +102,9 @@
 jm_PREREQ_QUOTEARG
 jm_PREREQ_ERROR
 AM_WITH_DMALLOC
+
+# Checks for types.
+AC_TYPE_PID_T
 
 # Gettext.
 GETTEXT_VERSION=0.11.2
Index: bison/lib/readpipe.c
===================================================================
RCS file: /cvsroot/bison/bison/lib/readpipe.c,v
retrieving revision 1.1
diff -u -r1.1 readpipe.c
--- bison/lib/readpipe.c        5 Feb 2002 10:14:20 -0000       1.1
+++ bison/lib/readpipe.c        12 May 2002 17:11:05 -0000
@@ -1,5 +1,5 @@
-/* Open a pipe to read from a program without intermediary sh.
-   Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+/* Create a subprocess as a filter.
+   Copyright (C) 1992, 1997, 2002 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,82 +15,79 @@
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-/* Written by David MacKenzie.  */
-
 #if HAVE_CONFIG_H
 # include <config.h>
 #endif
 
-#include <stdio.h>
-
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
 #if HAVE_UNISTD_H
+# include <sys/types.h>
 # include <unistd.h>
 #endif
 
-/* Open a pipe to read from a program without intermediary sh.  Checks
-   PATH.  Sample use:
+#ifndef _POSIX_VERSION
+# ifndef STDIN_FILENO
+#  define STDIN_FILENO 0
+# endif
+# ifndef STDOUT_FILENO
+#  define STDOUT_FILENO 1
+# endif
+#endif
+
+#include <errno.h>
+#include "readpipe.h"
+
+/* Creates a subprocess which is run as a filter. ARGV is the NULL-terminated
+   argument buffer for the subprocess. Upon success, the function returns the
+   id of the subprocess. The arguments FROM and TO will contain file handles
+   for communication with the subprocess. Otherwise, the function returns -1
+   and errno is set appropriately. */
+pid_t
+open_filter(const char **argv, int *from, int *to)
+{
+  int fds1[2], fds2[2];
+  pid_t pid;
 
-   stream = readpipe ("progname", "arg1", "arg2", (char *) 0);
+#if HAVE_WORKING_FORK || HAVE_WORKING_VFORK
 
-   Return 0 on error.  */
+  if (pipe (fds1) < 0 || pipe (fds2) < 0)
+    return -1;
+
+  if ((pid = fork ()) < 0)
+    return -1;
+  
+  if (pid > 0) {
+    /* parent */
+    close (fds1[0]);
+    close (fds2[1]);
+
+    *from = fds2[0];
+    *to   = fds1[1];
+  } else {
+    /* child */
+    close(fds1[1]);
+    close(fds2[0]);
+
+    if (fds1[0] != STDIN_FILENO) {
+      if (dup2(fds1[0], STDIN_FILENO) != STDIN_FILENO) 
+       return -1;
+      close (fds1[0]);
+    }
+    if (fds2[1] != STDOUT_FILENO) {
+      if (dup2(fds2[1], STDOUT_FILENO) != STDOUT_FILENO) 
+       return -1;
+      close (fds2[1]);
+    }
+
+    /* The cast to (char **) is needed for portability to older
+       hosts with a nonstandard prototype for execvp.  */
+    execvp (argv[0], (char **)argv);
+    
+    _exit (errno == ENOEXEC ? 126 : 127);
+  }
+
+  return pid;
 
-#if __STDC__
-FILE *
-readpipe (char *progname, ...)
-#else
-FILE *
-readpipe (va_alist)
-#endif
-{
-#if ! __STDC__
-  char *progname;
-#endif
-  int fds[2];
-  va_list ap;
-  char *args[100];
-  int argno = 0;
-
-  /* Copy arguments into `args'. */
-#if __STDC__
-  va_start (ap, progname);
 #else
-  va_start (ap);
-  progname = va_arg (ap, char *);
+#error Bison requires working fork
 #endif
-  args[argno++] = progname;
-  while ((args[argno++] = va_arg (ap, char *)) != NULL)
-    ;
-  va_end (ap);
-
-  if (pipe (fds) == -1)
-    return 0;
-
-  switch (fork ())
-    {
-    case 0:                    /* Child.  Write to pipe. */
-      close (fds[0]);          /* Not needed. */
-      if (fds[1] != 1)         /* Redirect 1 (stdout) only if needed.  */
-       {
-         close (1);            /* We don't want the old stdout. */
-         if (dup (fds[1]) == 0)/* Maybe stdin was closed. */
-           {
-             dup (fds[1]);     /* Guaranteed to dup to 1 (stdout). */
-             close (0);
-           }
-         close (fds[1]);       /* No longer needed. */
-       }
-      execvp (args[0], args);
-      _exit (2);               /* 2 for `cmp'. */
-    case -1:                   /* Error. */
-      return 0;
-    default:                   /* Parent.  Read from pipe. */
-      close (fds[1]);          /* Not needed. */
-      return fdopen (fds[0], "r");
-    }
 }
Index: bison/src/muscle_tab.c
===================================================================
RCS file: /cvsroot/bison/bison/src/muscle_tab.c,v
retrieving revision 1.16
diff -u -r1.16 muscle_tab.c
--- bison/src/muscle_tab.c      6 May 2002 08:23:54 -0000       1.16
+++ bison/src/muscle_tab.c      12 May 2002 17:11:08 -0000
@@ -98,10 +98,15 @@
    m4_defines.  */
 
 static int
-muscle_m4_output (muscle_entry_t *entry, FILE *out)
+muscle_m4_output (muscle_entry_t *entry, struct obstack *out)
 {
-  fprintf (out, "m4_define([b4_%s],\n", entry->key);
-  fprintf (out, "          [[%s]])\n\n\n", entry->value);
+  obstack_fgrow1 (out, "m4_define([b4_%s],\n", entry->key);
+
+  /* Cannot use obstack_fgrow1 here because of buffer overflow */
+  obstack_sgrow  (out, "          [[");
+  obstack_sgrow  (out, entry->value);
+  obstack_sgrow  (out, "]])\n\n\n");
+
   return 1;
 }
 
@@ -110,7 +115,7 @@
    m4_defines.  */
 
 void
-muscles_m4_output (FILE *out)
+muscles_m4_output (struct obstack *out)
 {
   hash_do_for_each (muscle_table,
                    (Hash_processor) muscle_m4_output,
Index: bison/src/muscle_tab.h
===================================================================
RCS file: /cvsroot/bison/bison/src/muscle_tab.h,v
retrieving revision 1.4
diff -u -r1.4 muscle_tab.h
--- bison/src/muscle_tab.h      7 Apr 2002 17:44:59 -0000       1.4
+++ bison/src/muscle_tab.h      12 May 2002 17:11:08 -0000
@@ -19,7 +19,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #ifndef MUSCLE_TAB_H_
-# define MUSCLE_TAB_H
+# define MUSCLE_TAB_H_
 
 # define MTABSIZE 101
 
@@ -63,6 +63,6 @@
 }
 
 
-void muscles_m4_output PARAMS ((FILE *out));
+void muscles_m4_output PARAMS ((struct obstack *out));
 
 #endif /* not MUSCLE_TAB_H_ */
Index: bison/src/output.c
===================================================================
RCS file: /cvsroot/bison/bison/src/output.c,v
retrieving revision 1.154
diff -u -r1.154 output.c
--- bison/src/output.c  7 May 2002 08:07:32 -0000       1.154
+++ bison/src/output.c  12 May 2002 17:11:19 -0000
@@ -103,9 +103,7 @@
 #include "symtab.h"
 #include "conflicts.h"
 #include "muscle_tab.h"
-
-/* From lib/readpipe.h.  */
-FILE *readpipe PARAMS ((const char *, ...));
+#include "readpipe.h"
 
 /* From src/scan-skel.l. */
 int skel_lex PARAMS ((void));
@@ -132,6 +130,9 @@
 static int lowzero;
 static int high;
 
+static void actions_output (struct obstack *out);
+static void token_definitions_output (struct obstack *out);
+
 struct obstack muscle_obstack;
 static struct obstack format_obstack;
 
@@ -534,26 +535,26 @@
 | Output the actions to OOUT.  |
 `-----------------------------*/
 
-void
-actions_output (FILE *out)
+static void
+actions_output (struct obstack *out)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
     if (rules[rule].action)
       {
-       fprintf (out, "  case %d:\n", rule);
+       obstack_fgrow1 (out, "  case %d:\n", rule);
 
        if (!no_lines_flag)
-         fprintf (out, muscle_find ("linef"),
+         obstack_fgrow2 (out, muscle_find ("linef"),
                   rules[rule].action_line,
                   quotearg_style (c_quoting_style,
                                   muscle_find ("filename")));
        /* As a Bison extension, add the ending semicolon.  Since some
           Yacc don't do that, help people using bison as a Yacc
           finding their missing semicolons.  */
-       fprintf (out, "{ %s%s }\n    break;\n\n",
-                rules[rule].action,
-                yacc_flag ? ";" : "");
+       obstack_fgrow2 (out, "{ %s%s }\n    break;\n\n",
+                       rules[rule].action,
+                       yacc_flag ? ";" : "");
       }
 }
 
@@ -562,8 +563,8 @@
 | Output the tokens definition to OOUT.  |
 `---------------------------------------*/
 
-void
-token_definitions_output (FILE *out)
+static void
+token_definitions_output (struct obstack *out)
 {
   int i;
   int first = 1;
@@ -597,8 +598,8 @@
       if (strchr (symbol->tag, '.') || strchr (symbol->tag, '$'))
        continue;
 
-      fprintf (out, "%s[[[%s]], [%d]]",
-              first ? "" : ",\n", symbol->tag, number);
+      obstack_fgrow3 (out, "%s[[[%s]], [%d]]",
+                     first ? "" : ",\n", symbol->tag, number);
 
       first = 0;
     }
@@ -949,73 +950,90 @@
 /*---------------------------.
 | Call the skeleton parser.  |
 `---------------------------*/
-
 static void
 output_skeleton (void)
 {
   /* Store the definition of all the muscles. */
-  const char *tempdir = getenv ("TMPDIR");
-  char *tempfile = NULL;
-  FILE *out = NULL;
-  int fd;
-
-  if (tempdir == NULL)
-    tempdir = DEFAULT_TMPDIR;
-  tempfile = xmalloc (strlen (tempdir) + 11);
-  sprintf (tempfile, "%s/bsnXXXXXX", tempdir);
-  fd = mkstemp (tempfile);
-  if (fd == -1)
-    error (EXIT_FAILURE, errno, "%s", tempfile);
-
-  out = fdopen (fd, "w");
-  if (out == NULL)
-    error (EXIT_FAILURE, errno, "%s", tempfile);
+  struct obstack m4_obstack, *out = &m4_obstack;
+  const char *m4_buffer;
+
+  obstack_init (out);
 
   /* There are no comments, especially not `#': we do want M4 expansion
      after `#': think of CPP macros!  */
-  fputs ("m4_changecom()\n", out);
-  fputs ("m4_init()\n", out);
+  obstack_sgrow (out, "m4_changecom()\n");
+  obstack_sgrow (out, "m4_init()\n");
 
-  fputs ("m4_define([b4_actions], \n[[", out);
+  obstack_sgrow (out, "m4_define([b4_actions], \n[[");
   actions_output (out);
-  fputs ("]])\n\n", out);
+  obstack_sgrow (out, "]])\n\n");
 
-  fputs ("m4_define([b4_tokens], \n[", out);
+  obstack_sgrow (out, "m4_define([b4_tokens], \n[");
   token_definitions_output (out);
-  fputs ("])\n\n", out);
+  obstack_sgrow (out, "])\n\n");
 
   muscles_m4_output (out);
 
-  fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
-  fputs ("m4_divert_push(0)dnl\n", out);
-  xfclose (out);
+  obstack_sgrow (out, "m4_wrap([m4_divert_pop(0)])\n");
+  obstack_sgrow (out, "m4_divert_push(0)dnl\n");
+  obstack_1grow(out, '\0');
+
+  m4_buffer = obstack_finish (out);
 
   /* Invoke m4 on the definition of the muscles, and the skeleton. */
   {
+    const char *argv[8];
+    int from, to;
+    size_t len;
+    pid_t pid;
     const char *bison_pkgdatadir = getenv ("BISON_PKGDATADIR");
     const char *m4 = getenv ("M4");
+
     if (!m4)
       m4 = M4;
     if (!bison_pkgdatadir)
       bison_pkgdatadir = PKGDATADIR;
+
+    argv[0] = m4;
+    argv[1] = "-e";   /* input and output are unbuffered */
+    argv[2] = "-I";
+    argv[3] = bison_pkgdatadir;
+    argv[4] = "m4sugar/m4sugar.m4";
+    argv[5] = "-";
+    argv[6] = skeleton;
+    argv[7] = NULL;
+    
     if (trace_flag)
-      fprintf (stderr,
-              "running: %s -I %s m4sugar/m4sugar.m4 %s %s\n",
-              m4, bison_pkgdatadir, tempfile, skeleton);
-    skel_in = readpipe (m4,
-                       "-I", bison_pkgdatadir,
-                       "m4sugar/m4sugar.m4",
-                       tempfile,
-                       skeleton,
-                       NULL);
-    if (!skel_in)
+      {
+       const char **p;
+       
+       fprintf (stderr, "running the following shell command:\n");
+       for (p = argv; *p; ++p) {
+         fprintf (stderr, "%s ", *p);
+       }
+       fprintf (stderr, "<<'m4_EOF'\n");
+       fprintf (stderr, "%s", m4_buffer);
+       fprintf (stderr, "m4_EOF\n\n");
+      }
+
+    pid = open_filter(argv, &from, &to);
+    if (pid < 0)
       error (EXIT_FAILURE, errno, "cannot run m4");
-    skel_lex ();
 
-    /* If `debugging', keep this file alive. */
-    if (!trace_flag)
-      unlink (tempfile);
+    len = strlen (m4_buffer);
+    if (write (to, m4_buffer, len) != len) 
+      error (EXIT_FAILURE, errno, "write");
+    close(to);
+
+    skel_in = fdopen (from, "r");
+    if (skel_in == NULL)
+      error (EXIT_FAILURE, errno, "fdopen");
+    skel_lex ();
+    
+    close(from);
   }
+
+  obstack_free (out, NULL);
 }
 
 static void
@@ -1087,3 +1105,4 @@
   obstack_free (&pre_prologue_obstack, NULL);
   obstack_free (&post_prologue_obstack, NULL);
 }
+
Index: bison/src/output.h
===================================================================
RCS file: /cvsroot/bison/bison/src/output.h,v
retrieving revision 1.9
diff -u -r1.9 output.h
--- bison/src/output.h  2 May 2002 15:06:46 -0000       1.9
+++ bison/src/output.h  12 May 2002 17:11:19 -0000
@@ -26,9 +26,6 @@
 /* Output the parsing tables and the parser code to FTABLE.  */
 void output PARAMS ((void));
 
-void actions_output PARAMS ((FILE *out));
-void token_definitions_output PARAMS ((FILE *out));
-
 extern struct obstack muscle_obstack;
 
 #endif /* !OUTPUT_H_ */



reply via email to

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