First batch of changes to support W32CE.
authorWerner Koch <wk@gnupg.org>
Fri, 26 Feb 2010 18:44:36 +0000 (18:44 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 26 Feb 2010 18:44:36 +0000 (18:44 +0000)
Note that jnlib/w32-reg.c is not yet ready.

25 files changed:
ChangeLog
NEWS
autogen.sh
configure.ac
gl/Makefile.am
gl/mkdtemp.c
gl/setenv.c
gl/unsetenv.c
jnlib/ChangeLog
jnlib/Makefile.am
jnlib/dotlock.c
jnlib/dynload.h
jnlib/libjnlib-config.h
jnlib/mischelp.c
jnlib/mischelp.h
jnlib/stringhelp.c
jnlib/t-stringhelp.c
jnlib/t-support.c
jnlib/t-support.h
jnlib/t-timestuff.c [new file with mode: 0644]
jnlib/utf8conv.c
jnlib/utf8conv.h
jnlib/w32-afunix.c
jnlib/w32-gettext.c [deleted file]
jnlib/w32help.h

index b72f89c..adefd49 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,15 @@
 2010-02-26  Werner Koch  <wk@g10code.com>
 
+       * gl/mkdtemp.c (__set_errno) [W32CE]: Use gpg_err_set_errno.
+       * gl/setenv.c (__set_errno) [W32CE]: Ditto.
+       * gl/unsetenv.c (__set_errno) [W32CE]: Ditto.
+
        * configure.ac (HAVE_W32CE_SYSTEM): New ac_define and
        am_conditional.
-       * autogen.sh: New option --build-w32ce.
+       (signal.h, getenv): Check for them.
+
+       * autogen.sh: New option --build-w32ce.  Remove obsolete option
+       --without-included-gettext.
 
 2009-12-08  Werner Koch  <wk@g10code.com>
 
 2006-09-18  Werner Koch  <wk@g10code.com>
 
        Released 1.9.23.
-       
+
        * configure.ac (--enable-agent-only): Donot build tools and doc
        (--disable-tools,--disable-doc): New.
        * Makefile.am (SUBDIRS): Allow to conditional build tools and doc.
 
        Replaced all call gpg_error_from_errno(errno) by
        gpg_error_from_syserror().
-       
+
        * configure.ac: Build gpg by default.
        (GNUPG_SYS_SO_PEERCRED): Removed.
 
 2006-09-06  Werner Koch  <wk@g10code.com>
 
        * configure.ac: Define _ASSUAN_ONLY_GPG_ERRORS.  Require Assuan
-       0.9 and libgpg-error 1.4 
+       0.9 and libgpg-error 1.4.
 
 2006-08-31  Werner Koch  <wk@g10code.com>
 
 
 2006-07-03  Werner Koch  <wk@g10code.com>
 
-       * configure.ac: Test for ksba_dn_teststr. 
+       * configure.ac: Test for ksba_dn_teststr.
 
 2006-06-30  Werner Koch  <wk@g10code.com>
 
        * Makefile.am (SUBDIRS): Include keyserver/.
        * configure.ac: Include keyserver/.
        (FAKE_CURL, GPGKEYS_CURL): New.
-       
+
 2006-06-20  Werner Koch  <wk@g10code.com>
 
        Released 1.9.21.
 2005-08-01  Werner Koch  <wk@g10code.com>
 
        Released 1.9.18.
-       
+
        * configure.ac: Require libksba 0.9.12 to match new features in gpgsm.
 
 2005-06-20  Werner Koch  <wk@g10code.com>
 2005-04-21  Werner Koch  <wk@g10code.com>
 
        Released 1.9.16.
-       
+
        * configure.ac: Do not build gpg by default.
 
 2005-04-20  Werner Koch  <wk@g10code.com>
 2005-04-15  Marcus Brinkmann  <marcus@g10code.de>
 
        * configure.ac: Check for /usr/bin/shred and define SHRED.
-       
+
        * configure.ac: Add --enable-symcryptrun, disabled by default.
        Define automake variable BUILD_SYMCRYPTRUN.
        Check for openpty -lutil, define LIBUTIL_LIBS.
 2004-12-20  Werner Koch  <wk@g10code.com>
 
        * configure.ac: Add PATHSEP_C and PATHSEP_S. For W32 let all
-       directories default to c:/gnupg.  Require libassuan 0.6.9.      
-       
+       directories default to c:/gnupg.  Require libassuan 0.6.9.
+
 2004-12-18  Werner Koch  <wk@g10code.com>
 
        * configure.ac (AH_BOTTOM): Define EXEEXT_S.
 
        * configure.ac: Replace strsep.  Replaced use of "target" by
        "host".
-       
+
 2004-10-22  Werner Koch  <wk@g10code.com>
 
        Released 1.9.12.
 
        * configure.ac: Build Makefile for tests/pkits.  New option
        --with-pkits-tests.
-       
+
 2004-08-05  Werner Koch  <wk@g10code.de>
 
        * configure.ac: Changed tests for libusb to also suuport the
 2004-03-06  Werner Koch  <wk@gnupg.org>
 
        Released 1.9.6.
-       
+
        * configure.ac: Check the Libgcrypt API.
 
 2004-02-25  Werner Koch  <wk@gnupg.org>
 2003-11-17  Werner Koch  <wk@gnupg.org>
 
        Release 1.9.2.
-       
+
        * configure.ac: Requires now libassuan 0.6.1.
 
 2003-10-31  Werner Koch  <wk@gnupg.org>
 
 2003-10-01  Werner Koch  <wk@gnupg.org>
 
-       * configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION. 
+       * configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION.
 
 2003-09-23  Werner Koch  <wk@gnupg.org>
 
        Merged most of David Shaw's changes in 1.3 since 2003-06-03.
-       
+
        * configure.ac: Drop all TIGER/192 support.
        (uint64_t): Check for UINT64_C to go along with uint64_t.
        (getaddrinfo): Check for it.
 2003-09-06  Werner Koch  <wk@gnupg.org>
 
        Released 1.9.1.
-       
+
        * configure.ac: Require newer versions of some libraries.
 
 2003-09-02  Werner Koch  <wk@gnupg.org>
 2003-08-05  Werner Koch  <wk@gnupg.org>
 
        Released 1.9.0.
-       
+
        * configure.ac (GNUPG_DEFAULT_HONMEDIR): Changed back to ~/.gnupg.
-       
+
 2003-07-31  Werner Koch  <wk@gnupg.org>
 
        * Makefile.am (DISTCLEANFILES): Add g10defs.h
 
        * configure.ac: Build a limited version of scdaemon if libopensc
        is not available.
-       
+
        * configure.ac (ALL_LINUGAS): Removed.
 
        * Makefile.am (ACLOCAL_AMFLAGS): New.
 
 2003-01-09  Werner Koch  <wk@gnupg.org>
 
-       * configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool. 
+       * configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool.
        (NEED_KSBA_VERSION): Does now require 0.4.6.
 
-       * README: Noted where to find gpg-protect-tool. 
+       * README: Noted where to find gpg-protect-tool.
 
 2002-10-31  Neal H. Walfield  <neal@g10code.de>
 
 2002-08-10  Werner Koch  <wk@gnupg.org>
 
        Released 0.3.10.
-       
+
        * configure.ac (NEED_LIBKSBA_VERSION): Require 0.4.4. Add support
        for gettext.
 
 2002-07-01  Werner Koch  <wk@gnupg.org>
 
         Released 0.3.9.
-       
+
        * README: Short note on how to export in pkcs-12 format.
 
 2002-06-29  Werner Koch  <wk@gnupg.org>
 2002-06-25  Werner Koch  <wk@gnupg.org>
 
        Released 0.3.8.
-       
+
        * configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.1.8.
 
 2002-06-12  Werner Koch  <wk@gnupg.org>
 2002-05-14  Werner Koch  <wk@gnupg.org>
 
        * doc/: New
-       * configure.ac, Makefile.am:  Added doc/ 
+       * configure.ac, Makefile.am:  Added doc/.
 
 2002-05-03  Werner Koch  <wk@gnupg.org>
 
 2002-04-15  Werner Koch  <wk@gnupg.org>
 
        Released 0.3.5.
-       
+
        * NEWS: Started to describe release notes.
-       
+
        * configure.ac (NEED_LIBKSBA_VERSION, NEED_LIBGCRYPT_VERSION): Defined
 
 2002-04-01  Werner Koch  <wk@gnupg.org>
 
        * configure.ac (HAVE_JNLIB_LOGGING): always define it.
 
-       
- Copyright 2001, 2002, 2003, 2004, 2005, 2006,
-          2007 Free Software Foundation, Inc.
+
+ Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007.
+          2010 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without
  This file is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-               
+
 
diff --git a/NEWS b/NEWS
index 2fcf9fa..a81215c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,8 @@ Noteworthy changes in version 2.1.x (under development)
  * New and changed passphrases are now created with an iteration count
    requiring about 100ms of CPU work.
 
+ * Ported to Windows CE.
+
 
 Noteworthy changes in version 2.0.13 (2009-09-04)
 -------------------------------------------------
index 86552ee..2edbaba 100755 (executable)
@@ -123,8 +123,7 @@ if [ "$myhost" = "w32" ]; then
             --with-zlib=${w32root} \
             --with-regex=${w32root} \
              --with-pth-prefix=${w32root} \
-             --with-adns=${w32root} \
-             --without-included-gettext "$@"
+             --with-adns=${w32root} "$@"
     rc=$?
     exit $rc
 fi
index 7ac5ec0..abb26cf 100644 (file)
@@ -918,6 +918,9 @@ AC_SUBST(GPGKEYS_MAILTO)
 # Construct a printable name of the OS
 #
 case "${host}" in
+    *-mingw32ce*)
+        PRINTABLE_OS_NAME="W32CE"
+        ;;
     *-mingw32*)
         PRINTABLE_OS_NAME="MingW32"
         ;;
@@ -1089,9 +1092,11 @@ AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include <signal.h>])
 #
 # These are needed by libjnlib - fixme: we should use a jnlib.m4
 # Note:  We already checked pwd.h.
-AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol])
-AC_CHECK_FUNCS([memrchr isascii timegm getrusage setrlimit stat setlocale])
-AC_CHECK_FUNCS([flockfile funlockfile fopencookie funopen getpwnam getpwuid])
+AC_CHECK_HEADERS([signal.h])
+AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \
+                memrchr isascii timegm getrusage setrlimit stat setlocale   \
+                flockfile funlockfile fopencookie funopen getpwnam getpwuid \
+                getenv ])
 
 #
 # gnulib checks
index 59667db..5c1d7c4 100644 (file)
@@ -29,6 +29,10 @@ MAINTAINERCLEANFILES =
 
 AM_CPPFLAGS =
 
+if HAVE_W32CE_SYSTEM
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+endif
+
 ## begin gnulib module alloca-opt
 
 BUILT_SOURCES += $(ALLOCA_H)
index 4cf86a0..e3abb11 100644 (file)
 
 #include <errno.h>
 #ifndef __set_errno
-# define __set_errno(Val) errno = (Val)
+# ifdef HAVE_W32CE_SYSTEM
+#  include <gpg-error.h>
+#  define __set_errno(Val) gpg_err_set_errno ((Val))
+# else
+#  define __set_errno(Val) errno = (Val)
+# endif
 #endif
 
 #include <stddef.h>
index 7c03d62..a748396 100644 (file)
 
 #include <errno.h>
 #ifndef __set_errno
-# define __set_errno(ev) ((errno) = (ev))
+# ifdef HAVE_W32CE_SYSTEM
+#  include <gpg-error.h>
+#  define __set_errno(ev) gpg_err_set_errno ((ev))
+# else
+#  define __set_errno(ev) ((errno) = (ev))
+# endif
 #endif
 
 #include <stdlib.h>
index 76b707c..222d7fc 100644 (file)
 
 #include <errno.h>
 #if !_LIBC
-# define __set_errno(ev) ((errno) = (ev))
+# ifdef HAVE_W32CE_SYSTEM
+#  include <gpg-error.h>
+#  define __set_errno(ev) gpg_err_set_errno ((ev))
+# else
+#  define __set_errno(ev) ((errno) = (ev))
+# endif
 #endif
 
 #include <stdlib.h>
