1
/* gettext - retrieve text string from message catalog and print it.
2
Copyright (C) 1995-1997, 2000-2004 Free Software Foundation, Inc.
3
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, May 1995.
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)
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.
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. */
33
#include "relocatable.h"
40
#define _(str) gettext (str)
42
/* If true, add newline after last string. This makes only sense in
43
the `echo' emulation mode. */
44
static bool add_newline;
46
/* If true, expand escape sequences in strings before looking in the
48
static bool do_expand;
51
static const struct option long_options[] =
53
{ "domain", required_argument, NULL, 'd' },
54
{ "help", no_argument, NULL, 'h' },
55
{ "shell-script", no_argument, NULL, 's' },
56
{ "version", no_argument, NULL, 'V' },
60
/* Forward declaration of local functions. */
61
static void usage (int status)
62
#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
63
__attribute__ ((noreturn))
66
static const char *expand_escape (const char *str);
69
main (int argc, char *argv[])
74
/* Default values for command line options. */
76
bool do_shell = false;
77
bool do_version = false;
78
const char *domain = getenv ("TEXTDOMAIN");
79
const char *domaindir = getenv ("TEXTDOMAINDIR");
83
/* Set program name for message texts. */
84
set_program_name (argv[0]);
87
/* Set locale via LC_ALL. */
88
setlocale (LC_ALL, "");
91
/* Set the text message domain. */
92
bindtextdomain (PACKAGE, relocate (LOCALEDIR));
95
/* Ensure that write errors on stdout are detected. */
96
atexit (close_stdout);
98
/* Parse command line options. */
99
while ((optchar = getopt_long (argc, argv, "+d:eEhnsV", long_options, NULL))
103
case '\0': /* Long option. */
112
/* Ignore. Just for compatibility. */
127
usage (EXIT_FAILURE);
130
/* Version information is requested. */
133
printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
134
/* xgettext: no-wrap */
135
printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
136
This is free software; see the source for copying conditions. There is NO\n\
137
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
139
"1995-1997, 2000-2004");
140
printf (_("Written by %s.\n"), "Ulrich Drepper");
144
/* Help is requested. */
146
usage (EXIT_SUCCESS);
148
/* We have two major modes: use following Uniforum spec and as
149
internationalized `echo' program. */
152
/* We have to write a single strings translation to stdout. */
155
switch (argc - optind)
158
error (EXIT_FAILURE, 0, _("too many arguments"));
161
domain = argv[optind++];
168
error (EXIT_FAILURE, 0, _("missing arguments"));
171
msgid = argv[optind++];
173
/* Expand escape sequences if enabled. */
175
msgid = expand_escape (msgid);
177
/* If no domain name is given we don't translate. */
178
if (domain == NULL || domain[0] == '\0')
180
fputs (msgid, stdout);
184
/* Bind domain to appropriate directory. */
185
if (domaindir != NULL && domaindir[0] != '\0')
186
bindtextdomain (domain, domaindir);
188
/* Write out the result. */
189
fputs (dgettext (domain, msgid), stdout);
196
/* If no domain name is given we print the original string.
197
We mark this assigning NULL to domain. */
198
if (domain == NULL || domain[0] == '\0')
201
/* Bind domain to appropriate directory. */
202
if (domaindir != NULL && domaindir[0] != '\0')
203
bindtextdomain (domain, domaindir);
205
/* We have to simulate `echo'. All arguments are strings. */
208
msgid = argv[optind++];
210
/* Expand escape sequences if enabled. */
212
msgid = expand_escape (msgid);
214
/* Write out the result. */
215
fputs (domain == NULL ? msgid : dgettext (domain, msgid),
218
/* We separate the arguments by a single ' '. */
222
while (optind < argc);
225
/* If not otherwise told: add trailing newline. */
227
fputc ('\n', stdout);
234
/* Display usage information and exit. */
238
if (status != EXIT_SUCCESS)
239
fprintf (stderr, _("Try `%s --help' for more information.\n"),
243
/* xgettext: no-wrap */
245
Usage: %s [OPTION] [[TEXTDOMAIN] MSGID]\n\
246
or: %s [OPTION] -s [MSGID]...\n\
247
"), program_name, program_name);
249
/* xgettext: no-wrap */
251
Display native language translation of a textual message.\n"));
253
/* xgettext: no-wrap */
255
-d, --domain=TEXTDOMAIN retrieve translated messages from TEXTDOMAIN\n\
256
-e enable expansion of some escape sequences\n\
257
-E (ignored for compatibility)\n\
258
-h, --help display this help and exit\n\
259
-n suppress trailing newline\n\
260
-V, --version display version information and exit\n\
261
[TEXTDOMAIN] MSGID retrieve translated message corresponding\n\
262
to MSGID from TEXTDOMAIN\n"));
264
/* xgettext: no-wrap */
266
If the TEXTDOMAIN parameter is not given, the domain is determined from the\n\
267
environment variable TEXTDOMAIN. If the message catalog is not found in the\n\
268
regular directory, another location can be specified with the environment\n\
269
variable TEXTDOMAINDIR.\n\
270
When used with the -s option the program behaves like the `echo' command.\n\
271
But it does not simply copy its arguments to stdout. Instead those messages\n\
272
found in the selected catalog are translated.\n\
273
Standard search directory: %s\n"),
274
getenv ("IN_HELP2MAN") == NULL ? LOCALEDIR : "@localedir@");
276
fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"), stdout);
283
/* Expand some escape sequences found in the argument string. */
285
expand_escape (const char *str)
288
const char *cp = str;
292
while (cp[0] != '\0' && cp[0] != '\\')
295
while (cp[0] != '\0' && cp[1] != '\0'
296
&& strchr ("bcfnrt\\01234567", cp[1]) == NULL);
301
retval = (char *) xmalloc (strlen (str));
303
rp = retval + (cp - str);
304
memcpy (retval, str, cp - str);
310
case 'b': /* backspace */
314
case 'c': /* suppress trailing newline */
318
case 'f': /* form feed */
322
case 'n': /* new line */
326
case 'r': /* carriage return */
330
case 't': /* horizontal tab */
338
case '0': case '1': case '2': case '3':
339
case '4': case '5': case '6': case '7':
341
int ch = *cp++ - '0';
343
if (*cp >= '0' && *cp <= '7')
348
if (*cp >= '0' && *cp <= '7')
362
while (cp[0] != '\0' && cp[0] != '\\')
365
while (cp[0] != '\0');
367
/* Terminate string. */
370
return (const char *) retval;