Module Name: src Committed By: christos Date: Wed Jun 3 14:32:17 UTC 2015
Modified Files: src/usr.bin: Makefile Added Files: src/usr.bin/gettext: Makefile gettext.1 gettext.c Log Message: Add a gettext implementation from William Orr. To generate a diff of this commit: cvs rdiff -u -r1.220 -r1.221 src/usr.bin/Makefile cvs rdiff -u -r0 -r1.1 src/usr.bin/gettext/Makefile \ src/usr.bin/gettext/gettext.1 src/usr.bin/gettext/gettext.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/Makefile diff -u src/usr.bin/Makefile:1.220 src/usr.bin/Makefile:1.221 --- src/usr.bin/Makefile:1.220 Mon Mar 2 16:54:13 2015 +++ src/usr.bin/Makefile Wed Jun 3 10:32:16 2015 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.220 2015/03/02 21:54:13 christos Exp $ +# $NetBSD: Makefile,v 1.221 2015/06/03 14:32:16 christos Exp $ # from: @(#)Makefile 8.3 (Berkeley) 1/7/94 .include <bsd.own.mk> @@ -12,7 +12,7 @@ SUBDIR= apply asa at audio audiocfg \ eject elf2aout elf2ecoff env error expand extattr \ false fdformat fgen fincore find finger flock fmt fold fpr from \ fsplit fstat ftp gcore genassym gencat getaddrinfo getconf getent \ - getopt gprof \ + getopt gettext gprof \ head hexdump iconv id indent infocmp innetgr ipcrm ipcs join jot \ kdump ktrace ktruss lam last lastcomm ldd leave \ locale locate lock logger login logname look lorder m4 \ Added files: Index: src/usr.bin/gettext/Makefile diff -u /dev/null src/usr.bin/gettext/Makefile:1.1 --- /dev/null Wed Jun 3 10:32:17 2015 +++ src/usr.bin/gettext/Makefile Wed Jun 3 10:32:17 2015 @@ -0,0 +1,10 @@ +# $NetBSD: Makefile,v 1.1 2015/06/03 14:32:17 christos Exp $ + +.include <bsd.own.mk> + +PROG= gettext + +LDADD+= -lintl -lutil +DPADD+= ${LIBINTL} ${LIBUTIL} + +.include <bsd.prog.mk> Index: src/usr.bin/gettext/gettext.1 diff -u /dev/null src/usr.bin/gettext/gettext.1:1.1 --- /dev/null Wed Jun 3 10:32:17 2015 +++ src/usr.bin/gettext/gettext.1 Wed Jun 3 10:32:17 2015 @@ -0,0 +1,104 @@ +.\" $NetBSD: gettext.1,v 1.1 2015/06/03 14:32:17 christos Exp $ +.\" +.\" Copyright (c) 2015 William Orr <w...@worrbase.com>, +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd June 3, 2015 +.Dt GETTEXT 1 +.Os +.Sh NAME +.Nm gettext +.Nd message translation front-end +.Sh SYNOPSIS +.Nm +.Op Fl h +.Nm +.Op Fl en +.Op Ar textdomain +.Ar msgid +.Nm +.Fl s +.Op Fl n +.Op Ar msgid... +.Sh DESCRIPTION +.Nm +attempts to translate a given +.Ar msgid +into the locale-specific string as determined by the environment. +If a translation file is not found, or a translation for the given +.Ar msgid +is not found, the original string will be echoed. +.Pp +If the +.Ar textdomain +is not provided as an argument, the +.Ev textdomain +environment variable will be consulted instead. +.Pp +By default +.Nm +will look for message catalogs in +.Pa /usr/share/locale . +If the environment variable +.Ev TEXTDOMAINDIR +is defined, then that will override the default location. +.Pp +The following flags are available: +.Bl -tag -width Ds +.It Fl e +Interpret backslash escape sequences prior to translation. +.It Fl h +Print the usage information +.It Fl n +If +.Fl s +is used, do not add the trailing newline. If +.Fl s +is not provided, this flag will do nothing. +.It Fl s +Act similarly to +.Xr echo 1 . +All +.Ar msgid +arguments will be translated, and a newline will be appended to the output +string. +.Sh ENVIRONMENT +.Bl -tag -width Ds +.It Ev TEXTDOMAIN +The domain to use when looking up +.Ar msgids +.It Ev TEXTDOMAINDIR +The location of message catalogs to use, overriding +.Pa /usr/share/locale +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +.Bd -literal -offset indent +$ LANG=es gettext grep 'writing output' +escribiendo el resultado +.Ed +.Sh SEE ALSO +.Xr gettext 3 +.Xr echo 1 +.Xr environ 7 Index: src/usr.bin/gettext/gettext.c diff -u /dev/null src/usr.bin/gettext/gettext.c:1.1 --- /dev/null Wed Jun 3 10:32:17 2015 +++ src/usr.bin/gettext/gettext.c Wed Jun 3 10:32:17 2015 @@ -0,0 +1,223 @@ +/* $NetBSD: gettext.c,v 1.1 2015/06/03 14:32:17 christos Exp $ */ + +/*- + * Copyright (c) 2015 William Orr <w...@worrbase.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: gettext.c,v 1.1 2015/06/03 14:32:17 christos Exp $"); + +#include <err.h> +#include <errno.h> +#include <getopt.h> +#include <libintl.h> +#include <locale.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <util.h> + +static __dead void +usage(int exit_status) +{ + + fprintf(stderr, "Usage: %s [-ehn] [[<textdomain>] <msgid>]\n", + getprogname()); + fprintf(stderr, "Usage: %s -s [<msgid>]...\n", getprogname()); + exit(exit_status); +} + +static bool +expand(char *str) +{ + char *fp, *sp, ch, pl; + bool nflag = false; + + for (fp = str, sp = str; *fp != 0;) { + if (*fp == '\\') { + switch (*++fp) { + case 'a': + *sp++ = '\a'; + fp++; + break; + case 'b': + *sp++ = '\b'; + fp++; + break; + case 'c': + nflag = true; + fp++; + break; + case 'f': + *sp++ = '\f'; + fp++; + break; + case 'n': + *sp++ = '\n'; + fp++; + break; + case 'r': + *sp++ = '\r'; + fp++; + break; + case 't': + *sp++ = '\t'; + fp++; + break; + case 'v': + *sp++ = '\v'; + fp++; + break; + case '\\': + *sp++ = '\\'; + fp++; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + ch = *fp++ - '0'; + pl = 0; + while (*fp >= '0' && *fp <= '7' && pl < 2) { + ch *= 8; + ch += *fp++ - '0'; + pl++; + } + + *sp++ = ch; + break; + default: + *sp++ = '\\'; + break; + } + } + *sp++ = *fp++; + } + + *sp = '\0'; + return nflag; +} + +int +main(int argc, char **argv) +{ + char *msgdomain = NULL; + char *msgdomaindir = NULL; + char *translation = NULL; + char *s; + bool eflag = false; + bool sflag = false; + bool nflag = false; + int ch; + + setlocale(LC_ALL, ""); + setprogname(argv[0]); + + while ((ch = getopt(argc, argv, "d:EehnsV")) != -1) { + switch (ch) { + case 'd': + msgdomain = estrdup(optarg); + break; + case 'E': + /* GNU gettext compat */ + break; + case 'e': + eflag = true; + break; + case 'V': + case 'h': + free(msgdomain); + usage(EXIT_SUCCESS); + /* NOTREACHED */ + case 'n': + nflag = true; + break; + case 's': + sflag = true; + break; + default: + free(msgdomain); + usage(EXIT_FAILURE); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + if (argc == 0) { + free(msgdomain); + errx(EXIT_FAILURE, "missing msgid"); + } + + /* msgdomain can be passed as optional arg iff -s is not passed */ + if (!sflag) { + if (argc == 2) { + free(msgdomain); + msgdomain = estrdup(argv[0]); + + argc -= 1; + argv += 1; + } else if (argc > 2) + errx(EXIT_FAILURE, "too many arguments"); + } + + /* msgdomain can be passed as env var */ + if (msgdomain == NULL) { + if ((s = getenv("TEXTDOMAIN")) != NULL) + msgdomain = estrdup(s); + } + + if (msgdomain != NULL) { + if ((s = getenv("TEXTDOMAINDIR")) != NULL) + msgdomaindir = estrdup(s); + if (msgdomaindir) + bindtextdomain(msgdomain, msgdomaindir); + } + + do { + if (eflag) + nflag |= expand(*argv); + + translation = dgettext(msgdomain, argv[0]); + printf("%s", translation); + + argc--; + argv++; + if (argc) + printf(" "); + } while (sflag && argc != 0); + + if (sflag && !nflag) + printf("\n"); + + free(msgdomain); + free(msgdomaindir); + + return EXIT_SUCCESS; +}