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