index 5498493..5a9e707 100644 (file)
@@ -1,3 +1,44 @@
+2010-02-26  Werner Koch  <wk@g10code.com>
+
+       * t-timestuff.c: New.
+
+       * dynload.h (dlopen, dlsym) [W32CE]: Map to wchar_t.
+
+       * mischelp.c (_jnlib_free): New.
+       (same_file_p) [W32CE]: Map to wchar_t.
+
+       * utf8conv.c (set_native_charset) [W32CE]: Do not use
+       GetConsoleOutputCP.
+       (wchar_to_utf8, utf8_to_wchar) [W32]: New.
+
+       * Makefile.am (t_jnlib_ldadd) [W32CE]: Add gpg-error.
+
+       * t-support.h (getenv) [HAVE_GETENV]: Add getenv stub.
+       [W32CE]: Include gpg-error.h
+       * t-support.c (gpg_err_code_from_errno)
+       (gpg_err_code_from_syserror) [GPG_ERROR_H]: Do not build.
+
+       * t-stringhelp.c (gethome) [!HAVE_GETPWUID]: Keep result of getenv.
+
+       * dotlock.c [!HAVE_SIGNAL_H]: Don't include signal.h.
+       (create_dotlock) [W32CE]: Map filename top wchar_t.
+
+       * libjnlib-config.h [USE_SIMPLE_GETTEXT]: Include gpg-error.h and
+       remove w32help.h.
+       (jnlib_set_errno): New.  Use it everywhere to set ERRNO.
+       (getenv) [!HAVE_GETENV]: New.
+       (getpid) [W32E]: New.
+
+       * stringhelp.c (get_pwdir) [!HAVE_PWD_H]: Mark unused args.
+       (w32_strerror) [W32CE]: Use a simple implementation.
+
+       * w32help.h [USE_SIMPLE_GETTEXT]: Remove all definitions; we are
+       now using the gpg-error included implementation.
+       * w32-gettext.c: Remove.
+
+       * mischelp.c (same_file_p): Fix bug in case the second file can't
+       be opened.
+
 2009-10-19  Werner Koch  <wk@g10code.com>
 
        * strlist.c (add_to_strlist_try): New.
@@ -696,10 +737,10 @@ Mon Jan 24 13:04:28 CET 2000  Werner Koch  <wk@gnupg.de>
      ***********************************************************
      * Please note that JNLIB is maintained as part of GnuPG.  *
      * You may find it source-copied in other packages.        *
-     ***********************************************************       
-       
- Copyright 2000, 2001, 2002, 2003, 2004,
-          2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+     ***********************************************************
+
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+          2010 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without
index c6d0b3a..a0da872 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for the JNLIB part of GnuPG
-# Copyright (C) 1999, 2000, 2001, 2004,
-#               2006 Feee Software Soundation, Inc.
+# Copyright (C) 1999, 2000, 2001, 2004, 2006,
+#               2010 Feee Software Soundation, Inc.
 # 
 # This file is part of JNLIB.
 # 
@@ -44,7 +44,7 @@ libjnlib_a_SOURCES = \
        types.h mischelp.c mischelp.h dynload.h w32help.h
 
 if HAVE_W32_SYSTEM
-libjnlib_a_SOURCES += w32-reg.c w32-afunix.c w32-afunix.h w32-gettext.c
+libjnlib_a_SOURCES += w32-reg.c w32-afunix.c w32-afunix.h
 endif
 
 
@@ -60,11 +60,19 @@ endif
 # defines replacements for the actual used memory allocation functions
 # so that there is no dependency on libgcrypt.
 #
-module_tests = t-stringhelp
+module_tests = t-stringhelp t-timestuff
 
 t_jnlib_src = t-support.c t-support.h 
 t_jnlib_ldadd = libjnlib.a $(LIBINTL) $(LIBICONV)
+# For W32 we need libgpg-error because it provides gettext.
+if HAVE_W32_SYSTEM
+t_jnlib_ldadd += $(GPG_ERROR_LIBS)
+endif
 
 t_stringhelp_SOURCES = t-stringhelp.c $(t_jnlib_src)
 t_stringhelp_LDADD = $(t_jnlib_ldadd)
 
+t_timestuff_SOURCES = t-timestuff.c $(t_jnlib_src)
+t_timestuff_LDADD = $(t_jnlib_ldadd)
+
+
index bf179be..0d5a7bc 100644 (file)
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <signal.h>
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
 
 #include "libjnlib-config.h"
 #include "stringhelp.h"
 #include "dotlock.h"
+#include "utf8conv.h"
 
 #if !defined(DIRSEP_C) && !defined(EXTSEP_C) \
     && !defined(DIRSEP_S) && !defined(EXTSEP_S)
@@ -222,7 +225,7 @@ create_dotlock (const char *file_to_lock)
 
   do 
     {
-      errno = 0;
+      jnlib_set_errno (0);
       fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
                  S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
     } 
@@ -301,10 +304,23 @@ create_dotlock (const char *file_to_lock)
      would not stop as expected but spin til until Windows crashes.
      Our solution is to keep the lock file open; that does not
      harm. */ 
-  h->lockhd = CreateFile (h->lockname,
-                          GENERIC_READ|GENERIC_WRITE,
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          NULL, OPEN_ALWAYS, 0, NULL);
+  {
+#ifdef HAVE_W32CE_SYSTEM
+    wchar_t *wname = utf8_to_wchar (h->lockname);
+    
+    h->lockhd = INVALID_HANDLE_VALUE;
+    if (wname)
+      h->lockhd = CreateFile (wname,
+#else
+    h->lockhd = CreateFile (h->lockname,
+#endif
+                            GENERIC_READ|GENERIC_WRITE,
+                            FILE_SHARE_READ|FILE_SHARE_WRITE,
+                            NULL, OPEN_ALWAYS, 0, NULL);
+#ifdef HAVE_W32CE_SYSTEM
+    jnlib_free (wname);                           
+#endif
+  }
   if (h->lockhd == INVALID_HANDLE_VALUE)
     {
       log_error (_("can't create `%s': %s\n"), h->lockname, w32_strerror (-1));
@@ -613,7 +629,7 @@ read_lockfile (dotlock_t h, int *same_node )
                 h->lockname, strerror(errno) );
       if (buffer != buffer_space)
         jnlib_free (buffer);
-      errno = e; /* Need to return ERRNO here. */
+      jnlib_set_errno (e); /* Need to return ERRNO here. */
       return -1;
     }
 
@@ -630,7 +646,7 @@ read_lockfile (dotlock_t h, int *same_node )
           close (fd); 
           if (buffer != buffer_space)
             jnlib_free (buffer);
-          errno = 0; /* Do not return an inappropriate ERRNO. */
+          jnlib_set_errno (0); /* Do not return an inappropriate ERRNO. */
           return -1;
         }
       p += res;
@@ -644,7 +660,7 @@ read_lockfile (dotlock_t h, int *same_node )
       log_info ("invalid size of lockfile `%s'", h->lockname );
       if (buffer != buffer_space)
         jnlib_free (buffer);
-      errno = 0; /* Better don't return an inappropriate ERRNO. */
+      jnlib_set_errno (0); /* Better don't return an inappropriate ERRNO. */
       return -1;
     }
 
@@ -660,7 +676,7 @@ read_lockfile (dotlock_t h, int *same_node )
       log_error ("invalid pid %d in lockfile `%s'", pid, h->lockname );
       if (buffer != buffer_space)
         jnlib_free (buffer);
-      errno = 0;
+      jnlib_set_errno (0);
       return -1;
     }
 
index 5477465..0c8a3bb 100644 (file)
@@ -1,5 +1,5 @@
 /* dynload.h - Wrapper functions for run-time dynamic loading
- *      Copyright (C) 2003 Free Software Foundation, Inc.
+ *      Copyright (C) 2003, 2010 Free Software Foundation, Inc.
  *
  * This file is part of JNLIB.
  *
 # include <dlfcn.h>
 #else
 # include <windows.h>
-
+# include "utf8conv.h"
+# include "mischelp.h"
 # define RTLD_LAZY 0
 
 static inline void *
-dlopen (const char * name, int flag)
+dlopen (const char *name, int flag)
 {
-  void * hd = LoadLibrary (name);
+  void *hd;
+#ifdef HAVE_W32CE_SYSTEM
+  wchar_t *wname = utf8_to_wchar (name);
+  hd = wname? LoadLibrary (wname) : NULL;
+  _jnlib_free (wname);
+#else
+  hd = LoadLibrary (name);
+#endif
   (void)flag;
   return hd;
 }
@@ -40,7 +48,13 @@ dlsym (void *hd, const char *sym)
 {
   if (hd && sym)
     {
-      void * fnc = GetProcAddress (hd, sym);
+#ifdef HAVE_W32CE_SYSTEM
+      wchar_t *wsym = utf8_to_wchar (sym);
+      void *fnc = wsym? GetProcAddress (hd, wsym) : NULL;
+      _jnlib_free (wsym);
+#else
+      void *fnc = GetProcAddress (hd, sym);
+#endif
       if (!fnc)
         return NULL;
       return fnc;
@@ -53,7 +67,7 @@ static inline const char *
 dlerror (void)
 {
   static char buf[32];
-  sprintf (buf, "ec=%lu", GetLastError ());
+  snprintf (buf, sizeof buf, "ec=%lu", GetLastError ());
   return buf;
 }
 
index 5c61442..621e89f 100644 (file)
@@ -39,7 +39,7 @@
 
 /* Gettext stuff */
 #ifdef USE_SIMPLE_GETTEXT
-# include "w32help.h"
+# include <gpg-error.h>
 # define _(a) gettext (a)
 # define N_(a) (a)
 
 #define jnlib_log_fatal    log_fatal
 #define jnlib_log_bug     log_bug
 
+/* Wrapper to set ERRNO.  */
+#ifdef HAVE_W32CE_SYSTEM
+# define jnlib_set_errno(e)  gpg_err_set_errno ((e))
+#else
+# define jnlib_set_errno(e)  do { errno = (e); } while (0)
+#endif
+
+/* Dummy replacement for getenv.  */
+#ifndef HAVE_GETENV
+#define getenv(a)  (NULL)
+#endif
+
+#ifdef HAVE_W32CE_SYSTEM
+#define getpid() GetCurrentProcessId ()
+#endif
 
 #endif /*LIBJNUTIL_CONFIG_H*/
index f7df5c1..e06be21 100644 (file)
 # include <sys/stat.h>
 # include <unistd.h>
 #endif /*!HAVE_W32_SYSTEM*/
+#include <errno.h>
 
 #include "libjnlib-config.h"
 #include "stringhelp.h"
+#include "utf8conv.h"
 #include "mischelp.h"
 
 
+/* Because we can't use our jnlib_free macro in inline functions we
+   provide this wrapper.  */
+void
+_jnlib_free (void *p)
+{
+  if (p)
+    jnlib_free (p);
+}
+
+
 /* Check whether the files NAME1 and NAME2 are identical.  This is for
    example achieved by comparing the inode numbers of the files.  */
 int
@@ -50,14 +62,36 @@ same_file_p (const char *name1, const char *name2)
 #ifdef HAVE_W32_SYSTEM  
       HANDLE file1, file2;
       BY_HANDLE_FILE_INFORMATION info1, info2;
