~ubuntu-branches/ubuntu/breezy/gettext/breezy

« back to all changes in this revision

Viewing changes to gettext-tools/src/msguniq.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2004-03-14 17:40:02 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040314174002-p1ad5ldve1hqzhye
Tags: 0.14.1-2
* Added libexpat1-dev to Build-Depends, for glade support.
* Added libc0.1-dev to Build-Depends, for GNU/kFreeBSD.
* Removed special-casing of knetbsd-gnu in debian/rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Remove, select or merge duplicate translations.
 
2
   Copyright (C) 2001-2004 Free Software Foundation, Inc.
 
3
   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
4
 
 
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.
 
9
 
 
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.
 
14
 
 
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.  */
 
18
 
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
# include "config.h"
 
22
#endif
 
23
 
 
24
#include <getopt.h>
 
25
#include <limits.h>
 
26
#include <stdio.h>
 
27
#include <stdlib.h>
 
28
#include <locale.h>
 
29
 
 
30
#include "closeout.h"
 
31
#include "dir-list.h"
 
32
#include "str-list.h"
 
33
#include "error.h"
 
34
#include "error-progname.h"
 
35
#include "progname.h"
 
36
#include "relocatable.h"
 
37
#include "basename.h"
 
38
#include "message.h"
 
39
#include "read-po.h"
 
40
#include "write-po.h"
 
41
#include "msgl-cat.h"
 
42
#include "exit.h"
 
43
#include "gettext.h"
 
44
 
 
45
#define _(str) gettext (str)
 
46
 
 
47
 
 
48
/* Force output of PO file even if empty.  */
 
49
static int force_po;
 
50
 
 
51
/* Target encoding.  */
 
52
static const char *to_code;
 
53
 
 
54
/* Long options.  */
 
55
static const struct option long_options[] =
 
56
{
 
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', },
 
80
  { NULL, 0, NULL, 0 }
 
81
};
 
82
 
 
83
 
 
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))
 
88
#endif
 
89
;
 
90
 
 
91
 
 
92
int
 
93
main (int argc, char **argv)
 
