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