~ubuntu-branches/ubuntu/utopic/gettext/utopic

« back to all changes in this revision

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

  • Committer: Colin Watson
  • Date: 2010-08-01 21:36:08 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: cjwatson@canonical.com-20100801213608-yy7vkm8lpatep3ci
merge from Debian 0.18.1.1-1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Manipulates attributes of messages in translation catalogs.
2
 
   Copyright (C) 2001-2007 Free Software Foundation, Inc.
 
2
   Copyright (C) 2001-2007, 2009-2010 Free Software Foundation, Inc.
3
3
   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4
4
 
5
5
   This program is free software: you can redistribute it and/or modify
42
42
#include "write-po.h"
43
43
#include "write-properties.h"
44
44
#include "write-stringtable.h"
 
45
#include "color.h"
45
46
#include "propername.h"
46
47
#include "gettext.h"
47
48
 
54
55
/* Bit mask of subsets to remove.  */
55
56
enum
56
57
{
57
 
  REMOVE_UNTRANSLATED   = 1 << 0,
58
 
  REMOVE_TRANSLATED     = 1 << 1,
59
 
  REMOVE_FUZZY          = 1 << 2,
60
 
  REMOVE_NONFUZZY       = 1 << 3,
61
 
  REMOVE_OBSOLETE       = 1 << 4,
62
 
  REMOVE_NONOBSOLETE    = 1 << 5
 
58
  REMOVE_UNTRANSLATED   = 1 << 0,
 
59
  REMOVE_TRANSLATED     = 1 << 1,
 
60
  REMOVE_FUZZY          = 1 << 2,
 
61
  REMOVE_NONFUZZY       = 1 << 3,
 
62
  REMOVE_OBSOLETE       = 1 << 4,
 
63
  REMOVE_NONOBSOLETE    = 1 << 5
63
64
};
64
65
static int to_remove;
65
66
 
66
67
/* Bit mask of actions to perform on all messages.  */
67
68
enum
68
69
{
69
 
  SET_FUZZY             = 1 << 0,
70
 
  RESET_FUZZY           = 1 << 1,
71
 
  SET_OBSOLETE          = 1 << 2,
72
 
  RESET_OBSOLETE        = 1 << 3,
73
 
  REMOVE_PREV           = 1 << 4
 
70
  SET_FUZZY             = 1 << 0,
 
71
  RESET_FUZZY           = 1 << 1,
 
72
  SET_OBSOLETE          = 1 << 2,
 
73
  RESET_OBSOLETE        = 1 << 3,
 
74
  REMOVE_PREV           = 1 << 4
74
75
};
75
76
static int to_change;
76
77
 
81
82
  { "clear-fuzzy", no_argument, NULL, CHAR_MAX + 8 },
82
83
  { "clear-obsolete", no_argument, NULL, CHAR_MAX + 10 },
83
84
  { "clear-previous", no_argument, NULL, CHAR_MAX + 18 },
 
85
  { "color", optional_argument, NULL, CHAR_MAX + 19 },
84
86
  { "directory", required_argument, NULL, 'D' },
85
87
  { "escape", no_argument, NULL, 'E' },
86
88
  { "force-po", no_argument, &force_po, 1 },
107
109
  { "stringtable-input", no_argument, NULL, CHAR_MAX + 16 },
108
110
  { "stringtable-output", no_argument, NULL, CHAR_MAX + 17 },
109
111
  { "strict", no_argument, NULL, 'S' },
 
112
  { "style", required_argument, NULL, CHAR_MAX + 20 },
110
113
  { "translated", no_argument, NULL, CHAR_MAX + 1 },
111
114
  { "untranslated", no_argument, NULL, CHAR_MAX + 2 },
112
115
  { "version", no_argument, NULL, 'V' },
118
121
/* Forward declaration of local functions.  */
119
122
static void usage (int status)
120
123
#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
121
 
        __attribute__ ((noreturn))
 
124
        __attribute__ ((noreturn))
122
125
#endif
123
126
;
124
127
static msgdomain_list_ty *process_msgdomain_list (msgdomain_list_ty *mdlp,
125
 
                                                  msgdomain_list_ty *only_mdlp,
126
 
                                                msgdomain_list_ty *ignore_mdlp);
 
128
                                                  msgdomain_list_ty *only_mdlp,
 
129
                                                msgdomain_list_ty *ignore_mdlp);
