tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: [PATCH 3/3] Added initial implementation of context function



In article <1432396450-5296-3-git-send-email-will%worrbase.com@localhost>,
William Orr  <will%worrbase.com@localhost> wrote:
>- Added most *p*gettext functions
>- Added basic function to concat msgctxt and msgid
>
>Work needed:
>
>- Tests!
>---
> src/lib/libintl/gettext.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++
> src/lib/libintl/libintl.h |  21 +++++++++
> 2 files changed, 131 insertions(+)
>
>diff --git a/src/lib/libintl/gettext.c b/src/lib/libintl/gettext.c
>index 479b4be..b9e2369 100644
>--- a/src/lib/libintl/gettext.c
>+++ b/src/lib/libintl/gettext.c
>@@ -51,6 +51,16 @@ __RCSID("$NetBSD: gettext.c,v 1.28 2012/07/30
>23:04:42 yamt Exp $");
> #include "plural_parser.h"
> #include "pathnames.h"
> 
>+/* GNU gettext added a hack to add some context to messages. If a message is
>+ * used in multiple locations, it needs some amount of context to make the
>+ * translation clear to translators. GNU gettext, rather than modifying the
>+ * message format, concatenates the context, \004 and the message id.
>+ */
>+#define	MSGCTXT_ID_SEPARATOR	'\004'
>+
>+static const char *pgettext_impl(const char *, const char *, const char *,
>+				const char *, unsigned long int, int);

Again KNF indent.

>+static char *concatenate_ctxt_id(const char *, const char *);
> static const char *lookup_category(int);
> static const char *split_locale(const char *);
> static const char *lookup_mofile(char *, size_t, const char *, const char *,
>@@ -105,6 +115,73 @@ dngettext(const char *domainname, const char
>*msgid1, const char *msgid2,
> 	return dcngettext(domainname, msgid1, msgid2, n, LC_MESSAGES);
> }
> 
>+const char *
>+pgettext(const char *msgctxt, const char *msgid)
>+{
>+
>+	return pgettext_impl(NULL, msgctxt, msgid, NULL, 1UL, LC_MESSAGES);
>+}
>+
>+const char *
>+dpgettext(const char *domainname, const char *msgctxt, const char *msgid)
>+{
>+
>+	return pgettext_impl(domainname, msgctxt, msgid, NULL, 1UL, LC_MESSAGES);
>+}
>+
>+const char *
>+dcpgettext(const char *domainname, const char *msgctxt, const char *msgid,
>+	int category)
>+{
>+
>+	return pgettext_impl(domainname, msgctxt, msgid, NULL, 1UL, category);
>+}
>+
>+const char *
>+npgettext(const char *msgctxt, const char *msgid1, const char *msgid2,
>+	unsigned long int n)
>+{
>+
>+	return pgettext_impl(NULL, msgctxt, msgid1, msgid2, n, LC_MESSAGES);
>+}
>+
>+const char *
>+dnpgettext(const char *domainname, const char *msgctxt, const char *msgid1,
>+	const char *msgid2, unsigned long int n)
>+{
>+
>+	return pgettext_impl(domainname, msgctxt, msgid1, msgid2, n, LC_MESSAGES);
>+}
>+
>+const char *
>+dcnpgettext(const char *domainname, const char *msgctxt, const char *msgid1,
>+	const char *msgid2, unsigned long int n, int category)
>+{
>+
>+	return pgettext_impl(domainname, msgctxt, msgid1, msgid2, n, category);
>+}
>+
>+static const char *
>+pgettext_impl(const char *domainname, const char *msgctxt, const char *msgid1,
>+	const char *msgid2, unsigned long int n, int category)
>+{
>+	char *msgctxt_id;
>+	char *translation;
>+	char *p;
>+
>+	if ((msgctxt_id = concatenate_ctxt_id(msgctxt, msgid1)) == NULL)
>+		return msgid1;
>+
>+	translation = dcngettext(domainname, msgctxt_id,
>+		msgid2, n, category);
>+	free(msgctxt_id);
>+
>+	p = strchr(translation, '\004');
>+	if (p)
>+		return p + 1;
>+	return translation;
>+}
>+
> /*
>  * dcngettext() -
>  * lookup internationalized message on database locale/category/domainname
>@@ -126,6 +203,39 @@ dngettext(const char *domainname, const char
>*msgid1, const char *msgid2,
>  * /usr/share/locale! (or we should move those files into /usr/libdata)
>  */
> 
>+static char *
>+concatenate_ctxt_id(const char *msgctxt, const char *msgid)
>+{
>+	char *ret;
>+	size_t msgctxt_id_siz;
>+
>+	msgctxt_id_siz = strlen(msgctxt) + strlen(msgid) + 2;
>+	ret = malloc(msgctxt_id_siz);
>+
>+	if (!ret)
>+		return ret;
>+
>+	// if truncation occurs, integer overflow happened; abort
>+	if (strlcpy(ret, msgctxt, msgctxt_id_siz) >= msgctxt_id_siz) {
>+		free(ret);
>+		return NULL;
>+	}
>+
>+	if (strlen(ret) + 2 > msgctxt_id_siz) {
>+		free(ret);
>+		return NULL;
>+	}
>+
>+	ret[strlen(msgctxt)] = MSGCTXT_ID_SEPARATOR;
>+
>+	if (strlcat(ret, msgid, msgctxt_id_siz) >= msgctxt_id_siz) {
>+		free(ret);
>+		return NULL;
>+	}

The whole thing can be replaced with asprintf().

>+
>+	return ret;
>+}
>+
> static const char *
> lookup_category(int category)
> {
>diff --git a/src/lib/libintl/libintl.h b/src/lib/libintl/libintl.h
>index 39f53b8..0c045f4 100644
>--- a/src/lib/libintl/libintl.h
>+++ b/src/lib/libintl/libintl.h
>@@ -31,6 +31,18 @@
> 
> #include <sys/cdefs.h>
> 
>+#define pgettext_expr(msgctxt, msgid) pgettext((msgctxt), (msgid))
>+#define dpggettext_expr(domainname, msgctxt, msgid) \
>+	dpgettext((domainname), (msgctxt), (msgid))
>+#define dcpgettext_expr(domainname, msgctxt, msgid, category) \
>+	dcpgettext((domainname), (msgctxt), (msgid), (category))
>+#define npgettext_expr(msgctxt, msgid1, msgid2, n) \
>+	npgettext((msgctxt), (msgid1), (msgid2), (n))
>+#define dnpgettext_expr(domainname, msgctxt, msgid1, n) \
>+	dnpgettext((domainname), (msgctxt), (msgid1), (msgid2), (n))
>+#define dcnpgettext_expr(domainname, msgctxt, msgid1, msgid2, n, category) \
>+	dcnpgettext((domainname), (msgctxt), (msgid1), (msgid2), (n), (category))

Second line indents again.

>+
> __BEGIN_DECLS
> char *gettext(const char *) __format_arg(1);
> char *dgettext(const char *, const char *) __format_arg(2);
>@@ -41,6 +53,15 @@ char *dngettext(const char *, const char *, const
>char *, unsigned long int)
>     __format_arg(2) __format_arg(3);
> char *dcngettext(const char *, const char *, const char *, unsigned long int,
>     int) __format_arg(2) __format_arg(3);
>+const char *pgettext(const char *, const char *) __format_arg(2);
>+const char *dpgettext(const char *, const char *, const char *)
>__format_arg(3);
>+const char *dcpgettext(const char *, const char *, const char *, int)
>__format_arg(3);
>+const char *npgettext(const char *, const char *, const char *,
>+    unsigned long int) __format_arg(2) __format_arg(3);
>+const char *dnpgettext(const char *, const char *, const char *,
>+	const char *, unsigned long int) __format_arg(3) __format_arg(4);
>+const char *dcnpgettext(const char *, const char *, const char *,
>+	const char *, unsigned long int, int) __format_arg(3) __format_arg(4);

Second line indents again.

> 
> char *textdomain(const char *);
> char *bindtextdomain(const char *, const char *);
>-- 
>2.1.0
>
>

Thanks for doing that,

christos



Home | Main Index | Thread Index | Old Index