diff options
Diffstat (limited to 'plugins/MirOTR/libgpg-error-1.9/w32-gettext.c')
-rw-r--r-- | plugins/MirOTR/libgpg-error-1.9/w32-gettext.c | 1886 |
1 files changed, 0 insertions, 1886 deletions
diff --git a/plugins/MirOTR/libgpg-error-1.9/w32-gettext.c b/plugins/MirOTR/libgpg-error-1.9/w32-gettext.c deleted file mode 100644 index da07a25695..0000000000 --- a/plugins/MirOTR/libgpg-error-1.9/w32-gettext.c +++ /dev/null @@ -1,1886 +0,0 @@ -/* w32-gettext.h - A simple gettext implementation for Windows targets. - Copyright (C) 1995, 1996, 1997, 1999, 2005, 2007, -2 2008, 2010 Free Software Foundation, Inc. - - This file is part of libgpg-error. - - libgpg-error 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. - - libgpg-error 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> -#ifndef HAVE_W32CE_SYSTEM -# include <locale.h> -#endif /*HAVE_W32CE_SYSTEM*/ -#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) not_used -#endif /*!jnlib_malloc*/ - -#include "init.h" - - - -/* 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. */ - - - -/* 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; -} - - -/* 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; - 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; - 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; - - 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; - } - 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: - { - 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. */ - goto bailout; - } - - /* Allocate an array to keep track of code page mappings. */ - 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 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)) - { - gpg_err_set_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; -} - - - - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -const char * -_gpg_w32_bindtextdomain (const char *domainname, const char *dirname) -{ - const char *catval_full; - char *catval; - char *fname; - const char *retvalue; - - 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 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"); - } - - jnlib_free (catval); - - /* 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; - - 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; -} - - - - -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; - 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) - goto not_found; /* No MO file. */ - - /* 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; -} - - -const char * -_gpg_w32_textdomain (const 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; -} - - -/* 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) -{ - 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 switches back to translated 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*/ |