127
130
 
128
131
 
129
132
int
170
173
  ignore_file = NULL;
171
174
 
172
175
  while ((optchar = getopt_long (argc, argv, "D:eEFhino:pPsVw:", long_options,
173
 
                                 NULL)) != EOF)
 
176
                                 NULL)) != EOF)
174
177
    switch (optchar)
175
178
      {
176
 
      case '\0':                /* Long option.  */
177
 
        break;
 
179
      case '\0':                /* Long option.  */
 
180
        break;
178
181
 
179
182
      case 'D':
180
 
        dir_list_append (optarg);
181
 
        break;
 
183
        dir_list_append (optarg);
 
184
        break;
182
185
 
183
186
      case 'e':
184
 
        message_print_style_escape (false);
185
 
        break;
 
187
        message_print_style_escape (false);
 
188
        break;
186
189
 
187
190
      case 'E':
188
 
        message_print_style_escape (true);
189
 
        break;
 
191
        message_print_style_escape (true);
 
192
        break;
190
193
 
191
194
      case 'F':
192
 
        sort_by_filepos = true;
193
 
        break;
 
195
        sort_by_filepos = true;
 
196
        break;
194
197
 
195
198
      case 'h':
196
 
        do_help = true;
197
 
        break;
 
199
        do_help = true;
 
200
        break;
198
201
 
199
202
      case 'i':
200
 
        message_print_style_indent ();
201
 
        break;
 
203
        message_print_style_indent ();
 
204
        break;
202
205
 
203
206
      case 'n':
204
 
        line_comment = 1;
205
 
        break;
 
207
        line_comment = 1;
 
208
        break;
206
209
 
207
210
      case 'o':
208
 
        output_file = optarg;
209
 
        break;
 
211
        output_file = optarg;
 
212
        break;
210
213
 
211
214
      case 'p':
212
 
        output_syntax = &output_format_properties;
213
 
        break;
 
215
        output_syntax = &output_format_properties;
 
216
        break;
214
217
 
215
218
      case 'P':
216
 
        input_syntax = &input_format_properties;
217
 
        break;
 
219
        input_syntax = &input_format_properties;
 
220
        break;
218
221
 
219
222
      case 's':
220
 
        sort_by_msgid = true;
221
 
        break;
 
223
        sort_by_msgid = true;
 
224
        break;
222
225
 
223
226
      case 'S':
224
 
        message_print_style_uniforum ();
225
 
        break;
 
227
        message_print_style_uniforum ();
 
228
        break;
226
229
 
227
230
      case 'V':
228
 
        do_version = true;
229
 
        break;
 
231
        do_version = true;
 
232
        break;
230
233
 
231
234
      case 'w':
232
 
        {
233
 
          int value;
234
 
          char *endp;
235
 
          value = strtol (optarg, &endp, 10);
236
 
          if (endp != optarg)
237
 
            message_page_width_set (value);
238
 
        }
239
 
        break;
 
235
        {
 
236
          int value;
 
237
          char *endp;
 
238
          value = strtol (optarg, &endp, 10);
 
239
          if (endp != optarg)
 
240
            message_page_width_set (value);
 
241
        }
 
242
        break;
240
243
 
241
244
      case CHAR_MAX + 1: /* --translated */
242
 
        to_remove |= REMOVE_UNTRANSLATED;
243
 
        break;
 
245
        to_remove |= REMOVE_UNTRANSLATED;
 
246
        break;
244
247
 
245
248
      case CHAR_MAX + 2: /* --untranslated */
246
 
        to_remove |= REMOVE_TRANSLATED;
247
 
        break;
 
249
        to_remove |= REMOVE_TRANSLATED;
 
250
        break;
248
251
 
249
252
      case CHAR_MAX + 3: /* --no-fuzzy */
250
 
        to_remove |= REMOVE_FUZZY;
251
 
        break;
 
253
        to_remove |= REMOVE_FUZZY;
 
254
        break;
252
255
 
253
256
      case CHAR_MAX + 4: /* --only-fuzzy */
254
 
        to_remove |= REMOVE_NONFUZZY;
255
 
        break;
 
257
        to_remove |= REMOVE_NONFUZZY;
 
258
        break;
256
259
 
257
260
      case CHAR_MAX + 5: /* --no-obsolete */
258
 
        to_remove |= REMOVE_OBSOLETE;
259
 
        break;
 
261
        to_remove |= REMOVE_OBSOLETE;
 
262
        break;
260
263
 
261
264
      case CHAR_MAX + 6: /* --only-obsolete */
262
 
        to_remove |= REMOVE_NONOBSOLETE;
263
 
        break;
 
265
        to_remove |= REMOVE_NONOBSOLETE;
 
266
        break;
264
267
 
265
268
      case CHAR_MAX + 7: /* --set-fuzzy */
266
 
        to_change |= SET_FUZZY;
267
 
        break;
 
269
        to_change |= SET_FUZZY;
 
270
        break;
268
271
 
269
272
      case CHAR_MAX + 8: /* --clear-fuzzy */
270
 
        to_change |= RESET_FUZZY;
271
 
        break;
 
273
        to_change |= RESET_FUZZY;
 
274
        break;
272
275
 
273
276
      case CHAR_MAX + 9: /* --set-obsolete */
274
 
        to_change |= SET_OBSOLETE;
275
 
        break;
 
277
        to_change |= SET_OBSOLETE;
 
278
        break;
276
279
 
277
280
      case CHAR_MAX + 10: /* --clear-obsolete */
278
 
        to_change |= RESET_OBSOLETE;
279
 
        break;
 
281
        to_change |= RESET_OBSOLETE;
 
282
        break;
280
283
 
281
284
      case CHAR_MAX + 11: /* --fuzzy */
282
 
        to_remove |= REMOVE_NONFUZZY;
283
 
        to_change |= RESET_FUZZY;
284
 
        break;
 
285
        to_remove |= REMOVE_NONFUZZY;
 
286
        to_change |= RESET_FUZZY;
 
287
        break;
285
288
 
286
289
      case CHAR_MAX + 12: /* --obsolete */
287
 
        to_remove |= REMOVE_NONOBSOLETE;
288
 
        to_change |= RESET_OBSOLETE;
289
 
        break;
 
290
        to_remove |= REMOVE_NONOBSOLETE;
 
291
        to_change |= RESET_OBSOLETE;
 
292
        break;
290
293
 
291
294
      case CHAR_MAX + 13: /* --no-wrap */
292
 
        message_page_width_ignore ();
293
 
        break;
 
295
        message_page_width_ignore ();
 
296
        break;
294
297
 
295
298
      case CHAR_MAX + 14: /* --only-file */
296
 
        only_file = optarg;
297
 
        break;
 
299
        only_file = optarg;
 
300
        break;
298
301
 
299
302
      case CHAR_MAX + 15: /* --ignore-file */
300
 
        ignore_file = optarg;
301
 
        break;
 
303
        ignore_file = optarg;
 
304
        break;
302
305
 
303
306
      case CHAR_MAX + 16: /* --stringtable-input */
304
 
        input_syntax = &input_format_stringtable;
305
 
        break;
 
307
        input_syntax = &input_format_stringtable;
 
308
        break;
306
309
 
307
310
      case CHAR_MAX + 17: /* --stringtable-output */
308
 
        output_syntax = &output_format_stringtable;
309
 
        break;
 
311
        output_syntax = &output_format_stringtable;
 
312
        break;
310
313
 
311
314
      case CHAR_MAX + 18: /* --clear-previous */
312
 
        to_change |= REMOVE_PREV;
313
 
        break;
 
315
        to_change |= REMOVE_PREV;
 
316
        break;
 
317
 
 
318
      case CHAR_MAX + 19: /* --color */
 
319
        if (handle_color_option (optarg) || color_test_mode)
 
320
          usage (EXIT_FAILURE);
 
321
        break;
 
322
 
 
323
      case CHAR_MAX + 20: /* --style */
 
324
        handle_style_option (optarg);
 
325
        break;
314
326
 
315
327
      default:
316
 
        usage (EXIT_FAILURE);
317
 
        /* NOTREACHED */
 
328
        usage (EXIT_FAILURE);
 
329
        /* NOTREACHED */
318
330
      }
