1 /* msgunfmt - converts binary .mo files to Uniforum style .po files
2 Copyright (C) 1995-1998, 2000-2007, 2009-2010 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 3 of the License, or
8 (at your option) 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, see <http://www.gnu.org/licenses/>. */
31 #include "error-progname.h"
33 #include "relocatable.h"
38 #include "read-java.h"
39 #include "read-csharp.h"
40 #include "read-resources.h"
42 #include "write-catalog.h"
44 #include "write-properties.h"
45 #include "write-stringtable.h"
47 #include "propername.h"
50 #define _(str) gettext (str)
53 /* Be more verbose. */
56 /* Java mode input file specification. */
57 static bool java_mode;
58 static const char *java_resource_name;
59 static const char *java_locale_name;
61 /* C# mode input file specification. */
62 static bool csharp_mode;
63 static const char *csharp_resource_name;
64 static const char *csharp_locale_name;
65 static const char *csharp_base_directory;
67 /* C# resources mode input file specification. */
68 static bool csharp_resources_mode;
70 /* Tcl mode input file specification. */
72 static const char *tcl_locale_name;
73 static const char *tcl_base_directory;
75 /* Force output of PO file even if empty. */
79 static const struct option long_options[] =
81 { "color", optional_argument, NULL, CHAR_MAX + 6 },
82 { "csharp", no_argument, NULL, CHAR_MAX + 4 },
83 { "csharp-resources", no_argument, NULL, CHAR_MAX + 5 },
84 { "escape", no_argument, NULL, 'E' },
85 { "force-po", no_argument, &force_po, 1 },
86 { "help", no_argument, NULL, 'h' },
87 { "indent", no_argument, NULL, 'i' },
88 { "java", no_argument, NULL, 'j' },
89 { "locale", required_argument, NULL, 'l' },
90 { "no-escape", no_argument, NULL, 'e' },
91 { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
92 { "output-file", required_argument, NULL, 'o' },
93 { "properties-output", no_argument, NULL, 'p' },
94 { "resource", required_argument, NULL, 'r' },
95 { "sort-output", no_argument, NULL, 's' },
96 { "strict", no_argument, NULL, 'S' },
97 { "stringtable-output", no_argument, NULL, CHAR_MAX + 3 },
98 { "style", required_argument, NULL, CHAR_MAX + 7 },
99 { "tcl", no_argument, NULL, CHAR_MAX + 1 },
100 { "verbose", no_argument, NULL, 'v' },
101 { "version", no_argument, NULL, 'V' },
102 { "width", required_argument, NULL, 'w', },
107 /* Forward declaration of local functions. */
108 static void usage (int status)
109 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
110 __attribute__ ((noreturn))
113 static void read_one_file (message_list_ty *mlp, const char *filename);
117 main (int argc, char **argv)
120 bool do_help = false;
121 bool do_version = false;
122 const char *output_file = "-";
123 msgdomain_list_ty *result;
124 catalog_output_format_ty output_syntax = &output_format_po;
125 bool sort_by_msgid = false;
127 /* Set program name for messages. */
128 set_program_name (argv[0]);
129 error_print_progname = maybe_print_progname;
131 #ifdef HAVE_SETLOCALE
132 /* Set locale via LC_ALL. */
133 setlocale (LC_ALL, "");
136 /* Set the text message domain. */
137 bindtextdomain (PACKAGE, relocate (LOCALEDIR));
138 bindtextdomain ("bison-runtime", relocate (BISON_LOCALEDIR));
139 textdomain (PACKAGE);
141 /* Ensure that write errors on stdout are detected. */
142 atexit (close_stdout);
144 while ((optchar = getopt_long (argc, argv, "d:eEhijl:o:pr:svVw:",
154 csharp_base_directory = optarg;
155 tcl_base_directory = optarg;
159 message_print_style_escape (false);
163 message_print_style_escape (true);
171 message_print_style_indent ();
179 java_locale_name = optarg;
180 csharp_locale_name = optarg;
181 tcl_locale_name = optarg;
185 output_file = optarg;
189 output_syntax = &output_format_properties;
193 java_resource_name = optarg;
194 csharp_resource_name = optarg;
198 sort_by_msgid = true;
202 message_print_style_uniforum ();
217 value = strtol (optarg, &endp, 10);
219 message_page_width_set (value);
223 case CHAR_MAX + 1: /* --tcl */
227 case CHAR_MAX + 2: /* --no-wrap */
228 message_page_width_ignore ();
231 case CHAR_MAX + 3: /* --stringtable-output */
232 output_syntax = &output_format_stringtable;
235 case CHAR_MAX + 4: /* --csharp */
239 case CHAR_MAX + 5: /* --csharp-resources */
240 csharp_resources_mode = true;
243 case CHAR_MAX + 6: /* --color */
244 if (handle_color_option (optarg) || color_test_mode)
245 usage (EXIT_FAILURE);
248 case CHAR_MAX + 7: /* --style */
249 handle_style_option (optarg);
253 usage (EXIT_FAILURE);
257 /* Version information is requested. */
260 printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
261 /* xgettext: no-wrap */
262 printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
263 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
264 This is free software: you are free to change and redistribute it.\n\
265 There is NO WARRANTY, to the extent permitted by law.\n\
267 "1995-1998, 2000-2010");
268 printf (_("Written by %s.\n"), proper_name ("Ulrich Drepper"));
272 /* Help is requested. */
274 usage (EXIT_SUCCESS);
276 /* Check for contradicting options. */
280 | (csharp_mode ? 2 : 0)
281 | (csharp_resources_mode ? 4 : 0)
282 | (tcl_mode ? 8 : 0);
283 static const char *mode_options[] =
284 { "--java", "--csharp", "--csharp-resources", "--tcl" };
285 /* More than one bit set? */
286 if (modes & (modes - 1))
288 const char *first_option;
289 const char *second_option;
292 if (modes & (1 << i))
294 first_option = mode_options[i];
295 for (i = i + 1; ; i++)
296 if (modes & (1 << i))
298 second_option = mode_options[i];
299 error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
300 first_option, second_option);
307 error (EXIT_FAILURE, 0,
308 _("%s and explicit file names are mutually exclusive"),
312 else if (csharp_mode)
316 error (EXIT_FAILURE, 0,
317 _("%s and explicit file names are mutually exclusive"),
320 if (csharp_locale_name == NULL)
322 error (EXIT_SUCCESS, 0,
323 _("%s requires a \"-l locale\" specification"),
325 usage (EXIT_FAILURE);
327 if (csharp_base_directory == NULL)
329 error (EXIT_SUCCESS, 0,
330 _("%s requires a \"-d directory\" specification"),
332 usage (EXIT_FAILURE);
339 error (EXIT_FAILURE, 0,
340 _("%s and explicit file names are mutually exclusive"),
343 if (tcl_locale_name == NULL)
345 error (EXIT_SUCCESS, 0,
346 _("%s requires a \"-l locale\" specification"),
348 usage (EXIT_FAILURE);
350 if (tcl_base_directory == NULL)
352 error (EXIT_SUCCESS, 0,
353 _("%s requires a \"-d directory\" specification"),
355 usage (EXIT_FAILURE);
360 if (java_resource_name != NULL)
362 error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"),
363 "--resource", "--java", "--csharp");
364 usage (EXIT_FAILURE);
366 if (java_locale_name != NULL)
368 error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"),
369 "--locale", "--java", "--csharp");
370 usage (EXIT_FAILURE);
374 /* Read the given .mo file. */
377 result = msgdomain_read_java (java_resource_name, java_locale_name);
379 else if (csharp_mode)
381 result = msgdomain_read_csharp (csharp_resource_name, csharp_locale_name,
382 csharp_base_directory);
386 result = msgdomain_read_tcl (tcl_locale_name, tcl_base_directory);
390 message_list_ty *mlp;
392 mlp = message_list_alloc (false);
396 read_one_file (mlp, argv[optind]);
397 while (++optind < argc);
400 read_one_file (mlp, "-");
402 result = msgdomain_list_alloc (false);
403 result->item[0]->messages = mlp;
406 /* Sorting the list of messages. */
408 msgdomain_list_sort_by_msgid (result);
410 /* Write the resulting message list to the given .po file. */
411 msgdomain_list_print (result, output_file, output_syntax, force_po, false);
418 /* Display usage information and exit. */
422 if (status != EXIT_SUCCESS)
423 fprintf (stderr, _("Try `%s --help' for more information.\n"),
428 Usage: %s [OPTION] [FILE]...\n\
432 Convert binary message catalog to Uniforum style .po file.\n\
436 Mandatory arguments to long options are mandatory for short options too.\n"));
439 Operation mode:\n"));
441 -j, --java Java mode: input is a Java ResourceBundle class\n"));
443 --csharp C# mode: input is a .NET .dll file\n"));
445 --csharp-resources C# resources mode: input is a .NET .resources file\n"));
447 --tcl Tcl mode: input is a tcl/msgcat .msg file\n"));
450 Input file location:\n"));
452 FILE ... input .mo files\n"));
454 If no input file is given or if it is -, standard input is read.\n"));
457 Input file location in Java mode:\n"));
459 -r, --resource=RESOURCE resource name\n"));
461 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
463 The class name is determined by appending the locale name to the resource name,\n\
464 separated with an underscore. The class is located using the CLASSPATH.\n\
468 Input file location in C# mode:\n"));
470 -r, --resource=RESOURCE resource name\n"));
472 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
474 -d DIRECTORY base directory for locale dependent .dll files\n"));
476 The -l and -d options are mandatory. The .dll file is located in a\n\
477 subdirectory of the specified directory whose name depends on the locale.\n"));
480 Input file location in Tcl mode:\n"));
482 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
484 -d DIRECTORY base directory of .msg message catalogs\n"));
486 The -l and -d options are mandatory. The .msg file is located in the\n\
487 specified directory.\n"));
490 Output file location:\n"));
492 -o, --output-file=FILE write output to specified file\n"));
494 The results are written to standard output if no output file is specified\n\
498 Output details:\n"));
500 --color use colors and other text attributes always\n\
501 --color=WHEN use colors and other text attributes if WHEN.\n\
502 WHEN may be 'always', 'never', 'auto', or 'html'.\n"));
504 --style=STYLEFILE specify CSS style rule file for --color\n"));
506 -e, --no-escape do not use C escapes in output (default)\n"));
508 -E, --escape use C escapes in output, no extended chars\n"));
510 --force-po write PO file even if empty\n"));
512 -i, --indent write indented output style\n"));
514 --strict write strict uniforum style\n"));
516 -p, --properties-output write out a Java .properties file\n"));
518 --stringtable-output write out a NeXTstep/GNUstep .strings file\n"));
520 -w, --width=NUMBER set output page width\n"));
522 --no-wrap do not break long message lines, longer than\n\
523 the output page width, into several lines\n"));
525 -s, --sort-output generate sorted output\n"));
528 Informative output:\n"));
530 -h, --help display this help and exit\n"));
532 -V, --version output version information and exit\n"));
534 -v, --verbose increase verbosity level\n"));
536 /* TRANSLATORS: The placeholder indicates the bug-reporting address
537 for this package. Please add _another line_ saying
538 "Report translation bugs to <...>\n" with the address for translation
539 bugs (typically your translation team's web or email address). */
540 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
549 read_one_file (message_list_ty *mlp, const char *filename)
551 if (csharp_resources_mode)
552 read_resources_file (mlp, filename);
554 read_mo_file (mlp, filename);