]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Port msgfilter to Woe32 platforms.
authorBruno Haible <bruno@clisp.org>
Tue, 4 Aug 2009 06:55:16 +0000 (08:55 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 4 Aug 2009 06:55:16 +0000 (08:55 +0200)
ChangeLog
NEWS
autogen.sh
gettext-tools/gnulib-lib/.gitignore
gettext-tools/gnulib-tests/.gitignore
gettext-tools/src/ChangeLog
gettext-tools/src/msgfilter.c

index efde4744255d4e2f1ab9f3a518368e4fa8a9f15b..a6e0b3879c7fbd756ca28b7612afd8839feaf9bb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-08-04  Bruno Haible  <bruno@clisp.org>
+
+       Port msgfilter to Woe32 platforms.
+       * autogen.sh (GNULIB_MODULES_TOOLS_FOR_SRC): Add pipe-filter-ii.
+
 2009-08-03  Bruno Haible  <bruno@clisp.org>
 
        * autogen.sh: Remove statements to fix permissions. Now fixed in git.
diff --git a/NEWS b/NEWS
index ab8bb1b6448722ae6bed3e917bdf4afa0b6cff0a..6870a42e53a2c415f678ff2684be8e0582db1aa6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,9 @@ Version 0.18 - January 2008
   'gfc-internal-format'.
 
 * Updated the meaning of 'gcc-internal-format' to match GCC 4.3.
+
+* Portability:
+  The msgfilter program now also works on native Woe32 platforms.
 \f
 Version 0.17 - November 2007
 
index 9b637ee3e361fd6e151978a34dc7762edd8d856d..98a2803501a2cb1e022c672e38a481cb5ca4c049 100755 (executable)
@@ -152,6 +152,7 @@ if ! $skip_gnulib; then
       openmp
       ostream
       pipe
+      pipe-filter-ii
       progname
       propername
       relocatable-prog
index 2c6fda36819c31182ed88bada936db51d2280f0e..3a3dde744ff762a25ec352d36c563d5fffcad3be 100644 (file)
 /ostream.oo.c
 /ostream.oo.h
 /pathmax.h
+/pipe-filter-aux.h
+/pipe-filter-ii.c
+/pipe-filter.c
+/pipe-filter.h
 /pipe-safer.c
 /pipe.c
 /pipe.h
index b37c6747d4fc6116b510d3d44e5fc3d507afcc44..d78e0bfb302689164beadd3228fef395704aadd4 100644 (file)
 /test-moo-sub2.oo.c
 /test-moo-sub2.oo.h
 /test-open.c
+/test-pipe-filter-ii1.c
+/test-pipe-filter-ii1.sh
+/test-pipe-filter-ii2-child.c
+/test-pipe-filter-ii2-main.c
+/test-pipe-filter-ii2.sh
+/test-pipe-filter.c
+/test-pipe-filter.sh
 /test-pipe.c
 /test-pipe.sh
 /test-posix_spawn1.c
 /test-term-ostream.c
 /test-tls.c
 /test-unistd.c
+/test-vasnprintf-posix.c
 /test-vasnprintf.c
 /test-vasprintf.c
 /test-vsnprintf.c
index 0d68bdcbd4682bf4e2794b0ca463f0d25884d2e3..83588505b5d52de1efb06b7726a2ca3df0dd82bf 100644 (file)
@@ -1,3 +1,17 @@
+2009-08-04  Bruno Haible  <bruno@clisp.org>
+
+       Port msgfilter to Woe32 platforms.
+       * msgfilter.c: Don't include errno.h, fcntl.h, io.h, sys/select.h,
+       pipe.h, wait-process.h. Include pipe-filter.h instead.
+       (HAVE_SELECT): Remove undefine.
+       (nonintr_close, nonintr_read, nonintr_write, nonintr_select): Remove
+       functions.
+       (O_NONBLOCK): Remove fallback.
+       (IS_EAGAIN): Remove macro.
+       (struct locals): New type.
+       (prepare_write, done_write, prepare_read, done_read): New functions.
+       (generic_filter): Implement using pipe_filter_ii_execute.
+
 2009-07-27  Часлав Илић (Chusslove Illich)  <caslav.ilic@gmx.net>
 
        Extend recode-sr-latin to also transform letters with accents.
index 69f67a560d6a08696d5747a723a6cb3dc9677dd4..88662ba0e9ae58c538fa1d8f9a1f4d0c9e2799fb 100644 (file)
@@ -20,8 +20,6 @@
 # include "config.h"
 #endif
 
-#include <errno.h>
-#include <fcntl.h>
 #include <getopt.h>
 #include <limits.h>
 #include <locale.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <unistd.h>
-#if defined _MSC_VER || defined __MINGW32__
-# include <io.h>
-#endif
-
-/* Get fd_set (on AIX or Minix) or select() declaration (on EMX).  */
-#if defined (_AIX) || defined (_MINIX) || defined (__EMX__)
-# include <sys/select.h>
-#endif
 
 #include "closeout.h"
 #include "dir-list.h"
@@ -60,8 +50,7 @@
 #include "msgl-charset.h"
 #include "xalloc.h"
 #include "findprog.h"
-#include "pipe.h"
-#include "wait-process.h"
+#include "pipe-filter.h"
 #include "xsetenv.h"
 #include "filters.h"
 #include "msgl-iconv.h"
 #define _(str) gettext (str)
 
 
-/* We use a child process, and communicate through a bidirectional pipe.
-   To avoid deadlocks, let the child process decide when it wants to read
-   or to write, and let the parent behave accordingly.  The parent uses
-   select() to know whether it must write or read.  On platforms without
-   select(), we use non-blocking I/O.  (This means the parent is busy
-   looping while waiting for the child.  Not good.)  */
-
-/* On BeOS select() works only on sockets, not on normal file descriptors.  */
-#ifdef __BEOS__
-# undef HAVE_SELECT
-#endif
+/* We use a child process, and communicate through a bidirectional pipe.  */
 
 
 /* Force output of PO file even if empty.  */
@@ -495,87 +474,64 @@ Informative output:\n"));
 }
 
 
