1/* Creates an English translation catalog. 2 Copyright (C) 2001-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 "error.h" 33#include "error-progname.h" 34#include "progname.h" 35#include "relocatable.h" 36#include "basename.h" 37#include "message.h" 38#include "read-catalog.h" 39#include "read-po.h" 40#include "read-properties.h" 41#include "read-stringtable.h" 42#include "msgl-english.h" 43#include "write-catalog.h" 44#include "write-po.h" 45#include "write-properties.h" 46#include "write-stringtable.h" 47#include "exit.h" 48#include "propername.h" 49#include "gettext.h" 50 51#define _(str) gettext (str) 52 53 54/* Force output of PO file even if empty. */ 55static int force_po; 56 57/* Long options. */ 58static const struct option long_options[] = 59{ 60 { "add-location", no_argument, &line_comment, 1 }, 61 { "directory", required_argument, NULL, 'D' }, 62 { "escape", no_argument, NULL, 'E' }, 63 { "force-po", no_argument, &force_po, 1 }, 64 { "help", no_argument, NULL, 'h' }, 65 { "indent", no_argument, NULL, 'i' }, 66 { "no-escape", no_argument, NULL, 'e' }, 67 { "no-location", no_argument, &line_comment, 0 }, 68 { "no-wrap", no_argument, NULL, CHAR_MAX + 1 }, 69 { "output-file", required_argument, NULL, 'o' }, 70 { "properties-input", no_argument, NULL, 'P' }, 71 { "properties-output", no_argument, NULL, 'p' }, 72 { "sort-by-file", no_argument, NULL, 'F' }, 73 { "sort-output", no_argument, NULL, 's' }, 74 { "strict", no_argument, NULL, 'S' }, 75 { "stringtable-input", no_argument, NULL, CHAR_MAX + 2 }, 76 { "stringtable-output", no_argument, NULL, CHAR_MAX + 3 }, 77 { "version", no_argument, NULL, 'V' }, 78 { "width", required_argument, NULL, 'w', }, 79 { NULL, 0, NULL, 0 } 80}; 81 82 83/* Forward declaration of local functions. */ 84static void usage (int status) 85#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2) 86 __attribute__ ((noreturn)) 87#endif 88; 89 90 91int 92main (int argc, char **argv) 93{ 94 int opt; 95 bool do_help; 96 bool do_version; 97 char *output_file; 98 msgdomain_list_ty *result; 99 catalog_input_format_ty input_syntax = &input_format_po; 100 catalog_output_format_ty output_syntax = &output_format_po; 101 bool sort_by_filepos = false; 102 bool sort_by_msgid = false; 103 104 /* Set program name for messages. */ 105 set_program_name (argv[0]); 106 error_print_progname = maybe_print_progname; 107 108#ifdef HAVE_SETLOCALE 109 /* Set locale via LC_ALL. */ 110 setlocale (LC_ALL, ""); 111#endif 112 113 /* Set the text message domain. */ 114 bindtextdomain (PACKAGE, relocate (LOCALEDIR)); 115 bindtextdomain ("bison-runtime", relocate (BISON_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 126 while ((opt = getopt_long (argc, argv, "D:eEFhio:pPsVw:", long_options, NULL)) 127 != EOF) 128 switch (opt) 129 { 130 case '\0': /* Long option. */ 131 break; 132 133 case 'D': 134 dir_list_append (optarg); 135 break; 136 137 case 'e': 138 message_print_style_escape (false); 139 break; 140 141 case 'E': 142 message_print_style_escape (true); 143 break; 144 145 case 'F': 146 sort_by_filepos = true; 147 break; 148 149 case 'h': 150 do_help = true; 151 break; 152 153 case 'i': 154 message_print_style_indent (); 155 break; 156 157 case 'o': 158 output_file = optarg; 159 break; 160 161 case 'p': 162 output_syntax = &output_format_properties; 163 break; 164 165 case 'P': 166 input_syntax = &input_format_properties; 167 break; 168 169 case 's': 170 sort_by_msgid = true; 171 break; 172 173 case 'S': 174 message_print_style_uniforum (); 175 break; 176 177 case 'V': 178 do_version = true; 179 break; 180 181 case 'w': 182 { 183 int value; 184 char *endp; 185 value = strtol (optarg, &endp, 10); 186 if (endp != optarg) 187 message_page_width_set (value); 188 } 189 break; 190 191 case CHAR_MAX + 1: /* --no-wrap */ 192 message_page_width_ignore (); 193 break; 194 195 case CHAR_MAX + 2: /* --stringtable-input */ 196 input_syntax = &input_format_stringtable; 197 break; 198 199 case CHAR_MAX + 3: /* --stringtable-output */ 200 output_syntax = &output_format_stringtable; 201 break; 202 203 default: 204 usage (EXIT_FAILURE); 205 break; 206 } 207 208 /* Version information is requested. */ 209 if (do_version) 210 { 211 printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); 212 /* xgettext: no-wrap */ 213 printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ 214This is free software; see the source for copying conditions. There is NO\n\ 215warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 216"), 217 "2001-2006"); 218 printf (_("Written by %s.\n"), proper_name ("Bruno Haible")); 219 exit (EXIT_SUCCESS); 220 } 221 222 /* Help is requested. */ 223 if (do_help) 224 usage (EXIT_SUCCESS); 225 226 /* Test whether we have an .po file name as argument. */ 227 if (optind >= argc) 228 { 229 error (EXIT_SUCCESS, 0, _("no input file given")); 230 usage (EXIT_FAILURE); 231 } 232 if (optind + 1 != argc) 233 { 234 error (EXIT_SUCCESS, 0, _("exactly one input file required")); 235 usage (EXIT_FAILURE); 236 } 237 238 /* Verify selected options. */ 239 if (!line_comment && sort_by_filepos) 240 error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), 241 "--no-location", "--sort-by-file"); 242 243 if (sort_by_msgid && sort_by_filepos) 244 error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), 245 "--sort-output", "--sort-by-file"); 246 247 /* Read input file. */ 248 result = read_catalog_file (argv[optind], input_syntax); 249 250 /* Add English translations. */ 251 result = msgdomain_list_english (result); 252 253 /* Sort the results. */ 254 if (sort_by_filepos) 255 msgdomain_list_sort_by_filepos (result); 256 else if (sort_by_msgid) 257 msgdomain_list_sort_by_msgid (result); 258 259 /* Write the merged message list out. */ 260 msgdomain_list_print (result, output_file, output_syntax, force_po, false); 261 262 exit (EXIT_SUCCESS); 263} 264 265 266/* Display usage information and exit. */ 267static void 268usage (int status) 269{ 270 if (status != EXIT_SUCCESS) 271 fprintf (stderr, _("Try `%s --help' for more information.\n"), 272 program_name); 273 else 274 { 275 printf (_("\ 276Usage: %s [OPTION] INPUTFILE\n\ 277"), program_name); 278 printf ("\n"); 279 /* xgettext: no-wrap */ 280 printf (_("\ 281Creates an English translation catalog. The input file is the last\n\ 282created English PO file, or a PO Template file (generally created by\n\ 283xgettext). Untranslated entries are assigned a translation that is\n\ 284identical to the msgid.\n\ 285")); 286 printf ("\n"); 287 printf (_("\ 288Mandatory arguments to long options are mandatory for short options too.\n")); 289 printf ("\n"); 290 printf (_("\ 291Input file location:\n")); 292 printf (_("\ 293 INPUTFILE input PO or POT file\n")); 294 printf (_("\ 295 -D, --directory=DIRECTORY add DIRECTORY to list for input files search\n")); 296 printf (_("\ 297If input file is -, standard input is read.\n")); 298 printf ("\n"); 299 printf (_("\ 300Output file location:\n")); 301 printf (_("\ 302 -o, --output-file=FILE write output to specified file\n")); 303 printf (_("\ 304The results are written to standard output if no output file is specified\n\ 305or if it is -.\n")); 306 printf ("\n"); 307 printf (_("\ 308Input file syntax:\n")); 309 printf (_("\ 310 -P, --properties-input input file is in Java .properties syntax\n")); 311 printf (_("\ 312 --stringtable-input input file is in NeXTstep/GNUstep .strings syntax\n")); 313 printf ("\n"); 314 printf (_("\ 315Output details:\n")); 316 printf (_("\ 317 -e, --no-escape do not use C escapes in output (default)\n")); 318 printf (_("\ 319 -E, --escape use C escapes in output, no extended chars\n")); 320 printf (_("\ 321 --force-po write PO file even if empty\n")); 322 printf (_("\ 323 -i, --indent indented output style\n")); 324 printf (_("\ 325 --no-location suppress '#: filename:line' lines\n")); 326 printf (_("\ 327 --add-location preserve '#: filename:line' lines (default)\n")); 328 printf (_("\ 329 --strict strict Uniforum output style\n")); 330 printf (_("\ 331 -p, --properties-output write out a Java .properties file\n")); 332 printf (_("\ 333 --stringtable-output write out a NeXTstep/GNUstep .strings file\n")); 334 printf (_("\ 335 -w, --width=NUMBER set output page width\n")); 336 printf (_("\ 337 --no-wrap do not break long message lines, longer than\n\ 338 the output page width, into several lines\n")); 339 printf (_("\ 340 -s, --sort-output generate sorted output\n")); 341 printf (_("\ 342 -F, --sort-by-file sort output by file location\n")); 343 printf ("\n"); 344 printf (_("\ 345Informative output:\n")); 346 printf (_("\ 347 -h, --help display this help and exit\n")); 348 printf (_("\ 349 -V, --version output version information and exit\n")); 350 printf ("\n"); 351 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"), 352 stdout); 353 } 354 355 exit (status); 356} 357