[git] GnuPG - branch, master, updated. gnupg-2.1.5-43-ga65447f

by Werner Koch cvs at cvs.gnupg.org
Wed Jul 1 11:57:27 CEST 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  a65447f0d64d0c53ddbdcfc988f26ecc9a8a6f08 (commit)
      from  816824953c91959c23a57c047bdba6a902ffdde6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a65447f0d64d0c53ddbdcfc988f26ecc9a8a6f08
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Jul 1 11:49:37 2015 +0200

    common: Implement i18n_localegettext.
    
    * common/i18n.c (msg_cache_s, msg_cache_head_s): New.
    (msgcache): New.
    (i18n_localegettext): Implement locale dependent lookup.
    --
    
    This is the second and final part of the change to use the gpg
    provided locale for Pinentry strings.  It does not yet work on
    Windows, though.
    
    This commit should resolve
    Debian-bug-id: 788983
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/common/i18n.c b/common/i18n.c
index e6d3f5e..d1f157c 100644
--- a/common/i18n.c
+++ b/common/i18n.c
@@ -1,5 +1,6 @@
 /* i18n.c - gettext initialization
- *	Copyright (C) 2007, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2007, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2015 g10 Code GmbH
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of either
@@ -37,6 +38,37 @@
 #include "i18n.h"
 
 
+/* An object to store pointers to static strings and there static
+   translation.  A linked list is not optimal but given that we only
+   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;
+
+
+
 void
 i18n_init (void)
 {
@@ -117,11 +149,79 @@ i18n_utf8 (const char *string)
 
 /* A variant of gettext which allows to specify the local to use for
    translating the message.  The function assumes that utf-8 is used
-   for the encoding.  FIXME: The locale back and forth switching is
-   likely very expensive, thus we should consider to implement our own
-   cache here.  */
+   for the encoding.  */
 const char *
 i18n_localegettext (const char *lc_messages, const char *string)
 {
+#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)             \
+  && !defined(USE_SIMPLE_GETTEXT) && defined(ENABLE_NLS)
+  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);
+
+#else /*!(HAVE_SETLOCALE && LC_MESSAGES ...)*/
+  (void)lc_messages;
   return _(string);
+#endif /*!(HAVE_SETLOCALE && LC_MESSAGES ...)*/
 }

-----------------------------------------------------------------------

Summary of changes:
 common/i18n.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 104 insertions(+), 4 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list