1 /* Remove, select or merge duplicate translations.
2 Copyright (C) 2001-2005 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
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. */
34 #include "error-progname.h"
36 #include "relocatable.h"
45 #define _(str) gettext (str)
48 /* Force output of PO file even if empty. */
51 /* Target encoding. */
52 static const char *to_code
;
55 static const struct option long_options
[] =
57 { "add-location", no_argument
, &line_comment
, 1 },
58 { "directory", required_argument
, NULL
, 'D' },
59 { "escape", no_argument
, NULL
, 'E' },
60 { "force-po", no_argument
, &force_po
, 1 },
61 { "help", no_argument
, NULL
, 'h' },
62 { "indent", no_argument
, NULL
, 'i' },
63 { "no-escape", no_argument
, NULL
, 'e' },
64 { "no-location", no_argument
, &line_comment
, 0 },
65 { "no-wrap", no_argument
, NULL
, CHAR_MAX
+ 2 },
66 { "output-file", required_argument
, NULL
, 'o' },
67 { "properties-input", no_argument
, NULL
, 'P' },
68 { "properties-output", no_argument
, NULL
, 'p' },
69 { "repeated", no_argument
, NULL
, 'd' },
70 { "sort-by-file", no_argument
, NULL
, 'F' },
71 { "sort-output", no_argument
, NULL
, 's' },
72 { "strict", no_argument
, NULL
, 'S' },
73 { "stringtable-input", no_argument
, NULL
, CHAR_MAX
+ 3 },
74 { "stringtable-output", no_argument
, NULL
, CHAR_MAX
+ 4 },
75 { "to-code", required_argument
, NULL
, 't' },
76 { "unique", no_argument
, NULL
, 'u' },
77 { "use-first", no_argument
, NULL
, CHAR_MAX
+ 1 },
78 { "version", no_argument
, NULL
, 'V' },
79 { "width", required_argument
, NULL
, 'w', },
84 /* Forward declaration of local functions. */
85 static void usage (int status
)
86 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
87 __attribute__ ((noreturn
))
93 main (int argc
, char **argv
)
99 const char *input_file
;
100 string_list_ty
*file_list
;
101 msgdomain_list_ty
*result
;
102 bool sort_by_msgid
= false;
103 bool sort_by_filepos
= false;
105 /* Set program name for messages. */
106 set_program_name (argv
[0]);
107 error_print_progname
= maybe_print_progname
;
109 #ifdef HAVE_SETLOCALE
110 /* Set locale via LC_ALL. */
111 setlocale (LC_ALL
, "");
114 /* Set the text message domain. */
115 bindtextdomain (PACKAGE
, relocate (LOCALEDIR
));
116 textdomain (PACKAGE
);
118 /* Ensure that write errors on stdout are detected. */
119 atexit (close_stdout
);
121 /* Set default values for variables. */
130 while ((optchar
= getopt_long (argc
, argv
, "dD:eEFhino:pPst:uVw:",
131 long_options
, NULL
)) != EOF
)
134 case '\0': /* Long option. */
143 dir_list_append (optarg
);
147 message_print_style_escape (false);
151 message_print_style_escape (true);
155 sort_by_filepos
= true;
163 message_print_style_indent ();
171 output_file
= optarg
;
175 message_print_syntax_properties ();
179 input_syntax
= syntax_properties
;
183 sort_by_msgid
= true;
187 message_print_style_uniforum ();
207 value
= strtol (optarg
, &endp
, 10);
209 message_page_width_set (value
);
217 case CHAR_MAX
+ 2: /* --no-wrap */
218 message_page_width_ignore ();
221 case CHAR_MAX
+ 3: /* --stringtable-input */
222 input_syntax
= syntax_stringtable
;
225 case CHAR_MAX
+ 4: /* --stringtable-output */
226 message_print_syntax_stringtable ();
230 usage (EXIT_FAILURE
);
234 /* Version information requested. */
237 printf ("%s (GNU %s) %s\n", basename (program_name
), PACKAGE
, VERSION
);
238 /* xgettext: no-wrap */
239 printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
240 This is free software; see the source for copying conditions. There is NO\n\
241 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
244 printf (_("Written by %s.\n"), "Bruno Haible");
248 /* Help is requested. */
250 usage (EXIT_SUCCESS
);
252 /* Test whether we have an .po file name as argument. */
255 else if (optind
+ 1 == argc
)
256 input_file
= argv
[optind
];
259 error (EXIT_SUCCESS
, 0, _("at most one input file allowed"));
260 usage (EXIT_FAILURE
);
263 /* Verify selected options. */
264 if (!line_comment
&& sort_by_filepos
)
265 error (EXIT_FAILURE
, 0, _("%s and %s are mutually exclusive"),
266 "--no-location", "--sort-by-file");
268 if (sort_by_msgid
&& sort_by_filepos
)
269 error (EXIT_FAILURE
, 0, _("%s and %s are mutually exclusive"),
270 "--sort-output", "--sort-by-file");
272 /* Determine list of files we have to process: a single file. */
273 file_list
= string_list_alloc ();
274 string_list_append (file_list
, input_file
);
276 /* Read input files, then filter, convert and merge messages. */
277 allow_duplicates
= true;
278 result
= catenate_msgdomain_list (file_list
, to_code
);
280 string_list_free (file_list
);
282 /* Sorting the list of messages. */
284 msgdomain_list_sort_by_filepos (result
);
285 else if (sort_by_msgid
)
286 msgdomain_list_sort_by_msgid (result
);
288 /* Write the PO file. */
289 msgdomain_list_print (result
, output_file
, force_po
, false);
295 /* Display usage information and exit. */
299 if (status
!= EXIT_SUCCESS
)
300 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
305 Usage: %s [OPTION] [INPUTFILE]\n\
308 /* xgettext: no-wrap */
310 Unifies duplicate translations in a translation catalog.\n\
311 Finds duplicate translations of the same message ID. Such duplicates are\n\
312 invalid input for other programs like msgfmt, msgmerge or msgcat. By\n\
313 default, duplicates are merged together. When using the --repeated option,\n\
314 only duplicates are output, and all other messages are discarded. Comments\n\
315 and extracted comments will be cumulated, except that if --use-first is\n\
316 specified, they will be taken from the first translation. File positions\n\
317 will be cumulated. When using the --unique option, duplicates are discarded.\n\
321 Mandatory arguments to long options are mandatory for short options too.\n"));
324 Input file location:\n"));
326 INPUTFILE input PO file\n"));
328 -D, --directory=DIRECTORY add DIRECTORY to list for input files search\n"));
330 If no input file is given or if it is -, standard input is read.\n"));
333 Output file location:\n"));
335 -o, --output-file=FILE write output to specified file\n"));
337 The results are written to standard output if no output file is specified\n\
341 Message selection:\n"));
343 -d, --repeated print only duplicates\n"));
345 -u, --unique print only unique messages, discard duplicates\n"));
348 Input file syntax:\n"));
350 -P, --properties-input input file is in Java .properties syntax\n"));
352 --stringtable-input input file is in NeXTstep/GNUstep .strings syntax\n"));
355 Output details:\n"));
357 -t, --to-code=NAME encoding for output\n"));
359 --use-first use first available translation for each\n\
360 message, don't merge several translations\n"));
362 -e, --no-escape do not use C escapes in output (default)\n"));
364 -E, --escape use C escapes in output, no extended chars\n"));
366 --force-po write PO file even if empty\n"));
368 -i, --indent write the .po file using indented style\n"));
370 --no-location do not write '#: filename:line' lines\n"));
372 -n, --add-location generate '#: filename:line' lines (default)\n"));
374 --strict write out strict Uniforum conforming .po file\n"));
376 -p, --properties-output write out a Java .properties file\n"));
378 --stringtable-output write out a NeXTstep/GNUstep .strings file\n"));
380 -w, --width=NUMBER set output page width\n"));
382 --no-wrap do not break long message lines, longer than\n\
383 the output page width, into several lines\n"));
385 -s, --sort-output generate sorted output\n"));
387 -F, --sort-by-file sort output by file location\n"));
390 Informative output:\n"));
392 -h, --help display this help and exit\n"));
394 -V, --version output version information and exit\n"));
396 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),