[W32] Make use of the LANGUAGE envvar.
authorWerner Koch <wk@gnupg.org>
Mon, 26 Feb 2007 14:26:32 +0000 (14:26 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 26 Feb 2007 14:26:32 +0000 (14:26 +0000)
NEWS
util/ChangeLog
util/simple-gettext.c

diff --git a/NEWS b/NEWS
index fd63f9a..def94c2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
 Noteworthy changes in version 1.4.7
 ------------------------------------------------
 
+    * [W32] The environment variable LANGUAGE may be used to override
+      the language given by HKCU\Software\GNU\GnuPG:Lang.  The
+      language files "*.mo" are expected in a directory named
+      "gnupg.nls" below the directory with the gpg.exe binary.
+
 
 Noteworthy changes in version 1.4.6 (2006-12-06)
 ------------------------------------------------
index 890019e..6a3a785 100644 (file)
@@ -1,3 +1,8 @@
+2007-02-26  Werner Koch  <wk@g10code.com>
+
+       * simple-gettext.c (set_gettext_file): Make use of the envvar
+       LANGUAGE to allow overriding of the registry setting.
+
 2007-02-12  Werner Koch  <wk@g10code.com>
 
        * secmem.c (ptr_into_pool_p): New.
index 3249775..f1f504a 100644 (file)
@@ -43,6 +43,7 @@
 #include "types.h"
 #include "util.h"
 
+#include "windows.h" /* For GetModuleFileName.  */
 
 /* The magic number of the GNU message catalog format. */
 #define MAGIC        0x950412de
@@ -232,96 +233,154 @@ load_domain( const char *filename )
 }
 
 
