xref: /netbsd-src/external/gpl2/gettext/dist/gettext-tools/src/msgen.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /* Creates an English translation catalog.
2    Copyright (C) 2001-2006 Free Software Foundation, Inc.
3    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2, or (at your option)
8    any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software Foundation,
17    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
18 
19 
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23 
24 #include <getopt.h>
25 #include <limits.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <locale.h>
29 
30 #include "closeout.h"
31 #include "dir-list.h"
32 #include "error.h"
33 #include "error-progname.h"
34 #include "progname.h"
35 #include "relocatable.h"
36 #include "basename.h"
37 #include "message.h"
38 #include "read-catalog.h"
39 #include "read-po.h"
40 #include "read-properties.h"
41 #include "read-stringtable.h"
42 #include "msgl-english.h"
43 #include "write-catalog.h"
44 #include "write-po.h"
45 #include "write-properties.h"
46 #include "write-stringtable.h"
47 #include "exit.h"
48 #include "propername.h"
49 #include "gettext.h"
50 
51 #define _(str) gettext (str)
52 
53 
54 /* Force output of PO file even if empty.  */
55 static int force_po;
56 
57 /* Long options.  */
58 static const struct option long_options[] =
59 {
60   { "add-location", no_argument, &line_comment, 1 },
61   { "directory", required_argument, NULL, 'D' },
62   { "escape", no_argument, NULL, 'E' },
63   { "force-po", no_argument, &force_po, 1 },
64   { "help", no_argument, NULL, 'h' },
65   { "indent", no_argument, NULL, 'i' },
66   { "no-escape", no_argument, NULL, 'e' },
67   { "no-location", no_argument, &line_comment, 0 },
68   { "no-wrap", no_argument, NULL, CHAR_MAX + 1 },
69   { "output-file", required_argument, NULL, 'o' },
70   { "properties-input", no_argument, NULL, 'P' },
71   { "properties-output", no_argument, NULL, 'p' },
72   { "sort-by-file", no_argument, NULL, 'F' },
73   { "sort-output", no_argument, NULL, 's' },
74   { "strict", no_argument, NULL, 'S' },
75   { "stringtable-input", no_argument, NULL, CHAR_MAX + 2 },
76   { "stringtable-output", no_argument, NULL, CHAR_MAX + 3 },
77   { "version", no_argument, NULL, 'V' },
78   { "width", required_argument, NULL, 'w', },
79   { NULL, 0, NULL, 0 }
80 };
81 
82 
83 /* Forward declaration of local functions.  */
84 static void usage (int status)
85 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
86 	__attribute__ ((noreturn))
87 #endif
88 ;
89 
90 
91 int
main(int argc,char ** argv)92 main (int argc, char **argv)
93 {
94   int opt;
95   bool do_help;
96   bool do_version;
97   char *output_file;
98   msgdomain_list_ty *result;
99   catalog_input_format_ty input_syntax = &input_format_po;
100   catalog_output_format_ty output_syntax = &output_format_po;
101   bool sort_by_filepos = false;
102   bool sort_by_msgid = false;
103 
104   /* Set program name for messages.  */
105   set_program_name (argv[0]);
106   error_print_progname = maybe_print_progname;
107 
108 #ifdef HAVE_SETLOCALE
109   /* Set locale via LC_ALL.  */
110   setlocale (LC_ALL, "");
111 #endif
112 
113   /* Set the text message domain.  */
114   bindtextdomain (PACKAGE, relocate (LOCALEDIR));
115   bindtextdomain ("bison-runtime", relocate (BISON_LOCALEDIR));
116   textdomain (PACKAGE);
117 
118   /* Ensure that write errors on stdout are detected.  */
119   atexit (close_stdout);
120 
121   /* Set default values for variables.  */
122   do_help = false;
123   do_version = false;
124   output_file = NULL;
125 
126   while ((opt = getopt_long (argc, argv, "D:eEFhio:pPsVw:", long_options, NULL))
127 	 != EOF)
128     switch (opt)
129       {
130       case '\0':		/* Long option.  */
131 	break;
132 
133       case 'D':
134 	dir_list_append (optarg);
135 	break;
136 
137       case 'e':
138 	message_print_style_escape (false);
139 	break;
140 
141       case 'E':
142 	message_print_style_escape (true);
143 	break;
144 
145       case 'F':
146 	sort_by_filepos = true;
147 	break;
148 
149       case 'h':
150 	do_help = true;
151 	break;
152 
153       case 'i':
154 	message_print_style_indent ();
155 	break;
156 
157       case 'o':
158 	output_file = optarg;
159 	break;
160 
161       case 'p':
162 	output_syntax = &output_format_properties;
163 	break;
164 
165       case 'P':
166 	input_syntax = &input_format_properties;
167 	break;
168 
169       case 's':
170 	sort_by_msgid = true;
171 	break;
172 
173       case 'S':
174 	message_print_style_uniforum ();
175 	break;
176 
177       case 'V':
178 	do_version = true;
179 	break;
180 
181       case 'w':
182 	{
183 	  int value;
184 	  char *endp;
185 	  value = strtol (optarg, &endp, 10);
186 	  if (endp != optarg)
187 	    message_page_width_set (value);
188 	}
189 	break;
190 
191       case CHAR_MAX + 1: /* --no-wrap */
192 	message_page_width_ignore ();
193 	break;
194 
195       case CHAR_MAX + 2: /* --stringtable-input */
196 	input_syntax = &input_format_stringtable;
197 	break;
198 
199       case CHAR_MAX + 3: /* --stringtable-output */
200 	output_syntax = &output_format_stringtable;
201 	break;
202 
203       default:
204 	usage (EXIT_FAILURE);
205 	break;
206       }
207 
208   /* Version information is requested.  */
209   if (do_version)
210     {
211       printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
212       /* xgettext: no-wrap */
213       printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
214 This is free software; see the source for copying conditions.  There is NO\n\
215 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
216 "),
217 	      "2001-2006");
218       printf (_("Written by %s.\n"), proper_name ("Bruno Haible"));
219       exit (EXIT_SUCCESS);
220     }
221 
222   /* Help is requested.  */
223   if (do_help)
224     usage (EXIT_SUCCESS);
225 
226   /* Test whether we have an .po file name as argument.  */
227   if (optind >= argc)
228     {
229       error (EXIT_SUCCESS, 0, _("no input file given"));
230       usage (EXIT_FAILURE);
231     }
232   if (optind + 1 != argc)
233     {
234       error (EXIT_SUCCESS, 0, _("exactly one input file required"));
235       usage (EXIT_FAILURE);
236     }
237 
238   /* Verify selected options.  */
239   if (!line_comment && sort_by_filepos)
240     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
241 	   "--no-location", "--sort-by-file");
242 
243   if (sort_by_msgid && sort_by_filepos)
244     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
245 	   "--sort-output", "--sort-by-file");
246 
247   /* Read input file.  */
248   result = read_catalog_file (argv[optind], input_syntax);
249 
250   /* Add English translations.  */
251   result = msgdomain_list_english (result);
252 
253   /* Sort the results.  */
254   if (sort_by_filepos)
255     msgdomain_list_sort_by_filepos (result);
256   else if (sort_by_msgid)
257     msgdomain_list_sort_by_msgid (result);
258 
259   /* Write the merged message list out.  */
260   msgdomain_list_print (result, output_file, output_syntax, force_po, false);
261 
262   exit (EXIT_SUCCESS);
263 }
264 
265 
266 /* Display usage information and exit.  */
267 static void
usage(int status)268 usage (int status)
269 {
270   if (status != EXIT_SUCCESS)
271     fprintf (stderr, _("Try `%s --help' for more information.\n"),
272 	     program_name);
273   else
274     {
275       printf (_("\
276 Usage: %s [OPTION] INPUTFILE\n\
277 "), program_name);
278       printf ("\n");
279       /* xgettext: no-wrap */
280       printf (_("\
281 Creates an English translation catalog.  The input file is the last\n\
282 created English PO file, or a PO Template file (generally created by\n\
283 xgettext).  Untranslated entries are assigned a translation that is\n\
284 identical to the msgid.\n\
285 "));
286       printf ("\n");
287       printf (_("\
288 Mandatory arguments to long options are mandatory for short options too.\n"));
289       printf ("\n");
290       printf (_("\
291 Input file location:\n"));
292       printf (_("\
293   INPUTFILE                   input PO or POT file\n"));
294       printf (_("\
295   -D, --directory=DIRECTORY   add DIRECTORY to list for input files search\n"));
296       printf (_("\
297 If input file is -, standard input is read.\n"));
298       printf ("\n");
299       printf (_("\
300 Output file location:\n"));
301       printf (_("\
302   -o, --output-file=FILE      write output to specified file\n"));
303       printf (_("\
304 The results are written to standard output if no output file is specified\n\
305 or if it is -.\n"));
306       printf ("\n");
307       printf (_("\
308 Input file syntax:\n"));
309       printf (_("\
310   -P, --properties-input      input file is in Java .properties syntax\n"));
311       printf (_("\
312       --stringtable-input     input file is in NeXTstep/GNUstep .strings syntax\n"));
313       printf ("\n");
314       printf (_("\
315 Output details:\n"));
316       printf (_("\
317   -e, --no-escape             do not use C escapes in output (default)\n"));
318       printf (_("\
319   -E, --escape                use C escapes in output, no extended chars\n"));
320       printf (_("\
321       --force-po              write PO file even if empty\n"));
322       printf (_("\
323   -i, --indent                indented output style\n"));
324       printf (_("\
325       --no-location           suppress '#: filename:line' lines\n"));
326       printf (_("\
327       --add-location          preserve '#: filename:line' lines (default)\n"));
328       printf (_("\
329       --strict                strict Uniforum output style\n"));
330       printf (_("\
331   -p, --properties-output     write out a Java .properties file\n"));
332       printf (_("\
333       --stringtable-output    write out a NeXTstep/GNUstep .strings file\n"));
334       printf (_("\
335   -w, --width=NUMBER          set output page width\n"));
336       printf (_("\
337       --no-wrap               do not break long message lines, longer than\n\
338                               the output page width, into several lines\n"));
339       printf (_("\
340   -s, --sort-output           generate sorted output\n"));
341       printf (_("\
342   -F, --sort-by-file          sort output by file location\n"));
343       printf ("\n");
344       printf (_("\
345 Informative output:\n"));
346       printf (_("\
347   -h, --help                  display this help and exit\n"));
348       printf (_("\
349   -V, --version               output version information and exit\n"));
350       printf ("\n");
351       fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
352 	     stdout);
353     }
354 
355   exit (status);
356 }
357