1 /* gettext - retrieve text string from message catalog and print it.
2 Copyright (C) 1995-1997, 2000-2005 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"
39 #define HAVE_SETLOCALE 1
40 /* Make sure we use the included libintl, not the system's one. */
42 #include "libgnuintl.h"
44 #define _(str) gettext (str)
46 /* If true, add newline after last string. This makes only sense in
47 the `echo' emulation mode. */
48 static bool add_newline
;
50 /* If true, expand escape sequences in strings before looking in the
52 static bool do_expand
;
55 static const struct option long_options
[] =
57 { "domain", required_argument
, NULL
, 'd' },
58 { "env", required_argument
, NULL
, '=' },
59 { "help", no_argument
, NULL
, 'h' },
60 { "shell-script", no_argument
, NULL
, 's' },
61 { "version", no_argument
, NULL
, 'V' },
65 /* Forward declaration of local functions. */
66 static void usage (int status
)
67 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
68 __attribute__ ((noreturn
))
71 static const char *expand_escape (const char *str
);
74 main (int argc
, char *argv
[])
79 /* Default values for command line options. */
81 bool do_shell
= false;
82 bool do_version
= false;
83 bool environ_changed
= false;
84 const char *domain
= getenv ("TEXTDOMAIN");
85 const char *domaindir
= getenv ("TEXTDOMAINDIR");
89 /* Set program name for message texts. */
90 set_program_name (argv
[0]);
93 /* Set locale via LC_ALL. */
94 setlocale (LC_ALL
, "");
97 /* Set the text message domain. */
98 bindtextdomain (PACKAGE
, relocate (LOCALEDIR
));
101 /* Ensure that write errors on stdout are detected. */
102 atexit (close_stdout
);
104 /* Parse command line options. */
105 while ((optchar
= getopt_long (argc
, argv
, "+d:eEhnsV", long_options
, NULL
))
109 case '\0': /* Long option. */
118 /* Ignore. Just for compatibility. */
134 /* Undocumented option --env sets an environment variable. */
135 char *separator
= strchr (optarg
, '=');
136 if (separator
!= NULL
)
139 xsetenv (optarg
, separator
+ 1, 1);
140 environ_changed
= true;
146 usage (EXIT_FAILURE
);
149 #ifdef HAVE_SETLOCALE
151 /* Set locale again via LC_ALL. */
152 setlocale (LC_ALL
, "");
155 /* Version information is requested. */
158 printf ("%s (GNU %s) %s\n", basename (program_name
), PACKAGE
, VERSION
);
159 /* xgettext: no-wrap */
160 printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
161 This is free software; see the source for copying conditions. There is NO\n\
162 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
164 "1995-1997, 2000-2005");
165 printf (_("Written by %s.\n"), "Ulrich Drepper");
169 /* Help is requested. */
171 usage (EXIT_SUCCESS
);
173 /* We have two major modes: use following Uniforum spec and as
174 internationalized `echo' program. */
177 /* We have to write a single strings translation to stdout. */
180 switch (argc
- optind
)
183 error (EXIT_FAILURE
, 0, _("too many arguments"));
186 domain
= argv
[optind
++];
193 error (EXIT_FAILURE
, 0, _("missing arguments"));
196 msgid
= argv
[optind
++];
198 /* Expand escape sequences if enabled. */
200 msgid
= expand_escape (msgid
);
202 /* If no domain name is given we don't translate. */
203 if (domain
== NULL
|| domain
[0] == '\0')
205 fputs (msgid
, stdout
);
209 /* Bind domain to appropriate directory. */
210 if (domaindir
!= NULL
&& domaindir
[0] != '\0')
211 bindtextdomain (domain
, domaindir
);
213 /* Write out the result. */
214 fputs (dgettext (domain
, msgid
), stdout
);
221 /* If no domain name is given we print the original string.
222 We mark this assigning NULL to domain. */
223 if (domain
== NULL
|| domain
[0] == '\0')
226 /* Bind domain to appropriate directory. */
227 if (domaindir
!= NULL
&& domaindir
[0] != '\0')
228 bindtextdomain (domain
, domaindir
);
230 /* We have to simulate `echo'. All arguments are strings. */
233 msgid
= argv
[optind
++];
235 /* Expand escape sequences if enabled. */
237 msgid
= expand_escape (msgid
);
239 /* Write out the result. */
240 fputs (domain
== NULL
? msgid
: dgettext (domain
, msgid
),
243 /* We separate the arguments by a single ' '. */
247 while (optind
< argc
);
250 /* If not otherwise told: add trailing newline. */
252 fputc ('\n', stdout
);
259 /* Display usage information and exit. */
263 if (status
!= EXIT_SUCCESS
)
264 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
268 /* xgettext: no-wrap */
270 Usage: %s [OPTION] [[TEXTDOMAIN] MSGID]\n\
271 or: %s [OPTION] -s [MSGID]...\n\
272 "), program_name
, program_name
);
274 /* xgettext: no-wrap */
276 Display native language translation of a textual message.\n"));
278 /* xgettext: no-wrap */
280 -d, --domain=TEXTDOMAIN retrieve translated messages from TEXTDOMAIN\n\
281 -e enable expansion of some escape sequences\n\
282 -E (ignored for compatibility)\n\
283 -h, --help display this help and exit\n\
284 -n suppress trailing newline\n\
285 -V, --version display version information and exit\n\
286 [TEXTDOMAIN] MSGID retrieve translated message corresponding\n\
287 to MSGID from TEXTDOMAIN\n"));
289 /* xgettext: no-wrap */
291 If the TEXTDOMAIN parameter is not given, the domain is determined from the\n\
292 environment variable TEXTDOMAIN. If the message catalog is not found in the\n\
293 regular directory, another location can be specified with the environment\n\
294 variable TEXTDOMAINDIR.\n\
295 When used with the -s option the program behaves like the `echo' command.\n\
296 But it does not simply copy its arguments to stdout. Instead those messages\n\
297 found in the selected catalog are translated.\n\
298 Standard search directory: %s\n"),
299 getenv ("IN_HELP2MAN") == NULL
? LOCALEDIR
: "@localedir@");
301 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"), stdout
);
308 /* Expand some escape sequences found in the argument string. */
310 expand_escape (const char *str
)
313 const char *cp
= str
;
317 while (cp
[0] != '\0' && cp
[0] != '\\')
321 /* Found a backslash. */
324 if (strchr ("abcfnrtv\\01234567", cp
[1]) != NULL
)
329 retval
= (char *) xmalloc (strlen (str
));
331 rp
= retval
+ (cp
- str
);
332 memcpy (retval
, str
, cp
- str
);
336 /* Here cp[0] == '\\'. */
339 case 'a': /* alert */
343 case 'b': /* backspace */
347 case 'c': /* suppress trailing newline */
351 case 'f': /* form feed */
355 case 'n': /* new line */
359 case 'r': /* carriage return */
363 case 't': /* horizontal tab */
367 case 'v': /* vertical tab */
375 case '0': case '1': case '2': case '3':
376 case '4': case '5': case '6': case '7':
378 int ch
= *cp
++ - '0';
380 if (*cp
>= '0' && *cp
<= '7')
385 if (*cp
>= '0' && *cp
<= '7')
399 while (cp
[0] != '\0' && cp
[0] != '\\')
402 while (cp
[0] != '\0');
404 /* Terminate string. */
407 return (const char *) retval
;