aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32-gettext.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-01-21 12:41:21 +0000
committerWerner Koch <[email protected]>2010-01-21 12:41:21 +0000
commit7664da8dde0d37fc6a8f1061742a175e69d0414f (patch)
tree2f599fd95403a2302f9c1680c9a10e9ed1ac1a69 /src/w32-gettext.c
parentFix w32ce strerror. (diff)
downloadlibgpg-error-7664da8dde0d37fc6a8f1061742a175e69d0414f.tar.gz
libgpg-error-7664da8dde0d37fc6a8f1061742a175e69d0414f.zip
Finished W32CE support.
Diffstat (limited to 'src/w32-gettext.c')
-rw-r--r--src/w32-gettext.c2092
1 files changed, 1133 insertions, 959 deletions
diff --git a/src/w32-gettext.c b/src/w32-gettext.c
index 1b6eb3d..a35af1f 100644
--- a/src/w32-gettext.c
+++ b/src/w32-gettext.c
@@ -1,6 +1,6 @@
/* w32-gettext.h - A simple gettext implementation for Windows targets.
- Copyright (C) 1995,1996,1997,1999,2005 Free Software Foundation, Inc.
- Copyright (C) 2005 g10 Code GmbH
+ Copyright (C) 1995, 1996, 1997, 1999, 2005, 2007,
+2 2008, 2010 Free Software Foundation, Inc.
This file is part of libgpg-error.
@@ -15,13 +15,15 @@
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with libgpg-error; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ 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>
@@ -31,16 +33,27 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
+#ifndef HAVE_W32CE_SYSTEM
+# include <locale.h>
+#endif /*HAVE_W32CE_SYSTEM*/
+#include <windows.h>
-#include <gpg-error.h>
+#ifdef JNLIB_IN_JNLIB
+#include "libjnlib-config.h"
+#endif
-#include "gettext.h"
+#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) not_used
+#endif /*!jnlib_malloc*/
+
+#include "init.h"
-
-/* localname.c from gettext. */
-/* Edit: Added a "static" to _nl_locale_name. Note that the category
- argument is ignored on w32. */
+
+/* localname.c from gettext BEGIN. */
/* Determine the current selected locale.
Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
@@ -62,716 +75,543 @@
/* Written by Ulrich Drepper <[email protected]>, 1995. */
/* Win32 code written by Tor Lillqvist <[email protected]>. */
+/* Renamed _nl_locale_name, removed unsed args, removed include files,
+ non-W32 code and changed comments <[email protected]>. */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
+/* Mingw headers don't have latest language and sublanguage codes. */
+#ifndef LANG_AFRIKAANS
+#define LANG_AFRIKAANS 0x36
#endif
-
-#include <stdlib.h>
-#ifndef HAVE_W32CE_SYSTEM
-# include <locale.h>
+#ifndef LANG_ALBANIAN
+#define LANG_ALBANIAN 0x1c
#endif
-
-#ifdef HAVE_W32_SYSTEM
-# include <windows.h>
-/* List of language codes, sorted by value:
- 0x01 LANG_ARABIC
- 0x02 LANG_BULGARIAN
- 0x03 LANG_CATALAN
- 0x04 LANG_CHINESE
- 0x05 LANG_CZECH
- 0x06 LANG_DANISH
- 0x07 LANG_GERMAN
- 0x08 LANG_GREEK
- 0x09 LANG_ENGLISH
- 0x0a LANG_SPANISH
- 0x0b LANG_FINNISH
- 0x0c LANG_FRENCH
- 0x0d LANG_HEBREW
- 0x0e LANG_HUNGARIAN
- 0x0f LANG_ICELANDIC
- 0x10 LANG_ITALIAN
- 0x11 LANG_JAPANESE
- 0x12 LANG_KOREAN
- 0x13 LANG_DUTCH
- 0x14 LANG_NORWEGIAN
- 0x15 LANG_POLISH
- 0x16 LANG_PORTUGUESE
- 0x17 LANG_RHAETO_ROMANCE
- 0x18 LANG_ROMANIAN
- 0x19 LANG_RUSSIAN
- 0x1a LANG_CROATIAN == LANG_SERBIAN
- 0x1b LANG_SLOVAK
- 0x1c LANG_ALBANIAN
- 0x1d LANG_SWEDISH
- 0x1e LANG_THAI
- 0x1f LANG_TURKISH
- 0x20 LANG_URDU
- 0x21 LANG_INDONESIAN
- 0x22 LANG_UKRAINIAN
- 0x23 LANG_BELARUSIAN
- 0x24 LANG_SLOVENIAN
- 0x25 LANG_ESTONIAN
- 0x26 LANG_LATVIAN
- 0x27 LANG_LITHUANIAN
- 0x28 LANG_TAJIK
- 0x29 LANG_FARSI
- 0x2a LANG_VIETNAMESE
- 0x2b LANG_ARMENIAN
- 0x2c LANG_AZERI
- 0x2d LANG_BASQUE
- 0x2e LANG_SORBIAN
- 0x2f LANG_MACEDONIAN
- 0x30 LANG_SUTU
- 0x31 LANG_TSONGA
- 0x32 LANG_TSWANA
- 0x33 LANG_VENDA
- 0x34 LANG_XHOSA
- 0x35 LANG_ZULU
- 0x36 LANG_AFRIKAANS
- 0x37 LANG_GEORGIAN
- 0x38 LANG_FAEROESE
- 0x39 LANG_HINDI
- 0x3a LANG_MALTESE
- 0x3b LANG_SAAMI
- 0x3c LANG_GAELIC
- 0x3d LANG_YIDDISH
- 0x3e LANG_MALAY
- 0x3f LANG_KAZAK
- 0x40 LANG_KYRGYZ
- 0x41 LANG_SWAHILI
- 0x42 LANG_TURKMEN
- 0x43 LANG_UZBEK
- 0x44 LANG_TATAR
- 0x45 LANG_BENGALI
- 0x46 LANG_PUNJABI
- 0x47 LANG_GUJARATI
- 0x48 LANG_ORIYA
- 0x49 LANG_TAMIL
- 0x4a LANG_TELUGU
- 0x4b LANG_KANNADA
- 0x4c LANG_MALAYALAM
- 0x4d LANG_ASSAMESE
- 0x4e LANG_MARATHI
- 0x4f LANG_SANSKRIT
- 0x50 LANG_MONGOLIAN
- 0x51 LANG_TIBETAN
- 0x52 LANG_WELSH
- 0x53 LANG_CAMBODIAN
- 0x54 LANG_LAO
- 0x55 LANG_BURMESE
- 0x56 LANG_GALICIAN
- 0x57 LANG_KONKANI
- 0x58 LANG_MANIPURI
- 0x59 LANG_SINDHI
- 0x5a LANG_SYRIAC
- 0x5b LANG_SINHALESE
- 0x5c LANG_CHEROKEE
- 0x5d LANG_INUKTITUT
- 0x5e LANG_AMHARIC
- 0x5f LANG_TAMAZIGHT
- 0x60 LANG_KASHMIRI
- 0x61 LANG_NEPALI
- 0x62 LANG_FRISIAN
- 0x63 LANG_PASHTO
- 0x64 LANG_TAGALOG
- 0x65 LANG_DIVEHI
- 0x66 LANG_EDO
- 0x67 LANG_FULFULDE
- 0x68 LANG_HAUSA
- 0x69 LANG_IBIBIO
- 0x6a LANG_YORUBA
- 0x70 LANG_IGBO
- 0x71 LANG_KANURI
- 0x72 LANG_OROMO
- 0x73 LANG_TIGRINYA
- 0x74 LANG_GUARANI
- 0x75 LANG_HAWAIIAN
- 0x76 LANG_LATIN
- 0x77 LANG_SOMALI
- 0x78 LANG_YI
- 0x79 LANG_PAPIAMENTU
-*/
-/* 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
-#endif /* HAVE_W32_SYSTEM */
-
-/* XPG3 defines the result of 'setlocale (category, NULL)' as:
- "Directs 'setlocale()' to query 'category' and return the current
- setting of 'local'."
- However it does not specify the exact format. Neither do SUSV2 and
- ISO C 99. So we can use this feature only on selected systems (e.g.
- those using GNU C Library). */
-#if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2)
-# define HAVE_LOCALE_NULL
-#endif
-
-/* Determine the current locale's name, and canonicalize it into XPG syntax
- language[_territory[.codeset]][@modifier]
- The codeset part in the result is not reliable; the locale_charset()
- should be used for codeset information instead.
- The result must not be freed; it is statically allocated. */
-
+#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 *
-_nl_locale_name (int category, const char *categoryname)
+my_nl_locale_name (const char *categoryname)
{
const char *retval;
-
-#ifndef HAVE_W32_SYSTEM
-
- /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
- On some systems this can be done by the 'setlocale' function itself. */
-# if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
- retval = setlocale (category, NULL);
-# else
- /* Setting of LC_ALL overwrites all other. */
- retval = getenv ("LC_ALL");
- if (retval == NULL || retval[0] == '\0')
- {
- /* Next comes the name of the desired category. */
- retval = getenv (categoryname);
- if (retval == NULL || retval[0] == '\0')
- {
- /* Last possibility is the LANG environment variable. */
- retval = getenv ("LANG");
- if (retval == NULL || retval[0] == '\0')
- /* We use C as the default domain. POSIX says this is
- implementation defined. */
- retval = "C";
- }
- }
-# endif
-
- return retval;
-
-#else /* HAVE_W32_SYSTEM */
-
- /* Return an XPG style locale name language[_territory][@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. */
-
LCID lcid;
LANGID langid;
int primary, sub;
@@ -1178,19 +1018,16 @@ _nl_locale_name (int category, const char *categoryname)
case LANG_ZULU: return "zu_ZA";
default: return "C";
}
-
-#endif /* HAVE_W32_SYSTEM */
}
/* localname.c from gettext END. */
+
+
/* Support functions. */
-typedef uint32_t u32;
-typedef unsigned long ulong;
-
-static __inline__ u32
-do_swap_u32 (u32 i)
+static __inline__ uint32_t
+do_swap_u32 (uint32_t i)
{
return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
}
@@ -1204,26 +1041,25 @@ do_swap_u32 (u32 i)
/* 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__ ulong
+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')
+ 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 <<= 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;
+ return hval;
}
@@ -1236,74 +1072,106 @@ hash_string( const char *str_param )
/* 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. */
- u32 magic;
+ uint32_t magic;
/* The revision number of the file format. */
- u32 revision;
+ uint32_t revision;
/* The number of strings pairs. */
- u32 nstrings;
+ uint32_t nstrings;
/* Offset of table with start offsets of original strings. */
- u32 orig_tab_offset;
+ uint32_t orig_tab_offset;
/* Offset of table with start offsets of translation strings. */
- u32 trans_tab_offset;
+ uint32_t trans_tab_offset;
/* Size of hashing table. */
- u32 hash_tab_size;
+ uint32_t hash_tab_size;
/* Offset of first hashing entry. */
- u32 hash_tab_offset;
+ uint32_t hash_tab_offset;
};
+
struct string_desc
{
/* Length of addressed string. */
- u32 length;
+ uint32_t length;
/* Offset of string in file. */
- u32 offset;
+ uint32_t offset;
};
struct overflow_space_s
{
struct overflow_space_s *next;
- u32 idx;
+ 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;
- u32 nstrings;
- char *mapped; /* 0 = not yet mapped, 1 = mapped,
- 2 = mapped to
- overflow space */
+ uint16_t nstrings; /* Number of strings. */
+ uint16_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;
- u32 hash_size;
- u32 *hash_tab;
+ uint32_t hash_size;
+ uint32_t *hash_tab;
};
+
+/* The list of domains we we are aware of. This list is protected by
+ the criticla section DOMAINLIST_ACCESS_CS. */
+static struct domainlist_s *domainlist;
+
+/* A critical section to guard access to the domainlist. */
+static CRITICAL_SECTION domainlist_access_cs;
+
+/* The name of the current domain. This is a malloced string. This
+ is a gobal variable which is not thread-safe. */
+static char *current_domainname;
+
+
+/* Constructor for this module. Called from DllMain. */
+static void module_init (void) __attribute__ ((__constructor__));
+static void
+module_init (void)
+{
+ InitializeCriticalSection (&domainlist_access_cs);
+}
+
+
/* Free the domain data. */
static void
free_domain (struct loaded_domain *domain)
{
struct overflow_space_s *os, *os2;
- free (domain->data);
- free (domain->mapped);
+
+ jnlib_free (domain->data);
+ jnlib_free (domain->mapped);
for (os = domain->overflow_space; os; os = os2)
{
os2 = os->next;
- free (os);
+ jnlib_free (os);
}
- free (domain);
+ jnlib_free (domain);
}
-/* The gettext implementation; support functions. */
static struct loaded_domain *
load_domain (const char *filename)
{
@@ -1317,9 +1185,9 @@ load_domain (const char *filename)
fp = fopen (filename, "rb");
if (!fp)
- return NULL;
-
- /* Determine the file size. */
+ {
+ return NULL;
+ }
if (fstat (fileno (fp), &st)
|| (size = (size_t) st.st_size) != st.st_size
|| size < sizeof (struct mo_file_header))
@@ -1328,7 +1196,7 @@ load_domain (const char *filename)
return NULL;
}
- data = malloc (size);
+ data = (2*size <= size)? NULL : jnlib_malloc (2*size);
if (!data)
{
fclose (fp);
@@ -1343,7 +1211,7 @@ load_domain (const char *filename)
if (nb < to_read)
{
fclose (fp);
- free (data);
+ jnlib_free (data);
return NULL;
}
read_ptr += nb;
@@ -1357,205 +1225,186 @@ load_domain (const char *filename)
if (data->magic != MAGIC && data->magic != MAGIC_SWAPPED)
{
/* The magic number is wrong: not a message catalog file. */
- free (data);
+ jnlib_free (data);
return NULL;
}
- domain = calloc (1, sizeof *domain);
+ domain = jnlib_calloc (1, sizeof *domain);
if (!domain)
{
- free (data);
+ 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 0:
- 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 = (u32 *)
- ((char *) data + SWAPIT (domain->must_swap, data->hash_tab_offset));
+ case MO_REVISION_NUMBER:
+ {
+ uint32_t nstrings;
+
+ /* Because we use 16 bit values for the mapping array, we
+ can't support more that 65534 strings (65535 would be okay,
+ but it is often used as a special value). A PO file with
+ that many translations is very unlikely given that GnuPG
+ with its very large number of strings has only about 1600
+ strings + variants. */
+ nstrings = SWAPIT (domain->must_swap, data->nstrings);
+ if (nstrings > 65534)
+ goto bailout;
+ domain->nstrings = 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. */
- free (data);
- free (domain);
- return NULL;
+ default: /* This is an invalid revision. */
+ goto bailout;
}
/* Allocate an array to keep track of code page mappings. */
- domain->mapped = calloc (1, domain->nstrings);
- if (!domain->mapped)
- {
- free (data);
- free (domain);
- return NULL;
- }
-
- return domain;
+ domain->mapped = jnlib_calloc (domain->nstrings, sizeof *domain->mapped);
+ if (domain->mapped)
+ return domain; /* Okay. */
+
+ bailout:
+ jnlib_free (data);
+ jnlib_free (domain);
+ return NULL;
}
-/* Return a malloced string encoded in UTF-8 from the wide char input
+/* Return a malloced wide char string from an UTF-8 encoded input
string STRING. Caller must free this value. On failure returns
- NULL; caller may use GetLastError to get the actual error number.
- The result of calling this function with STRING set to NULL is not
- defined. */
-static char *
-wchar_to_native (const wchar_t *string)
+ 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;
- char *result;
+ wchar_t *result;
+ size_t nbytes;
- n = WideCharToMultiByte (CP_ACP, 0, string, -1, NULL, 0, NULL, NULL);
- if (n < 0)
+ n = MultiByteToWideChar (CP_UTF8, 0, string, length, NULL, 0);
+ if (n < 0 || (n+1) <= 0)
return NULL;
- result = malloc (n+1);
+ nbytes = (size_t)(n+1) * sizeof(*result);
+ if (nbytes / sizeof(*result) != (n+1))
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ result = jnlib_malloc (nbytes);
if (!result)
return NULL;
- n = WideCharToMultiByte (CP_ACP, 0, string, -1, result, n, NULL, NULL);
+ n = MultiByteToWideChar (CP_UTF8, 0, string, length, result, n);
if (n < 0)
{
- free (result);
+ jnlib_free (result);
return NULL;
}
+ *retlen = n;
return result;
}
-/* Return a malloced wide char string from an UTF-8 encoded input
+/* Return a malloced string encoded in UTF-8 from the wide char input
string STRING. Caller must free this value. On failure returns
- NULL; caller may use GetLastError to get the actual error number.
- The result of calling this function with STRING set to NULL is not
- defined. */
-static wchar_t *
-utf8_to_wchar (const char *string)
+ 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;
- wchar_t *result;
+ char *result;
- n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
- if (n < 0)
+ n = WideCharToMultiByte (CP_ACP, 0, string, length, NULL, 0, NULL, NULL);
+ if (n < 0 || (n+1) <= 0)
return NULL;
- result = malloc ((n+1) * sizeof *result);
+ result = jnlib_malloc (n+1);
if (!result)
return NULL;
- n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+ n = WideCharToMultiByte (CP_ACP, 0, string, length, result, n, NULL, NULL);
if (n < 0)
{
- free (result);
+ 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)
+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);
- if (!wstring)
- return NULL;
-
- result = wchar_to_native (wstring);
- free (wstring);
-
- return result;
-}
-
-
-static const char*
-get_string (struct loaded_domain *domain, u32 idx)
-{
- struct overflow_space_s *os;
- char *p;
-
- p = domain->data + SWAPIT (domain->must_swap, domain->trans_tab[idx].offset);
- if (!domain->mapped[idx])
- {
- size_t plen, buflen;
- char *buf;
-
- domain->mapped[idx] = 1;
-
- plen = strlen (p);
- buf = utf8_to_native (p);
- buflen = strlen (buf);
- if (buflen <= plen)
- strcpy (p, buf);
- else
- {
- /* There is not enough space for the translation - store it
- in the overflow_space else and mark that in the mapped
- array. Because we expect that this won't happen too
- often, we use a simple linked list. */
- os = malloc (sizeof *os + buflen);
- if (os)
- {
- os->idx = idx;
- strcpy (os->d, buf);
- os->next = domain->overflow_space;
- domain->overflow_space = os;
- p = os->d;
- }
- else
- p = "ERROR in GETTEXT MALLOC";
- }
- free (buf);
- }
- else if (domain->mapped[idx] == 2)
+ wstring = utf8_to_wchar (string, length, &newlen);
+ if (wstring)
{
- /* We need to get the string from the overflow_space. */
- for (os=domain->overflow_space; os; os = os->next)
- if (os->idx == idx)
- return (const char*) os->d;
- p = "ERROR in GETTEXT\n";
+ result = wchar_to_native (wstring, newlen, &newlen);
+ jnlib_free (wstring);
}
- return (const char*) p;
+ else
+ result = NULL;
+ *retlen = result? newlen : 0;
+ return result;
}
-
-/* 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;
/* 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)
+const char *
+_gpg_w32_bindtextdomain (const char *domainname, const char *dirname)
{
- struct loaded_domain *domain = NULL;
const char *catval_full;
char *catval;
char *fname;
+ const char *retvalue;
- /* DOMAINNAME is ignored. We only support one domain. */
+ if (!dirname)
+ {
+ struct domainlist_s *dl;
+
+ retvalue = NULL;
+ EnterCriticalSection (&domainlist_access_cs);
+ {
+ for (dl = domainlist; dl; dl = dl->next)
+ if (!strcmp (dl->name, domainname))
+ {
+ retvalue = dl->dname;
+ break;
+ }
+ }
+ LeaveCriticalSection (&domainlist_access_cs);
+ return retvalue;
+ }
/* DIRNAME is "$INSTALLDIR\share\locale". */
- /* First found out the category value. */
+ /* First find out the category value. */
catval = NULL;
- catval_full = _nl_locale_name (LC_MESSAGES, "LC_MESSAGES");
+ catval_full = my_nl_locale_name ("LC_MESSAGES");
- /* Normally, we would have to loop over all returned locales, and
+ /* 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. */
@@ -1563,7 +1412,7 @@ bindtextdomain (const char *domainname, const char *dirname)
{
char *p;
- catval = malloc (strlen (catval_full) + 1);
+ catval = jnlib_malloc (strlen (catval_full) + 1);
if (catval)
{
strcpy (catval, catval_full);
@@ -1578,15 +1427,15 @@ bindtextdomain (const char *domainname, const char *dirname)
/* 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;
+ int len = (strlen (dirname) + 1 + strlen (catval) + 13
+ + strlen (domainname) + 3 + 1);
char *p;
- fname = malloc (len);
+ fname = jnlib_malloc (len);
if (!fname)
{
- free (catval);
- return;
+ jnlib_free (catval);
+ return NULL;
}
p = fname;
@@ -1602,74 +1451,294 @@ bindtextdomain (const char *domainname, const char *dirname)
strcpy (p, ".mo");
}
- domain = load_domain (fname);
- free (catval);
- free (fname);
+ jnlib_free (catval);
- /* 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;
+ /* Store the domain information in the domainlist. */
+ {
+ struct domainlist_s *item, *dl;
+ char *rel_ptr1 = NULL;
+ char *rel_ptr2 = NULL;
+
+ item = jnlib_calloc (1, sizeof *dl + strlen (domainname));
+ if (!item)
+ {
+ jnlib_free (fname);
+ return NULL;
+ }
+ strcpy (item->name, domainname);
+ item->dname = jnlib_malloc (strlen (dirname) +1);
+ if(!item->dname)
+ {
+ jnlib_free (item);
+ jnlib_free (fname);
+ return NULL;
+ }
+ strcpy (item->dname, dirname);
+ retvalue = item->dname;
- /* For historic reasoins we are not allowed to return a const char*. */
- return (char*)dirname;
+ EnterCriticalSection (&domainlist_access_cs);
+ {
+ for (dl = domainlist; dl; dl = dl->next)
+ if (!strcmp (dl->name, domainname))
+ break;
+ if (!dl) /* First time called for this domainname. */
+ {
+ item->fname = fname;
+ fname = NULL;
+ item->next = domainlist;
+ domainlist = item;
+ item = NULL;
+ }
+ else /* Update only. */
+ {
+ rel_ptr1 = dl->fname;
+ dl->fname = fname;
+ fname = NULL;
+ rel_ptr2 = dl->dname;
+ dl->dname = item->dname;
+ item->dname = NULL;
+ }
+ }
+ LeaveCriticalSection (&domainlist_access_cs);
+
+ jnlib_free (item);
+ jnlib_free (rel_ptr1);
+ jnlib_free (rel_ptr2);
+ }
+
+ return retvalue;
}
-const char *
-gettext (const char *msgid)
+
+
+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 tls_space_s *tls = get_tls ();
+ struct overflow_space_s *os;
+ const char *trans; /* Pointer to the translated entry. */
+ size_t translen; /* Length of that entry. */
+
+ if (idx > 65534)
+ return "ERROR in GETTEXT (too many strings)";
+
+ if (tls->gt_use_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 *domainname,
+ const char *msgid, const char *msgid2, unsigned long nplural)
{
+ struct domainlist_s *dl;
struct loaded_domain *domain;
- size_t act = 0;
- size_t top, bottom;
+ int load_failed;
+ uint32_t top, bottom, nstr;
+ char *filename;
+
+ if (!domainname)
+ domainname = current_domainname? current_domainname : "";
+
+ /* FIXME: The whole locking stuff is a bit questionable because
+ gettext does not claim to be thread-safe. We need to investigate
+ this further. */
+
+ load_failed = 0;
+ domain = NULL;
+ filename = NULL;
+ EnterCriticalSection (&domainlist_access_cs);
+ {
+ for (dl = domainlist; dl; dl = dl->next)
+ if (!strcmp (dl->name, domainname))
+ {
+ load_failed = dl->load_failed;
+ domain = dl->domain;
+ break;
+ }
+ if (dl && !domain && !load_failed && dl->fname)
+ {
+ filename = jnlib_malloc (strlen (dl->fname) + 1);
+ if (filename)
+ strcpy (filename, dl->fname);
+ }
+ }
+ LeaveCriticalSection (&domainlist_access_cs);
+ if (!dl)
+ goto not_found; /* DOMAINNAME not bound. */
+ if (filename)
+ {
+ /* No attempt so far to load the MO file. Try now. */
+ int updated = 0;
+
+ domain = load_domain (filename);
+ jnlib_free (filename);
+ filename = NULL;
+ EnterCriticalSection (&domainlist_access_cs);
+ {
+ for (dl = domainlist; dl; dl = dl->next)
+ if (!strcmp (dl->name, domainname))
+ {
+ if (domain)
+ dl->domain = domain;
+ else
+ dl->load_failed = 1;
+ updated = 1;
+ break;
+ }
+ }
+ LeaveCriticalSection (&domainlist_access_cs);
+ if (!updated)
+ {
+ /* Ooops - lost the domain. */
+ free_domain (domain);
+ domain = NULL;
+ }
+ }
- if (!(domain = the_domain))
- goto not_found;
+ if (!domain)
+ goto not_found; /* No MO file. */
- /* Locate the MSGID and its translation. */
+ /* First try to use the hash table. */
if (domain->hash_size > 2 && domain->hash_tab)
{
/* Use the hashing table. */
- u32 len = strlen (msgid);
- u32 hash_val = hash_string (msgid);
- u32 idx = hash_val % domain->hash_size;
- u32 incr = 1 + (hash_val % (domain->hash_size - 2));
- u32 nstr = SWAPIT (domain->must_swap, domain->hash_tab[idx]);
-
- if (!nstr)
- /* Hash table entry is empty. */
- goto not_found;
-
- if (SWAPIT (domain->must_swap,
- domain->orig_tab[nstr - 1].length) == len
- && !strcmp (msgid,
- domain->data
- + SWAPIT (domain->must_swap,
- domain->orig_tab[nstr - 1].offset)))
- return get_string (domain, nstr - 1);
-
- for(;;)
- {
- if (idx >= domain->hash_size - incr)
- idx -= domain->hash_size - incr;
- else
- idx += incr;
-
- nstr = SWAPIT (domain->must_swap, domain->hash_tab[idx]);
- if (!nstr)
- /* Hash table entry is empty. */
- goto not_found;
-
- if (SWAPIT (domain->must_swap,
- domain->orig_tab[nstr - 1].length) == len
- && !strcmp (msgid,
- domain->data
- + SWAPIT (domain->must_swap,
- domain->orig_tab[nstr - 1].offset)))
- return get_string (domain, nstr-1);
- }
- /* NOTREACHED */
+ 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
@@ -1680,33 +1749,138 @@ gettext (const char *msgid)
{
int cmp_val;
- act = (bottom + top) / 2;
- cmp_val = strcmp(msgid, domain->data
- + SWAPIT (domain->must_swap,
- domain->orig_tab[act].offset));
+ nstr = (bottom + top) / 2;
+ cmp_val = strcmp (msgid, (domain->data
+ + SWAPIT(domain->must_swap,
+ domain->orig_tab[nstr].offset)));
if (cmp_val < 0)
- top = act;
+ top = nstr;
else if (cmp_val > 0)
- bottom = act + 1;
+ bottom = nstr + 1;
else
- return get_string (domain, act);
+ {
+ return get_string (domain, nstr, !!msgid2, nplural);
+ }
}
-
+
not_found:
- return msgid;
+ /* We use the standard Germanic rule if plural has been requested. */
+ return msgid2? (nplural == 1? msgid : msgid2) : msgid;
}
-char *
-textdomain (const char *domainname)
+const char *
+_gpg_w32_textdomain (const char *domainname)
{
- /* For now, support only one domain. */
- return (char*)domainname;
+ char *string;
+
+ if (!domainname)
+ {
+ if (!current_domainname)
+ gpg_err_set_errno (0);
+ }
+ else
+ {
+ string = malloc (strlen (domainname) + 1);
+ if (!string)
+ return NULL;
+ strcpy (string, domainname);
+ current_domainname = string;
+ }
+ return current_domainname;
}
-char *
-dgettext (const char *domainname, const char *msgid)
+
+/* A direct implementation of gettext instead of a macro calling
+ dngettext. This is so that the caller does not need to push dummy
+ values on the stack. The used domain is the first one registered
+ with bindtextdomain. */
+const char *
+_gpg_w32_gettext (const char *msgid)
{
- /* For now, support only one domain. */
- return (char*)gettext (msgid);
+ return do_gettext (NULL, msgid, NULL, 0);
+}
+
+
+/* A direct implementation of dgettext instead of a macro calling
+ dngettext. This is so that the caller does not need to push dummy
+ values on the stack. */
+const char *
+_gpg_w32_dgettext (const char *domainname, const char *msgid)
+{
+ return do_gettext (domainname, msgid, NULL, 0);
+}
+
+
+/* Our implementation of dngettext. This is the most genereic
+ function we have; a macro implements ngettext. */
+const char *
+_gpg_w32_dngettext (const char *domainname, const char *msgid1,
+ const char *msgid2, unsigned long int n)
+{
+ /* We use the simple Germanic plural rule. */
+ return do_gettext (domainname, msgid1, msgid2, n);
+}
+
+
+/* Return the locale name as used by gettext. The return value will
+ never be NULL. */
+const char *
+_gpg_w32_gettext_localename (void)
+{
+ const char *s;
+
+ s = my_nl_locale_name ("LC_MESSAGES");
+ return s? s:"";
+}
+
+
+/* With a VALUE of 1 switch the gettext functions into utf8 mode.
+ That is the strings are returned without translation to the native
+ charset. A VALUE of 0 swicthes back to trnslated strings. A VALUE
+ of -1 returns the current value. */
+int
+_gpg_w32_gettext_use_utf8 (int value)
+{
+ struct tls_space_s *tls = get_tls ();
+ int last = tls->gt_use_utf8;
+ if (value != -1)
+ tls->gt_use_utf8 = value;
+ return last;
+}
+
+
+#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++;
+ }
+
+ _gpg_err_w32_bindtextdomain ("gnupg2", "c:/programme/gnu/gnupg/share/locale");
+
+ printf ("locale is `%s'\n", _gpg_err_w32_gettext_localename ());
+ fputs ("text with N=1:\n", stdout);
+ fputs (_gpg_err_w32_ngettext (atext1, atext2, 1), stdout);
+ fputs ("\n\ntext with N=2:\n", stdout);
+ fputs (_gpg_err_w32_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*/