]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Split off the .mo file reader from msgunfmt.
authorBruno Haible <bruno@clisp.org>
Thu, 6 Sep 2001 00:18:00 +0000 (00:18 +0000)
committerBruno Haible <bruno@clisp.org>
Thu, 6 Sep 2001 00:18:00 +0000 (00:18 +0000)
src/ChangeLog
src/Makefile.am
src/msgunfmt.c
src/read-mo.c [new file with mode: 0644]
src/read-mo.h [new file with mode: 0644]

index e1ea0ca491d608956c5afe0fa7a35e0fdf0a1501..0281874c161635b063c7bfdc8a3bc6e6b4dd70eb 100644 (file)
@@ -1,3 +1,14 @@
+2001-09-02  Bruno Haible  <haible@clisp.cons.org>
+
+       * read-mo.h: New file.
+       * read-mo.c: New file, extracted from msgunfmt.c.
+       (read_mo_file): Require non-null message list argument. Return void.
+       * msgunfmt.c (endian, read32, seek32, string32, read_mo_file): Move to
+       read-mo.c.
+       (main): Pass a fresh list, not NULL, to read_mo_file.
+       * Makefile.am (noinst_HEADERS): Add read-mo.h.
+       (msgunfmt_SOURCES): Add read-mo.c.
+
 2001-09-02  Bruno Haible  <haible@clisp.cons.org>
 
        * msgfmt.h (struct hashtable_entry): Remove type.
index 8586a9f7afe0460c9faf94192dfc0b0666fab227..8d9f3c947adb7a54d0e6099e14ffd1137429ebbf 100644 (file)
@@ -26,7 +26,7 @@ msgcat msgcomm msgconv msgen msgexec msggrep msguniq
 noinst_HEADERS = pos.h message.h po-gram.h po-hash.h po-charset.h po-lex.h \
 po.h open-po.h read-po.h str-list.h write-po.h dir-list.h file-list.h \
 po-gram-gen.h po-hash-gen.h msgl-charset.h msgl-iconv.h msgl-ascii.h \
-msgl-cat.h msgfmt.h write-mo.h xgettext.h x-c.h x-po.h
+msgl-cat.h msgfmt.h read-mo.h write-mo.h xgettext.h x-c.h x-po.h
 
 EXTRA_DIST = FILES
 
@@ -51,7 +51,8 @@ format.c format-c.c format-java.c format-lisp.c format-python.c format-ycp.c
 msgmerge_SOURCES = message.c msgmerge.c open-po.c po-gram-gen.y po-hash-gen.y \
 po-charset.c po-lex.c po.c read-po.c str-list.c dir-list.c write-po.c \
 msgl-ascii.c
-msgunfmt_SOURCES = message.c msgunfmt.c str-list.c write-po.c msgl-ascii.c
+msgunfmt_SOURCES = message.c msgunfmt.c str-list.c write-po.c msgl-ascii.c \
+read-mo.c
 xgettext_SOURCES = message.c open-po.c po-gram-gen.y po-hash-gen.y \
 po-charset.c po-lex.c po.c str-list.c xgettext.c dir-list.c write-po.c \
 msgl-ascii.c file-list.c x-c.c x-po.c \
index 4e7f36189d5005c151bf989ecec78f0927bc6fa9..c44aba4009ae176fe1cec5f5ee7e1b23aa70481a 100644 (file)
 # include <config.h>
 #endif
 
-#include <errno.h>
 #include <getopt.h>
 #include <stdio.h>
-#include <sys/param.h>
-#include <sys/types.h>
 #include <stdlib.h>
 #include <locale.h>
 
-#include "hash.h"
-
 #include "error.h"
 #include "progname.h"
-#include "getline.h"
-#include "printf.h"
-#include <system.h>
-
-#include "gettext.h"
-#include "hash-string.h"
-#include "libgettext.h"
+#include "system.h"
 #include "message.h"
+#include "read-mo.h"
 #include "write-po.h"
+#include "libgettext.h"
 
 #define _(str) gettext (str)
 
-#ifndef errno
-extern int errno;
-#endif
-
 
 /* Force output of PO file even if empty.  */
 static int force_po;
@@ -69,20 +56,9 @@ static const struct option long_options[] =
 };
 
 
-/* This defines the byte order within the file.  It needs to be set
-   appropriately once we have the file open.  */
-static enum { MO_LITTLE_ENDIAN, MO_BIG_ENDIAN } endian;
-
-
 /* Prototypes for local functions.  Needed to ensure compiler checking of
    function argument counts despite of K&R C function definition syntax.  */
 static void usage PARAMS ((int status));