319
331
 
320
332
  /* Version information requested.  */
327
339
This is free software: you are free to change and redistribute it.\n\
328
340
There is NO WARRANTY, to the extent permitted by law.\n\
329
341
"),
330
 
              "2001-2007");
 
342
              "2001-2010");
331
343
      printf (_("Written by %s.\n"), proper_name ("Bruno Haible"));
332
344
      exit (EXIT_SUCCESS);
333
345
    }
350
362
  /* Verify selected options.  */
351
363
  if (!line_comment && sort_by_filepos)
352
364
    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
353
 
           "--no-location", "--sort-by-file");
 
365
           "--no-location", "--sort-by-file");
354
366
 
355
367
  if (sort_by_msgid && sort_by_filepos)
356
368
    error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
357
 
           "--sort-output", "--sort-by-file");
 
369
           "--sort-output", "--sort-by-file");
358
370
 
359
371
  /* Read input file.  */
360
372
  result = read_catalog_file (input_file, input_syntax);
361
373
 
362
374
  /* Read optional files that limit the extent of the attribute changes.  */
363
375
  only_mdlp = (only_file != NULL
364
 
               ? read_catalog_file (only_file, input_syntax)
365
 
               : NULL);
 
376
               ? read_catalog_file (only_file, input_syntax)
 
