]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
New program 'ngettext'.
authorBruno Haible <bruno@clisp.org>
Tue, 20 Mar 2001 15:06:33 +0000 (15:06 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 20 Mar 2001 15:06:33 +0000 (15:06 +0000)
po/ChangeLog
po/POTFILES.in
src/ChangeLog
src/Makefile.am
src/ngettext.c [new file with mode: 0644]
tests/xg-test1.ok.po

index d14334026ffe854841a75b71db70cbf5bf1a5ef5..48bd48b56a08634783365d21a6394363e10da39e 100644 (file)
@@ -1,3 +1,7 @@
+2001-03-18  Bruno Haible  <haible@clisp.cons.org>
+
+       * POTFILES.in: Add src/ngettext.c.
+
 2001-03-11  Bruno Haible  <haible@clisp.cons.org>
 
        * de.po: Update from Karl Eichwalder.
index b852f0fbd2528746a192fecc2ebfe2721371f075..c344640703810bc065756642160680666c3b2d6e 100644 (file)
@@ -18,6 +18,7 @@ src/msgcomm.c
 src/msgfmt.c
 src/msgmerge.c
 src/msgunfmt.c
+src/ngettext.c
 src/open-po.c
 src/po-gram-gen.c
 src/po-lex.h
index 29f40a49ae7198c8671178e2e3ac8ff2ab197872..f3f726a98942b364ccc6e63227757e3ca594d1e0 100644 (file)
@@ -1,3 +1,12 @@
+2001-03-18  Bruno Haible  <haible@clisp.cons.org>
+
+       * gettext.c [TESTS]: When testing, set HAVE_SETLOCALE.
+       (main): Expand escape sequences also if no domain is given. Don't need
+       to call bindtextdomain if there are no string arguments.
+       * ngettext.c: New file.
+       * Makefile.am (bin_PROGRAMS): Add ngettext.
+       (ngettext_SOURCES): New variable.
+
 2001-03-19  Bruno Haible  <haible@clisp.cons.org>
 
        * xgettext.c (extension_to_language): Recognize "*.cpp" and "*.hpp" as
index 2284f19d4a14dc32eb8dd6eda95ee0f6ad5cc3d7..1b8e8ec325f539358d918deae05b182b39a23b64 100644 (file)
@@ -19,7 +19,7 @@
 
 AUTOMAKE_OPTIONS = 1.2 gnits
 
-bin_PROGRAMS = gettext msgcmp msgfmt msgmerge msgunfmt xgettext msgcomm
+bin_PROGRAMS = gettext ngettext msgcmp msgfmt msgmerge msgunfmt xgettext msgcomm
 
 noinst_HEADERS = pos.h message.h po-gram.h po-hash.h po-lex.h po.h open-po.h \
 str-list.h write-po.h xget-lex.h dir-list.h po-gram-gen.h po-hash-gen.h
@@ -39,6 +39,7 @@ YACC = @YACC@ -d
 
 # Source dependencies.
 gettext_SOURCES = gettext.c
+ngettext_SOURCES = ngettext.c
 msgcmp_SOURCES = message.c msgcmp.c open-po.c po-gram-gen.y po-hash-gen.y \
 po-lex.c po.c str-list.c dir-list.c
 msgfmt_SOURCES = msgfmt.c open-po.c po-gram-gen.y po-hash-gen.y po-lex.c po.c \
diff --git a/src/ngettext.c b/src/ngettext.c
new file mode 100644 (file)
index 0000000..2b31f83
--- /dev/null
@@ -0,0 +1,320 @@
+/* ngettext - retrieve plural form string from message catalog and print it.
+   Copyright (C) 1995-1997, 2000, 2001 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.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <errno.h>
+
+#include "error.h"
+#include "system.h"
+
+#include "libgettext.h"
+
+#define _(str) gettext (str)
+
+/* If nonzero expand escape sequences in strings before looking in the
+   message catalog.  */
+int do_expand;
+
+/* Name the program is called with.  */
+char *program_name;
+
+/* Long options.  */
+static const struct option long_options[] =
+{
+  { "domain", required_argument, NULL, 'd' },
+  { "help", no_argument, NULL, 'h' },
+  { "version", no_argument, NULL, 'V' },
+  { NULL, 0, NULL, 0 }
+};
+
+/* Prototypes for local functions.  */
+static void usage PARAMS ((int __status))
+#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
+     __attribute__ ((noreturn))
+#endif
+;
+static const char *expand_escape PARAMS ((const char *__str));
+
+int
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+  int optchar;
+  const char *msgid;
+  const char *msgid_plural;
+  const char *count;
+  unsigned long n;
+
+  /* Default values for command line options.  */
+  int do_help = 0;
+  int do_version = 0;
+  const char *domain = getenv ("TEXTDOMAIN");
+  const char *domaindir = getenv ("TEXTDOMAINDIR");
+  do_expand = 0;
+
+  /* Set program name for message texts.  */
+  program_name = argv[0];
+
+#ifdef HAVE_SETLOCALE
+  /* Set locale via LC_ALL.  */
+  setlocale (LC_ALL, "");
+#endif
+
+  /* Set the text message domain.  */
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
+  /* Parse command line options.  */
+  while ((optchar = getopt_long (argc, argv, "+d:eEhV", long_options, NULL))
+        != EOF)
+    switch (optchar)
+    {
+    case '\0':         /* Long option.  */
+      break;
+    case 'd':
+      domain = optarg;
+      break;
+    case 'e':
+      do_expand = 1;
+      break;
+    case 'E':
+      /* Ignore.  Just for compatibility.  */
+      break;
+    case 'h':
+      do_help = 1;
+      break;
+    case 'V':
+      do_version = 1;
+      break;
+    default:
+      usage (EXIT_FAILURE);
+    }
+
+  /* Version information is requested.  */
+  if (do_version)
+    {
+      printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
+      /* xgettext: no-wrap */
+      printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
+This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"),
+             "1995-1997, 2000, 2001");
+      printf (_("Written by %s.\n"), "Ulrich Drepper");
+      exit (EXIT_SUCCESS);
+    }
+
+  /* Help is requested.  */
+  if (do_help)
+    usage (EXIT_SUCCESS);
+
+  /* More optional command line options.  */
+  switch (argc - optind)
+    {
+    default:
+      error (EXIT_FAILURE, 0, _("too many arguments"));
+
+    case 4:
+      domain = argv[optind++];
+      /* FALLTHROUGH */
+
+    case 3:
+      break;
+
+    case 2:
+    case 1:
+    case 0:
+      error (EXIT_FAILURE, 0, _("missing arguments"));
+    }
+
+  /* Now the mandatory command line options.  */
+  msgid = argv[optind++];
+  msgid_plural = argv[optind++];
+  count = argv[optind++];
+
+  if (optind != argc)
+    abort ();
+
+  {
+    char *endp;
+    unsigned long tmp_val;
+
+    errno = 0;
+    tmp_val = strtoul (count, &endp, 10);
+    if (errno == 0 && count[0] != '\0' && endp[0] == '\0')
+      n = tmp_val;
+    else
+      /* When COUNT is not valid, use plural.  */
+      n = 99;
+  }
+
+  /* Expand escape sequences if enabled.  */
+  if (do_expand)
+    {
+      msgid = expand_escape (msgid);
+      msgid_plural = expand_escape (msgid_plural);
+    }
+
+  /* If no domain name is given we don't translate, and we use English
+     plural form handling.  */
+  if (domain == NULL || domain[0] == '\0')
+    fputs (n == 1 ? msgid : msgid_plural, stdout);
+  else
+    {
+      /* Bind domain to appropriate directory.  */
+      if (domaindir != NULL && domaindir[0] != '\0')
+       bindtextdomain (domain, domaindir);
+
+      /* Write out the result.  */
+      fputs (dngettext (domain, msgid, msgid_plural, n), stdout);
+    }
+
+  exit (EXIT_SUCCESS);
+}
+
+
+/* Display usage information and exit.  */
+static void
+usage (status)
+     int status;
+{
+  if (status != EXIT_SUCCESS)
+    fprintf (stderr, _("Try `%s --help' for more information.\n"),
+            program_name);
+  else
+    {
+      /* xgettext: no-wrap */
+      printf (_("\
+Usage: %s [OPTION] [TEXTDOMAIN] MSGID MSGID-PLURAL COUNT\n\
+  -d, --domain=TEXTDOMAIN   retrieve translated message from TEXTDOMAIN\n\
+  -e                        enable expansion of some escape sequences\n\
+  -E                        (ignored for compatibility)\n\
+  -h, --help                display this help and exit\n\
+  -V, --version             display version information and exit\n\
+  [TEXTDOMAIN]              retrieve translated message from TEXTDOMAIN\n\
+  MSGID MSGID-PLURAL        translate MSGID (singular) / MSGID-PLURAL (plural)\n\
+  COUNT                     choose singular/plural form based on this value\n"),
+             program_name);
+      /* xgettext: no-wrap */
+      printf (_("\
+\n\
+If the TEXTDOMAIN parameter is not given, the domain is determined from the\n\
+environment variable TEXTDOMAIN.  If the message catalog is not found in the\n\
+regular directory, another location can be specified with the environment\n\
+variable TEXTDOMAINDIR.\n\
+Standard search directory: %s\n"), LOCALEDIR);
+      fputs (_("Report bugs to <bug-gnu-utils@gnu.org>.\n"), stdout);
+    }
+
+  exit (status);
+}
+
+
+/* Expand some escape sequences found in the argument string.  */
+static const char *
+expand_escape (str)
+     const char *str;
+{
+  char *retval, *rp;
+  const char *cp = str;
+
+  do
+    {
+      while (cp[0] != '\0' && cp[0] != '\\')
+       ++cp;
+    }
+  while (cp[0] != '\0' && cp[1] != '\0'
+        && strchr ("bfnrt\\01234567", cp[1]) == NULL);
+
+  if (cp[0] == '\0')
+    return str;
+
+  retval = (char *) xmalloc (strlen (str));
+
+  rp = retval + (cp - str);
+  memcpy (retval, str, cp - str);
+
+  do
+    {
+      switch (*++cp)
+       {
+       case 'b':               /* backspace */
+         *rp++ = '\b';
+         ++cp;
+         break;
+       case 'f':               /* form feed */
+         *rp++ = '\f';
+         ++cp;
+         break;
+       case 'n':               /* new line */
+         *rp++ = '\n';
+         ++cp;
+         break;
+       case 'r':               /* carriage return */
+         *rp++ = '\r';
+         ++cp;
+         break;
+       case 't':               /* horizontal tab */
+         *rp++ = '\t';
+         ++cp;
+         break;
+       case '\\':
+         *rp = '\\';
+         ++cp;
+         break;
+       case '0': case '1': case '2': case '3':
+       case '4': case '5': case '6': case '7':
+         {
+           int ch = *cp++ - '0';
+
+           if (*cp >= '0' && *cp <= '7')
+             {
+               ch *= 8;
+               ch += *cp++ - '0';
+
+               if (*cp >= '0' && *cp <= '7')
+                 {
+                   ch *= 8;
+                   ch += *cp++ - '0';
+                 }
+             }
+           *rp = ch;
+         }
+         break;
+       default:
+         *rp = '\\';
+         break;
+       }
+
+      while (cp[0] != '\0' && cp[0] != '\\')
+       *rp++ = *cp++;
+    }
+  while (cp[0] != '\0');
+
+  /* Terminate string.  */
+  *rp = '\0';
+
+  return (const char *) retval;
+}
index 0b01f9f9a50438327b3bf220c0672d4589568308..bc4d73a18f2b1d9b68e9a4567aa01a7893f40cc1 100644 (file)
@@ -232,10 +232,10 @@ msgstr ""
 msgid "format specifications for argument %lu are not the same"
 msgstr ""
 
-msgid "missing arguments"
+msgid "too many arguments"
 msgstr ""
 
-msgid "too many arguments"
+msgid "missing arguments"
 msgstr ""
 
 #, c-format, no-wrap