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;
+}

Reply via email to