-#ifdef EINTR
-
-/* EINTR handling for close(), read(), write(), select().
-   These functions can return -1/EINTR even though we don't have any
-   signal handlers set up, namely when we get interrupted via SIGSTOP.  */
+/* Callbacks called from pipe_filter_ii_execute.  */
 
-static inline int
-nonintr_close (int fd)
+struct locals
 {
-  int retval;
+  /* String being written.  */
+  const char *str;
+  size_t len;
+  /* String being read and accumulated.  */
+  char *result;
+  size_t allocated;
+  size_t length;
+};
 
-  do
-    retval = close (fd);
-  while (retval < 0 && errno == EINTR);
+static const void *
+prepare_write (size_t *num_bytes_p, void *private_data)
+{
+  struct locals *l = (struct locals *) private_data;
 
-  return retval;
+  if (l->len > 0)
+    {
+      *num_bytes_p = l->len;
+      return l->str;
+    }
+  else
+    return NULL;
 }
-#define close nonintr_close
 
-static inline ssize_t
-nonintr_read (int fd, void *buf, size_t count)
+static void
+done_write (void *data_written, size_t num_bytes_written, void *private_data)
 {
-  ssize_t retval;
+  struct locals *l = (struct locals *) private_data;
 
-  do
-    retval = read (fd, buf, count);
-  while (retval < 0 && errno == EINTR);
-
-  return retval;
+  l->str += num_bytes_written;
+  l->len -= num_bytes_written;
 }
-#define read nonintr_read
 
-static inline ssize_t
-nonintr_write (int fd, const void *buf, size_t count)
+static void *
+prepare_read (size_t *num_bytes_p, void *private_data)
 {
-  ssize_t retval;
-
-  do
-    retval = write (fd, buf, count);
-  while (retval < 0 && errno == EINTR);
+  struct locals *l = (struct locals *) private_data;
 
-  return retval;
+  if (l->length == l->allocated)
+    {
+      l->allocated = l->allocated + (l->allocated >> 1);
+      l->result = (char *) xrealloc (l->result, l->allocated);
+    }
+  *num_bytes_p = l->allocated - l->length;
+  return l->result + l->length;
 }
-#undef write /* avoid warning on VMS */
-#define write nonintr_write
 
-# if HAVE_SELECT
-
-static inline int
-nonintr_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-               struct timeval *timeout)
+static void
+done_read (void *data_read, size_t num_bytes_read, void *private_data)
 {
-  int retval;
-
-  do
-    retval = select (n, readfds, writefds, exceptfds, timeout);
-  while (retval < 0 && errno == EINTR);
+  struct locals *l = (struct locals *) private_data;
 
-  return retval;
+  l->length += num_bytes_read;
 }
-#undef select /* avoid warning on VMS */
-#define select nonintr_select
 
