xref: /netbsd-src/external/gpl2/gettext/dist/gettext-tools/tests/tstngettext.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /* ngettext - retrieve plural form strings from message catalog and print them.
2    Copyright (C) 1995-1997, 2000-2006 Free Software Foundation, Inc.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17 
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 
22 #include <getopt.h>
23 #include <stdbool.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <locale.h>
27 #include <errno.h>
28 
29 #include "closeout.h"
30 #include "error.h"
31 #include "progname.h"
32 #include "relocatable.h"
33 #include "basename.h"
34 #include "exit.h"
35 #include "propername.h"
36 #include "xsetenv.h"
37 
38 #define HAVE_SETLOCALE 1
39 /* Make sure we use the included libintl, not the system's one. */
40 #undef _LIBINTL_H
41 #include "libgnuintl.h"
42 
43 #define _(str) gettext (str)
44 
45 /* Long options.  */
46 static const struct option long_options[] =
47 {
48   { "domain", required_argument, NULL, 'd' },
49   { "env", required_argument, NULL, '=' },
50   { "help", no_argument, NULL, 'h' },
51   { "version", no_argument, NULL, 'V' },
52   { NULL, 0, NULL, 0 }
53 };
54 
55 /* Forward declaration of local functions.  */
56 static void usage (int __status)
57 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
58      __attribute__ ((noreturn))
59 #endif
60 ;
61 
62 int
main(int argc,char * argv[])63 main (int argc, char *argv[])
64 {
65   int optchar;
66   const char *msgid;
67   const char *msgid_plural;
68   const char *count;
69   unsigned long n;
70 
71   /* Default values for command line options.  */
72   bool do_help = false;
73   bool do_version = false;
74   bool environ_changed = false;
75   const char *domain = getenv ("TEXTDOMAIN");
76   const char *domaindir = getenv ("TEXTDOMAINDIR");
77 
78   /* Set program name for message texts.  */
79   set_program_name (argv[0]);
80 
81 #ifdef HAVE_SETLOCALE
82   /* Set locale via LC_ALL.  */
83   setlocale (LC_ALL, "");
84 #endif
85 
86   /* Set the text message domain.  */
87   bindtextdomain (PACKAGE, relocate (LOCALEDIR));
88   textdomain (PACKAGE);
89 
90   /* Ensure that write errors on stdout are detected.  */
91   atexit (close_stdout);
92 
93   /* Parse command line options.  */
94   while ((optchar = getopt_long (argc, argv, "+d:hV", long_options, NULL))
95 	 != EOF)
96     switch (optchar)
97     {
98     case '\0':		/* Long option.  */
99       break;
100     case 'd':
101       domain = optarg;
102       break;
103     case 'h':
104       do_help = true;
105       break;
106     case 'V':
107       do_version = true;
108       break;
109     case '=':
110       {
111 	/* Undocumented option --env sets an environment variable.  */
112 	char *separator = strchr (optarg, '=');
113 	if (separator != NULL)
114 	  {
115 	    *separator = '\0';
116 	    xsetenv (optarg, separator + 1, 1);
117 	    environ_changed = true;
118 	    break;
119 	  }
120       }
121       /*FALLTHROUGH*/
122     default:
123       usage (EXIT_FAILURE);
124     }
125 
126 #ifdef HAVE_SETLOCALE
127   if (environ_changed)
128     /* Set locale again via LC_ALL.  */
129     setlocale (LC_ALL, "");
130 #endif
131 
132   /* Version information is requested.  */
133   if (do_version)
134     {
135       printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
136       /* xgettext: no-wrap */
137       printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
138 This is free software; see the source for copying conditions.  There is NO\n\
139 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
140 "),
141 	      "1995-1997, 2000-2006");
142       printf (_("Written by %s.\n"), proper_name ("Ulrich Drepper"));
143       exit (EXIT_SUCCESS);
144     }
145 
146   /* Help is requested.  */
147   if (do_help)
148     usage (EXIT_SUCCESS);
149 
150   /* More optional command line options.  */
151   if (argc - optind <= 2)
152     error (EXIT_FAILURE, 0, _("missing arguments"));
153 
154   /* Now the mandatory command line options.  */
155   msgid = argv[optind++];
156   msgid_plural = argv[optind++];
157 
158   /* If no domain name is given we print the original string.
159      We mark this assigning NULL to domain.  */
160   if (domain == NULL || domain[0] == '\0')
161     domain = NULL;
162   else
163     /* Bind domain to appropriate directory.  */
164     if (domaindir != NULL && domaindir[0] != '\0')
165       bindtextdomain (domain, domaindir);
166 
167   /* To speed up the plural-2 test, we accept more than one COUNT in one
168      call.  */
169   while (optind < argc)
170     {
171       count = argv[optind++];
172 
173       {
174 	char *endp;
175 	unsigned long tmp_val;
176 
177 	errno = 0;
178 	tmp_val = strtoul (count, &endp, 10);
179 	if (errno == 0 && count[0] != '\0' && endp[0] == '\0')
180 	  n = tmp_val;
181 	else
182 	  /* When COUNT is not valid, use plural.  */
183 	  n = 99;
184       }
185 
186       /* If no domain name is given we don't translate, and we use English
187 	 plural form handling.  */
188       if (domain == NULL)
189 	fputs (n == 1 ? msgid : msgid_plural, stdout);
190       else
191 	/* Write out the result.  */
192 	fputs (dngettext (domain, msgid, msgid_plural, n), stdout);
193     }
194 
195   exit (EXIT_SUCCESS);
196 }
197 
198 
199 /* Display usage information and exit.  */
200 static void
usage(int status)201 usage (int status)
202 {
203   if (status != EXIT_SUCCESS)
204     fprintf (stderr, _("Try `%s --help' for more information.\n"),
205 	     program_name);
206   else
207     {
208       /* xgettext: no-wrap */
209       printf (_("\
210 Usage: %s [OPTION] MSGID MSGID-PLURAL COUNT...\n\
211   -d, --domain=TEXTDOMAIN   retrieve translated message from TEXTDOMAIN\n\
212   -h, --help                display this help and exit\n\
213   -V, --version             display version information and exit\n\
214   MSGID MSGID-PLURAL        translate MSGID (singular) / MSGID-PLURAL (plural)\n\
215   COUNT                     choose singular/plural form based on this value\n"),
216 	      program_name);
217       /* xgettext: no-wrap */
218       printf (_("\
219 \n\
220 If the TEXTDOMAIN parameter is not given, the domain is determined from the\n\
221 environment variable TEXTDOMAIN.  If the message catalog is not found in the\n\
222 regular directory, another location can be specified with the environment\n\
223 variable TEXTDOMAINDIR.\n\
224 Standard search directory: %s\n"), LOCALEDIR);
225       fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"), stdout);
226     }
227 
228   exit (status);
229 }
230