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