94
{
 
95
  int optchar;
 
96
  bool do_help;
 
97
  bool do_version;
 
98
  char *output_file;
 
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;
 
104
 
 
105
  /* Set program name for messages.  */
 
106
  set_program_name (argv[0]);
 
107
  error_print_progname = maybe_print_progname;
 
108
 
 
109
#ifdef HAVE_SETLOCALE
 
110
  /* Set locale via LC_ALL.  */
 
111
  setlocale (LC_ALL, "");
 
112
#endif
 
113
 
 
114
  /* Set the text message domain.  */
 
115
  bindtextdomain (PACKAGE, relocate (LOCALEDIR));
 
116
  textdomain (PACKAGE);
 
117
 
 
118
  /* Ensure that write errors on stdout are detected.  */
 
119
  atexit (close_stdout);
 
120
 
 
121
  /* Set default values for variables.  */
 
122
  do_help = false;
 
123
  do_version = false;
 
124
  output_file = NULL;
 
125
  input_file = NULL;
 
126
  more_than = 0;
 
127
  less_than = INT_MAX;
 
128
  use_first = false;
 
129
 
 
130
  while ((optchar = getopt_long (argc, argv, "dD:eEFhino:pPst:uVw:",
 
131
                                 long_options, NULL)) != EOF)
 
132
    switch (optchar)
 
133
      {
 
134
      case '\0':                /* Long option.  */
 
135
        break;
 
136
 
 
137
      case 'd':
 
138
        more_than = 1;
 
139
        less_than = INT_MAX;
 
140
        break;
 
141
 
 
142
      case 'D':
 
143
        dir_list_append (optarg);
 
144
        break;
 
145
 
 
146
      case 'e':
 
147
        message_print_style_escape (false);
 
148
        break;
 
149
 
 
150
      case 'E':
 
151
        message_print_style_escape (true);
 
152
        break;
 
153
 
 
154
      case 'F':
 
155
        sort_by_filepos = true;
 
156
        break;
 
157
 
 
158
      case 'h':
 
159
        do_help = true;
 
160
        break;
 
161
 
 
162
      case 'i':
 
163
        message_print_style_indent ();
 
164
        break;
 
165
 
 
166
      case 'n':
 
167
        line_comment = 1;
 
168
        break;
 
169
 
 
170
      case 'o':
 
171
        output_file = optarg;
 
172
        break;
 
173
 
 
174
      case 'p':
 
175
        message_print_syntax_properties ();
 
176
        break;
 
177
 
 
178
      case 'P':
 
179
        input_syntax = syntax_properties;
 
180
        break;
 
181
 
 
182
      case 's':
 
183
        sort_by_msgid = true;
 
184
        break;
 
185
 
 
186
      case 'S':
 
187
        message_print_style_uniforum ();
 
188
        break;
 
189
 
 
190
      case 't':
 
191
        to_code = optarg;
 
192
        break;
 
193
 
 
194
      case 'u':
 
195
        more_than = 0;
 
196
        less_than = 2;
 
197
        break;
 
198
 
 
199
      case 'V':
 
200
        do_version = true;
 
201
        break;
 
202
 
 
203
      case 'w':
 
204
        {
 
205
          int value;
 
206
          char *endp;
 
207
          value = strtol (optarg, &endp, 10);
 
208
          if (endp != optarg)
 
209
            message_page_width_set (value);
 
210
        }
 
211
        break;
 
212
 
 
213
      case CHAR_MAX + 1:
 
214
        use_first = true;
 
215
        break;
 
216
 
 
217
      case CHAR_MAX + 2: /* --no-wrap */
 
218
        message_page_width_ignore ();
 
219
        break;
 
220
 
 
221
      case CHAR_MAX + 3: /* --stringtable-input */
 
222
        input_syntax = syntax_stringtable;
 
223
        break;
 
224
 
 
225
      case CHAR_MAX + 4: /* --stringtable-output */
 
226
        message_print_syntax_stringtable ();
 
227
        break;
 
228
 
 
229
      default:
 
230
        usage (EXIT_FAILURE);
 
231
        /* NOTREACHED */
 
232
      }
 
233
 
 
234
  /* Version information requested.  */
 
235
  if (do_version)
 
236
    {
 
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\
 
242
"),
 
243
              "2001-2004");
 
244
      printf (_("Written by %s.\n"), "Bruno Haible");
 
245
      exit (EXIT_SUCCESS);
 
246
    }
 
247
 
 
248
  /* Help is requested.  */
 
249
  if (do_help)
 
250
    usage (EXIT_SUCCESS);
 
251
 
 
252
  /* Test whether we have an .po file name as argument.  */
 
253
  if (optind == argc)
 
254
    input_file = "-";
 
255
  else if (optind + 1 == argc)
 
256
    input_file = argv[optind];
 
257
  else
 
258
    {
 
259
      error (EXIT_SUCCESS, 0, _("at most one input file allowed"));
 
260
      usage (EXIT_FAILURE);
 
261
    }
 
262
 
 
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");
 
267
 
 
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");
 
271
 
 
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);
 
275
 
 
276
  /* Read input files, then filter, convert and merge messages.  */
 
277
  allow_duplicates = true;
 
278
  result = catenate_msgdomain_list (file_list, to_code);
 
279
 
 
280
  string_list_free (file_list);
 
281
 
 
282
  /* Sorting the list of messages.  */
 
283
  if (sort_by_filepos)
 
284
    msgdomain_list_sort_by_filepos (result);
 
285
  else if (sort_by_msgid)
 
286
    msgdomain_list_sort_by_msgid (result);
 
287
 
 
288
  /* Write the PO file.  */
 
289
  msgdomain_list_print (result, output_file, force_po, false);
 
290
 
 
291
  exit (EXIT_SUCCESS);
 
292
}
 
293
 
 
294
 
 
295
/* Display usage information and exit.  */
 
296
static void
 
297
usage (int status)
 
