No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gettext / gettext-tools / src / msgcomm.c
blob36c97fe9dbfc4bcb8745f6499c5aa782f531d5d7
1 /* GNU gettext - internationalization aids
2 Copyright (C) 1997-1998, 2000-2005 Free Software Foundation, Inc.
4 This file was written by Peter Miller <millerp@canb.auug.org.au>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #include <getopt.h>
25 #include <limits.h>
26 #include <locale.h>
27 #include <stdio.h>
28 #include <stdlib.h>
30 #include "closeout.h"
31 #include "dir-list.h"
32 #include "str-list.h"
33 #include "file-list.h"
34 #include "error.h"
35 #include "error-progname.h"
36 #include "progname.h"
37 #include "relocatable.h"
38 #include "basename.h"
39 #include "message.h"
40 #include "read-po.h"
41 #include "write-po.h"
42 #include "msgl-cat.h"
43 #include "exit.h"
44 #include "gettext.h"
47 /* A convenience macro. I don't like writing gettext() every time. */
48 #define _(str) gettext (str)
51 /* Force output of PO file even if empty. */
52 static int force_po;
54 /* Target encoding. */
55 static const char *to_code;
57 /* Long options. */
58 static const struct option long_options[] =
60 { "add-location", no_argument, &line_comment, 1 },
61 { "directory", required_argument, NULL, 'D' },
62 { "escape", no_argument, NULL, 'E' },
63 { "files-from", required_argument, NULL, 'f' },
64 { "force-po", no_argument, &force_po, 1 },
65 { "help", no_argument, NULL, 'h' },
66 { "indent", no_argument, NULL, 'i' },
67 { "no-escape", no_argument, NULL, 'e' },
68 { "no-location", no_argument, &line_comment, 0 },
69 { "no-wrap", no_argument, NULL, CHAR_MAX + 2 },
70 { "omit-header", no_argument, NULL, CHAR_MAX + 1 },
71 { "output", required_argument, NULL, 'o' }, /* for backward compatibility */
72 { "output-file", required_argument, NULL, 'o' },
73 { "properties-input", no_argument, NULL, 'P' },
74 { "properties-output", no_argument, NULL, 'p' },
75 { "sort-by-file", no_argument, NULL, 'F' },
76 { "sort-output", no_argument, NULL, 's' },
77 { "strict", no_argument, NULL, 'S' },
78 { "stringtable-input", no_argument, NULL, CHAR_MAX + 3 },
79 { "stringtable-output", no_argument, NULL, CHAR_MAX + 4 },
80 { "to-code", required_argument, NULL, 't' },
81 { "unique", no_argument, NULL, 'u' },
82 { "version", no_argument, NULL, 'V' },
83 { "width", required_argument, NULL, 'w', },
84 { "more-than", required_argument, NULL, '>', },
85 { "less-than", required_argument, NULL, '<', },
86 { NULL, 0, NULL, 0 }
90 /* Forward declaration of local functions. */
91 static void usage (int status)
92 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ > 4) || __GNUC__ > 2)
93 __attribute__ ((noreturn))
94 #endif
98 int
99 main (int argc, char *argv[])
101 int cnt;
102 int optchar;
103 bool do_help = false;
104 bool do_version = false;
105 msgdomain_list_ty *result;
106 bool sort_by_msgid = false;
107 bool sort_by_filepos = false;
108 const char *files_from = NULL;
109 string_list_ty *file_list;
110 char *output_file = NULL;
112 /* Set program name for messages. */
113 set_program_name (argv[0]);
114 error_print_progname = maybe_print_progname;
116 #ifdef HAVE_SETLOCALE
117 /* Set locale via LC_ALL. */
118 setlocale (LC_ALL, "");
119 #endif
121 /* Set the text message domain. */
122 bindtextdomain (PACKAGE, relocate (LOCALEDIR));
123 textdomain (PACKAGE);
125 /* Ensure that write errors on stdout are detected. */
126 atexit (close_stdout);
128 /* Set default values for variables. */
129 more_than = -1;
130 less_than = -1;
131 use_first = false;
133 while ((optchar = getopt_long (argc, argv, "<:>:D:eEf:Fhino:pPst:uVw:",
134 long_options, NULL)) != EOF)
135 switch (optchar)
137 case '\0': /* Long option. */
138 break;
140 case '>':
142 int value;
143 char *endp;
144 value = strtol (optarg, &endp, 10);
145 if (endp != optarg)
146 more_than = value;
148 break;
150 case '<':
152 int value;
153 char *endp;
154 value = strtol (optarg, &endp, 10);
155 if (endp != optarg)
156 less_than = value;
158 break;
160 case 'D':
161 dir_list_append (optarg);
162 break;
164 case 'e':
165 message_print_style_escape (false);
166 break;
168 case 'E':
169 message_print_style_escape (true);
170 break;
172 case 'f':
173 files_from = optarg;
174 break;
176 case 'F':
177 sort_by_filepos = true;
178 break;
180 case 'h':
181 do_help = true;
182 break;
184 case 'i':
185 message_print_style_indent ();
186 break;
188 case 'n':
189 line_comment = 1;
190 break;
192 case 'o':
193 output_file = optarg;
194 break;
196 case 'p':
197 message_print_syntax_properties ();
198 break;
200 case 'P':
201 input_syntax = syntax_properties;
202 break;
204 case 's':
205 sort_by_msgid = true;
206 break;
208 case 'S':
209 message_print_style_uniforum ();
210 break;
212 case 't':
213 to_code = optarg;
214 break;
216 case 'u':
217 less_than = 2;
218 break;
220 case 'V':
221 do_version = true;
222 break;
224 case 'w':
226 int value;
227 char *endp;
228 value = strtol (optarg, &endp, 10);
229 if (endp != optarg)
230 message_page_width_set (value);
232 break;
234 case CHAR_MAX + 1:
235 omit_header = true;
236 break;
238 case CHAR_MAX + 2: /* --no-wrap */
239 message_page_width_ignore ();
240 break;
242 case CHAR_MAX + 3: /* --stringtable-input */
243 input_syntax = syntax_stringtable;
244 break;
246 case CHAR_MAX + 4: /* --stringtable-output */
247 message_print_syntax_stringtable ();
248 break;
250 default:
251 usage (EXIT_FAILURE);
252 /* NOTREACHED */
255 /* Version information requested. */
256 if (do_version)
258 printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
259 /* xgettext: no-wrap */
260 printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
261 This is free software; see the source for copying conditions. There is NO\n\
262 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
264 "1995-1998, 2000-2005");
265 printf (_("Written by %s.\n"), "Peter Miller");
266 exit (EXIT_SUCCESS);
269 /* Help is requested. */
270 if (do_help)
271 usage (EXIT_SUCCESS);
273 /* Verify selected options. */
274 if (!line_comment && sort_by_filepos)
275 error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
276 "--no-location", "--sort-by-file");
278 if (sort_by_msgid && sort_by_filepos)
279 error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
280 "--sort-output", "--sort-by-file");
282 /* Determine list of files we have to process. */
283 if (files_from != NULL)
284 file_list = read_names_from_file (files_from);
285 else
286 file_list = string_list_alloc ();
287 /* Append names from command line. */
288 for (cnt = optind; cnt < argc; ++cnt)
289 string_list_append_unique (file_list, argv[cnt]);
291 /* Test whether sufficient input files were given. */
292 if (file_list->nitems < 2)
294 error (EXIT_SUCCESS, 0, _("at least two files must be specified"));
295 usage (EXIT_FAILURE);
298 /* Default the message selection criteria, and check them for sanity. */
299 if (more_than < 0)
300 more_than = (less_than < 0 ? 1 : 0);
301 if (less_than < 0)
302 less_than = INT_MAX;
303 if (more_than >= less_than || less_than < 2)
304 error (EXIT_FAILURE, 0,
305 _("impossible selection criteria specified (%d < n < %d)"),
306 more_than, less_than);
308 /* Read input files, then filter, convert and merge messages. */
309 allow_duplicates = true;
310 msgcomm_mode = true;
311 result = catenate_msgdomain_list (file_list, to_code);
313 string_list_free (file_list);
315 /* Sorting the list of messages. */
316 if (sort_by_filepos)
317 msgdomain_list_sort_by_filepos (result);
318 else if (sort_by_msgid)
319 msgdomain_list_sort_by_msgid (result);
321 /* Write the PO file. */
322 msgdomain_list_print (result, output_file, force_po, false);
324 exit (EXIT_SUCCESS);
328 /* Display usage information and exit. */
329 static void
330 usage (int status)
332 if (status != EXIT_SUCCESS)
333 fprintf (stderr, _("Try `%s --help' for more information.\n"),
334 program_name);
335 else
337 printf (_("\
338 Usage: %s [OPTION] [INPUTFILE]...\n\
339 "), program_name);
340 printf ("\n");
341 /* xgettext: no-wrap */
342 printf (_("\
343 Find messages which are common to two or more of the specified PO files.\n\
344 By using the --more-than option, greater commonality may be requested\n\
345 before messages are printed. Conversely, the --less-than option may be\n\
346 used to specify less commonality before messages are printed (i.e.\n\
347 --less-than=2 will only print the unique messages). Translations,\n\
348 comments and extract comments will be preserved, but only from the first\n\
349 PO file to define them. File positions from all PO files will be\n\
350 cumulated.\n\
351 "));
352 printf ("\n");
353 printf (_("\
354 Mandatory arguments to long options are mandatory for short options too.\n"));
355 printf ("\n");
356 printf (_("\
357 Input file location:\n"));
358 printf (_("\
359 INPUTFILE ... input files\n"));
360 printf (_("\
361 -f, --files-from=FILE get list of input files from FILE\n"));
362 printf (_("\
363 -D, --directory=DIRECTORY add DIRECTORY to list for input files search\n"));
364 printf (_("\
365 If input file is -, standard input is read.\n"));
366 printf ("\n");
367 printf (_("\
368 Output file location:\n"));
369 printf (_("\
370 -o, --output-file=FILE write output to specified file\n"));
371 printf (_("\
372 The results are written to standard output if no output file is specified\n\
373 or if it is -.\n"));
374 printf ("\n");
375 printf (_("\
376 Message selection:\n"));
377 printf (_("\
378 -<, --less-than=NUMBER print messages with less than this many\n\
379 definitions, defaults to infinite if not set\n"));
380 printf (_("\
381 ->, --more-than=NUMBER print messages with more than this many\n\
382 definitions, defaults to 1 if not set\n"));
383 printf (_("\
384 -u, --unique shorthand for --less-than=2, requests\n\
385 that only unique messages be printed\n"));
386 printf ("\n");
387 printf (_("\
388 Input file syntax:\n"));
389 printf (_("\
390 -P, --properties-input input files are in Java .properties syntax\n"));
391 printf (_("\
392 --stringtable-input input files are in NeXTstep/GNUstep .strings\n\
393 syntax\n"));
394 printf ("\n");
395 printf (_("\
396 Output details:\n"));
397 printf (_("\
398 -e, --no-escape do not use C escapes in output (default)\n"));
399 printf (_("\
400 -E, --escape use C escapes in output, no extended chars\n"));
401 printf (_("\
402 --force-po write PO file even if empty\n"));
403 printf (_("\
404 -i, --indent write the .po file using indented style\n"));
405 printf (_("\
406 --no-location do not write '#: filename:line' lines\n"));
407 printf (_("\
408 -n, --add-location generate '#: filename:line' lines (default)\n"));
409 printf (_("\
410 --strict write out strict Uniforum conforming .po file\n"));
411 printf (_("\
412 -p, --properties-output write out a Java .properties file\n"));
413 printf (_("\
414 --stringtable-output write out a NeXTstep/GNUstep .strings file\n"));
415 printf (_("\
416 -w, --width=NUMBER set output page width\n"));
417 printf (_("\
418 --no-wrap do not break long message lines, longer than\n\
419 the output page width, into several lines\n"));
420 printf (_("\
421 -s, --sort-output generate sorted output\n"));
422 printf (_("\
423 -F, --sort-by-file sort output by file location\n"));
424 printf (_("\
425 --omit-header don't write header with `msgid \"\"' entry\n"));
426 printf ("\n");
427 printf (_("\
428 Informative output:\n"));
429 printf (_("\
430 -h, --help display this help and exit\n"));
431 printf (_("\
432 -V, --version output version information and exit\n"));
433 printf ("\n");
434 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
435 stdout);
438 exit (status);