tech-userlevel archive

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

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



- Added most *p*gettext functions
- Added basic function to concat msgctxt and msgid

Work needed:

- Tests!
---
 src/lib/libintl/gettext.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/libintl/libintl.h | 31 +++++++++++++++--
 2 files changed, 128 insertions(+), 10 deletions(-)

diff --git a/src/lib/libintl/gettext.c b/src/lib/libintl/gettext.c
index ab18caa..f76b682 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);
+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,17 @@ 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;
+
+	if (asprintf(&ret, "%s%c%s", msgctxt, MSGCTXT_ID_SEPARATOR, msgid) == -1)
+		return NULL;
+
+	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..5360768 100644
--- a/src/lib/libintl/libintl.h
+++ b/src/lib/libintl/libintl.h
@@ -31,16 +31,41 @@
 
 #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))
+
 __BEGIN_DECLS
 char *gettext(const char *) __format_arg(1);
 char *dgettext(const char *, const char *) __format_arg(2);
 char *dcgettext(const char *, const char *, int) __format_arg(2);
 char *ngettext(const char *, const char *, unsigned long int)
-    __format_arg(1) __format_arg(2);
+	       __format_arg(1) __format_arg(2);
 char *dngettext(const char *, const char *, const char *, unsigned long int)
-    __format_arg(2) __format_arg(3);
+		__format_arg(2) __format_arg(3);
 char *dcngettext(const char *, const char *, const char *, unsigned long int,
-    int) __format_arg(2) __format_arg(3);
+		 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);
 
 char *textdomain(const char *);
 char *bindtextdomain(const char *, const char *);
-- 
2.1.0



Home | Main Index | Thread Index | Old Index