No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gettext / gettext-tools / src / msgunfmt.c
blobb79e3f44d9f82197e74789bdf7d66509918652c4
1 /* msgunfmt - converts binary .mo files to Uniforum style .po files
2 Copyright (C) 1995-1998, 2000-2005 Free Software Foundation, Inc.
3 Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, April 1995.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
23 #include <getopt.h>
24 #include <limits.h>
25 #include <stdbool.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <locale.h>
30 #include "closeout.h"
31 #include "error.h"
32 #include "error-progname.h"
33 #include "progname.h"
34 #include "relocatable.h"
35 #include "basename.h"
36 #include "exit.h"
37 #include "message.h"
38 #include "msgunfmt.h"
39 #include "read-mo.h"
40 #include "read-java.h"
41 #include "read-csharp.h"
42 #include "read-resources.h"
43 #include "read-tcl.h"
44 #include "write-po.h"
45 #include "gettext.h"
47 #define _(str) gettext (str)
50 /* Be more verbose. */
51 bool verbose;
53 /* Java mode input file specification. */
54 static bool java_mode;
55 static const char *java_resource_name;
56 static const char *java_locale_name;
58 /* C# mode input file specification. */
59 static bool csharp_mode;
60 static const char *csharp_resource_name;
61 static const char *csharp_locale_name;
62 static const char *csharp_base_directory;
64 /* C# resources mode input file specification. */
65 static bool csharp_resources_mode;
67 /* Tcl mode input file specification. */
68 static bool tcl_mode;
69 static const char *tcl_locale_name;
70 static const char *tcl_base_directory;
72 /* Force output of PO file even if empty. */
73 static int force_po;
75 /* Long options. */
76 static const struct option long_options[] =
78 { "csharp", no_argument, NULL, CHAR_MAX + 4 },
79 { "csharp-resources", no_argument, NULL, CHAR_MAX + 5 },
80 { "escape", no_argument, NULL, 'E' },
81 { "force-po", no_argument, &force_po, 1 },
82 { "help", no_argument, NULL, 'h' },
83 { "indent", no_argument, NULL, 'i' },
84 { "java", no_argument, NULL, 'j' },
85 { "locale", required_argument, NULL, 'l' },
86 { "no-escape", no_argument, NULL, 'e' },
87 { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
88 { "output-file", required_argument, NULL, 'o' },
89 { "properties-output", no_argument, NULL, 'p' },
90 { "resource", required_argument, NULL, 'r' },
91 { "sort-output", no_argument, NULL, 's' },
92 { "strict", no_argument, NULL, 'S' },
93 { "stringtable-output", no_argument, NULL, CHAR_MAX + 3 },
94 { "tcl", no_argument, NULL, CHAR_MAX + 1 },
95 { "verbose", no_argument, NULL, 'v' },
96 { "version", no_argument, NULL, 'V' },
97 { "width", required_argument, NULL, 'w', },
98 { NULL, 0, NULL, 0 }
102 /* Forward declaration of local functions. */
103 static void usage (int status)
104 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
105 __attribute__ ((noreturn))
106 #endif
108 static void read_one_file (message_list_ty *mlp, const char *filename);
112 main (int argc, char **argv)
114 int optchar;
115 bool do_help = false;
116 bool do_version = false;
117 const char *output_file = "-";
118 msgdomain_list_ty *result;
119 bool sort_by_msgid = false;
121 /* Set program name for messages. */
122 set_program_name (argv[0]);
123 error_print_progname = maybe_print_progname;
125 #ifdef HAVE_SETLOCALE
126 /* Set locale via LC_ALL. */
127 setlocale (LC_ALL, "");
128 #endif
130 /* Set the text message domain. */
131 bindtextdomain (PACKAGE, relocate (LOCALEDIR));
132 textdomain (PACKAGE);
134 /* Ensure that write errors on stdout are detected. */
135 atexit (close_stdout);
137 while ((optchar = getopt_long (argc, argv, "d:eEhijl:o:pr:svVw:",
138 long_options, NULL))
139 != EOF)
140 switch (optchar)
142 case '\0':
143 /* long option */
144 break;
146 case 'd':
147 csharp_base_directory = optarg;
148 tcl_base_directory = optarg;
149 break;
151 case 'e':
152 message_print_style_escape (false);
153 break;
155 case 'E':
156 message_print_style_escape (true);
157 break;
159 case 'h':
160 do_help = true;
161 break;
163 case 'i':
164 message_print_style_indent ();
165 break;
167 case 'j':
168 java_mode = true;
169 break;
171 case 'l':
172 java_locale_name = optarg;
173 csharp_locale_name = optarg;
174 tcl_locale_name = optarg;
175 break;
177 case 'o':
178 output_file = optarg;
179 break;
181 case 'p':
182 message_print_syntax_properties ();
183 break;
185 case 'r':
186 java_resource_name = optarg;
187 csharp_resource_name = optarg;
188 break;
190 case 's':
191 sort_by_msgid = true;
192 break;
194 case 'S':
195 message_print_style_uniforum ();
196 break;
198 case 'v':
199 verbose = true;
200 break;
202 case 'V':
203 do_version = true;
204 break;
206 case 'w':
208 int value;
209 char *endp;
210 value = strtol (optarg, &endp, 10);
211 if (endp != optarg)
212 message_page_width_set (value);
214 break;
216 case CHAR_MAX + 1: /* --tcl */
217 tcl_mode = true;
218 break;
220 case CHAR_MAX + 2: /* --no-wrap */
221 message_page_width_ignore ();
222 break;
224 case CHAR_MAX + 3: /* --stringtable-output */
225 message_print_syntax_stringtable ();
226 break;
228 case CHAR_MAX + 4: /* --csharp */
229 csharp_mode = true;
230 break;
232 case CHAR_MAX + 5: /* --csharp-resources */
233 csharp_resources_mode = true;
234 break;
236 default:
237 usage (EXIT_FAILURE);
238 break;
241 /* Version information is requested. */
242 if (do_version)
244 printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
245 /* xgettext: no-wrap */
246 printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
247 This is free software; see the source for copying conditions. There is NO\n\
248 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
250 "1995-1998, 2000-2005");
251 printf (_("Written by %s.\n"), "Ulrich Drepper");
252 exit (EXIT_SUCCESS);
255 /* Help is requested. */
256 if (do_help)
257 usage (EXIT_SUCCESS);
259 /* Check for contradicting options. */
261 unsigned int modes =
262 (java_mode ? 1 : 0)
263 | (csharp_mode ? 2 : 0)
264 | (csharp_resources_mode ? 4 : 0)
265 | (tcl_mode ? 8 : 0);
266 static const char *mode_options[] =
267 { "--java", "--csharp", "--csharp-resources", "--tcl" };
268 /* More than one bit set? */
269 if (modes & (modes - 1))
271 const char *first_option;
272 const char *second_option;
273 unsigned int i;
274 for (i = 0; ; i++)
275 if (modes & (1 << i))
276 break;
277 first_option = mode_options[i];
278 for (i = i + 1; ; i++)
279 if (modes & (1 << i))
280 break;
281 second_option = mode_options[i];
282 error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
283 first_option, second_option);
286 if (java_mode)
288 if (optind < argc)
290 error (EXIT_FAILURE, 0,
291 _("%s and explicit file names are mutually exclusive"),
292 "--java");
295 else if (csharp_mode)
297 if (optind < argc)
299 error (EXIT_FAILURE, 0,
300 _("%s and explicit file names are mutually exclusive"),
301 "--csharp");
303 if (csharp_locale_name == NULL)
305 error (EXIT_SUCCESS, 0,
306 _("%s requires a \"-l locale\" specification"),
307 "--csharp");
308 usage (EXIT_FAILURE);
310 if (csharp_base_directory == NULL)
312 error (EXIT_SUCCESS, 0,
313 _("%s requires a \"-d directory\" specification"),
314 "--csharp");
315 usage (EXIT_FAILURE);
318 else if (tcl_mode)
320 if (optind < argc)
322 error (EXIT_FAILURE, 0,
323 _("%s and explicit file names are mutually exclusive"),
324 "--tcl");
326 if (tcl_locale_name == NULL)
328 error (EXIT_SUCCESS, 0,
329 _("%s requires a \"-l locale\" specification"),
330 "--tcl");
331 usage (EXIT_FAILURE);
333 if (tcl_base_directory == NULL)
335 error (EXIT_SUCCESS, 0,
336 _("%s requires a \"-d directory\" specification"),
337 "--tcl");
338 usage (EXIT_FAILURE);
341 else
343 if (java_resource_name != NULL)
345 error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"),
346 "--resource", "--java", "--csharp");
347 usage (EXIT_FAILURE);
349 if (java_locale_name != NULL)
351 error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"),
352 "--locale", "--java", "--csharp");
353 usage (EXIT_FAILURE);
357 /* Read the given .mo file. */
358 if (java_mode)
360 result = msgdomain_read_java (java_resource_name, java_locale_name);
362 else if (csharp_mode)
364 result = msgdomain_read_csharp (csharp_resource_name, csharp_locale_name,
365 csharp_base_directory);
367 else if (tcl_mode)
369 result = msgdomain_read_tcl (tcl_locale_name, tcl_base_directory);
371 else
373 message_list_ty *mlp;
375 mlp = message_list_alloc (false);
376 if (optind < argc)
379 read_one_file (mlp, argv[optind]);
380 while (++optind < argc);
382 else
383 read_one_file (mlp, "-");
385 result = msgdomain_list_alloc (false);
386 result->item[0]->messages = mlp;
389 /* Sorting the list of messages. */
390 if (sort_by_msgid)
391 msgdomain_list_sort_by_msgid (result);
393 /* Write the resulting message list to the given .po file. */
394 msgdomain_list_print (result, output_file, force_po, false);
396 /* No problems. */
397 exit (EXIT_SUCCESS);
401 /* Display usage information and exit. */
402 static void
403 usage (int status)
405 if (status != EXIT_SUCCESS)
406 fprintf (stderr, _("Try `%s --help' for more information.\n"),
407 program_name);
408 else
410 printf (_("\
411 Usage: %s [OPTION] [FILE]...\n\
412 "), program_name);
413 printf ("\n");
414 printf (_("\
415 Convert binary message catalog to Uniforum style .po file.\n\
416 "));
417 printf ("\n");
418 printf (_("\
419 Mandatory arguments to long options are mandatory for short options too.\n"));
420 printf ("\n");
421 printf (_("\
422 Operation mode:\n"));
423 printf (_("\
424 -j, --java Java mode: input is a Java ResourceBundle class\n"));
425 printf (_("\
426 --csharp C# mode: input is a .NET .dll file\n"));
427 printf (_("\
428 --csharp-resources C# resources mode: input is a .NET .resources file\n"));
429 printf (_("\
430 --tcl Tcl mode: input is a tcl/msgcat .msg file\n"));
431 printf ("\n");
432 printf (_("\
433 Input file location:\n"));
434 printf (_("\
435 FILE ... input .mo files\n"));
436 printf (_("\
437 If no input file is given or if it is -, standard input is read.\n"));
438 printf ("\n");
439 printf (_("\
440 Input file location in Java mode:\n"));
441 printf (_("\
442 -r, --resource=RESOURCE resource name\n"));
443 printf (_("\
444 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
445 printf (_("\
446 The class name is determined by appending the locale name to the resource name,\n\
447 separated with an underscore. The class is located using the CLASSPATH.\n\
448 "));
449 printf ("\n");
450 printf (_("\
451 Input file location in C# mode:\n"));
452 printf (_("\
453 -r, --resource=RESOURCE resource name\n"));
454 printf (_("\
455 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
456 printf (_("\
457 -d DIRECTORY base directory for locale dependent .dll files\n"));
458 printf (_("\
459 The -l and -d options are mandatory. The .dll file is located in a\n\
460 subdirectory of the specified directory whose name depends on the locale.\n"));
461 printf ("\n");
462 printf (_("\
463 Input file location in Tcl mode:\n"));
464 printf (_("\
465 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
466 printf (_("\
467 -d DIRECTORY base directory of .msg message catalogs\n"));
468 printf (_("\
469 The -l and -d options are mandatory. The .msg file is located in the\n\
470 specified directory.\n"));
471 printf ("\n");
472 printf (_("\
473 Output file location:\n"));
474 printf (_("\
475 -o, --output-file=FILE write output to specified file\n"));
476 printf (_("\
477 The results are written to standard output if no output file is specified\n\
478 or if it is -.\n"));
479 printf ("\n");
480 printf (_("\
481 Output details:\n"));
482 printf (_("\
483 -e, --no-escape do not use C escapes in output (default)\n"));
484 printf (_("\
485 -E, --escape use C escapes in output, no extended chars\n"));
486 printf (_("\
487 --force-po write PO file even if empty\n"));
488 printf (_("\
489 -i, --indent write indented output style\n"));
490 printf (_("\
491 --strict write strict uniforum style\n"));
492 printf (_("\
493 -p, --properties-output write out a Java .properties file\n"));
494 printf (_("\
495 --stringtable-output write out a NeXTstep/GNUstep .strings file\n"));
496 printf (_("\
497 -w, --width=NUMBER set output page width\n"));
498 printf (_("\
499 --no-wrap do not break long message lines, longer than\n\
500 the output page width, into several lines\n"));
501 printf (_("\
502 -s, --sort-output generate sorted output\n"));
503 printf ("\n");
504 printf (_("\
505 Informative output:\n"));
506 printf (_("\
507 -h, --help display this help and exit\n"));
508 printf (_("\
509 -V, --version output version information and exit\n"));
510 printf (_("\
511 -v, --verbose increase verbosity level\n"));
512 printf ("\n");
513 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
514 stdout);
517 exit (status);
521 static void
522 read_one_file (message_list_ty *mlp, const char *filename)
524 if (csharp_resources_mode)
525 read_resources_file (mlp, filename);
526 else
527 read_mo_file (mlp, filename);