-/****************
- * Set the file used for translations. Pass a NULL to disable
- * translation.  A new filename may be set at anytime.  If REGKEY is
- * not NULL, the function tries to selected the language the registry
- * key "Lang" below that key.  WARNING: After changing the filename you
- * should not access any data retrieved by gettext().
+/* Set the file used for translations.  Pass a NULL to disable
+   translation.  A new filename may be set at anytime.  WARNING: After
+   changing the filename you should not access any data retrieved by
+   gettext().
+
+   If REGKEY is not NULL, the function tries to selected the language
+   the registry key "Lang" below that key.  If in addition the
+   environment variable LANGUAGE has been set, that value will
+   override a value set by the registry key.
  */
 int
 set_gettext_file ( const char *filename, const char *regkey )
 {
-    struct loaded_domain *domain = NULL;
+  struct loaded_domain *domain = NULL;
 
-    if( filename && *filename ) {
-       if( filename[0] == '/'
+  if ( filename && *filename )
+    {
+      if ( filename[0] == '/'
 #ifdef HAVE_DRIVE_LETTERS
-           || ( isalpha(filename[0])
-                && filename[1] == ':'
-                && (filename[2] == '/' || filename[2] == '\\') )
+           || ( isalpha(filename[0])
+                && filename[1] == ':'
+                && (filename[2] == '/' || filename[2] == '\\') )
 #endif
-          ) {
-           /* absolute path - use it as is */
-           domain = load_domain( filename );
+          )
+        {
+          /* absolute path - use it as is */
+          domain = load_domain( filename );
        }
-       else if (regkey) { /* Standard.  */
-            char *instdir, *langid, *fname;
-            char *p;
-
-            instdir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
-                                                regkey,
-                                                "Install Directory");
-            if (!instdir)
-                return -1;
-            langid = read_w32_registry_string (NULL, /* HKCU then HKLM */
-                                               regkey,
-                                               "Lang");
-            if (!langid) {
-                free (instdir);
+      else if (regkey)  /* Standard.  */
+        {
+          char *instdir, *langid, *fname;
+          char *p;
+          int envvar_mode = 0;
+          
+        again:
+          if (!envvar_mode && (p = getenv ("LANGUAGE")) && *p)
+            {
+              envvar_mode = 1;
+              langid = malloc (strlen (p)+1);
+              if (!langid)
                 return -1;
-            }
-            /* Strip stuff after a dot in case the user tried to enter
-             * the entire locale synatcs as usual for POSIX. */
-            p = strchr (langid, '.');
-            if (p)
+              strcpy (langid, p);
+              /* We only make use of the first language given.  Strip
+                 the rest.  */
+              p = strchr (langid, ':');
+              if (p)
                 *p = 0;
-                
-            /* Build the key: "<instdir>/<domain>.nls/<langid>.mo" We
-               use a directory below the installation directory with
-               the domain included in case the software has been
-               insalled with other software altogether at the same
-               place. */
-            fname = malloc (strlen (instdir) + 1 + strlen (filename) + 5
-                            + strlen (langid) + 3 + 1);
-            if (!fname) {
-                free (instdir);
-                free (langid);
+              
+              /* In the $LANGUAGE case we do not use the registered
+                 installation directory but the one where the gpg
+                 binary has been found.  */
+              instdir = malloc (MAX_PATH+5);
+              if ( !instdir || !GetModuleFileName (NULL, instdir, MAX_PATH) )
+                {
+                  free (langid);
+                  free (instdir);
+                  return -1; /* Error getting the process' file name.  */
+                }
+              p = strrchr (instdir, DIRSEP_C);
+              if (!p)
+                {
+                  free (langid);
+                  free (instdir);
+                  return -1; /* Invalid file name returned.  */
+                }
+              *p = 0;
+            }
+          else
+            {
+              instdir = read_w32_registry_string ("HKEY_LOCAL_MACHINE",
+                                                  regkey,
+                                                  "Install Directory");
+              if (!instdir)
                 return -1;
+              langid = read_w32_registry_string (NULL, /* HKCU then HKLM */
+                                                 regkey,
+                                                 "Lang");
+              if (!langid)
+                {
+                  free (instdir);
+                  return -1;
+                }
+            }
+          
+          /* Strip stuff after a dot in case the user tried to enter
+             the entire locale syntacs as usual for POSIX.  */
+          p = strchr (langid, '.');
+          if (p)
+            *p = 0;
+          
+          /* Build the key: "<instdir>/<domain>.nls/<langid>.mo" We
+             use a directory below the installation directory with the
+             domain included in case the software has been insalled
+             with other software altogether at the same place.  */
+          fname = malloc (strlen (instdir) + 1 + strlen (filename) + 5
+                          + strlen (langid) + 3 + 1);
+          if (!fname)
+            {
+              free (instdir);
+              free (langid);
+              return -1;
+            }
+          strcpy (stpcpy (stpcpy (stpcpy (stpcpy ( stpcpy (fname,
+                  instdir),"\\"), filename), ".nls\\"), langid), ".mo");
+          free (instdir);
+          free (langid);
+
+          /* Better make sure that we don't mix forward and backward
+             slashes.  It seems that some Windoze versions don't
+             accept this. */
+          for (p=fname; *p; p++) 
+            {
+              if (*p == '/')
+                *p = '\\';
             }
-            strcpy (stpcpy (stpcpy (stpcpy (stpcpy ( stpcpy (fname,
-                   instdir),"\\"), filename), ".nls\\"), langid), ".mo");
-            free (instdir);
-            free (langid);
-
-            /* Better make sure that we don't mix forward and
-               backward slashes.  It seems that some Windoze
-               versions don't accept this. */
-            for (p=fname; *p; p++) {
-                if (*p == '/')
-                    *p = '\\';
+          domain = load_domain (fname);
+          free(fname);
+
+          if (!domain && envvar_mode == 1)
+            {
+              /* In case it failed, we try again using the registry
+                 method. */
+              envvar_mode++;
+              goto again;
             }
-            domain = load_domain (fname);
-            free(fname);
        }
+      
 
-       if (!domain)
-           return -1;
+      if (!domain)
+        return -1;
     }
 
-    if( the_domain ) {
-        struct overflow_space_s *os, *os2;
-       free( the_domain->data );
-       free( the_domain->mapped );
-        for (os=the_domain->overflow_space; os; os = os2) {
-            os2 = os->next;
-            free (os);
+  if ( the_domain )
+    {
+      struct overflow_space_s *os, *os2;
+
+      free ( the_domain->data );
+      free ( the_domain->mapped );
+      for (os=the_domain->overflow_space; os; os = os2)
+        {
+          os2 = os->next;
+          free (os);
         }
-       free( the_domain );
-       the_domain = NULL;
+      free ( the_domain );
+      the_domain = NULL;
     }
-    the_domain = domain;
-    return 0;
+  the_domain = domain;
+  return 0;
 }