diff options
Diffstat (limited to 'tests/tstgettext.c')
-rw-r--r-- | tests/tstgettext.c | 406 |
1 files changed, 403 insertions, 3 deletions
diff --git a/tests/tstgettext.c b/tests/tstgettext.c index 98cd74d..732cc26 100644 --- a/tests/tstgettext.c +++ b/tests/tstgettext.c @@ -1,3 +1,403 @@ -/* A version of the gettext program that uses the included libintl. */ -#define TESTS -#include "../src/gettext.c" +/* gettext - retrieve text string from message catalog and print it. + Copyright (C) 1995-1997, 2000-2002 Free Software Foundation, Inc. + Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, May 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <getopt.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> + +#include "error.h" +#include "basename.h" +#include "xmalloc.h" +#include "exit.h" +#include "xsetenv.h" + +#define HAVE_SETLOCALE 1 +/* Make sure we use the included libintl, not the system's one. */ +#define textdomain textdomain__ +#define bindtextdomain bindtextdomain__ +#define gettext gettext__ +#define dgettext dgettext__ +#undef _LIBINTL_H +#include "libgnuintl.h" + +#define _(str) gettext (str) + +/* If nonzero add newline after last string. This makes only sense in + the `echo' emulation mode. */ +int add_newline; +/* If nonzero expand escape sequences in strings before looking in the + message catalog. */ +int do_expand; + +/* Name the program is called with. */ +const char *program_name; + +/* Long options. */ +static const struct option long_options[] = +{ + { "domain", required_argument, NULL, 'd' }, + { "env", required_argument, NULL, '=' }, + { "help", no_argument, NULL, 'h' }, + { "shell-script", no_argument, NULL, 's' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + +/* Prototypes for local functions. Needed to ensure compiler checking of + function argument counts despite of K&R C function definition syntax. */ +static void usage PARAMS ((int status)) +#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2) + __attribute__ ((noreturn)) +#endif +; +static const char *expand_escape PARAMS ((const char *str)); + +int +main (argc, argv) + int argc; + char *argv[]; +{ + int optchar; + const char *msgid; + + /* Default values for command line options. */ + int do_help = 0; + int do_shell = 0; + int do_version = 0; + bool environ_changed = false; + const char *domain = getenv ("TEXTDOMAIN"); + const char *domaindir = getenv ("TEXTDOMAINDIR"); + add_newline = 1; + do_expand = 0; + + /* Set program name for message texts. */ + program_name = argv[0]; + if (strncmp (program_name, "lt-", 3) == 0) + program_name += 3; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + /* Parse command line options. */ + while ((optchar = getopt_long (argc, argv, "+d:eEhnsV", long_options, NULL)) + != EOF) + switch (optchar) + { + case '\0': /* Long option. */ + break; + case 'd': + domain = optarg; + break; + case 'e': + do_expand = 1; + break; + case 'E': + /* Ignore. Just for compatibility. */ + break; + case 'h': + do_help = 1; + break; + case 'n': + add_newline = 0; + break; + case 's': + do_shell = 1; + break; + case 'V': + do_version = 1; + break; + case '=': + { + /* Undocumented option --env sets an environment variable. */ + char *separator = strchr (optarg, '='); + if (separator != NULL) + { + *separator = '\0'; + xsetenv (optarg, separator + 1, 1); + environ_changed = true; + break; + } + } + /*FALLTHROUGH*/ + default: + usage (EXIT_FAILURE); + } + +#ifdef HAVE_SETLOCALE + if (environ_changed) + /* Set locale again via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Version information is requested. */ + if (do_version) + { + printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION); + /* xgettext: no-wrap */ + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), + "1995-1997, 2000, 2001"); + printf (_("Written by %s.\n"), "Ulrich Drepper"); + exit (EXIT_SUCCESS); + } + + /* Help is requested. */ + if (do_help) + usage (EXIT_SUCCESS); + + /* We have two major modes: use following Uniforum spec and as + internationalized `echo' program. */ + if (do_shell == 0) + { + /* We have to write a single strings translation to stdout. */ + + /* Get arguments. */ + switch (argc - optind) + { + default: + error (EXIT_FAILURE, 0, _("too many arguments")); + + case 2: + domain = argv[optind++]; + /* FALLTHROUGH */ + + case 1: + break; + + case 0: + error (EXIT_FAILURE, 0, _("missing arguments")); + } + + msgid = argv[optind++]; + + /* Expand escape sequences if enabled. */ + if (do_expand) + msgid = expand_escape (msgid); + + /* If no domain name is given we don't translate. */ + if (domain == NULL || domain[0] == '\0') + { + fputs (msgid, stdout); + } + else + { + /* Bind domain to appropriate directory. */ + if (domaindir != NULL && domaindir[0] != '\0') + bindtextdomain (domain, domaindir); + + /* Write out the result. */ + fputs (dgettext (domain, msgid), stdout); + } + } + else + { + if (optind < argc) + { + /* If no domain name is given we print the original string. + We mark this assigning NULL to domain. */ + if (domain == NULL || domain[0] == '\0') + domain = NULL; + else + /* Bind domain to appropriate directory. */ + if (domaindir != NULL && domaindir[0] != '\0') + bindtextdomain (domain, domaindir); + + /* We have to simulate `echo'. All arguments are strings. */ + do + { + msgid = argv[optind++]; + + /* Expand escape sequences if enabled. */ + if (do_expand) + msgid = expand_escape (msgid); + + /* Write out the result. */ + fputs (domain == NULL ? msgid : dgettext (domain, msgid), + stdout); + + /* We separate the arguments by a single ' '. */ + if (optind < argc) + fputc (' ', stdout); + } + while (optind < argc); + } + + /* If not otherwise told: add trailing newline. */ + if (add_newline) + fputc ('\n', stdout); + } + + exit (EXIT_SUCCESS); +} + + +/* Display usage information and exit. */ +static void +usage (status) + int status; +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + /* xgettext: no-wrap */ + printf (_("\ +Usage: %s [OPTION] [[TEXTDOMAIN] MSGID]\n\ +or: %s [OPTION] -s [MSGID]...\n\ +"), program_name, program_name); + printf ("\n"); + /* xgettext: no-wrap */ + printf (_("\ +Display native language translation of a textual message.\n")); + printf ("\n"); + /* xgettext: no-wrap */ + printf (_("\ + -d, --domain=TEXTDOMAIN retrieve translated messages from TEXTDOMAIN\n\ + -e enable expansion of some escape sequences\n\ + -E (ignored for compatibility)\n\ + -h, --help display this help and exit\n\ + -n suppress trailing newline\n\ + -V, --version display version information and exit\n\ + [TEXTDOMAIN] MSGID retrieve translated message corresponding\n\ + to MSGID from TEXTDOMAIN\n")); + printf ("\n"); + /* xgettext: no-wrap */ + printf (_("\ +If the TEXTDOMAIN parameter is not given, the domain is determined from the\n\ +environment variable TEXTDOMAIN. If the message catalog is not found in the\n\ +regular directory, another location can be specified with the environment\n\ +variable TEXTDOMAINDIR.\n\ +When used with the -s option the program behaves like the `echo' command.\n\ +But it does not simply copy its arguments to stdout. Instead those messages\n\ +found in the selected catalog are translated.\n\ +Standard search directory: %s\n"), + getenv ("IN_HELP2MAN") == NULL ? LOCALEDIR : "@localedir@"); + printf ("\n"); + fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"), stdout); + } + + exit (status); +} + + +/* Expand some escape sequences found in the argument string. */ +static const char * +expand_escape (str) + const char *str; +{ + char *retval, *rp; + const char *cp = str; + + do + { + while (cp[0] != '\0' && cp[0] != '\\') + ++cp; + } + while (cp[0] != '\0' && cp[1] != '\0' + && strchr ("bcfnrt\\01234567", cp[1]) == NULL); + + if (cp[0] == '\0') + return str; + + retval = (char *) xmalloc (strlen (str)); + + rp = retval + (cp - str); + memcpy (retval, str, cp - str); + + do + { + switch (*++cp) + { + case 'b': /* backspace */ + *rp++ = '\b'; + ++cp; + break; + case 'c': /* suppress trailing newline */ + add_newline = 0; + ++cp; + break; + case 'f': /* form feed */ + *rp++ = '\f'; + ++cp; + break; + case 'n': /* new line */ + *rp++ = '\n'; + ++cp; + break; + case 'r': /* carriage return */ + *rp++ = '\r'; + ++cp; + break; + case 't': /* horizontal tab */ + *rp++ = '\t'; + ++cp; + break; + case '\\': + *rp = '\\'; + ++cp; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + int ch = *cp++ - '0'; + + if (*cp >= '0' && *cp <= '7') + { + ch *= 8; + ch += *cp++ - '0'; + + if (*cp >= '0' && *cp <= '7') + { + ch *= 8; + ch += *cp++ - '0'; + } + } + *rp = ch; + } + break; + default: + *rp = '\\'; + break; + } + + while (cp[0] != '\0' && cp[0] != '\\') + *rp++ = *cp++; + } + while (cp[0] != '\0'); + + /* Terminate string. */ + *rp = '\0'; + + return (const char *) retval; +} |