Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/lib/libintl/gettext.c,v rcsdiff: /ftp/cvs/cvsroot/src/lib/libintl/gettext.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.28 retrieving revision 1.29 diff -u -p -r1.28 -r1.29 --- src/lib/libintl/gettext.c 2012/07/30 23:04:42 1.28 +++ src/lib/libintl/gettext.c 2015/05/29 12:26:28 1.29 @@ -1,4 +1,4 @@ -/* $NetBSD: gettext.c,v 1.28 2012/07/30 23:04:42 yamt Exp $ */ +/* $NetBSD: gettext.c,v 1.29 2015/05/29 12:26:28 christos Exp $ */ /*- * Copyright (c) 2000, 2001 Citrus Project, @@ -29,7 +29,7 @@ */ #include -__RCSID("$NetBSD: gettext.c,v 1.28 2012/07/30 23:04:42 yamt Exp $"); +__RCSID("$NetBSD: gettext.c,v 1.29 2015/05/29 12:26:28 christos Exp $"); #include #include @@ -51,6 +51,16 @@ __RCSID("$NetBSD: gettext.c,v 1.28 2012/ #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 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 * /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) { @@ -659,12 +747,13 @@ fail: static void free_sysdep_table(struct mosysdepstr_h **table, uint32_t nstring) { - uint32_t i; - for (i=0; iexpanded) - free(table[i]->expanded); + free(table[i]->expanded); free(table[i]); } } @@ -680,26 +769,16 @@ unmapit(struct domainbinding *db) if (mohandle->addr && mohandle->addr != MAP_FAILED) munmap(mohandle->addr, mohandle->len); mohandle->addr = NULL; - if (mohandle->mo.mo_otable) - free(mohandle->mo.mo_otable); - if (mohandle->mo.mo_ttable) - free(mohandle->mo.mo_ttable); - if (mohandle->mo.mo_charset) - free(mohandle->mo.mo_charset); - if (mohandle->mo.mo_htable) - free(mohandle->mo.mo_htable); - if (mohandle->mo.mo_sysdep_segs) - free(mohandle->mo.mo_sysdep_segs); - if (mohandle->mo.mo_sysdep_otable) { - free_sysdep_table(mohandle->mo.mo_sysdep_otable, - mohandle->mo.mo_sysdep_nstring); - } - if (mohandle->mo.mo_sysdep_ttable) { - free_sysdep_table(mohandle->mo.mo_sysdep_ttable, - mohandle->mo.mo_sysdep_nstring); - } - if (mohandle->mo.mo_plural) - _gettext_free_plural(mohandle->mo.mo_plural); + free(mohandle->mo.mo_otable); + free(mohandle->mo.mo_ttable); + free(mohandle->mo.mo_charset); + free(mohandle->mo.mo_htable); + free(mohandle->mo.mo_sysdep_segs); + free_sysdep_table(mohandle->mo.mo_sysdep_otable, + mohandle->mo.mo_sysdep_nstring); + free_sysdep_table(mohandle->mo.mo_sysdep_ttable, + mohandle->mo.mo_sysdep_nstring); + _gettext_free_plural(mohandle->mo.mo_plural); memset(&mohandle->mo, 0, sizeof(mohandle->mo)); return 0; } @@ -918,17 +997,15 @@ dcngettext(const char *domainname, const domainname, db) == NULL) goto fail; - if (odomainname) - free(odomainname); - if (ocname) - free(ocname); + free(odomainname); + free(ocname); + odomainname = strdup(domainname); ocname = strdup(cname); if (!odomainname || !ocname) { - if (odomainname) - free(odomainname); - if (ocname) - free(ocname); + free(odomainname); + free(ocname); + odomainname = ocname = NULL; } else