-static nls_uint32 read32 PARAMS ((FILE *fp, const char *fn));
-static void seek32 PARAMS ((FILE *fp, const char *fn, long offset));
-static char *string32 PARAMS ((FILE *fp, const char *fn, long offset,
-                              size_t *lengthp));
-static message_list_ty *read_mo_file PARAMS ((message_list_ty *mlp,
-                                             const char *fn));
 
 
 int
@@ -185,15 +161,15 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
     usage (EXIT_SUCCESS);
 
   /* Read the given .mo file. */
+  mlp = message_list_alloc ();
   if (optind < argc)
     {
-      mlp = NULL;
       do
-       mlp = read_mo_file (mlp, argv[optind]);
+       read_mo_file (mlp, argv[optind]);
       while (++optind < argc);
     }
   else
-    mlp = read_mo_file (NULL, "-");
+    read_mo_file (mlp, "-");
 
   result = msgdomain_list_alloc ();
   result->item[0]->messages = mlp;
@@ -275,179 +251,3 @@ Informative output:\n\
 
   exit (status);
 }
-
-
-/* This function reads a 32-bit number from the file, and assembles it
-   according to the current ``endian'' setting.  */
-static nls_uint32
-read32 (fp, fn)
-     FILE *fp;
-     const char *fn;
-{
-  int c1, c2, c3, c4;
-
-  c1 = getc (fp);
-  if (c1 == EOF)
-    {
-    bomb:
-      if (ferror (fp))
-       error (EXIT_FAILURE, errno, _("error while reading \"%s\""), fn);
-      error (EXIT_FAILURE, 0, _("file \"%s\" truncated"), fn);
-    }
-  c2 = getc (fp);
-  if (c2 == EOF)
-    goto bomb;
-  c3 = getc (fp);
-  if (c3 == EOF)
-    goto bomb;
-  c4 = getc (fp);
-  if (c4 == EOF)
-    goto bomb;
-  if (endian == MO_LITTLE_ENDIAN)
-    return (((nls_uint32) c1)
-           | ((nls_uint32) c2 << 8)
-           | ((nls_uint32) c3 << 16)
-           | ((nls_uint32) c4 << 24));
-
-  return (((nls_uint32) c1 << 24)
-         | ((nls_uint32) c2 << 16)
-         | ((nls_uint32) c3 << 8)
-         | ((nls_uint32) c4));
-}
-
-
-static void
-seek32 (fp, fn, offset)
-     FILE *fp;
-     const char *fn;
-     long offset;
-{
-  if (fseek (fp, offset, 0) < 0)
-    error (EXIT_FAILURE, errno, _("seek \"%s\" offset %ld failed"),
-          fn, offset);
-}
-
-
-static char *
-string32 (fp, fn, offset, lengthp)
-     FILE *fp;
-     const char *fn;
-     long offset;
-     size_t *lengthp;
-{
-  long length;
-  char *buffer;
-  long n;
-
-  /* Read the string_desc structure, describing where in the file to
-     find the string.  */
-  seek32 (fp, fn, offset);
-  length = read32 (fp, fn);
-  offset = read32 (fp, fn);
-
-  /* Allocate memory for the string to be read into.  Leave space for
-     the NUL on the end.  */
-  buffer = (char *) xmalloc (length + 1);
-
-  /* Read in the string.  Complain if there is an error or it comes up
-     short.  Add the NUL ourselves.  */
-  seek32 (fp, fn, offset);
-  n = fread (buffer, 1, length + 1, fp);
-  if (n != length + 1)
-    {
-      if (ferror (fp))
-       error (EXIT_FAILURE, errno, _("error while reading \"%s\""), fn);
-      error (EXIT_FAILURE, 0, _("file \"%s\" truncated"), fn);
-    }
-  if (buffer[length] != '\0')
-    {
-      error (EXIT_FAILURE, 0,
-            _("file \"%s\" contains a not NUL terminated string"), fn);
-    }
-
-  /* Return the string to the caller.  */
-  *lengthp = length + 1;
-  return buffer;
-}
-
-
-/* This function reads an existing .mo file.  Return a message list.  */
-static message_list_ty *
-read_mo_file (mlp, fn)
-     message_list_ty *mlp;
-     const char *fn;
-{
-  FILE *fp;
-  struct mo_file_header header;
-  int j;
-
-  if (strcmp (fn, "-") == 0 || strcmp (fn, "/dev/stdin") == 0)
-    {
-      fp = stdin;
-      SET_BINARY (fileno (fp));
-    }
-  else
-    {
-      fp = fopen (fn, "rb");
-      if (fp == NULL)
-       error (EXIT_FAILURE, errno,
-              _("error while opening \"%s\" for reading"), fn);
-    }
-
-  /* We must grope the file to determine which endian it is.
-     Perversity of the universe tends towards maximum, so it will
-     probably not match the currently executing architecture.  */
-  endian = MO_BIG_ENDIAN;
-  header.magic = read32 (fp, fn);
-  if (header.magic != _MAGIC)
-    {
-      endian = MO_LITTLE_ENDIAN;
-      seek32 (fp, fn, 0L);
-      header.magic = read32 (fp, fn);
-      if (header.magic != _MAGIC)
-       {
-       unrecognised:
-         error (EXIT_FAILURE, 0, _("file \"%s\" is not in GNU .mo format"),
-                fn);
-       }
-    }
-
-  /* Fill the structure describing the header.  */
-  header.revision = read32 (fp, fn);
-  if (header.revision != MO_REVISION_NUMBER)
-    goto unrecognised;
-  header.nstrings = read32 (fp, fn);
-  header.orig_tab_offset = read32 (fp, fn);
-  header.trans_tab_offset = read32 (fp, fn);
-  header.hash_tab_size = read32 (fp, fn);
-  header.hash_tab_offset = read32 (fp, fn);
-
-  if (mlp == NULL)
-    mlp = message_list_alloc ();
-  for (j = 0; j < header.nstrings; ++j)
-    {
-      static lex_pos_ty pos = { __FILE__, __LINE__ };
-      message_ty *mp;
-      char *msgid;
-      size_t msgid_len;
-      char *msgstr;
-      size_t msgstr_len;
-
-      /* Read the msgid.  */
-      msgid = string32 (fp, fn, header.orig_tab_offset + j * 8, &msgid_len);
-
-      /* Read the msgstr.  */
-      msgstr = string32 (fp, fn, header.trans_tab_offset + j * 8, &msgstr_len);
-
-      mp = message_alloc (msgid,
-                         (strlen (msgid) + 1 < msgid_len
-                          ? msgid + strlen (msgid) + 1
-                          : NULL),
-                         msgstr, msgstr_len, &pos);
-      message_list_append (mlp, mp);
-    }
-
-  if (fp != stdin)
-    fclose (fp);
-  return mlp;
-}
diff --git a/src/read-mo.c b/src/read-mo.c
new file mode 100644 (file)
index 0000000..0d7bf18
--- /dev/null
@@ -0,0 +1,224 @@
+/* Reading binary .mo files.
+   Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc.
+   Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, April 1995.
+
+   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.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "read-mo.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* This include file describes the main part of binary .mo format.  */
+#include "gettext.h"
+
+#include "error.h"
+#include "system.h"
+#include "message.h"
+#include "libgettext.h"
+
+#define _(str) gettext (str)
+
+
+/* This defines the byte order within the file.  It needs to be set
+   appropriately once we have the file open.  */
+static enum { MO_LITTLE_ENDIAN, MO_BIG_ENDIAN } endian;
+
+
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
+static nls_uint32 read32 PARAMS ((FILE *fp, const char *fn));
+static void seek32 PARAMS ((FILE *fp, const char *fn, long offset));
+static char *string32 PARAMS ((FILE *fp, const char *fn, long offset,
+                              size_t *lengthp));
+
+
+/* This function reads a 32-bit number from the file, and assembles it
+   according to the current ``endian'' setting.  */
+static nls_uint32
+read32 (fp, fn)
+     FILE *fp;
+     const char *fn;
+{
+  int c1, c2, c3, c4;
+
+  c1 = getc (fp);
+  if (c1 == EOF)
+    {
+    bomb:
+      if (ferror (fp))
+       error (EXIT_FAILURE, errno, _("error while reading \"%s\""), fn);
+      error (EXIT_FAILURE, 0, _("file \"%s\" truncated"), fn);
+    }
+  c2 = getc (fp);
+  if (c2 == EOF)
+    goto bomb;
+  c3 = getc (fp);
+  if (c3 == EOF)
+    goto bomb;
+  c4 = getc (fp);
+  if (c4 == EOF)
+    goto bomb;
+  if (endian == MO_LITTLE_ENDIAN)
+    return (((nls_uint32) c1)
+           | ((nls_uint32) c2 << 8)
+           | ((nls_uint32) c3 << 16)
+           | ((nls_uint32) c4 << 24));
+
+  return (((nls_uint32) c1 << 24)
+         | ((nls_uint32) c2 << 16)
+         | ((nls_uint32) c3 << 8)
+         | ((nls_uint32) c4));
+}
+
+
+static void
+seek32 (fp, fn, offset)
+     FILE *fp;
+     const char *fn;
+     long offset;
+{
+  if (fseek (fp, offset, 0) < 0)
+    error (EXIT_FAILURE, errno, _("seek \"%s\" offset %ld failed"),
+          fn, offset);
+}
+
+
+static char *
+string32 (fp, fn, offset, lengthp)
+     FILE *fp;
+     const char *fn;
+     long offset;
+     size_t *lengthp;
+{
+  long length;
+  char *buffer;
+  long n;
+
+  /* Read the string_desc structure, describing where in the file to
+     find the string.  */
+  seek32 (fp, fn, offset);
+  length = read32 (fp, fn);
+  offset = read32 (fp, fn);
+
+  /* Allocate memory for the string to be read into.  Leave space for
+     the NUL on the end.  */
+  buffer = (char *) xmalloc (length + 1);
+
+  /* Read in the string.  Complain if there is an error or it comes up
+     short.  Add the NUL ourselves.  */
+  seek32 (fp, fn, offset);
+  n = fread (buffer, 1, length + 1, fp);
+  if (n != length + 1)
+    {
+      if (ferror (fp))
+       error (EXIT_FAILURE, errno, _("error while reading \"%s\""), fn);
+      error (EXIT_FAILURE, 0, _("file \"%s\" truncated"), fn);
+    }
+  if (buffer[length] != '\0')
+    {
+      error (EXIT_FAILURE, 0,
+            _("file \"%s\" contains a not NUL terminated string"), fn);
+    }
+
+  /* Return the string to the caller.  */
+  *lengthp = length + 1;
+  return buffer;
+}
+
+
+/* This function reads an existing .mo file.  */
+void
+read_mo_file (mlp, fn)
+     message_list_ty *mlp;
+     const char *fn;
+{
+  FILE *fp;
+  struct mo_file_header header;
+  int j;
+
+  if (strcmp (fn, "-") == 0 || strcmp (fn, "/dev/stdin") == 0)
+    {
+      fp = stdin;
+      SET_BINARY (fileno (fp));
+    }
+  else
+    {
+      fp = fopen (fn, "rb");
+      if (fp == NULL)
+       error (EXIT_FAILURE, errno,
+              _("error while opening \"%s\" for reading"), fn);
+    }
+
+  /* We must grope the file to determine which endian it is.
+     Perversity of the universe tends towards maximum, so it will
+     probably not match the currently executing architecture.  */
+  endian = MO_BIG_ENDIAN;
+  header.magic = read32 (fp, fn);
+  if (header.magic != _MAGIC)
+    {
+      endian = MO_LITTLE_ENDIAN;
+      seek32 (fp, fn, 0L);
+      header.magic = read32 (fp, fn);
+      if (header.magic != _MAGIC)
+       {
+       unrecognised:
+         error (EXIT_FAILURE, 0, _("file \"%s\" is not in GNU .mo format"),
+                fn);
+       }
+    }
+
+  /* Fill the structure describing the header.  */
+  header.revision = read32 (fp, fn);
+  if (header.revision != MO_REVISION_NUMBER)
+    goto unrecognised;
+  header.nstrings = read32 (fp, fn);
+  header.orig_tab_offset = read32 (fp, fn);
+  header.trans_tab_offset = read32 (fp, fn);
+  header.hash_tab_size = read32 (fp, fn);
+  header.hash_tab_offset = read32 (fp, fn);
+
+  for (j = 0; j < header.nstrings; ++j)
+    {
+      static lex_pos_ty pos = { __FILE__, __LINE__ };
+      message_ty *mp;
+      char *msgid;
+      size_t msgid_len;
+      char *msgstr;
+      size_t msgstr_len;
+
+      /* Read the msgid.  */
+      msgid = string32 (fp, fn, header.orig_tab_offset + j * 8, &msgid_len);
+
+      /* Read the msgstr.  */
+      msgstr = string32 (fp, fn, header.trans_tab_offset + j * 8, &msgstr_len);
+
+      mp = message_alloc (msgid,
+                         (strlen (msgid) + 1 < msgid_len
+                          ? msgid + strlen (msgid) + 1
+                          : NULL),
+                         msgstr, msgstr_len, &pos);
+      message_list_append (mlp, mp);
+    }
+
+  if (fp != stdin)
+    fclose (fp);
+}
diff --git a/src/read-mo.h b/src/read-mo.h
new file mode 100644 (file)
index 0000000..de73286
--- /dev/null
@@ -0,0 +1,27 @@
+/* Reading binary .mo files.
+   Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc.
+   Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, April 1995.
+
+   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 _READ_MO_H
+#define _READ_MO_H
+
+#include "message.h"
+
+/* Reads an existing .mo file and adds the messages to mlp.  */
+extern void read_mo_file PARAMS ((message_list_ty *mlp, const char *fn));
+
+#endif /* _READ_MO_H */