2007-06-06 20:12:30 +02:00
|
|
|
/* i18n.c - gettext initialization
|
2015-07-01 11:49:37 +02:00
|
|
|
* Copyright (C) 2007, 2010 Free Software Foundation, Inc.
|
|
|
|
* Copyright (C) 2015 g10 Code GmbH
|
2007-06-06 20:12:30 +02:00
|
|
|
*
|
Change license for some files in common to LGPLv3+/GPLv2+.
Having the LGPL on the common GnuPG code helps to share code
between GnuPG and related projects (like GPGME and Libassuan). This
is good for interoperability and to reduces bugs.
* common/asshelp.c, common/asshelp.h, common/asshelp2.c, common/b64dec.c
* common/b64enc.c, common/convert.c, common/dns-cert.c
* common/dns-cert.h common/exechelp-posix.c, common/exechelp-w32.c
* common/exechelp-w32ce.c, common/exechelp.h, common/get-passphrase.c
* common/get-passphrase.h, common/gettime.c, common/gpgrlhelp.c
* common/helpfile.c, common/homedir.c, common/http.c, common/http.h
* common/i18n.c, common/init.c, common/init.h, common/iobuf.c
* common/iobuf.h, common/localename.c, common/membuf.c, common/membuf.h
* common/miscellaneous.c, common/openpgp-oid.c, common/openpgpdefs.h
* common/percent.c, common/pka.c, common/pka.h, common/session-env.c
* common/session-env.h, common/sexp-parse.h, common/sexputil.c
* common/signal.c, common/srv.c, common/srv.h, common/ssh-utils.c
* common/ssh-utils.h, common/sysutils.c, common/sysutils.h
* common/tlv.c, common/tlv.h, common/ttyio.c, common/ttyio.h
* common/userids.c, common/userids.h, common/xasprintf.c: Change
license to LGPLv3+/GPLv2+/
2012-04-20 15:43:06 +02:00
|
|
|
* This file is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of either
|
2007-06-06 20:12:30 +02:00
|
|
|
*
|
Change license for some files in common to LGPLv3+/GPLv2+.
Having the LGPL on the common GnuPG code helps to share code
between GnuPG and related projects (like GPGME and Libassuan). This
is good for interoperability and to reduces bugs.
* common/asshelp.c, common/asshelp.h, common/asshelp2.c, common/b64dec.c
* common/b64enc.c, common/convert.c, common/dns-cert.c
* common/dns-cert.h common/exechelp-posix.c, common/exechelp-w32.c
* common/exechelp-w32ce.c, common/exechelp.h, common/get-passphrase.c
* common/get-passphrase.h, common/gettime.c, common/gpgrlhelp.c
* common/helpfile.c, common/homedir.c, common/http.c, common/http.h
* common/i18n.c, common/init.c, common/init.h, common/iobuf.c
* common/iobuf.h, common/localename.c, common/membuf.c, common/membuf.h
* common/miscellaneous.c, common/openpgp-oid.c, common/openpgpdefs.h
* common/percent.c, common/pka.c, common/pka.h, common/session-env.c
* common/session-env.h, common/sexp-parse.h, common/sexputil.c
* common/signal.c, common/srv.c, common/srv.h, common/ssh-utils.c
* common/ssh-utils.h, common/sysutils.c, common/sysutils.h
* common/tlv.c, common/tlv.h, common/ttyio.c, common/ttyio.h
* common/userids.c, common/userids.h, common/xasprintf.c: Change
license to LGPLv3+/GPLv2+/
2012-04-20 15:43:06 +02:00
|
|
|
* - the GNU Lesser General Public License as published by the Free
|
|
|
|
* Software Foundation; either version 3 of the License, or (at
|
|
|
|
* your option) any later version.
|
2007-06-06 20:12:30 +02:00
|
|
|
*
|
Change license for some files in common to LGPLv3+/GPLv2+.
Having the LGPL on the common GnuPG code helps to share code
between GnuPG and related projects (like GPGME and Libassuan). This
is good for interoperability and to reduces bugs.
* common/asshelp.c, common/asshelp.h, common/asshelp2.c, common/b64dec.c
* common/b64enc.c, common/convert.c, common/dns-cert.c
* common/dns-cert.h common/exechelp-posix.c, common/exechelp-w32.c
* common/exechelp-w32ce.c, common/exechelp.h, common/get-passphrase.c
* common/get-passphrase.h, common/gettime.c, common/gpgrlhelp.c
* common/helpfile.c, common/homedir.c, common/http.c, common/http.h
* common/i18n.c, common/init.c, common/init.h, common/iobuf.c
* common/iobuf.h, common/localename.c, common/membuf.c, common/membuf.h
* common/miscellaneous.c, common/openpgp-oid.c, common/openpgpdefs.h
* common/percent.c, common/pka.c, common/pka.h, common/session-env.c
* common/session-env.h, common/sexp-parse.h, common/sexputil.c
* common/signal.c, common/srv.c, common/srv.h, common/ssh-utils.c
* common/ssh-utils.h, common/sysutils.c, common/sysutils.h
* common/tlv.c, common/tlv.h, common/ttyio.c, common/ttyio.h
* common/userids.c, common/userids.h, common/xasprintf.c: Change
license to LGPLv3+/GPLv2+/
2012-04-20 15:43:06 +02:00
|
|
|
* or
|
|
|
|
*
|
|
|
|
* - the GNU General Public License as published by the Free
|
|
|
|
* Software Foundation; either version 2 of the License, or (at
|
|
|
|
* your option) any later version.
|
|
|
|
*
|
|
|
|
* or both in parallel, as here.
|
|
|
|
*
|
|
|
|
* This file is distributed in the hope that it will be useful,
|
2007-06-06 20:12:30 +02:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2016-11-05 12:02:19 +01:00
|
|
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
2007-06-06 20:12:30 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
2007-10-19 17:58:38 +02:00
|
|
|
#ifdef HAVE_LOCALE_H
|
|
|
|
#include <locale.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LANGINFO_CODESET
|
|
|
|
#include <langinfo.h>
|
|
|
|
#endif
|
2007-06-06 20:12:30 +02:00
|
|
|
|
2007-10-19 17:58:38 +02:00
|
|
|
#include "util.h"
|
2007-06-06 20:12:30 +02:00
|
|
|
#include "i18n.h"
|
|
|
|
|
2007-10-19 17:58:38 +02:00
|
|
|
|
2015-07-28 17:38:44 +02:00
|
|
|
#undef USE_MSGCACHE
|
|
|
|
#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) \
|
|
|
|
&& !defined(USE_SIMPLE_GETTEXT) && defined(ENABLE_NLS)
|
|
|
|
# define USE_MSGCACHE 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef USE_MSGCACHE
|
|
|
|
/* An object to store pointers to static strings and their static
|
|
|
|
translations. A linked list is not optimal but given that we only
|
2015-07-01 11:49:37 +02:00
|
|
|
have a few dozen messages it should be acceptable. */
|
|
|
|
struct msg_cache_s
|
|
|
|
{
|
|
|
|
struct msg_cache_s *next;
|
|
|
|
const char *key;
|
|
|
|
const char *value;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* A object to store an lc_messages string and a link to the cache
|
|
|
|
object. */
|
|
|
|
struct msg_cache_heads_s
|
|
|
|
{
|
|
|
|
struct msg_cache_heads_s *next;
|
|
|
|
struct msg_cache_s *cache;
|
|
|
|
char lc_messages[1];
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Out static cache of translated messages. We need this because
|
|
|
|
there is no gettext API to return a translation depending on the
|
|
|
|
locale. Switching the locale for each access to a translatable
|
|
|
|
string seems to be too expensive. Note that this is used only for
|
|
|
|
strings in gpg-agent which are passed to Pinentry. All other
|
|
|
|
strings are using the regular gettext interface. Note that we can
|
|
|
|
never release this memory because consumers take the result as
|
|
|
|
static strings. */
|
|
|
|
static struct msg_cache_heads_s *msgcache;
|
|
|
|
|
2015-07-28 17:38:44 +02:00
|
|
|
#endif /*USE_MSGCACHE*/
|
2015-07-01 11:49:37 +02:00
|
|
|
|
|
|
|
|
2007-06-06 20:12:30 +02:00
|
|
|
void
|
|
|
|
i18n_init (void)
|
|
|
|
{
|
|
|
|
#ifdef USE_SIMPLE_GETTEXT
|
2008-11-04 20:54:02 +01:00
|
|
|
bindtextdomain (PACKAGE_GT, gnupg_localedir ());
|
2010-10-20 17:06:50 +02:00
|
|
|
textdomain (PACKAGE_GT);
|
2007-06-06 20:12:30 +02:00
|
|
|
#else
|
|
|
|
# ifdef ENABLE_NLS
|
|
|
|
setlocale (LC_ALL, "" );
|
|
|
|
bindtextdomain (PACKAGE_GT, LOCALEDIR);
|
|
|
|
textdomain (PACKAGE_GT);
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2007-10-19 17:58:38 +02:00
|
|
|
|
|
|
|
/* The Assuan agent protocol requires us to transmit utf-8 strings
|
2008-04-18 11:20:25 +02:00
|
|
|
thus we need a way to temporary switch gettext from native to
|
2007-10-19 17:58:38 +02:00
|
|
|
utf8. */
|
|
|
|
char *
|
|
|
|
i18n_switchto_utf8 (void)
|
|
|
|
{
|
2008-04-18 11:20:25 +02:00
|
|
|
#ifdef USE_SIMPLE_GETTEXT
|
2010-03-02 22:25:08 +01:00
|
|
|
/* Return an arbitrary pointer as true value. */
|
|
|
|
return gettext_use_utf8 (1) ? (char*)(-1) : NULL;
|
2008-04-21 21:13:36 +02:00
|
|
|
#elif defined(ENABLE_NLS)
|
2007-10-19 17:58:38 +02:00
|
|
|
char *orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL);
|
2008-04-18 11:20:25 +02:00
|
|
|
# ifdef HAVE_LANGINFO_CODESET
|
2007-10-19 17:58:38 +02:00
|
|
|
if (!orig_codeset)
|
|
|
|
orig_codeset = nl_langinfo (CODESET);
|
2008-04-18 11:20:25 +02:00
|
|
|
# endif
|
2007-10-19 17:58:38 +02:00
|
|
|
if (orig_codeset)
|
|
|
|
{ /* We only switch when we are able to restore the codeset later.
|
|
|
|
Note that bind_textdomain_codeset does only return on memory
|
|
|
|
errors but not if a codeset is not available. Thus we don't
|
|
|
|
bother printing a diagnostic here. */
|
|
|
|
orig_codeset = xstrdup (orig_codeset);
|
|
|
|
if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8"))
|
|
|
|
{
|
|
|
|
xfree (orig_codeset);
|
2011-02-04 12:57:53 +01:00
|
|
|
orig_codeset = NULL;
|
2007-10-19 17:58:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return orig_codeset;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Switch back to the saved codeset. */
|
|
|
|
void
|
|
|
|
i18n_switchback (char *saved_codeset)
|
|
|
|
{
|
2008-04-18 11:20:25 +02:00
|
|
|
#ifdef USE_SIMPLE_GETTEXT
|
2010-03-02 22:25:08 +01:00
|
|
|
gettext_use_utf8 (!!saved_codeset);
|
2008-04-18 11:20:25 +02:00
|
|
|
#elif defined(ENABLE_NLS)
|
2007-10-19 17:58:38 +02:00
|
|
|
if (saved_codeset)
|
|
|
|
{
|
|
|
|
bind_textdomain_codeset (PACKAGE_GT, saved_codeset);
|
|
|
|
xfree (saved_codeset);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void)saved_codeset;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Gettext variant which temporary switches to utf-8 for string. */
|
|
|
|
const char *
|
|
|
|
i18n_utf8 (const char *string)
|
|
|
|
{
|
|
|
|
char *saved = i18n_switchto_utf8 ();
|
|
|
|
const char *result = _(string);
|
|
|
|
i18n_switchback (saved);
|
|
|
|
return result;
|
|
|
|
}
|
2015-06-30 21:58:02 +02:00
|
|
|
|
|
|
|
|
More cleanup of "allow to".
* README, agent/command.c, agent/keyformat.txt, common/i18n.c,
common/iobuf.c, common/keyserver.h, dirmngr/cdblib.c,
dirmngr/ldap-wrapper.c, doc/DETAILS, doc/TRANSLATE,
doc/announce-2.1.txt, doc/gpg.texi, doc/gpgsm.texi,
doc/scdaemon.texi, doc/tools.texi, doc/whats-new-in-2.1.txt,
g10/export.c, g10/getkey.c, g10/import.c, g10/keyedit.c, m4/ksba.m4,
m4/libgcrypt.m4, m4/ntbtls.m4, po/ca.po, po/cs.po, po/da.po,
po/de.po, po/el.po, po/eo.po, po/es.po, po/et.po, po/fi.po,
po/fr.po, po/gl.po, po/hu.po, po/id.po, po/it.po, po/ja.po,
po/nb.po, po/pl.po, po/pt.po, po/ro.po, po/ru.po, po/sk.po,
po/sv.po, po/tr.po, po/uk.po, po/zh_CN.po, po/zh_TW.po,
scd/app-p15.c, scd/ccid-driver.c, scd/command.c, sm/gpgsm.c,
sm/sign.c, tools/gpgconf-comp.c, tools/gpgtar.h: replace "Allow to"
with clearer text.
In standard English, the normal construction is "${XXX} allows ${YYY}
to" -- that is, the subject (${XXX}) of the sentence is allowing the
object (${YYY}) to do something. When the object is missing, the
phrasing sounds awkward, even if the object is implied by context.
There's almost always a better construction that isn't as awkward.
These changes should make the language a bit clearer.
Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
2016-08-02 04:19:17 +02:00
|
|
|
/* A variant of gettext which allows the programmer to specify the
|
|
|
|
locale to use for translating the message. The function assumes
|
|
|
|
that utf-8 is used for the encoding. */
|
2015-06-30 21:58:02 +02:00
|
|
|
const char *
|
|
|
|
i18n_localegettext (const char *lc_messages, const char *string)
|
|
|
|
{
|
2015-07-28 17:38:44 +02:00
|
|
|
#if USE_MSGCACHE
|
2015-07-01 11:49:37 +02:00
|
|
|
const char *result = NULL;
|
|
|
|
char *saved = NULL;
|
|
|
|
struct msg_cache_heads_s *mh;
|
|
|
|
struct msg_cache_s *mc;
|
|
|
|
|
|
|
|
if (!lc_messages)
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
/* Lookup in the cache. */
|
|
|
|
for (mh = msgcache; mh; mh = mh->next)
|
|
|
|
if (!strcmp (mh->lc_messages, lc_messages))
|
|
|
|
break;
|
|
|
|
if (mh)
|
|
|
|
{
|
|
|
|
/* A cache entry for this local exists - find the string.
|
|
|
|
Because the system is designed for static strings it is
|
|
|
|
sufficient to compare the pointers. */
|
|
|
|
for (mc = mh->cache; mc; mc = mc->next)
|
|
|
|
if (mc->key == string)
|
|
|
|
{
|
|
|
|
/* Cache hit. */
|
|
|
|
result = mc->value;
|
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cached miss. Change the locale, translate, reset locale. */
|
|
|
|
saved = setlocale (LC_MESSAGES, NULL);
|
|
|
|
if (!saved)
|
|
|
|
goto leave;
|
|
|
|
saved = xtrystrdup (saved);
|
|
|
|
if (!saved)
|
|
|
|
goto leave;
|
|
|
|
if (!setlocale (LC_MESSAGES, lc_messages))
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
bindtextdomain (PACKAGE_GT, LOCALEDIR);
|
|
|
|
result = gettext (string);
|
|
|
|
setlocale (LC_MESSAGES, saved);
|
|
|
|
bindtextdomain (PACKAGE_GT, LOCALEDIR);
|
|
|
|
|
|
|
|
/* Cache the result. */
|
|
|
|
if (!mh)
|
|
|
|
{
|
|
|
|
/* First use of this locale - create an entry. */
|
|
|
|
mh = xtrymalloc (sizeof *mh + strlen (lc_messages));
|
|
|
|
if (!mh)
|
|
|
|
goto leave;
|
|
|
|
strcpy (mh->lc_messages, lc_messages);
|
|
|
|
mh->cache = NULL;
|
|
|
|
mh->next = msgcache;
|
|
|
|
msgcache = mh;
|
|
|
|
}
|
|
|
|
mc = xtrymalloc (sizeof *mc);
|
|
|
|
if (!mc)
|
|
|
|
goto leave;
|
|
|
|
mc->key = string;
|
|
|
|
mc->value = result;
|
|
|
|
mc->next = mh->cache;
|
|
|
|
mh->cache = mc;
|
|
|
|
|
|
|
|
leave:
|
|
|
|
xfree (saved);
|
|
|
|
return result? result : _(string);
|
|
|
|
|
2015-07-28 17:38:44 +02:00
|
|
|
#else /*!USE_MSGCACHE*/
|
|
|
|
|
2015-07-01 11:49:37 +02:00
|
|
|
(void)lc_messages;
|
2015-06-30 21:58:02 +02:00
|
|
|
return _(string);
|
2015-07-28 17:38:44 +02:00
|
|
|
|
|
|
|
#endif /*!USE_MSGCACHE*/
|
2015-06-30 21:58:02 +02:00
|
|
|
}
|