-# endif
-
-#endif
-
-
-/* Non-blocking I/O.  */
-#ifndef O_NONBLOCK
-# define O_NONBLOCK O_NDELAY
-#endif
-#if HAVE_SELECT
-# define IS_EAGAIN(errcode) 0
-#else
-# ifdef EWOULDBLOCK
-#  define IS_EAGAIN(errcode) ((errcode) == EAGAIN || (errcode) == EWOULDBLOCK)
-# else
-#  define IS_EAGAIN(errcode) ((errcode) == EAGAIN)
-# endif
-#endif
 
 /* Process a string STR of size LEN bytes through the subprogram.
    Store the freshly allocated result at *RESULTP and its length at *LENGTHP.
@@ -583,140 +539,20 @@ nonintr_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 static void
 generic_filter (const char *str, size_t len, char **resultp, size_t *lengthp)
 {
-#if defined _MSC_VER || defined __MINGW32__
-  /* Native Woe32 API.  */
-  /* Not yet implemented.  */
-  error (EXIT_FAILURE, 0, _("Not yet implemented."));
-#else
-  pid_t child;
-  int fd[2];
-  char *result;
-  size_t allocated;
-  size_t length;
-  int exitstatus;
-
-  /* Open a bidirectional pipe to a subprocess.  */
-  child = create_pipe_bidi (sub_name, sub_path, sub_argv, false, true, true,
-                           fd);
-
-  /* Enable non-blocking I/O.  This permits the read() and write() calls
-     to return -1/EAGAIN without blocking; this is important for polling
-     if HAVE_SELECT is not defined.  It also permits the read() and write()
-     calls to return after partial reads/writes; this is important if
-     HAVE_SELECT is defined, because select() only says that some data
-     can be read or written, not how many.  Without non-blocking I/O,
-     Linux 2.2.17 and BSD systems prefer to block instead of returning
-     with partial results.  */
-  {
-    int fcntl_flags;
-
-    if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0
-       || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) < 0
-       || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0
-       || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) < 0)
-      error (EXIT_FAILURE, errno,
-            _("cannot set up nonblocking I/O to %s subprocess"), sub_name);
-  }
-
-  allocated = len + (len >> 2) + 1;
-  result = XNMALLOC (allocated, char);
-  length = 0;
-
-  for (;;)
-    {
-#if HAVE_SELECT
-      int n;
-      fd_set readfds;
-      fd_set writefds;
-
-      FD_ZERO (&readfds);
-      FD_SET (fd[0], &readfds);
-      n = fd[0] + 1;
-      if (str != NULL)
-       {
-         FD_ZERO (&writefds);
-         FD_SET (fd[1], &writefds);
-         if (n <= fd[1])
-           n = fd[1] + 1;
-       }
-
-      n = select (n, &readfds, (str != NULL ? &writefds : NULL), NULL, NULL);
-      if (n < 0)
-       error (EXIT_FAILURE, errno,
-              _("communication with %s subprocess failed"), sub_name);
-      if (str != NULL && FD_ISSET (fd[1], &writefds))
-       goto try_write;
-      if (FD_ISSET (fd[0], &readfds))
-       goto try_read;
-      /* How could select() return if none of the two descriptors is ready?  */
-      abort ();
-#endif
-
-      /* Attempt to write.  */
-#if HAVE_SELECT
-    try_write:
-#endif
-      if (str != NULL)
-       {
-         if (len > 0)
-           {
-             ssize_t nwritten = write (fd[1], str, len);
-             if (nwritten < 0 && !IS_EAGAIN (errno))
-               error (EXIT_FAILURE, errno,
-                      _("write to %s subprocess failed"), sub_name);
-             if (nwritten > 0)
-               {
-                 str += nwritten;
-                 len -= nwritten;
-               }
-           }
-         else
-           {
-             /* Tell the child there is nothing more the parent will send.  */
-             close (fd[1]);
-             str = NULL;
-           }
-       }
-#if HAVE_SELECT
-      continue;
-#endif
-
-      /* Attempt to read.  */
-#if HAVE_SELECT
-    try_read:
-#endif
-      if (length == allocated)
-       {
-         allocated = allocated + (allocated >> 1);
-         result = (char *) xrealloc (result, allocated);
-       }
-      {
-       ssize_t nread = read (fd[0], result + length, allocated - length);
-       if (nread < 0 && !IS_EAGAIN (errno))
-         error (EXIT_FAILURE, errno,
-                _("read from %s subprocess failed"), sub_name);
-       if (nread > 0)
-         length += nread;
-       if (nread == 0 && str == NULL)
-         break;
-      }
-#if HAVE_SELECT
-      continue;
-#endif
-    }
+  struct locals l;
 
-  close (fd[0]);
+  l.str = str;
+  l.len = len;
+  l.allocated = len + (len >> 2) + 1;
+  l.result = XNMALLOC (l.allocated, char);
+  l.length = 0;
 
-  /* Remove zombie process from process list.  */
-  exitstatus =
-    wait_subprocess (child, sub_name, false, false, true, true, NULL);
-  if (exitstatus != 0)
-    error (EXIT_FAILURE, 0, _("%s subprocess terminated with exit code %d"),
-          sub_name, exitstatus);
+  pipe_filter_ii_execute (sub_name, sub_path, sub_argv, false, true,
+                         prepare_write, done_write, prepare_read, done_read,
+                         &l);
 
-  *resultp = result;
-  *lengthp = length;
-#endif
+  *resultp = l.result;
+  *lengthp = l.length;
 }