377
               : NULL);
366
378
  ignore_mdlp = (ignore_file != NULL
367
 
                 ? read_catalog_file (ignore_file, input_syntax)
368
 
                 : NULL);
 
379
                 ? read_catalog_file (ignore_file, input_syntax)
 
380
                 : NULL);
369
381
 
370
382
  /* Filter the messages and manipulate the attributes.  */
371
383
  result = process_msgdomain_list (result, only_mdlp, ignore_mdlp);
389
401
{
390
402
  if (status != EXIT_SUCCESS)
391
403
    fprintf (stderr, _("Try `%s --help' for more information.\n"),
392
 
             program_name);
 
404
             program_name);
393
405
  else
394
406
    {
395
407
      printf (_("\
467
479
      printf (_("\
468
480
Output details:\n"));
469
481
      printf (_("\
 
482
      --color                 use colors and other text attributes always\n\
 
483
      --color=WHEN            use colors and other text attributes if WHEN.\n\
 
484
                              WHEN may be 'always', 'never', 'auto', or 'html'.\n"));
 
485
      printf (_("\
 
486
      --style=STYLEFILE       specify CSS style rule file for --color\n"));
 
487
      printf (_("\
470
488
  -e, --no-escape             do not use C escapes in output (default)\n"));
471
489
      printf (_("\
472
490
  -E, --escape                use C escapes in output, no extended chars\n"));
506
524
         "Report translation bugs to <...>\n" with the address for translation
507
525
         bugs (typically your translation team's web or email address).  */
508
526
      fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
509
 
             stdout);
 
527
             stdout);
510
528
    }
511
529
 
512
530
  exit (status);
523
541
 
524
542
  if ((to_remove & (REMOVE_UNTRANSLATED | REMOVE_TRANSLATED))
525
543
      && (mp->msgstr[0] == '\0'
526
 
          ? to_remove & REMOVE_UNTRANSLATED
527
 
          : to_remove & REMOVE_TRANSLATED))
 
544
          ? to_remove & REMOVE_UNTRANSLATED
 
545
          : to_remove & REMOVE_TRANSLATED))
528
546
    return false;
529
547
 
530
548
  if ((to_remove & (REMOVE_FUZZY | REMOVE_NONFUZZY))
531
549
      && (mp->is_fuzzy
532
 
          ? to_remove & REMOVE_FUZZY
533
 
          : to_remove & REMOVE_NONFUZZY))
 
550
          ? to_remove & REMOVE_FUZZY
 
551
          : to_remove & REMOVE_NONFUZZY))
534
552
    return false;
535
553
 
536
554
  if ((to_remove & (REMOVE_OBSOLETE | REMOVE_NONOBSOLETE))
537
555
      && (mp->obsolete
538
 
          ? to_remove & REMOVE_OBSOLETE
539
 
          : to_remove & REMOVE_NONOBSOLETE))
 
556
          ? to_remove & REMOVE_OBSOLETE
 
557
          : to_remove & REMOVE_NONOBSOLETE))
540
558
    return false;
541
559
 
542
560
  return true;
545
563
 
546
564
static void
547
565
process_message_list (message_list_ty *mlp,
548
 
                      message_list_ty *only_mlp, message_list_ty *ignore_mlp)
 
566
                      message_list_ty *only_mlp, message_list_ty *ignore_mlp)
549
567
{
550
568
  /* Keep only the selected messages.  */
551
569
  message_list_remove_if_not (mlp, is_message_selected);
556
574
      size_t j;
557
575
 
558
576
      for (j = 0; j < mlp->nitems; j++)
559
 
        {
560
 
          message_ty *mp = mlp->item[j];
 
577
        {
 
578
          message_ty *mp = mlp->item[j];
561
579
 
562
 
          /* Attribute changes only affect messages listed in --only-file
563
 
             and not listed in --ignore-file.  */
564
 
          if ((only_mlp
565
 
               ? message_list_search (only_mlp, mp->msgctxt, mp->msgid) != NULL
566
 
               : true)
567
 
              && (ignore_mlp
568
 
                  ? message_list_search (ignore_mlp, mp->msgctxt, mp->msgid) == NULL
569
 
                  : true))
570
 
            {
571
 
              if (to_change & SET_FUZZY)
572
 
                mp->is_fuzzy = true;
573
 
              if (to_change & RESET_FUZZY)
574
 
                mp->is_fuzzy = false;
575
 
              /* Always keep the header entry non-obsolete.  */
576
 
              if ((to_change & SET_OBSOLETE) && !is_header (mp))
577
 
                mp->obsolete = true;
578
 
              if (to_change & RESET_OBSOLETE)
579
 
                mp->obsolete = false;
580
 
              if (to_change & REMOVE_PREV)
581
 
                {
582
 
                  mp->prev_msgctxt = NULL;
583
 
                  mp->prev_msgid = NULL;
584
 
                  mp->prev_msgid_plural = NULL;
585
 
                }
586
 
            }
587
 
        }
 
580
          /* Attribute changes only affect messages listed in --only-file
 
581
             and not listed in --ignore-file.  */
 
582
          if ((only_mlp
 
583
               ? message_list_search (only_mlp, mp->msgctxt, mp->msgid) != NULL
 
584
               : true)
 
585
              && (ignore_mlp
 
586
                  ? message_list_search (ignore_mlp, mp->msgctxt, mp->msgid) == NULL
 
587
                  : true))
 
588
            {
 
589
              if (to_change & SET_FUZZY)
 
590
                mp->is_fuzzy = true;
 
591
              if (to_change & RESET_FUZZY)
 
592
                mp->is_fuzzy = false;
 
593
              /* Always keep the header entry non-obsolete.  */
 
594
              if ((to_change & SET_OBSOLETE) && !is_header (mp))
 
595
                mp->obsolete = true;
 
596
              if (to_change & RESET_OBSOLETE)
 
597
                mp->obsolete = false;
 
598
              if (to_change & REMOVE_PREV)
 
599
                {
 
600
                  mp->prev_msgctxt = NULL;
 
601
                  mp->prev_msgid = NULL;
 
602
                  mp->prev_msgid_plural = NULL;
 
603
                }
 
604
            }
 
605
        }
588
606
    }
589
607
}
590
608
 
591
609
 
592
610
static msgdomain_list_ty *
593
611
process_msgdomain_list (msgdomain_list_ty *mdlp,
594
 
                        msgdomain_list_ty *only_mdlp,
595
 
                        msgdomain_list_ty *ignore_mdlp)
 
612
                        msgdomain_list_ty *only_mdlp,
 
613
                        msgdomain_list_ty *ignore_mdlp)
596
614
{
597
615
  size_t k;
598
616
 
599
617
  for (k = 0; k < mdlp->nitems; k++)
600
618
    process_message_list (mdlp->item[k]->messages,
601
 
                          only_mdlp
602
 
                          ? msgdomain_list_sublist (only_mdlp,
603
 
                                                    mdlp->item[k]->domain,
604
 
                                                    true)
605
 
                          : NULL,
606
 
                          ignore_mdlp
607
 
                          ? msgdomain_list_sublist (ignore_mdlp,
608
 
                                                    mdlp->item[k]->domain,
609
 
                                                    false)
610
 
                          : NULL);
 
619
                          only_mdlp
 
620
                          ? msgdomain_list_sublist (only_mdlp,
 
621
                                                    mdlp->item[k]->domain,
 
622
                                                    true)
 
623
                          : NULL,
 
624
                          ignore_mdlp
 
625
                          ? msgdomain_list_sublist (ignore_mdlp,
 
626
                                                    mdlp->item[k]->domain,
 
627
                                                    false)
 
628
                          : NULL);
611
629
 
612
630
  return mdlp;
613
631
}