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)
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. */
32 #include "error-progname.h"
34 #include "relocatable.h"
40 #include "read-java.h"
41 #include "read-csharp.h"
42 #include "read-resources.h"
47 #define _(str) gettext (str)
50 /* Be more 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. */
69 static const char *tcl_locale_name
;
70 static const char *tcl_base_directory
;
72 /* Force output of PO file even if empty. */
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', },
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
))
108 static void read_one_file (message_list_ty
*mlp
, const char *filename
);
112 main (int argc
, char **argv
)
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
, "");
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:",
147 csharp_base_directory
= optarg
;
148 tcl_base_directory
= optarg
;
152 message_print_style_escape (false);
156 message_print_style_escape (true);
164 message_print_style_indent ();
172 java_locale_name
= optarg
;
173 csharp_locale_name
= optarg
;
174 tcl_locale_name
= optarg
;
178 output_file
= optarg
;
182 message_print_syntax_properties ();
186 java_resource_name
= optarg
;
187 csharp_resource_name
= optarg
;
191 sort_by_msgid
= true;
195 message_print_style_uniforum ();
210 value
= strtol (optarg
, &endp
, 10);
212 message_page_width_set (value
);
216 case CHAR_MAX
+ 1: /* --tcl */
220 case CHAR_MAX
+ 2: /* --no-wrap */
221 message_page_width_ignore ();
224 case CHAR_MAX
+ 3: /* --stringtable-output */
225 message_print_syntax_stringtable ();
228 case CHAR_MAX
+ 4: /* --csharp */
232 case CHAR_MAX
+ 5: /* --csharp-resources */
233 csharp_resources_mode
= true;
237 usage (EXIT_FAILURE
);
241 /* Version information is requested. */
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");
255 /* Help is requested. */
257 usage (EXIT_SUCCESS
);
259 /* Check for contradicting options. */
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
;
275 if (modes
& (1 << i
))
277 first_option
= mode_options
[i
];
278 for (i
= i
+ 1; ; i
++)
279 if (modes
& (1 << i
))
281 second_option
= mode_options
[i
];
282 error (EXIT_FAILURE
, 0, _("%s and %s are mutually exclusive"),
283 first_option
, second_option
);
290 error (EXIT_FAILURE
, 0,
291 _("%s and explicit file names are mutually exclusive"),
295 else if (csharp_mode
)
299 error (EXIT_FAILURE
, 0,
300 _("%s and explicit file names are mutually exclusive"),
303 if (csharp_locale_name
== NULL
)
305 error (EXIT_SUCCESS
, 0,
306 _("%s requires a \"-l locale\" specification"),
308 usage (EXIT_FAILURE
);
310 if (csharp_base_directory
== NULL
)
312 error (EXIT_SUCCESS
, 0,
313 _("%s requires a \"-d directory\" specification"),
315 usage (EXIT_FAILURE
);
322 error (EXIT_FAILURE
, 0,
323 _("%s and explicit file names are mutually exclusive"),
326 if (tcl_locale_name
== NULL
)
328 error (EXIT_SUCCESS
, 0,
329 _("%s requires a \"-l locale\" specification"),
331 usage (EXIT_FAILURE
);
333 if (tcl_base_directory
== NULL
)
335 error (EXIT_SUCCESS
, 0,
336 _("%s requires a \"-d directory\" specification"),
338 usage (EXIT_FAILURE
);
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. */
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
);
369 result
= msgdomain_read_tcl (tcl_locale_name
, tcl_base_directory
);
373 message_list_ty
*mlp
;
375 mlp
= message_list_alloc (false);
379 read_one_file (mlp
, argv
[optind
]);
380 while (++optind
< argc
);
383 read_one_file (mlp
, "-");
385 result
= msgdomain_list_alloc (false);
386 result
->item
[0]->messages
= mlp
;
389 /* Sorting the list of messages. */
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);
401 /* Display usage information and exit. */
405 if (status
!= EXIT_SUCCESS
)
406 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
411 Usage: %s [OPTION] [FILE]...\n\
415 Convert binary message catalog to Uniforum style .po file.\n\
419 Mandatory arguments to long options are mandatory for short options too.\n"));
422 Operation mode:\n"));
424 -j, --java Java mode: input is a Java ResourceBundle class\n"));
426 --csharp C# mode: input is a .NET .dll file\n"));
428 --csharp-resources C# resources mode: input is a .NET .resources file\n"));
430 --tcl Tcl mode: input is a tcl/msgcat .msg file\n"));
433 Input file location:\n"));
435 FILE ... input .mo files\n"));
437 If no input file is given or if it is -, standard input is read.\n"));
440 Input file location in Java mode:\n"));
442 -r, --resource=RESOURCE resource name\n"));
444 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
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\
451 Input file location in C# mode:\n"));
453 -r, --resource=RESOURCE resource name\n"));
455 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
457 -d DIRECTORY base directory for locale dependent .dll files\n"));
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"));
463 Input file location in Tcl mode:\n"));
465 -l, --locale=LOCALE locale name, either language or language_COUNTRY\n"));
467 -d DIRECTORY base directory of .msg message catalogs\n"));
469 The -l and -d options are mandatory. The .msg file is located in the\n\
470 specified directory.\n"));
473 Output file location:\n"));
475 -o, --output-file=FILE write output to specified file\n"));
477 The results are written to standard output if no output file is specified\n\
481 Output details:\n"));
483 -e, --no-escape do not use C escapes in output (default)\n"));
485 -E, --escape use C escapes in output, no extended chars\n"));
487 --force-po write PO file even if empty\n"));
489 -i, --indent write indented output style\n"));
491 --strict write strict uniforum style\n"));
493 -p, --properties-output write out a Java .properties file\n"));
495 --stringtable-output write out a NeXTstep/GNUstep .strings file\n"));
497 -w, --width=NUMBER set output page width\n"));
499 --no-wrap do not break long message lines, longer than\n\
500 the output page width, into several lines\n"));
502 -s, --sort-output generate sorted output\n"));
505 Informative output:\n"));
507 -h, --help display this help and exit\n"));
509 -V, --version output version information and exit\n"));
511 -v, --verbose increase verbosity level\n"));
513 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
522 read_one_file (message_list_ty
*mlp
, const char *filename
)
524 if (csharp_resources_mode
)
525 read_resources_file (mlp
, filename
);
527 read_mo_file (mlp
, filename
);