298
{
 
299
  if (status != EXIT_SUCCESS)
 
300
    fprintf (stderr, _("Try `%s --help' for more information.\n"),
 
301
             program_name);
 
302
  else
 
303
    {
 
304
      printf (_("\
 
305
Usage: %s [OPTION] [INPUTFILE]\n\
 
306
"), program_name);
 
307
      printf ("\n");
 
308
      /* xgettext: no-wrap */
 
309
      printf (_("\
 
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\
 
318
"));
 
319
      printf ("\n");
 
320
      printf (_("\
 
321
Mandatory arguments to long options are mandatory for short options too.\n"));
 
322
      printf ("\n");
 
323
      printf (_("\
 
324
Input file location:\n"));
 
325
      printf (_("\
 
326
  INPUTFILE                   input PO file\n"));
 
327
      printf (_("\
 
328
  -D, --directory=DIRECTORY   add DIRECTORY to list for input files search\n"));
 
329
      printf (_("\
 
330
If no input file is given or if it is -, standard input is read.\n"));
 
331
      printf ("\n");
 
332
      printf (_("\
 
333
Output file location:\n"));
 
334
      printf (_("\
 
335
  -o, --output-file=FILE      write output to specified file\n"));
 
336
      printf (_("\
 
337
The results are written to standard output if no output file is specified\n\
 
338
or if it is -.\n"));
 
339
      printf ("\n");
 
340
      printf (_("\
 
341
Message selection:\n"));
 
342
      printf (_("\
 
343
  -d, --repeated              print only duplicates\n"));
 
344
      printf (_("\
 
345
  -u, --unique                print only unique messages, discard duplicates\n"));
 
346
      printf ("\n");
 
347
      printf (_("\
 
348
Input file syntax:\n"));
 
349
      printf (_("\
 
350
  -P, --properties-input      input file is in Java .properties syntax\n"));
 
351
      printf (_("\
 
352
      --stringtable-input     input file is in NeXTstep/GNUstep .strings syntax\n"));
 
353
      printf ("\n");
 
354
      printf (_("\
 
355
Output details:\n"));
 
356
      printf (_("\
 
357
  -t, --to-code=NAME          encoding for output\n"));
 
358
      printf (_("\
 
359
      --use-first             use first available translation for each\n\
 
360
                              message, don't merge several translations\n"));
 
361
      printf (_("\
 
362
  -e, --no-escape             do not use C escapes in output (default)\n"));
 
363
      printf (_("\
 
364
  -E, --escape                use C escapes in output, no extended chars\n"));
 
365
      printf (_("\
 
366
      --force-po              write PO file even if empty\n"));
 
367
      printf (_("\
 
368
  -i, --indent                write the .po file using indented style\n"));
 
369
      printf (_("\
 
370
      --no-location           do not write '#: filename:line' lines\n"));
 
371
      printf (_("\
 
372
  -n, --add-location          generate '#: filename:line' lines (default)\n"));
 
373
      printf (_("\
 
374
      --strict                write out strict Uniforum conforming .po file\n"));
 
375
      printf (_("\
 
376
  -p, --properties-output     write out a Java .properties file\n"));
 
377
      printf (_("\
 
378
      --stringtable-output    write out a NeXTstep/GNUstep .strings file\n"));
 
379
      printf (_("\
 
380
  -w, --width=NUMBER          set output page width\n"));
 
381
      printf (_("\
 
382
      --no-wrap               do not break long message lines, longer than\n\
 
383
                              the output page width, into several lines\n"));
 
384
      printf (_("\
 
385
  -s, --sort-output           generate sorted output\n"));
 
386
      printf (_("\
 
387
  -F, --sort-by-file          sort output by file location\n"));
 
388
      printf ("\n");
 
389
      printf (_("\
 
390
Informative output:\n"));
 
391
      printf (_("\
 
392
  -h, --help                  display this help and exit\n"));
 
393
      printf (_("\
 
394
  -V, --version               output version information and exit\n"));
 
395
      printf ("\n");
 
396
      fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
 
397
             stdout);
 
398
    }
 
399
 
 
400
  exit (status);
 
401
}
 
402