-      
+
+#ifdef HAVE_W32CE_SYSTEM
+      {
+        wchar_t *wname = utf8_to_wchar (name1);
+        if (wname)
+          file1 = CreateFile (wname, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+        else
+          file1 = INVALID_HANDLE_VALUE;
+        jnlib_free (wname);
+      }
+#else      
       file1 = CreateFile (name1, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+#endif
       if (file1 == INVALID_HANDLE_VALUE)
         yes = 0; /* If we can't open the file, it is not the same.  */
       else
         {
+#ifdef HAVE_W32CE_SYSTEM
+          {
+            wchar_t *wname = utf8_to_wchar (name2);
+            if (wname)
+              file2 = CreateFile (wname, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+            else
+              file2 = INVALID_HANDLE_VALUE;
+            jnlib_free (wname);
+          }
+#else
           file2 = CreateFile (name2, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
-          if (file1 == INVALID_HANDLE_VALUE)
+#endif
+          if (file2 == INVALID_HANDLE_VALUE)
             yes = 0; /* If we can't open the file, it is not the same.  */
           else
             {
@@ -87,7 +121,7 @@ same_file_p (const char *name1, const char *name2)
   and get back a time_t.  It differs from mktime() in that it handles
   the case where the struct tm is UTC and the local environment isn't.
 
-  Note, that this replacement implementaion is not thread-safe!
+  Note, that this replacement implementation might not be thread-safe!
 
   Some BSDs don't handle the putenv("foo") case properly, so we use
   unsetenv if the platform has it to remove environment variables.
@@ -96,6 +130,35 @@ same_file_p (const char *name1, const char *name2)
 time_t
 timegm (struct tm *tm)
 {
+#ifdef HAVE_W32_SYSTEM
+  /* This one is thread safe.  */
+  SYSTEMTIME st;
+  FILETIME ft;
+  unsigned long long cnsecs;
+
+  st.wYear   = tm->tm_year + 1900;
+  st.wMonth  = tm->tm_mon  + 1;
+  st.wDay    = tm->tm_mday;
+  st.wHour   = tm->tm_hour;
+  st.wMinute = tm->tm_min;
+  st.wSecond = tm->tm_sec;
+  st.wMilliseconds = 0; /* Not available.  */
+  st.wDayOfWeek = 0;    /* Ignored.  */
+
+  /* System time is UTC thus the conversion is pretty easy.  */
+  if (!SystemTimeToFileTime (&st, &ft))
+    {
+      jnlib_set_errno (EINVAL);
+      return (time_t)(-1);
+    }
+
+  cnsecs = (((unsigned long long)ft.dwHighDateTime << 32)
+            | ft.dwLowDateTime);
+  cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01.  */
+  return (time_t)(cnsecs / 10000000ULL);
+
+#else /* (Non thread safe implementation!) */
+
   time_t answer;
   char *zone;
 
@@ -128,6 +191,7 @@ timegm (struct tm *tm)
 
   tzset();
   return answer;
+#endif
 }
 #endif /*!HAVE_TIMEGM*/
 
index e478354..52781e1 100644 (file)
 #define LIBJNLIB_MISCHHELP_H
 
 
+/* Because we can't use the internal jnlib_free macro in inline
+   functions we provide a wrapper fucntion as well.   */
+void _jnlib_free (void *p);
+
 /* Check whether the files NAME1 and NAME2 are identical.  This is for
    example achieved by comparing the inode numbers of the files.  */
 int same_file_p (const char *name1, const char *name2);
index 3173ebc..36f96b8 100644 (file)
@@ -346,6 +346,10 @@ get_pwdir (int xmode, const char *name)
       else
         result = jnlib_strdup (pwd->pw_dir);
     }
+#else /*!HAVE_PWD_H*/
+  /* No support at all.  */
+  (void)xmode;
+  (void)name;
 #endif /*HAVE_PWD_H*/
   return result;
 }
@@ -369,7 +373,7 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
         {
           if (xmode)
             BUG ();
-          errno = EINVAL;
+          jnlib_set_errno (EINVAL);
           return NULL;
         }
       argc++; 
@@ -738,9 +742,15 @@ w32_strerror (int ec)
   
   if (ec == -1)
     ec = (int)GetLastError ();
+#ifdef HAVE_W32CE_SYSTEM
+  /* There is only a wchar_t FormatMessage.  It does not make much
+     sense to play the conversion game; we print only the code.  */
+  snprintf (strerr, sizeof strerr, "ec=%d", (int)GetLastError ());
+#else
   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
                  strerr, DIM (strerr)-1, NULL);
+#endif
   return strerr;    
 }
 #endif /*HAVE_W32_SYSTEM*/
@@ -1076,7 +1086,7 @@ do_strconcat (const char *s1, va_list arg_ptr)
       needed += strlen (argv[argc]);
       if (argc >= DIM (argv)-1)
         {
-          errno = EINVAL;
+          jnlib_set_errno (EINVAL);
           return NULL;
         }
       argc++;
index 02041d3..0c921b0 100644 (file)
@@ -43,9 +43,9 @@ gethome (void)
     {
       char *home = getenv("HOME");
       
-#if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H)
       if(home)
         home_buffer = xstrdup (home);
+#if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H)
       else
         {
           struct passwd *pwd;
index d8eba3b..bf05c4c 100644 (file)
@@ -120,6 +120,7 @@ gcry_free (void *a)
    require functions called from these inline fucntions.  Although we
    do not use gpg-error, gpg-error.h may get included via gcrypt.h if
    it happens to be used used in libjnlib-config.h.  */
+#ifndef GPG_ERROR_H /* Don't do this if gpg-error.h has been included.  */
 int
 gpg_err_code_from_errno (int err)
 {
@@ -127,17 +128,20 @@ gpg_err_code_from_errno (int err)
   assert (!"stub function");
   return -1;
 }
+#endif /*GPG_ERROR_H*/
 
 
 /* Retrieve the error code directly from the ERRNO variable.  This
    returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped
    (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */
+#ifndef GPG_ERROR_H /* Don't do this if gpg-error.h has been included.  */
 int
 gpg_err_code_from_syserror (void)
 {
   assert (!"stub function");
   return -1;
 }
+#endif /*GPG_ERROR_H*/
 
 
 
index 5270174..2dfbc09 100644 (file)
 #error The regression tests should not include with gcrypt.h
 #endif
 
-/* Repalcement prototypes. */
+#ifdef HAVE_W32CE_SYSTEM
+#include <gpg-error.h>  /* Defines strerror.  */
+#endif
+
+
+#ifndef HAVE_GETENV
+# define getenv(a)  (NULL)
+#endif
+
+
+/* Replacement prototypes. */
 void *gcry_xmalloc (size_t n);
 void *gcry_xcalloc (size_t n, size_t m);
 void *gcry_xrealloc (void *a, size_t n);
diff --git a/jnlib/t-timestuff.c b/jnlib/t-timestuff.c
new file mode 100644 (file)
index 0000000..4681676
--- /dev/null
@@ -0,0 +1,145 @@
+/* t-timestuff.c - Regression tests for time functions
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of 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.
+ *
+ * JNLIB is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include "mischelp.h"
+
+#include "t-support.h"
+
+
+static int
+cmp_time_s (struct tm *a, struct tm *b)
+{
+  if (a->tm_year != b->tm_year
+      || a->tm_mon  != b->tm_mon
+      || a->tm_mday != b->tm_mday
+      || a->tm_hour != b->tm_hour
+      || a->tm_min  != b->tm_min 
+      || a->tm_sec  != b->tm_sec 
+      || a->tm_wday != b->tm_wday
+      || a->tm_yday != b->tm_yday
+      || !a->tm_isdst != !b->tm_isdst)
+    return -1;
+  return 0;
+}
+
+
+
+static void
+test_timegm (void)
+{
+  static struct {
+    int year, mon, mday, hour, min, sec; 
+  } tvalues[] = {
+    { -1 },
+    { -2,  1 },
+    { -2,  2 },
+    { -2,  86399 },
+    { -2,  86400 },
+    { -2,  0x7ffffffe },
+    { -2,  0x7fffffff },
+    /* Note: Because we use mktime below we can only start with the
+       day after Epoch.  */
+    { 1970, 1, 2, 0, 0 , 1},
+    { 1970, 1, 2, 0, 0 , 2},
+    { 1970, 1, 2, 12, 0 , 0},
+    { 1970, 1, 2, 23, 59 , 59},
+    { 1999, 12, 31, 23, 59 , 59},
+    { 2000, 1, 1, 0, 0, 0},
+    { 2000, 1, 1, 0, 0, 1},
+    { 2010, 12, 31, 23, 59 , 59},
+    { 2010, 1, 1, 0, 0, 0},
+    { 2010, 1, 1, 0, 0, 1},
+    /* The date below is about the last time mktime works in CET on
+       Windows XP; this is a somewhat strange because 32 bit Unices
+       will happily work along for another month until they reach the
+       end of all ticks on 20380119T031408 (unless Uli takes
+       compassion on us and changes time_t to a u64).  */
+    { 2037, 12, 18, 23, 59, 59}
+
+  };
+  int tidx;
+  time_t now, atime, counter;
+  struct tm tbuf, tbuf2, *tp;
+
+  counter = 0;
+  for (tidx=0; tidx < DIM (tvalues); tidx++)
+    {
+      if (tvalues[tidx].year == -1)
+        {
+          now = time (NULL);
+        }
+      else if (tvalues[tidx].year == -2)
+        {
+          now = tvalues[tidx].mon;
+        }
+      else
+        {
+          memset (&tbuf, 0, sizeof tbuf);
+          tbuf.tm_year = tvalues[tidx].year - 1900;
+          tbuf.tm_mon  = tvalues[tidx].mon;
+          tbuf.tm_mday = tvalues[tidx].mday;
+          tbuf.tm_hour = tvalues[tidx].hour;
+          tbuf.tm_min  = tvalues[tidx].min;
+          tbuf.tm_sec  = tvalues[tidx].sec; 
+          now = mktime (&tbuf);
+        }
+      if (now == (time_t)(-1))
+        fail (tidx);
+      
+      tp = gmtime (&now);
+      if (!tp)
+        fail (tidx);
+      tbuf = *tp;
+      tbuf2 = tbuf;
+      atime = timegm (&tbuf);
+      if (atime == (time_t)(-1))
+        fail (tidx);
+      if (atime != now)
+        fail (tidx);
+      
+      tp = gmtime (&atime);
+      if (!tp)
+        fail (tidx);
+      if (cmp_time_s (tp, &tbuf))
+        fail (tidx);
+      if (cmp_time_s (tp, &tbuf2))
+        fail (tidx);
+    }
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+  (void)argc;
+  (void)argv;
+
+  test_timegm ();
+
+  return 0;
+}
+
index fee4dc6..6cbe4e9 100644 (file)
@@ -1,6 +1,6 @@
 /* utf8conf.c -  UTF8 character set conversion
- * Copyright (C) 1994, 1998, 1999, 2000, 2001,
- *               2003, 2006, 2008  Free Software Foundation, Inc.
+ * Copyright (C) 1994, 1998, 1999, 2000, 2001, 2003, 2006,
+ *               2008, 2010  Free Software Foundation, Inc.
  *
  * This file is part of JNLIB.
  *
@@ -50,12 +50,12 @@ static int use_iconv;          /* iconv comversion fucntions required. */
 #ifdef HAVE_W32_SYSTEM
 typedef void *iconv_t;
 #ifndef ICONV_CONST
-#define ICONV_CONST const 
+#define ICONV_CONST
 #endif
 static iconv_t (* __stdcall iconv_open) (const char *tocode,
                                          const char *fromcode);
 static size_t  (* __stdcall iconv) (iconv_t cd,
-                                    const char **inbuf, size_t *inbytesleft,
+                                    char **inbuf, size_t *inbytesleft,
                                     char **outbuf, size_t *outbytesleft);
 static int     (* __stdcall iconv_close) (iconv_t cd);
 
@@ -166,8 +166,10 @@ set_native_charset (const char *newset)
          different one for console input.  Not sure how to cope with
          that.  If the console Code page is not known we fall back to
          the system code page.  */
+#ifndef HAVE_W32CE_SYSTEM
       cpno = GetConsoleOutputCP ();
       if (!cpno)
+#endif
         cpno = GetACP ();
       sprintf (codepage, "CP%u", cpno );
       /* Resolve alias.  We use a long string string and not the usual
@@ -736,3 +738,76 @@ jnlib_iconv_close (jnlib_iconv_t cd)
 
   return iconv_close ((iconv_t)cd);
 }
+
+
+#ifdef HAVE_W32_SYSTEM
+/* Return a malloced string encoded in UTF-8 from the wide char input
+   string STRING.  Caller must free this value.  Returns NULL and sets
+   ERRNO on failure.  Calling this function with STRING set to NULL is
+   not defined.  */
+char *
+wchar_to_utf8 (const wchar_t *string)
+{
+  int n;
+  char *result;
+
+  n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
+  if (n < 0)
+    {
+      jnlib_set_errno (EINVAL);
+      return NULL;
+    }
+
+  result = jnlib_malloc (n+1);
+  if (!result)
+    return NULL;
+
+  n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
+  if (n < 0)
+    {
+      jnlib_free (result);
+      jnlib_set_errno (EINVAL);
+      result = NULL;
+    }
+  return result;
+}
+
+
+/* Return a malloced wide char string from an UTF-8 encoded input
+   string STRING.  Caller must free this value.  Returns NULL and sets
+   ERRNO on failure.  Calling this function with STRING set to NULL is
+   not defined.  */
+wchar_t *
+utf8_to_wchar (const char *string)
+{
+  int n;
+  size_t nbytes;
+  wchar_t *result;
+
+  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
+  if (n < 0)
+    {
+      jnlib_set_errno (EINVAL);
+      return NULL;
+    }
+
+  nbytes = (size_t)(n+1) * sizeof(*result);
+  if (nbytes / sizeof(*result) != (n+1)) 
+    {
+      jnlib_set_errno (ENOMEM);
+      return NULL;
+    }
+  result = malloc (nbytes);
+  if (!result)
+    return NULL;
+
+  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+  if (n < 0)
+    {
+      free (result);
+      jnlib_set_errno (EINVAL);
+      result = NULL;
+    }
+  return result;
+}
+#endif /*HAVE_W32_SYSTEM*/
index e800f81..28dd450 100644 (file)
@@ -36,6 +36,10 @@ size_t jnlib_iconv (jnlib_iconv_t cd, const char **inbuf, size_t *inbytesleft,
                     char **outbuf, size_t *outbytesleft);
 int jnlib_iconv_close (jnlib_iconv_t cd);
 
+#ifdef HAVE_W32_SYSTEM
+char *wchar_to_utf8 (const wchar_t *string);
+wchar_t *utf8_to_wchar (const char *string);
+#endif /*HAVE_W32_SYSTEM*/
 
 
 #endif /*LIBJNLIB_UTF8CONF_H*/
index 6365394..5796214 100644 (file)
@@ -51,14 +51,15 @@ read_port_and_nonce (const char *fname, unsigned short *port, char *nonce)
   fclose (fp);
   if (!nread)
     {
-      errno = ENOFILE;
+#warning remove this file
+      jnlib_set_errno (EIO);
       return -1;
     }
   buffer[nread] = 0;
   aval = atoi (buffer);
   if (aval < 1 || aval > 65535)
     {
-      errno = EINVAL;
+      jnlib_set_errno (EINVAL);
       return -1;
     }
   *port = (unsigned int)aval;
@@ -66,7 +67,7 @@ read_port_and_nonce (const char *fname, unsigned short *port, char *nonce)
     ;
   if (*p != '\n' || nread != 17)
     {
-      errno = EINVAL;
+      jnlib_set_errno (EINVAL);
       return -1;
     }
   p++; nread--;
@@ -126,7 +127,7 @@ _w32_sock_connect (int sockfd, struct sockaddr *addr, int addrlen)
       ret = send (sockfd, nonce, 16, 0);
       if (ret >= 0 && ret != 16)
         {
-          errno = EIO;
+          jnlib_set_errno (EIO);
           ret = -1;
         }
     }
diff --git a/jnlib/w32-gettext.c b/jnlib/w32-gettext.c
deleted file mode 100644 (file)
index 3060a96..0000000
+++ /dev/null
@@ -1,1710 +0,0 @@
-/* w32-gettext.h - A simple gettext implementation for Windows targets.
-   Copyright (C) 1995, 1996, 1997, 1999, 2005, 2007,
-                 2008, 2010 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License
-   as published by the Free Software Foundation; either version 2.1 of
-   the License, or (at your option) any later version.
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-   You should have received a copy of the GNU Lesser General Public
-   License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#if !defined (_WIN32) && !defined (__CYGWIN32__)
-#  error This module may only be build for Windows or Cygwin32
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <locale.h>
-#include <windows.h>
-
-#ifdef JNLIB_IN_JNLIB
-#include "libjnlib-config.h"
-#endif
-
-#ifndef jnlib_malloc
-# define jnlib_malloc(a)    malloc ((a))
-# define jnlib_calloc(a,b)  calloc ((a), (b))
-# define jnlib_free(a)      free ((a))
-# define jnlib_xstrdup(a)   my_xstrdup(a)
-#endif /*!jnlib_malloc*/
-
-
-\f
-/* localname.c from gettext BEGIN.  */
-
-/* Determine the current selected locale.
-   Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU Library General Public License as published
-   by the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-   USA.  */
-
-/* Written by Ulrich Drepper <drepper@gnu.org>, 1995.  */
-/* Win32 code written by Tor Lillqvist <tml@iki.fi>.  */
-/* Renamed _nl_locale_name, removed unsed args, removed include files,
-   non-W32 code and changed comments <wk@gnupg.org>.  */
-
-/* Mingw headers don't have latest language and sublanguage codes.  */
-#ifndef LANG_AFRIKAANS
-#define LANG_AFRIKAANS 0x36
-#endif
-#ifndef LANG_ALBANIAN
-#define LANG_ALBANIAN 0x1c
-#endif
-#ifndef LANG_AMHARIC
-#define LANG_AMHARIC 0x5e
-#endif
-#ifndef LANG_ARABIC
-#define LANG_ARABIC 0x01
-#endif
-#ifndef LANG_ARMENIAN
-#define LANG_ARMENIAN 0x2b
-#endif
-#ifndef LANG_ASSAMESE
-#define LANG_ASSAMESE 0x4d
-#endif
-#ifndef LANG_AZERI
-#define LANG_AZERI 0x2c
-#endif
-#ifndef LANG_BASQUE
-#define LANG_BASQUE 0x2d
-#endif
-#ifndef LANG_BELARUSIAN
-#define LANG_BELARUSIAN 0x23
-#endif
-#ifndef LANG_BENGALI
-#define LANG_BENGALI 0x45
-#endif
-#ifndef LANG_BURMESE
-#define LANG_BURMESE 0x55
-#endif
-#ifndef LANG_CAMBODIAN
-#define LANG_CAMBODIAN 0x53
-#endif
-#ifndef LANG_CATALAN
-#define LANG_CATALAN 0x03
-#endif
-#ifndef LANG_CHEROKEE
-#define LANG_CHEROKEE 0x5c
-#endif
-#ifndef LANG_DIVEHI
-#define LANG_DIVEHI 0x65
-#endif
-#ifndef LANG_EDO
-#define LANG_EDO 0x66
-#endif
-#ifndef LANG_ESTONIAN
-#define LANG_ESTONIAN 0x25
-#endif
-#ifndef LANG_FAEROESE
-#define LANG_FAEROESE 0x38
-#endif
-#ifndef LANG_FARSI
-#define LANG_FARSI 0x29
-#endif
-#ifndef LANG_FRISIAN
-#define LANG_FRISIAN 0x62
-#endif
-#ifndef LANG_FULFULDE
-#define LANG_FULFULDE 0x67
-#endif
-#ifndef LANG_GAELIC
-#define LANG_GAELIC 0x3c
-#endif
-#ifndef LANG_GALICIAN
-#define LANG_GALICIAN 0x56
-#endif
-#ifndef LANG_GEORGIAN
-#define LANG_GEORGIAN 0x37
-#endif
-#ifndef LANG_GUARANI
-#define LANG_GUARANI 0x74
-#endif
-#ifndef LANG_GUJARATI
-#define LANG_GUJARATI 0x47
-#endif
-#ifndef LANG_HAUSA
-#define LANG_HAUSA 0x68
-#endif
-#ifndef LANG_HAWAIIAN
-#define LANG_HAWAIIAN 0x75
-#endif
-#ifndef LANG_HEBREW
-#define LANG_HEBREW 0x0d
-#endif
-#ifndef LANG_HINDI
-#define LANG_HINDI 0x39
-#endif
-#ifndef LANG_IBIBIO
-#define LANG_IBIBIO 0x69
-#endif
-#ifndef LANG_IGBO
-#define LANG_IGBO 0x70
-#endif
-#ifndef LANG_INDONESIAN
-#define LANG_INDONESIAN 0x21
-#endif
-#ifndef LANG_INUKTITUT
-#define LANG_INUKTITUT 0x5d
-#endif
-#ifndef LANG_KANNADA
-#define LANG_KANNADA 0x4b
-#endif
-#ifndef LANG_KANURI
-#define LANG_KANURI 0x71
-#endif
-#ifndef LANG_KASHMIRI
-#define LANG_KASHMIRI 0x60
-#endif
-#ifndef LANG_KAZAK
-#define LANG_KAZAK 0x3f
-#endif
-#ifndef LANG_KONKANI
-#define LANG_KONKANI 0x57
-#endif
-#ifndef LANG_KYRGYZ
-#define LANG_KYRGYZ 0x40
-#endif
-#ifndef LANG_LAO
-#define LANG_LAO 0x54
-#endif
-#ifndef LANG_LATIN
-#define LANG_LATIN 0x76
-#endif
-#ifndef LANG_LATVIAN
-#define LANG_LATVIAN 0x26
-#endif
-#ifndef LANG_LITHUANIAN
-#define LANG_LITHUANIAN 0x27
-#endif
-#ifndef LANG_MACEDONIAN
-#define LANG_MACEDONIAN 0x2f
-#endif
-#ifndef LANG_MALAY
-#define LANG_MALAY 0x3e
-#endif
-#ifndef LANG_MALAYALAM
-#define LANG_MALAYALAM 0x4c
-#endif
-#ifndef LANG_MALTESE
-#define LANG_MALTESE 0x3a
-#endif
-#ifndef LANG_MANIPURI
-#define LANG_MANIPURI 0x58
-#endif
-#ifndef LANG_MARATHI
-#define LANG_MARATHI 0x4e
-#endif
-#ifndef LANG_MONGOLIAN
-#define LANG_MONGOLIAN 0x50
-#endif
-#ifndef LANG_NEPALI
-#define LANG_NEPALI 0x61
-#endif
-#ifndef LANG_ORIYA
-#define LANG_ORIYA 0x48
-#endif
-#ifndef LANG_OROMO
-#define LANG_OROMO 0x72
-#endif
-#ifndef LANG_PAPIAMENTU
-#define LANG_PAPIAMENTU 0x79
-#endif
-#ifndef LANG_PASHTO
-#define LANG_PASHTO 0x63
-#endif
-#ifndef LANG_PUNJABI
-#define LANG_PUNJABI 0x46
-#endif
-#ifndef LANG_RHAETO_ROMANCE
-#define LANG_RHAETO_ROMANCE 0x17
-#endif
-#ifndef LANG_SAAMI
-#define LANG_SAAMI 0x3b
-#endif
-#ifndef LANG_SANSKRIT
-#define LANG_SANSKRIT 0x4f
-#endif
-#ifndef LANG_SERBIAN
-#define LANG_SERBIAN 0x1a
-#endif
-#ifndef LANG_SINDHI
-#define LANG_SINDHI 0x59
-#endif
-#ifndef LANG_SINHALESE
-#define LANG_SINHALESE 0x5b
-#endif
-#ifndef LANG_SLOVAK
-#define LANG_SLOVAK 0x1b
-#endif
-#ifndef LANG_SOMALI
-#define LANG_SOMALI 0x77
-#endif
-#ifndef LANG_SORBIAN
-#define LANG_SORBIAN 0x2e
-#endif
-#ifndef LANG_SUTU
-#define LANG_SUTU 0x30
-#endif
-#ifndef LANG_SWAHILI
-#define LANG_SWAHILI 0x41
-#endif
-#ifndef LANG_SYRIAC
-#define LANG_SYRIAC 0x5a
-#endif
-#ifndef LANG_TAGALOG
-#define LANG_TAGALOG 0x64
-#endif
-#ifndef LANG_TAJIK
-#define LANG_TAJIK 0x28
-#endif
-#ifndef LANG_TAMAZIGHT
-#define LANG_TAMAZIGHT 0x5f
-#endif
-#ifndef LANG_TAMIL
-#define LANG_TAMIL 0x49
-#endif
-#ifndef LANG_TATAR
-#define LANG_TATAR 0x44
-#endif
-#ifndef LANG_TELUGU
-#define LANG_TELUGU 0x4a
-#endif
-#ifndef LANG_THAI
-#define LANG_THAI 0x1e
-#endif
-#ifndef LANG_TIBETAN
-#define LANG_TIBETAN 0x51
-#endif
-#ifndef LANG_TIGRINYA
-#define LANG_TIGRINYA 0x73
-#endif
-#ifndef LANG_TSONGA
-#define LANG_TSONGA 0x31
-#endif
-#ifndef LANG_TSWANA
-#define LANG_TSWANA 0x32
-#endif
-#ifndef LANG_TURKMEN
-#define LANG_TURKMEN 0x42
-#endif
-#ifndef LANG_UKRAINIAN
-#define LANG_UKRAINIAN 0x22
-#endif
-#ifndef LANG_URDU
-#define LANG_URDU 0x20
-#endif
-#ifndef LANG_UZBEK
-#define LANG_UZBEK 0x43
-#endif
-#ifndef LANG_VENDA
-#define LANG_VENDA 0x33
-#endif
-#ifndef LANG_VIETNAMESE
-#define LANG_VIETNAMESE 0x2a
-#endif
-#ifndef LANG_WELSH
-#define LANG_WELSH 0x52
-#endif
-#ifndef LANG_XHOSA
-#define LANG_XHOSA 0x34
-#endif
-#ifndef LANG_YI
-#define LANG_YI 0x78
-#endif
-#ifndef LANG_YIDDISH
-#define LANG_YIDDISH 0x3d
-#endif
-#ifndef LANG_YORUBA
-#define LANG_YORUBA 0x6a
-#endif
-#ifndef LANG_ZULU
-#define LANG_ZULU 0x35
-#endif
-#ifndef SUBLANG_ARABIC_SAUDI_ARABIA
-#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
-#endif
-#ifndef SUBLANG_ARABIC_IRAQ
-#define SUBLANG_ARABIC_IRAQ 0x02
-#endif
-#ifndef SUBLANG_ARABIC_EGYPT
-#define SUBLANG_ARABIC_EGYPT 0x03
-#endif
-#ifndef SUBLANG_ARABIC_LIBYA
-#define SUBLANG_ARABIC_LIBYA 0x04
-#endif
-#ifndef SUBLANG_ARABIC_ALGERIA
-#define SUBLANG_ARABIC_ALGERIA 0x05
-#endif
-#ifndef SUBLANG_ARABIC_MOROCCO
-#define SUBLANG_ARABIC_MOROCCO 0x06
-#endif
-#ifndef SUBLANG_ARABIC_TUNISIA
-#define SUBLANG_ARABIC_TUNISIA 0x07
-#endif
-#ifndef SUBLANG_ARABIC_OMAN
-#define SUBLANG_ARABIC_OMAN 0x08
-#endif
-#ifndef SUBLANG_ARABIC_YEMEN
-#define SUBLANG_ARABIC_YEMEN 0x09
-#endif
-#ifndef SUBLANG_ARABIC_SYRIA
-#define SUBLANG_ARABIC_SYRIA 0x0a
-#endif
-#ifndef SUBLANG_ARABIC_JORDAN
-#define SUBLANG_ARABIC_JORDAN 0x0b
-#endif
-#ifndef SUBLANG_ARABIC_LEBANON
-#define SUBLANG_ARABIC_LEBANON 0x0c
-#endif
-#ifndef SUBLANG_ARABIC_KUWAIT
-#define SUBLANG_ARABIC_KUWAIT 0x0d
-#endif
-#ifndef SUBLANG_ARABIC_UAE
-#define SUBLANG_ARABIC_UAE 0x0e
-#endif
-#ifndef SUBLANG_ARABIC_BAHRAIN
-#define SUBLANG_ARABIC_BAHRAIN 0x0f
-#endif
-#ifndef SUBLANG_ARABIC_QATAR
-#define SUBLANG_ARABIC_QATAR 0x10
-#endif
-#ifndef SUBLANG_AZERI_LATIN
-#define SUBLANG_AZERI_LATIN 0x01
-#endif
-#ifndef SUBLANG_AZERI_CYRILLIC
-#define SUBLANG_AZERI_CYRILLIC 0x02
-#endif
-#ifndef SUBLANG_BENGALI_INDIA
-#define SUBLANG_BENGALI_INDIA 0x01
-#endif
-#ifndef SUBLANG_BENGALI_BANGLADESH
-#define SUBLANG_BENGALI_BANGLADESH 0x02
-#endif
-#ifndef SUBLANG_CHINESE_MACAU
-#define SUBLANG_CHINESE_MACAU 0x05
-#endif
-#ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
-#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
-#endif
-#ifndef SUBLANG_ENGLISH_JAMAICA
-#define SUBLANG_ENGLISH_JAMAICA 0x08
-#endif
-#ifndef SUBLANG_ENGLISH_CARIBBEAN
-#define SUBLANG_ENGLISH_CARIBBEAN 0x09
-#endif
-#ifndef SUBLANG_ENGLISH_BELIZE
-#define SUBLANG_ENGLISH_BELIZE 0x0a
-#endif
-#ifndef SUBLANG_ENGLISH_TRINIDAD
-#define SUBLANG_ENGLISH_TRINIDAD 0x0b
-#endif
-#ifndef SUBLANG_ENGLISH_ZIMBABWE
-#define SUBLANG_ENGLISH_ZIMBABWE 0x0c
-#endif
-#ifndef SUBLANG_ENGLISH_PHILIPPINES
-#define SUBLANG_ENGLISH_PHILIPPINES 0x0d
-#endif
-#ifndef SUBLANG_ENGLISH_INDONESIA
-#define SUBLANG_ENGLISH_INDONESIA 0x0e
-#endif
-#ifndef SUBLANG_ENGLISH_HONGKONG
-#define SUBLANG_ENGLISH_HONGKONG 0x0f
-#endif
-#ifndef SUBLANG_ENGLISH_INDIA
-#define SUBLANG_ENGLISH_INDIA 0x10
-#endif
-#ifndef SUBLANG_ENGLISH_MALAYSIA
-#define SUBLANG_ENGLISH_MALAYSIA 0x11
-#endif
-#ifndef SUBLANG_ENGLISH_SINGAPORE
-#define SUBLANG_ENGLISH_SINGAPORE 0x12
-#endif
-#ifndef SUBLANG_FRENCH_LUXEMBOURG
-#define SUBLANG_FRENCH_LUXEMBOURG 0x05
-#endif
-#ifndef SUBLANG_FRENCH_MONACO
-#define SUBLANG_FRENCH_MONACO 0x06
-#endif
-#ifndef SUBLANG_FRENCH_WESTINDIES
-#define SUBLANG_FRENCH_WESTINDIES 0x07
-#endif
-#ifndef SUBLANG_FRENCH_REUNION
-#define SUBLANG_FRENCH_REUNION 0x08
-#endif
-#ifndef SUBLANG_FRENCH_CONGO
-#define SUBLANG_FRENCH_CONGO 0x09
-#endif
-#ifndef SUBLANG_FRENCH_SENEGAL
-#define SUBLANG_FRENCH_SENEGAL 0x0a
-#endif
-#ifndef SUBLANG_FRENCH_CAMEROON
-#define SUBLANG_FRENCH_CAMEROON 0x0b
-#endif
-#ifndef SUBLANG_FRENCH_COTEDIVOIRE
-#define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
-#endif
-#ifndef SUBLANG_FRENCH_MALI
-#define SUBLANG_FRENCH_MALI 0x0d
-#endif
-#ifndef SUBLANG_FRENCH_MOROCCO
-#define SUBLANG_FRENCH_MOROCCO 0x0e
-#endif
-#ifndef SUBLANG_FRENCH_HAITI
-#define SUBLANG_FRENCH_HAITI 0x0f
-#endif
-#ifndef SUBLANG_GERMAN_LUXEMBOURG
-#define SUBLANG_GERMAN_LUXEMBOURG 0x04
-#endif
-#ifndef SUBLANG_GERMAN_LIECHTENSTEIN
-#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
-#endif
-#ifndef SUBLANG_KASHMIRI_INDIA
-#define SUBLANG_KASHMIRI_INDIA 0x02
-#endif
-#ifndef SUBLANG_MALAY_MALAYSIA
-#define SUBLANG_MALAY_MALAYSIA 0x01
-#endif
-#ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
-#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
-#endif
-#ifndef SUBLANG_NEPALI_INDIA
-#define SUBLANG_NEPALI_INDIA 0x02
-#endif
-#ifndef SUBLANG_PUNJABI_INDIA
-#define SUBLANG_PUNJABI_INDIA 0x01
-#endif
-#ifndef SUBLANG_ROMANIAN_ROMANIA
-#define SUBLANG_ROMANIAN_ROMANIA 0x01
-#endif
-#ifndef SUBLANG_SERBIAN_LATIN
-#define SUBLANG_SERBIAN_LATIN 0x02
-#endif
-#ifndef SUBLANG_SERBIAN_CYRILLIC
-#define SUBLANG_SERBIAN_CYRILLIC 0x03
-#endif
-#ifndef SUBLANG_SINDHI_INDIA
-#define SUBLANG_SINDHI_INDIA 0x00
-#endif
-#ifndef SUBLANG_SINDHI_PAKISTAN
-#define SUBLANG_SINDHI_PAKISTAN 0x01
-#endif
-#ifndef SUBLANG_SPANISH_GUATEMALA
-#define SUBLANG_SPANISH_GUATEMALA 0x04
-#endif
-#ifndef SUBLANG_SPANISH_COSTA_RICA
-#define SUBLANG_SPANISH_COSTA_RICA 0x05
-#endif
-#ifndef SUBLANG_SPANISH_PANAMA
-#define SUBLANG_SPANISH_PANAMA 0x06
-#endif
-#ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
-#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
-#endif
-#ifndef SUBLANG_SPANISH_VENEZUELA
-#define SUBLANG_SPANISH_VENEZUELA 0x08
-#endif
-#ifndef SUBLANG_SPANISH_COLOMBIA
-#define SUBLANG_SPANISH_COLOMBIA 0x09
-#endif
-#ifndef SUBLANG_SPANISH_PERU
-#define SUBLANG_SPANISH_PERU 0x0a
-#endif
-#ifndef SUBLANG_SPANISH_ARGENTINA
-#define SUBLANG_SPANISH_ARGENTINA 0x0b
-#endif
-#ifndef SUBLANG_SPANISH_ECUADOR
-#define SUBLANG_SPANISH_ECUADOR 0x0c
-#endif
-#ifndef SUBLANG_SPANISH_CHILE
-#define SUBLANG_SPANISH_CHILE 0x0d
-#endif
-#ifndef SUBLANG_SPANISH_URUGUAY
-#define SUBLANG_SPANISH_URUGUAY 0x0e
-#endif
-#ifndef SUBLANG_SPANISH_PARAGUAY
-#define SUBLANG_SPANISH_PARAGUAY 0x0f
-#endif
-#ifndef SUBLANG_SPANISH_BOLIVIA
-#define SUBLANG_SPANISH_BOLIVIA 0x10
-#endif
-#ifndef SUBLANG_SPANISH_EL_SALVADOR
-#define SUBLANG_SPANISH_EL_SALVADOR 0x11
-#endif
-#ifndef SUBLANG_SPANISH_HONDURAS
-#define SUBLANG_SPANISH_HONDURAS 0x12
-#endif
-#ifndef SUBLANG_SPANISH_NICARAGUA
-#define SUBLANG_SPANISH_NICARAGUA 0x13
-#endif
-#ifndef SUBLANG_SPANISH_PUERTO_RICO
-#define SUBLANG_SPANISH_PUERTO_RICO 0x14
-#endif
-#ifndef SUBLANG_SWEDISH_FINLAND
-#define SUBLANG_SWEDISH_FINLAND 0x02
-#endif
-#ifndef SUBLANG_TAMAZIGHT_ARABIC
-#define SUBLANG_TAMAZIGHT_ARABIC 0x01
-#endif
-#ifndef SUBLANG_TAMAZIGHT_LATIN
-#define SUBLANG_TAMAZIGHT_LATIN 0x02
-#endif
-#ifndef SUBLANG_TIGRINYA_ETHIOPIA
-#define SUBLANG_TIGRINYA_ETHIOPIA 0x00
-#endif
-#ifndef SUBLANG_TIGRINYA_ERITREA
-#define SUBLANG_TIGRINYA_ERITREA 0x01
-#endif
-#ifndef SUBLANG_URDU_PAKISTAN
-#define SUBLANG_URDU_PAKISTAN 0x01
-#endif
-#ifndef SUBLANG_URDU_INDIA
-#define SUBLANG_URDU_INDIA 0x02
-#endif
-#ifndef SUBLANG_UZBEK_LATIN
-#define SUBLANG_UZBEK_LATIN 0x01
-#endif
-#ifndef SUBLANG_UZBEK_CYRILLIC
-#define SUBLANG_UZBEK_CYRILLIC 0x02
-#endif
-/* Return an XPG style locale name 
-     language[_territory[.codeset]][@modifier].
-   Don't even bother determining the codeset; it's not useful in this
-   context, because message catalogs are not specific to a single
-   codeset.  The result must not be freed; it is statically
-   allocated.  */
-static const char *
-my_nl_locale_name (const char *categoryname)
-{
-  const char *retval;
-  LCID lcid;
-  LANGID langid;
-  int primary, sub;
-
-  /* Let the user override the system settings through environment
-     variables, as on POSIX systems.  */
-#ifndef HAVE_W32CE_SYSTEM
-  retval = getenv ("LC_ALL");
-  if (retval != NULL && retval[0] != '\0')
-    return retval;
-  retval = getenv (categoryname);
-  if (retval != NULL && retval[0] != '\0')
-    return retval;
-  retval = getenv ("LANG");
-  if (retval != NULL && retval[0] != '\0')
-    return retval;
-#endif /*!HAVE_W32CE_SYSTEM*/
-
-  /* Use native Win32 API locale ID.  */
-#ifdef HAVE_W32CE_SYSTEM
-  lcid = GetSystemDefaultLCID ();
-#else
-  lcid = GetThreadLocale ();
-#endif
-
-  /* Strip off the sorting rules, keep only the language part.  */
-  langid = LANGIDFROMLCID (lcid);
-
-  /* Split into language and territory part.  */
-  primary = PRIMARYLANGID (langid);
-  sub = SUBLANGID (langid);
-
-  /* Dispatch on language.
-     See also http://www.unicode.org/unicode/onlinedat/languages.html .
-     For details about languages, see http://www.ethnologue.com/ .  */
-  switch (primary)
-    {
-    case LANG_AFRIKAANS: return "af_ZA";
-    case LANG_ALBANIAN: return "sq_AL";
-    case LANG_AMHARIC: return "am_ET";
-    case LANG_ARABIC:
-      switch (sub)
-       {
-       case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
-       case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
-       case SUBLANG_ARABIC_EGYPT: return "ar_EG";
-       case SUBLANG_ARABIC_LIBYA: return "ar_LY";
-       case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
-       case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
-       case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
-       case SUBLANG_ARABIC_OMAN: return "ar_OM";
-       case SUBLANG_ARABIC_YEMEN: return "ar_YE";
-       case SUBLANG_ARABIC_SYRIA: return "ar_SY";
-       case SUBLANG_ARABIC_JORDAN: return "ar_JO";
-       case SUBLANG_ARABIC_LEBANON: return "ar_LB";
-       case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
-       case SUBLANG_ARABIC_UAE: return "ar_AE";
-       case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
-       case SUBLANG_ARABIC_QATAR: return "ar_QA";
-       }
-      return "ar";
-    case LANG_ARMENIAN: return "hy_AM";
-    case LANG_ASSAMESE: return "as_IN";
-    case LANG_AZERI:
-      switch (sub)
-       {
-       /* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
-       case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
-       case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
-       }
-      return "az";
-    case LANG_BASQUE:
-      return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
-    case LANG_BELARUSIAN: return "be_BY";
-    case LANG_BENGALI:
-      switch (sub)
-       {
-       case SUBLANG_BENGALI_INDIA: return "bn_IN";
-       case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
-       }
-      return "bn";
-    case LANG_BULGARIAN: return "bg_BG";
-    case LANG_BURMESE: return "my_MM";
-    case LANG_CAMBODIAN: return "km_KH";
-    case LANG_CATALAN: return "ca_ES";
-    case LANG_CHEROKEE: return "chr_US";
-    case LANG_CHINESE:
-      switch (sub)
-       {
-       case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
-       case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
-       case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
-       case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
-       case SUBLANG_CHINESE_MACAU: return "zh_MO";
-       }
-      return "zh";
-    case LANG_CROATIAN:                /* LANG_CROATIAN == LANG_SERBIAN
-                                * What used to be called Serbo-Croatian
-                                * should really now be two separate
-                                * languages because of political reasons.
-                                * (Says tml, who knows nothing about Serbian
-                                * or Croatian.)
-                                * (I can feel those flames coming already.)
-                                */
-      switch (sub)
-       {
-       case SUBLANG_DEFAULT: return "hr_HR";
-       case SUBLANG_SERBIAN_LATIN: return "sr_CS";
-       case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
-       }
-      return "hr";
-    case LANG_CZECH: return "cs_CZ";
-    case LANG_DANISH: return "da_DK";
-    case LANG_DIVEHI: return "div_MV";
-    case LANG_DUTCH:
-      switch (sub)
-       {
-       case SUBLANG_DUTCH: return "nl_NL";
-       case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
-       }
-      return "nl";
-    case LANG_EDO: return "bin_NG";
-    case LANG_ENGLISH:
-      switch (sub)
-       {
-       /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
-        * English was the language spoken in England.
-        * Oh well.
-        */
-       case SUBLANG_ENGLISH_US: return "en_US";
-       case SUBLANG_ENGLISH_UK: return "en_GB";
-       case SUBLANG_ENGLISH_AUS: return "en_AU";
-       case SUBLANG_ENGLISH_CAN: return "en_CA";
-       case SUBLANG_ENGLISH_NZ: return "en_NZ";
-       case SUBLANG_ENGLISH_EIRE: return "en_IE";
-       case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
-       case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
-       case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
-       case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
-       case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
-       case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
-       case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
-       case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
-       case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
-       case SUBLANG_ENGLISH_INDIA: return "en_IN";
-       case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
-       case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
-       }
-      return "en";
-    case LANG_ESTONIAN: return "et_EE";
-    case LANG_FAEROESE: return "fo_FO";
-    case LANG_FARSI: return "fa_IR";
-    case LANG_FINNISH: return "fi_FI";
-    case LANG_FRENCH:
-      switch (sub)
-       {
-       case SUBLANG_FRENCH: return "fr_FR";
-       case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
-       case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
-       case SUBLANG_FRENCH_SWISS: return "fr_CH";
-       case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
-       case SUBLANG_FRENCH_MONACO: return "fr_MC";
-       case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
-       case SUBLANG_FRENCH_REUNION: return "fr_RE";
-       case SUBLANG_FRENCH_CONGO: return "fr_CG";
-       case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
-       case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
-       case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
-       case SUBLANG_FRENCH_MALI: return "fr_ML";
-       case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
-       case SUBLANG_FRENCH_HAITI: return "fr_HT";
-       }
-      return "fr";
-    case LANG_FRISIAN: return "fy_NL";
-    case LANG_FULFULDE: return "ful_NG";
-    case LANG_GAELIC:
-      switch (sub)
-       {
-       case 0x01: /* SCOTTISH */ return "gd_GB";
-       case 0x02: /* IRISH */ return "ga_IE";
-       }
-      return "C";
-    case LANG_GALICIAN: return "gl_ES";
-    case LANG_GEORGIAN: return "ka_GE";
-    case LANG_GERMAN:
-      switch (sub)
-       {
-       case SUBLANG_GERMAN: return "de_DE";
-       case SUBLANG_GERMAN_SWISS: return "de_CH";
-       case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
-       case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
-       case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
-       }
-      return "de";
-    case LANG_GREEK: return "el_GR";
-    case LANG_GUARANI: return "gn_PY";
-    case LANG_GUJARATI: return "gu_IN";
-    case LANG_HAUSA: return "ha_NG";
-    case LANG_HAWAIIAN:
-      /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
-        or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
-      return "cpe_US";
-    case LANG_HEBREW: return "he_IL";
-    case LANG_HINDI: return "hi_IN";
-    case LANG_HUNGARIAN: return "hu_HU";
-    case LANG_IBIBIO: return "nic_NG";
-    case LANG_ICELANDIC: return "is_IS";
-    case LANG_IGBO: return "ibo_NG";
-    case LANG_INDONESIAN: return "id_ID";
-    case LANG_INUKTITUT: return "iu_CA";
-    case LANG_ITALIAN:
-      switch (sub)
-       {
-       case SUBLANG_ITALIAN: return "it_IT";
-       case SUBLANG_ITALIAN_SWISS: return "it_CH";
-       }
-      return "it";
-    case LANG_JAPANESE: return "ja_JP";
-    case LANG_KANNADA: return "kn_IN";
-    case LANG_KANURI: return "kau_NG";
-    case LANG_KASHMIRI:
-      switch (sub)
-       {
-       case SUBLANG_DEFAULT: return "ks_PK";
-       case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
-       }
-      return "ks";
-    case LANG_KAZAK: return "kk_KZ";
-    case LANG_KONKANI:
-      /* FIXME: Adjust this when such locales appear on Unix.  */
-      return "kok_IN";
-    case LANG_KOREAN: return "ko_KR";
-    case LANG_KYRGYZ: return "ky_KG";
-    case LANG_LAO: return "lo_LA";
-    case LANG_LATIN: return "la_VA";
-    case LANG_LATVIAN: return "lv_LV";
-    case LANG_LITHUANIAN: return "lt_LT";
-    case LANG_MACEDONIAN: return "mk_MK";
-    case LANG_MALAY:
-      switch (sub)
-       {
-       case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
-       case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
-       }
-      return "ms";
-    case LANG_MALAYALAM: return "ml_IN";
-    case LANG_MALTESE: return "mt_MT";
-    case LANG_MANIPURI:
-      /* FIXME: Adjust this when such locales appear on Unix.  */
-      return "mni_IN";
-    case LANG_MARATHI: return "mr_IN";
-    case LANG_MONGOLIAN:
-      return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
-    case LANG_NEPALI:
-      switch (sub)
-       {
-       case SUBLANG_DEFAULT: return "ne_NP";
-       case SUBLANG_NEPALI_INDIA: return "ne_IN";
-       }
-      return "ne";
-    case LANG_NORWEGIAN:
-      switch (sub)
-       {
-       case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO";
-       case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
-       }
-      return "no";
-    case LANG_ORIYA: return "or_IN";
-    case LANG_OROMO: return "om_ET";
-    case LANG_PAPIAMENTU: return "pap_AN";
-    case LANG_PASHTO:
-      return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
-    case LANG_POLISH: return "pl_PL";
-    case LANG_PORTUGUESE:
-      switch (sub)
-       {
-       case SUBLANG_PORTUGUESE: return "pt_PT";
-       /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
-          Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
-       case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
-       }
-      return "pt";
-    case LANG_PUNJABI:
-      switch (sub)
-       {
-       case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
-       }
-      return "pa";
-    case LANG_RHAETO_ROMANCE: return "rm_CH";
-    case LANG_ROMANIAN:
-      switch (sub)
-       {
-       case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
-       }
-      return "ro";
-    case LANG_RUSSIAN:
-      return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD".  */
-    case LANG_SAAMI: /* actually Northern Sami */ return "se_NO";
-    case LANG_SANSKRIT: return "sa_IN";
-    case LANG_SINDHI:
-      switch (sub)
-       {
-       case SUBLANG_SINDHI_INDIA: return "sd_IN";
-       case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
-       }
-      return "sd";
-    case LANG_SINHALESE: return "si_LK";
-    case LANG_SLOVAK: return "sk_SK";
-    case LANG_SLOVENIAN: return "sl_SI";
-    case LANG_SOMALI: return "so_SO";
-    case LANG_SORBIAN:
-      /* FIXME: Adjust this when such locales appear on Unix.  */
-      return "wen_DE";
-    case LANG_SPANISH:
-      switch (sub)
-       {
-       case SUBLANG_SPANISH: return "es_ES";
-       case SUBLANG_SPANISH_MEXICAN: return "es_MX";
-       case SUBLANG_SPANISH_MODERN:
-         return "es_ES@modern";        /* not seen on Unix */
-       case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
-       case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
-       case SUBLANG_SPANISH_PANAMA: return "es_PA";
-       case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
-       case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
-       case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
-       case SUBLANG_SPANISH_PERU: return "es_PE";
-       case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
-       case SUBLANG_SPANISH_ECUADOR: return "es_EC";
-       case SUBLANG_SPANISH_CHILE: return "es_CL";
-       case SUBLANG_SPANISH_URUGUAY: return "es_UY";
-       case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
-       case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
-       case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
-       case SUBLANG_SPANISH_HONDURAS: return "es_HN";
-       case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
-       case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
-       }
-      return "es";
-    case LANG_SUTU: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
-    case LANG_SWAHILI: return "sw_KE";
-    case LANG_SWEDISH:
-      switch (sub)
-       {
-       case SUBLANG_DEFAULT: return "sv_SE";
-       case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
-       }
-      return "sv";
-    case LANG_SYRIAC: return "syr_TR"; /* An extinct language.  */
-    case LANG_TAGALOG: return "tl_PH";
-    case LANG_TAJIK: return "tg_TJ";
-    case LANG_TAMAZIGHT:
-      switch (sub)
-       {
-       /* FIXME: Adjust this when Tamazight locales appear on Unix.  */
-       case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
-       case SUBLANG_TAMAZIGHT_LATIN: return "ber_MA@latin";
-       }
-      return "ber_MA";
-    case LANG_TAMIL:
-      return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
-    case LANG_TATAR: return "tt_RU";
-    case LANG_TELUGU: return "te_IN";
-    case LANG_THAI: return "th_TH";
-    case LANG_TIBETAN: return "bo_CN";
-    case LANG_TIGRINYA:
-      switch (sub)
-       {
-       case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
-       case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
-       }
-      return "ti";
-    case LANG_TSONGA: return "ts_ZA";
-    case LANG_TSWANA: return "tn_BW";
-    case LANG_TURKISH: return "tr_TR";
-    case LANG_TURKMEN: return "tk_TM";
-    case LANG_UKRAINIAN: return "uk_UA";
-    case LANG_URDU:
-      switch (sub)
-       {
-       case SUBLANG_URDU_PAKISTAN: return "ur_PK";
-       case SUBLANG_URDU_INDIA: return "ur_IN";
-       }
-      return "ur";
-    case LANG_UZBEK:
-      switch (sub)
-       {
-       case SUBLANG_UZBEK_LATIN: return "uz_UZ";
-       case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
-       }
-      return "uz";
-    case LANG_VENDA:
-      /* FIXME: It's not clear whether Venda has the ISO 639-2 two-letter code
-        "ve" or not.
-        http://www.loc.gov/standards/iso639-2/englangn.html has it, but
-        http://lcweb.loc.gov/standards/iso639-2/codechanges.html doesn't,  */
-      return "ven_ZA"; /* or "ve_ZA"? */
-    case LANG_VIETNAMESE: return "vi_VN";
-    case LANG_WELSH: return "cy_GB";
-    case LANG_XHOSA: return "xh_ZA";
-    case LANG_YI: return "sit_CN";
-    case LANG_YIDDISH: return "yi_IL";
-    case LANG_YORUBA: return "yo_NG";
-    case LANG_ZULU: return "zu_ZA";
-    default: return "C";
-    }
-}
-
-/* localname.c from gettext END.  */
-
-
-\f
-/* Support functions.  */
-
-static __inline__ uint32_t
-do_swap_u32 (uint32_t i)
-{
-  return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
-}
-
-#define SWAPIT(flag, data) ((flag) ? do_swap_u32(data) : (data))
-
-
-/* We assume to have `unsigned long int' value with at least 32 bits.  */
-#define HASHWORDBITS 32
-
-/* The so called `hashpjw' function by P.J. Weinberger
-   [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
-   1986, 1987 Bell Telephone Laboratories, Inc.]  */
-static __inline__ unsigned long
-hash_string( const char *str_param )
-{
-  unsigned long int hval, g;
-  const char *str = str_param;
-  
-  hval = 0;
-  while (*str != '\0')
-    {
-      hval <<= 4;
-      hval += (unsigned long int) *str++;
-      g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
-      if (g != 0)
-       {
-         hval ^= g >> (HASHWORDBITS - 8);
-         hval ^= g;
-       }
-    }
-  return hval;
-}
-
-/* static char * */
-/* my_xstrdup (const char *s) */
-/* { */
-/*   size_t n = strlen (s) + 1; */
-/*   char *p = jnlib_malloc (n); */
-/*   if (!p) */
-/*     abort (); */
-/*   strcpy (p, s); */
-/*   return p; */
-/* } */
-
-
-\f
-/* Generic message catalog and gettext stuff.  */
-
-/* The magic number of the GNU message catalog format. */
-#define MAGIC        0x950412de
-#define MAGIC_SWAPPED 0xde120495
-
-/* Revision number of the currently used .mo (binary) file format.  */
-#define MO_REVISION_NUMBER 0
-
-
-/* Header for binary .mo file format.  */
-struct mo_file_header
-{
-  /* The magic number. */
-  uint32_t magic;
-  /* The revision number of the file format.  */
-  uint32_t revision;
-  /* The number of strings pairs.  */
-  uint32_t nstrings;
-  /* Offset of table with start offsets of original strings.  */
-  uint32_t orig_tab_offset;
-  /* Offset of table with start offsets of translation strings.  */
-  uint32_t trans_tab_offset;
-  /* Size of hashing table.  */
-  uint32_t hash_tab_size;
-  /* Offset of first hashing entry.  */
-  uint32_t hash_tab_offset;
-};
-
-
-struct string_desc
-{
-  /* Length of addressed string.  */
-  uint32_t length;
-  /* Offset of string in file. */
-  uint32_t offset;
-};
-
-
-struct overflow_space_s
-{
-  struct overflow_space_s *next;
-  uint32_t idx;
-  uint32_t length;
-  char d[1];
-};
-
-struct loaded_domain
-{
-  char *data;
-  char *data_native; /* Data mapped to the native version of the
-                        string.  (Allocated along with DATA). */
-  int must_swap;
-  uint32_t nstrings; /* Number of strings.  */
-  uint32_t *mapped;  /* Array of mapping indicators:
-                        0   := Not mapped (original utf8).
-                        1   := Mapped to native encoding in overflow space.
-                        >=2 := Mapped to native encoding. The value
-                               gives the length of the mapped string.
-                               Because the terminating nul is included
-                               in the length and an empty string is
-                               not allowed, values are always > 1.  */
-  struct overflow_space_s *overflow_space;
-  struct string_desc *orig_tab;
-  struct string_desc *trans_tab;
-  uint32_t hash_size;
-  uint32_t *hash_tab;
-};
-
-
-/* The domain we use.  We only support one domain at this point.  This
-   is why this implementation can not be shared.  Bindtextdomain and
-   dgettext will simply cheat and always use this one domain.  */
-static struct loaded_domain *the_domain;
-
-/* Global flag to switch gettext into an utf8 mode.  */
-static int want_utf8;
-
-
-\f
-/* Free the domain data.  */
-static void
-free_domain (struct loaded_domain *domain)
-{
-  struct overflow_space_s *os, *os2;
-
-  jnlib_free (domain->data);
-  jnlib_free (domain->mapped);
-  for (os = domain->overflow_space; os; os = os2)
-    {
-      os2 = os->next;
-      jnlib_free (os);
-    }
-  jnlib_free (domain);
-}
-
-  
-static struct loaded_domain *
-load_domain (const char *filename)
-{
-  FILE *fp;
-  size_t size;
-  struct stat st;
-  struct mo_file_header *data = NULL;
-  struct loaded_domain *domain = NULL;
-  size_t to_read;
-  char *read_ptr;
-  
-  fp = fopen (filename, "rb");
-  if (!fp)
-    return NULL;
-
-  /* Determine the file size.  */
-  if (fstat (fileno (fp), &st)
-      || (size = (size_t) st.st_size) != st.st_size
-      || size < sizeof (struct mo_file_header))
-    {
-      fclose (fp);
-      return NULL;
-    }
-
-  data = (2*size <= size)? NULL : jnlib_malloc (2*size);
-  if (!data)
-    {
-      fclose (fp);
-      return NULL;
-    }
-
-  to_read = size;
-  read_ptr = (char *) data;
-  do
-    {
-      long int nb = fread (read_ptr, 1, to_read, fp);
-      if (nb < to_read)
-       {
-         fclose (fp);
-         jnlib_free (data);
-         return NULL;
-       }
-      read_ptr += nb;
-      to_read -= nb;
-    }
-  while (to_read > 0);
-  fclose (fp);
-
-  /* Using the magic number we can test whether it really is a message
-     catalog file.  */
-  if (data->magic != MAGIC && data->magic != MAGIC_SWAPPED)
-    {
-      /* The magic number is wrong: not a message catalog file.  */
-      jnlib_free (data);
-      return NULL;
-    }
-
-  domain = jnlib_calloc (1, sizeof *domain);
-  if (!domain)
-    {
-      jnlib_free (data);
-      return NULL;
-    }
-  domain->data = (char *) data;
-  domain->data_native = (char *) data + size;
-  domain->must_swap = data->magic != MAGIC;
-  
-  /* Fill in the information about the available tables.  */
-  switch (SWAPIT (domain->must_swap, data->revision))
-    {
-    case MO_REVISION_NUMBER:
-      domain->nstrings = SWAPIT (domain->must_swap, data->nstrings);
-      domain->orig_tab = (struct string_desc *)
-       ((char *) data + SWAPIT (domain->must_swap, data->orig_tab_offset));
-      domain->trans_tab = (struct string_desc *)
-       ((char *) data + SWAPIT (domain->must_swap, data->trans_tab_offset));
-      domain->hash_size = SWAPIT (domain->must_swap, data->hash_tab_size);
-      domain->hash_tab = (uint32_t *)
-       ((char *) data + SWAPIT (domain->must_swap, data->hash_tab_offset));
-      break;
-
-    default:
-      /* This is an invalid revision.  */
-      jnlib_free (data);
-      jnlib_free (domain);
-      return NULL;
-    }
-
-  /* Allocate an array to keep track of code page mappings.  */
-  domain->mapped = jnlib_calloc (domain->nstrings, sizeof *domain->mapped);
-  if (!domain->mapped)
-    {
-      jnlib_free (data);
-      jnlib_free (domain);
-      return NULL;
-    }
-
-  return domain;
-}
-
-
-/* Return a malloced wide char string from an UTF-8 encoded input
-   string STRING.  Caller must free this value. On failure returns
-   NULL.  The result of calling this function with STRING set to NULL
-   is not defined. */
-static wchar_t *
-utf8_to_wchar (const char *string, size_t length, size_t *retlen)
-{
-  int n;
-  wchar_t *result;
-  size_t nbytes;
-
-  n = MultiByteToWideChar (CP_UTF8, 0, string, length, NULL, 0);
-  if (n < 0 || (n+1) <= 0)
-    return NULL;
-
-  nbytes = (size_t)(n+1) * sizeof(*result);
-  if (nbytes / sizeof(*result) != (n+1)) 
-    {
-      errno = ENOMEM;
-      return NULL;
-    }
-  result = jnlib_malloc (nbytes);
-  if (!result)
-    return NULL;
-
-  n = MultiByteToWideChar (CP_UTF8, 0, string, length, result, n);
-  if (n < 0)
-    {
-      jnlib_free (result);
-      return NULL;
-    }
-  *retlen = n;
-  return result;
-}
-
-
-/* Return a malloced string encoded in UTF-8 from the wide char input
-   string STRING.  Caller must free this value. On failure returns
-   NULL.  The result of calling this function with STRING set to NULL
-   is not defined. */
-static char *
-wchar_to_native (const wchar_t *string, size_t length, size_t *retlen)
-{
-  int n;
-  char *result;
-
-  n = WideCharToMultiByte (CP_ACP, 0, string, length, NULL, 0, NULL, NULL);
-  if (n < 0 || (n+1) <= 0)
-    return NULL;
-
-  result = jnlib_malloc (n+1);
-  if (!result)
-    return NULL;
-
-  n = WideCharToMultiByte (CP_ACP, 0, string, length, result, n, NULL, NULL);
-  if (n < 0)
-    {
-      jnlib_free (result);
-      return NULL;
-    }
-  *retlen = n;
-  return result;
-}
-
-
-/* Convert UTF8 to the native codepage.  Caller must free the return value. */
-static char *
-utf8_to_native (const char *string, size_t length, size_t *retlen)
-{
-  wchar_t *wstring;
-  char *result;
-  size_t newlen;
-
-  wstring = utf8_to_wchar (string, length, &newlen);
-  if (wstring)
-    {
-      result = wchar_to_native (wstring, newlen, &newlen);
-      jnlib_free (wstring);
-    }
-  else
-    result = NULL;
-  *retlen = result? newlen : 0;
-  return result;
-}
-
-
-
-\f
-/* Specify that the DOMAINNAME message catalog will be found
-   in DIRNAME rather than in the system locale data base.  */
-char *
-bindtextdomain (const char *domainname, const char *dirname)
-{
-  struct loaded_domain *domain = NULL;
-  const char *catval_full;
-  char *catval;
-  char *fname;
-
-  /* DOMAINNAME is ignored.  We only support one domain.  */
-
-  /* DIRNAME is "$INSTALLDIR\share\locale".  */
-
-  /* First find out the category value.  */
-  catval = NULL;
-  catval_full = my_nl_locale_name ("LC_MESSAGES");
-
-  /* Normally we would have to loop over all returned locales and
-     search for the right file.  See gettext intl/dcigettext.c for all
-     the gory details.  Here, we only support the basic category, and
-     ignore everything else.  */
-  if (catval_full)
-    {
-      char *p;
-
-      catval = jnlib_malloc (strlen (catval_full) + 1);
-      if (catval)
-       {
-         strcpy (catval, catval_full);
-         p = strchr (catval, '_');
-         if (p)
-           *p = '\0';
-       }
-    }
-  if (!catval)
-    return NULL;
-
-  /* Now build the filename string.  The complete filename is this:
-     DIRNAME + \ + CATVAL + \LC_MESSAGES\ + DOMAINNAME + .mo  */
-  {
-    int len = (strlen (dirname) + 1 + strlen (catval) + 13
-               + strlen (domainname) + 3 + 1);
-    char *p;
-
-    fname = jnlib_malloc (len);
-    if (!fname)
-      {
-       jnlib_free (catval);
-       return NULL;
-      }
-
-    p = fname;
-    strcpy (p, dirname);
-    p += strlen (dirname);
-    *(p++) = '\\';
-    strcpy (p, catval);
-    p += strlen (catval);
-    strcpy (p, "\\LC_MESSAGES\\");
-    p += 13;
-    strcpy (p, domainname);
-    p += strlen (domainname);
-    strcpy (p, ".mo");
-  }
-
-  domain = load_domain (fname);
-  jnlib_free (catval);
-  jnlib_free (fname);
-
-  /* We should not be invoked twice, but this is how you would do
-     it if it happened.  */
-  if (the_domain)
-    free_domain (the_domain);
-  the_domain = domain;
-
-  /* For historic reasons we are not allowed to return a const char*. */
-  return (char*)dirname;
-}
-
-
-
-\f
-static const char *
-get_plural (const char *data, size_t datalen, unsigned long nplural)
-{
-  const char *p;
-  int idx;
-
-  /* We only support the Germanic rule.  */
-  idx = (nplural == 1? 0 : 1);
-
-  for (; idx; idx--)
-    {
-      p = strchr (data, 0) + 1;
-      if (p >= data+datalen)
-        return "ERROR in GETTEXT (bad plural entry)";
-      datalen -= (p-data);
-      data = p;
-    }
-  return data;
-}
-
-
-static const char*
-get_string (struct loaded_domain *domain, uint32_t idx,
-            int use_plural, unsigned long nplural)
-{
-  struct overflow_space_s *os;
-  const char *trans;  /* Pointer to the translated entry.  */
-  size_t translen;    /* Length of that entry.  */
-
-  if (want_utf8)
-    {
-      trans = (domain->data
-               + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset));
-      translen = SWAPIT(domain->must_swap, domain->trans_tab[idx].length);
-    }
-  else if (!domain->mapped[idx]) 
-    {
-      /* Not yet mapped.  Map from utf-8 to native encoding now.  */
-      const char *p_utf8;
-      size_t plen_utf8, buflen;
-      char *buf;
-
-      p_utf8 = (domain->data 
-                + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset));
-      plen_utf8 = SWAPIT(domain->must_swap, domain->trans_tab[idx].length);
-      
-      buf = utf8_to_native (p_utf8, plen_utf8, &buflen);
-      if (!buf)
-        {
-          trans = "ERROR in GETTEXT MALLOC";
-          translen = 0;
-        }
-      else if (buflen <= plen_utf8 && buflen > 1)
-        {
-          /* Copy into the DATA_NATIVE area. */
-          char *p_tmp;
-
-          p_tmp = (domain->data_native 
-                   + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset));
-          memcpy (p_tmp, buf, buflen);
-          domain->mapped[idx] = buflen;
-          trans = p_tmp;
-          translen = buflen;
-        }
-      else
-        {
-          /* There is not enough space for the translation (or for
-             whatever reason an empty string is used): Store it in the
-             overflow_space and mark that in the mapped array.
-             Because UTF-8 strings are in general shorter than the
-             Windows 2 byte encodings, we expect that this won't
-             happen too often (if at all) and thus we use a linked
-             list to manage this space. */
-          os = jnlib_malloc (sizeof *os + buflen);
-          if (os)
-            {
-              os->idx = idx;
-              memcpy (os->d, buf, buflen);
-              os->length = buflen;
-              os->next = domain->overflow_space;
-              domain->overflow_space = os;
-              domain->mapped[idx] = 1;
-              trans = os->d;
-              translen = os->length;
-            }
-          else
-            {
-              trans = "ERROR in GETTEXT MALLOC";
-              translen = 0;
-            }
-        }
-      jnlib_free (buf);
-    }
-  else if (domain->mapped[idx] == 1) 
-    {
-      /* The translated string is in the overflow_space. */
-      for (os=domain->overflow_space; os; os = os->next)
-        if (os->idx == idx)
-          break;
-      if (os)
-        {
-          trans = os->d;
-          translen = os->length;
-        }
-      else
-        {
-          trans = "ERROR in GETTEXT (overflow space)\n";
-          translen = 0;
-        }
-    }
-  else 
-    { 
-      trans = (domain->data_native
-               + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset));
-      translen = domain->mapped[idx];
-    }
-
-  if (use_plural && translen)
-    return get_plural (trans, translen, nplural);
-  else
-    return trans;
-}
-
-
-static const char *
-do_gettext (const char *msgid, const char *msgid2, unsigned long nplural)
-{
-  struct loaded_domain *domain;
-  uint32_t top, bottom, nstr;
-  
-  if (!(domain = the_domain))
-    goto not_found;
-
-  /* First try to use the hash table.  */
-  if (domain->hash_size > 2 && domain->hash_tab)
-    {
-      /* Use the hashing table.  */
-      uint32_t len = strlen (msgid);
-      uint32_t hash_val = hash_string (msgid);
-      uint32_t idx = hash_val % domain->hash_size;
-      uint32_t incr = 1 + (hash_val % (domain->hash_size - 2));
-
-      while ( (nstr = SWAPIT (domain->must_swap, domain->hash_tab[idx])) )
-        {
-          nstr--;
-          if (nstr < domain->nstrings
-              && SWAPIT(domain->must_swap, 
-                        domain->orig_tab[nstr].length) >= len
-              && !strcmp (msgid, (domain->data
-                                  + SWAPIT(domain->must_swap,
-                                           domain->orig_tab[nstr].offset))))
-            {
-              return get_string (domain, nstr, !!msgid2, nplural);
-            }
-
-          if (idx >= domain->hash_size - incr)
-            idx -= domain->hash_size - incr;
-          else
-            idx += incr;
-       }
-    }
-
-  /* Now we try the default method: binary search in the sorted array
-     of messages.  */
-  bottom = 0;
-  top = domain->nstrings;
-  while (bottom < top)
-    {
-      int cmp_val;
-      
-      nstr = (bottom + top) / 2;
-      cmp_val = strcmp (msgid, (domain->data
-                                + SWAPIT(domain->must_swap,
-                                         domain->orig_tab[nstr].offset)));
-      if (cmp_val < 0)
-        top = nstr;
-      else if (cmp_val > 0)
-        bottom = nstr + 1;
-      else
-        return get_string (domain, nstr, !!msgid2, nplural);
-    }
-
- not_found:
-  /* We use the standard Germanic rule if plural has been requested.  */
-  return msgid2? (nplural == 1? msgid : msgid2) : msgid;
-}
-
-
-char *
-textdomain (const char *domainname)
-{
-  /* For now, support only one domain.  */
-  return (char*)domainname;
-}
-
-
-const char *
-gettext (const char *msgid)
-{
-  return do_gettext (msgid, NULL, 0);
-}
-
-char *
-dgettext (const char *domainname, const char *msgid)
-{
-  (void)domainname;
-
-  /* For now, support only one domain.  */
-  return (char*)do_gettext (msgid, NULL, 0);
-}
-
-const char *
-ngettext (const char *msgid1, const char *msgid2, unsigned long int n)
-{
-  /* We use the simple Germanic plural rule.  */
-  return do_gettext (msgid1, msgid2, n);
-}
-
-
-/* Return the locale name as used by gettext.  The return value will
-   never be NULL. */
-const char *
-gettext_localename (void)
-{
-  const char *s;
-
-  s = my_nl_locale_name ("LC_MESSAGES");
-  return s? s:"";
-}
-
-void
-gettext_select_utf8 (int value)
-{
-  want_utf8 = value;
-}
-
-
-#ifdef TEST
-int
-main (int argc, char **argv)
-{
-  const char atext1[] = 
-    "Warning: You have entered an insecure passphrase.%%0A"
-    "A passphrase should be at least %u character long.";
-  const char atext2[] = 
-    "Warning: You have entered an insecure passphrase.%%0A"
-    "A passphrase should be at least %u characters long.";
-
-  if (argc)
-    {
-      argc--;
-      argv++;
-    }
-  
-  bindtextdomain ("gnupg2", "c:/programme/gnu/gnupg/share/locale");
-
-  printf ("locale is `%s'\n", gettext_localename ());
-  fputs ("text with N=1:\n", stdout);
-  fputs (ngettext (atext1, atext2, 1), stdout);
-  fputs ("\n\ntext with N=2:\n", stdout);
-  fputs (ngettext (atext1, atext2, 2), stdout);
-  fputs ("\nready\n", stdout);
-
-  return 0;
-}
-/*
- * Local Variables:
- *  compile-command: "i586-mingw32msvc-gcc -DTEST -Wall -g w32-gettext.c"
- * End:
- */
-#endif /*TEST*/
index c503ad2..518d425 100644 (file)
@@ -27,15 +27,6 @@ char *read_w32_registry_string (const char *root,
 int write_w32_registry_string (const char *root, const char *dir,
                                const char *name, const char *value);
 
-#ifdef USE_SIMPLE_GETTEXT
-char *bindtextdomain (const char *domainname, const char *dirname);
-const char *gettext (const char *msgid );
-const char *ngettext (const char *msgid1, const char *msgid2,
-                      unsigned long int n);
-const char *gettext_localename (void);
-void gettext_select_utf8 (int value);
-#endif /*USE_SIMPLE_GETTEXT*/
-
 
 #endif /*HAVE_W32_SYSTEM*/
 #endif /*LIBJNLIB_MISCHELP_H*/