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