1 /* w32-gettext.h - A simple gettext implementation for Windows targets.
2 Copyright (C) 1995, 1996, 1997, 1999, 2005, 2007,
3 2008 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License
7 as published by the Free Software Foundation; either version 2.1 of
8 the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #if !defined (_WIN32) && !defined (__CYGWIN32__)
23 # error This module may only be build for Windows or Cygwin32
31 #include <sys/types.h>
38 #include "libjnlib-config.h"
42 # define jnlib_malloc(a) malloc ((a))
43 # define jnlib_calloc(a,b) calloc ((a), (b))
44 # define jnlib_free(a) free ((a))
45 # define jnlib_xstrdup(a) my_xstrdup(a)
46 #endif /*!jnlib_malloc*/
50 /* localname.c from gettext BEGIN. */
52 /* Determine the current selected locale.
53 Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
55 This program is free software; you can redistribute it and/or modify it
56 under the terms of the GNU Library General Public License as published
57 by the Free Software Foundation; either version 2, or (at your option)
60 This program is distributed in the hope that it will be useful,
61 but WITHOUT ANY WARRANTY; without even the implied warranty of
62 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
63 Library General Public License for more details.
65 You should have received a copy of the GNU Library General Public
66 License along with this program; if not, write to the Free Software
67 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
70 /* Written by Ulrich Drepper <drepper@gnu.org>, 1995. */
71 /* Win32 code written by Tor Lillqvist <tml@iki.fi>. */
72 /* Renamed _nl_locale_name, removed unsed args, removed include files,
73 non-W32 code and changed comments <wk@gnupg.org>. */
75 /* Mingw headers don't have latest language and sublanguage codes. */
76 #ifndef LANG_AFRIKAANS
77 #define LANG_AFRIKAANS 0x36
80 #define LANG_ALBANIAN 0x1c
83 #define LANG_AMHARIC 0x5e
86 #define LANG_ARABIC 0x01
89 #define LANG_ARMENIAN 0x2b
92 #define LANG_ASSAMESE 0x4d
95 #define LANG_AZERI 0x2c
98 #define LANG_BASQUE 0x2d
100 #ifndef LANG_BELARUSIAN
101 #define LANG_BELARUSIAN 0x23
104 #define LANG_BENGALI 0x45
107 #define LANG_BURMESE 0x55
109 #ifndef LANG_CAMBODIAN
110 #define LANG_CAMBODIAN 0x53
113 #define LANG_CATALAN 0x03
115 #ifndef LANG_CHEROKEE
116 #define LANG_CHEROKEE 0x5c
119 #define LANG_DIVEHI 0x65
122 #define LANG_EDO 0x66
124 #ifndef LANG_ESTONIAN
125 #define LANG_ESTONIAN 0x25
127 #ifndef LANG_FAEROESE
128 #define LANG_FAEROESE 0x38
131 #define LANG_FARSI 0x29
134 #define LANG_FRISIAN 0x62
136 #ifndef LANG_FULFULDE
137 #define LANG_FULFULDE 0x67
140 #define LANG_GAELIC 0x3c
142 #ifndef LANG_GALICIAN
143 #define LANG_GALICIAN 0x56
145 #ifndef LANG_GEORGIAN
146 #define LANG_GEORGIAN 0x37
149 #define LANG_GUARANI 0x74
151 #ifndef LANG_GUJARATI
152 #define LANG_GUJARATI 0x47
155 #define LANG_HAUSA 0x68
157 #ifndef LANG_HAWAIIAN
158 #define LANG_HAWAIIAN 0x75
161 #define LANG_HEBREW 0x0d
164 #define LANG_HINDI 0x39
167 #define LANG_IBIBIO 0x69
170 #define LANG_IGBO 0x70
172 #ifndef LANG_INDONESIAN
173 #define LANG_INDONESIAN 0x21
175 #ifndef LANG_INUKTITUT
176 #define LANG_INUKTITUT 0x5d
179 #define LANG_KANNADA 0x4b
182 #define LANG_KANURI 0x71
184 #ifndef LANG_KASHMIRI
185 #define LANG_KASHMIRI 0x60
188 #define LANG_KAZAK 0x3f
191 #define LANG_KONKANI 0x57
194 #define LANG_KYRGYZ 0x40
197 #define LANG_LAO 0x54
200 #define LANG_LATIN 0x76
203 #define LANG_LATVIAN 0x26
205 #ifndef LANG_LITHUANIAN
206 #define LANG_LITHUANIAN 0x27
208 #ifndef LANG_MACEDONIAN
209 #define LANG_MACEDONIAN 0x2f
212 #define LANG_MALAY 0x3e
214 #ifndef LANG_MALAYALAM
215 #define LANG_MALAYALAM 0x4c
218 #define LANG_MALTESE 0x3a
220 #ifndef LANG_MANIPURI
221 #define LANG_MANIPURI 0x58
224 #define LANG_MARATHI 0x4e
226 #ifndef LANG_MONGOLIAN
227 #define LANG_MONGOLIAN 0x50
230 #define LANG_NEPALI 0x61
233 #define LANG_ORIYA 0x48
236 #define LANG_OROMO 0x72
238 #ifndef LANG_PAPIAMENTU
239 #define LANG_PAPIAMENTU 0x79
242 #define LANG_PASHTO 0x63
245 #define LANG_PUNJABI 0x46
247 #ifndef LANG_RHAETO_ROMANCE
248 #define LANG_RHAETO_ROMANCE 0x17
251 #define LANG_SAAMI 0x3b
253 #ifndef LANG_SANSKRIT
254 #define LANG_SANSKRIT 0x4f
257 #define LANG_SERBIAN 0x1a
260 #define LANG_SINDHI 0x59
262 #ifndef LANG_SINHALESE
263 #define LANG_SINHALESE 0x5b
266 #define LANG_SLOVAK 0x1b
269 #define LANG_SOMALI 0x77
272 #define LANG_SORBIAN 0x2e
275 #define LANG_SUTU 0x30
278 #define LANG_SWAHILI 0x41
281 #define LANG_SYRIAC 0x5a
284 #define LANG_TAGALOG 0x64
287 #define LANG_TAJIK 0x28
289 #ifndef LANG_TAMAZIGHT
290 #define LANG_TAMAZIGHT 0x5f
293 #define LANG_TAMIL 0x49
296 #define LANG_TATAR 0x44
299 #define LANG_TELUGU 0x4a
302 #define LANG_THAI 0x1e
305 #define LANG_TIBETAN 0x51
307 #ifndef LANG_TIGRINYA
308 #define LANG_TIGRINYA 0x73
311 #define LANG_TSONGA 0x31
314 #define LANG_TSWANA 0x32
317 #define LANG_TURKMEN 0x42
319 #ifndef LANG_UKRAINIAN
320 #define LANG_UKRAINIAN 0x22
323 #define LANG_URDU 0x20
326 #define LANG_UZBEK 0x43
329 #define LANG_VENDA 0x33
331 #ifndef LANG_VIETNAMESE
332 #define LANG_VIETNAMESE 0x2a
335 #define LANG_WELSH 0x52
338 #define LANG_XHOSA 0x34
344 #define LANG_YIDDISH 0x3d
347 #define LANG_YORUBA 0x6a
350 #define LANG_ZULU 0x35
352 #ifndef SUBLANG_ARABIC_SAUDI_ARABIA
353 #define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
355 #ifndef SUBLANG_ARABIC_IRAQ
356 #define SUBLANG_ARABIC_IRAQ 0x02
358 #ifndef SUBLANG_ARABIC_EGYPT
359 #define SUBLANG_ARABIC_EGYPT 0x03
361 #ifndef SUBLANG_ARABIC_LIBYA
362 #define SUBLANG_ARABIC_LIBYA 0x04
364 #ifndef SUBLANG_ARABIC_ALGERIA
365 #define SUBLANG_ARABIC_ALGERIA 0x05
367 #ifndef SUBLANG_ARABIC_MOROCCO
368 #define SUBLANG_ARABIC_MOROCCO 0x06
370 #ifndef SUBLANG_ARABIC_TUNISIA
371 #define SUBLANG_ARABIC_TUNISIA 0x07
373 #ifndef SUBLANG_ARABIC_OMAN
374 #define SUBLANG_ARABIC_OMAN 0x08
376 #ifndef SUBLANG_ARABIC_YEMEN
377 #define SUBLANG_ARABIC_YEMEN 0x09
379 #ifndef SUBLANG_ARABIC_SYRIA
380 #define SUBLANG_ARABIC_SYRIA 0x0a
382 #ifndef SUBLANG_ARABIC_JORDAN
383 #define SUBLANG_ARABIC_JORDAN 0x0b
385 #ifndef SUBLANG_ARABIC_LEBANON
386 #define SUBLANG_ARABIC_LEBANON 0x0c
388 #ifndef SUBLANG_ARABIC_KUWAIT
389 #define SUBLANG_ARABIC_KUWAIT 0x0d
391 #ifndef SUBLANG_ARABIC_UAE
392 #define SUBLANG_ARABIC_UAE 0x0e
394 #ifndef SUBLANG_ARABIC_BAHRAIN
395 #define SUBLANG_ARABIC_BAHRAIN 0x0f
397 #ifndef SUBLANG_ARABIC_QATAR
398 #define SUBLANG_ARABIC_QATAR 0x10
400 #ifndef SUBLANG_AZERI_LATIN
401 #define SUBLANG_AZERI_LATIN 0x01
403 #ifndef SUBLANG_AZERI_CYRILLIC
404 #define SUBLANG_AZERI_CYRILLIC 0x02
406 #ifndef SUBLANG_BENGALI_INDIA
407 #define SUBLANG_BENGALI_INDIA 0x01
409 #ifndef SUBLANG_BENGALI_BANGLADESH
410 #define SUBLANG_BENGALI_BANGLADESH 0x02
412 #ifndef SUBLANG_CHINESE_MACAU
413 #define SUBLANG_CHINESE_MACAU 0x05
415 #ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
416 #define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
418 #ifndef SUBLANG_ENGLISH_JAMAICA
419 #define SUBLANG_ENGLISH_JAMAICA 0x08
421 #ifndef SUBLANG_ENGLISH_CARIBBEAN
422 #define SUBLANG_ENGLISH_CARIBBEAN 0x09
424 #ifndef SUBLANG_ENGLISH_BELIZE
425 #define SUBLANG_ENGLISH_BELIZE 0x0a
427 #ifndef SUBLANG_ENGLISH_TRINIDAD
428 #define SUBLANG_ENGLISH_TRINIDAD 0x0b
430 #ifndef SUBLANG_ENGLISH_ZIMBABWE
431 #define SUBLANG_ENGLISH_ZIMBABWE 0x0c
433 #ifndef SUBLANG_ENGLISH_PHILIPPINES
434 #define SUBLANG_ENGLISH_PHILIPPINES 0x0d
436 #ifndef SUBLANG_ENGLISH_INDONESIA
437 #define SUBLANG_ENGLISH_INDONESIA 0x0e
439 #ifndef SUBLANG_ENGLISH_HONGKONG
440 #define SUBLANG_ENGLISH_HONGKONG 0x0f
442 #ifndef SUBLANG_ENGLISH_INDIA
443 #define SUBLANG_ENGLISH_INDIA 0x10
445 #ifndef SUBLANG_ENGLISH_MALAYSIA
446 #define SUBLANG_ENGLISH_MALAYSIA 0x11
448 #ifndef SUBLANG_ENGLISH_SINGAPORE
449 #define SUBLANG_ENGLISH_SINGAPORE 0x12
451 #ifndef SUBLANG_FRENCH_LUXEMBOURG
452 #define SUBLANG_FRENCH_LUXEMBOURG 0x05
454 #ifndef SUBLANG_FRENCH_MONACO
455 #define SUBLANG_FRENCH_MONACO 0x06
457 #ifndef SUBLANG_FRENCH_WESTINDIES
458 #define SUBLANG_FRENCH_WESTINDIES 0x07
460 #ifndef SUBLANG_FRENCH_REUNION
461 #define SUBLANG_FRENCH_REUNION 0x08
463 #ifndef SUBLANG_FRENCH_CONGO
464 #define SUBLANG_FRENCH_CONGO 0x09
466 #ifndef SUBLANG_FRENCH_SENEGAL
467 #define SUBLANG_FRENCH_SENEGAL 0x0a
469 #ifndef SUBLANG_FRENCH_CAMEROON
470 #define SUBLANG_FRENCH_CAMEROON 0x0b
472 #ifndef SUBLANG_FRENCH_COTEDIVOIRE
473 #define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
475 #ifndef SUBLANG_FRENCH_MALI
476 #define SUBLANG_FRENCH_MALI 0x0d
478 #ifndef SUBLANG_FRENCH_MOROCCO
479 #define SUBLANG_FRENCH_MOROCCO 0x0e
481 #ifndef SUBLANG_FRENCH_HAITI
482 #define SUBLANG_FRENCH_HAITI 0x0f
484 #ifndef SUBLANG_GERMAN_LUXEMBOURG
485 #define SUBLANG_GERMAN_LUXEMBOURG 0x04
487 #ifndef SUBLANG_GERMAN_LIECHTENSTEIN
488 #define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
490 #ifndef SUBLANG_KASHMIRI_INDIA
491 #define SUBLANG_KASHMIRI_INDIA 0x02
493 #ifndef SUBLANG_MALAY_MALAYSIA
494 #define SUBLANG_MALAY_MALAYSIA 0x01
496 #ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
497 #define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
499 #ifndef SUBLANG_NEPALI_INDIA
500 #define SUBLANG_NEPALI_INDIA 0x02
502 #ifndef SUBLANG_PUNJABI_INDIA
503 #define SUBLANG_PUNJABI_INDIA 0x01
505 #ifndef SUBLANG_ROMANIAN_ROMANIA
506 #define SUBLANG_ROMANIAN_ROMANIA 0x01
508 #ifndef SUBLANG_SERBIAN_LATIN
509 #define SUBLANG_SERBIAN_LATIN 0x02
511 #ifndef SUBLANG_SERBIAN_CYRILLIC
512 #define SUBLANG_SERBIAN_CYRILLIC 0x03
514 #ifndef SUBLANG_SINDHI_INDIA
515 #define SUBLANG_SINDHI_INDIA 0x00
517 #ifndef SUBLANG_SINDHI_PAKISTAN
518 #define SUBLANG_SINDHI_PAKISTAN 0x01
520 #ifndef SUBLANG_SPANISH_GUATEMALA
521 #define SUBLANG_SPANISH_GUATEMALA 0x04
523 #ifndef SUBLANG_SPANISH_COSTA_RICA
524 #define SUBLANG_SPANISH_COSTA_RICA 0x05
526 #ifndef SUBLANG_SPANISH_PANAMA
527 #define SUBLANG_SPANISH_PANAMA 0x06
529 #ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
530 #define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
532 #ifndef SUBLANG_SPANISH_VENEZUELA
533 #define SUBLANG_SPANISH_VENEZUELA 0x08
535 #ifndef SUBLANG_SPANISH_COLOMBIA
536 #define SUBLANG_SPANISH_COLOMBIA 0x09
538 #ifndef SUBLANG_SPANISH_PERU
539 #define SUBLANG_SPANISH_PERU 0x0a
541 #ifndef SUBLANG_SPANISH_ARGENTINA
542 #define SUBLANG_SPANISH_ARGENTINA 0x0b
544 #ifndef SUBLANG_SPANISH_ECUADOR
545 #define SUBLANG_SPANISH_ECUADOR 0x0c
547 #ifndef SUBLANG_SPANISH_CHILE
548 #define SUBLANG_SPANISH_CHILE 0x0d
550 #ifndef SUBLANG_SPANISH_URUGUAY
551 #define SUBLANG_SPANISH_URUGUAY 0x0e
553 #ifndef SUBLANG_SPANISH_PARAGUAY
554 #define SUBLANG_SPANISH_PARAGUAY 0x0f
556 #ifndef SUBLANG_SPANISH_BOLIVIA
557 #define SUBLANG_SPANISH_BOLIVIA 0x10
559 #ifndef SUBLANG_SPANISH_EL_SALVADOR
560 #define SUBLANG_SPANISH_EL_SALVADOR 0x11
562 #ifndef SUBLANG_SPANISH_HONDURAS
563 #define SUBLANG_SPANISH_HONDURAS 0x12
565 #ifndef SUBLANG_SPANISH_NICARAGUA
566 #define SUBLANG_SPANISH_NICARAGUA 0x13
568 #ifndef SUBLANG_SPANISH_PUERTO_RICO
569 #define SUBLANG_SPANISH_PUERTO_RICO 0x14
571 #ifndef SUBLANG_SWEDISH_FINLAND
572 #define SUBLANG_SWEDISH_FINLAND 0x02
574 #ifndef SUBLANG_TAMAZIGHT_ARABIC
575 #define SUBLANG_TAMAZIGHT_ARABIC 0x01
577 #ifndef SUBLANG_TAMAZIGHT_LATIN
578 #define SUBLANG_TAMAZIGHT_LATIN 0x02
580 #ifndef SUBLANG_TIGRINYA_ETHIOPIA
581 #define SUBLANG_TIGRINYA_ETHIOPIA 0x00
583 #ifndef SUBLANG_TIGRINYA_ERITREA
584 #define SUBLANG_TIGRINYA_ERITREA 0x01
586 #ifndef SUBLANG_URDU_PAKISTAN
587 #define SUBLANG_URDU_PAKISTAN 0x01
589 #ifndef SUBLANG_URDU_INDIA
590 #define SUBLANG_URDU_INDIA 0x02
592 #ifndef SUBLANG_UZBEK_LATIN
593 #define SUBLANG_UZBEK_LATIN 0x01
595 #ifndef SUBLANG_UZBEK_CYRILLIC
596 #define SUBLANG_UZBEK_CYRILLIC 0x02
599 /* Return an XPG style locale name
600 language[_territory[.codeset]][@modifier].
601 Don't even bother determining the codeset; it's not useful in this
602 context, because message catalogs are not specific to a single
603 codeset. The result must not be freed; it is statically
606 my_nl_locale_name (const char *categoryname
)
613 /* Let the user override the system settings through environment
614 variables, as on POSIX systems. */
615 retval
= getenv ("LC_ALL");
616 if (retval
!= NULL
&& retval
[0] != '\0')
618 retval
= getenv (categoryname
);
619 if (retval
!= NULL
&& retval
[0] != '\0')
621 retval
= getenv ("LANG");
622 if (retval
!= NULL
&& retval
[0] != '\0')
625 /* Use native Win32 API locale ID. */
626 lcid
= GetThreadLocale ();
628 /* Strip off the sorting rules, keep only the language part. */
629 langid
= LANGIDFROMLCID (lcid
);
631 /* Split into language and territory part. */
632 primary
= PRIMARYLANGID (langid
);
633 sub
= SUBLANGID (langid
);
635 /* Dispatch on language.
636 See also http://www.unicode.org/unicode/onlinedat/languages.html .
637 For details about languages, see http://www.ethnologue.com/ . */
640 case LANG_AFRIKAANS
: return "af_ZA";
641 case LANG_ALBANIAN
: return "sq_AL";
642 case LANG_AMHARIC
: return "am_ET";
646 case SUBLANG_ARABIC_SAUDI_ARABIA
: return "ar_SA";
647 case SUBLANG_ARABIC_IRAQ
: return "ar_IQ";
648 case SUBLANG_ARABIC_EGYPT
: return "ar_EG";
649 case SUBLANG_ARABIC_LIBYA
: return "ar_LY";
650 case SUBLANG_ARABIC_ALGERIA
: return "ar_DZ";
651 case SUBLANG_ARABIC_MOROCCO
: return "ar_MA";
652 case SUBLANG_ARABIC_TUNISIA
: return "ar_TN";
653 case SUBLANG_ARABIC_OMAN
: return "ar_OM";
654 case SUBLANG_ARABIC_YEMEN
: return "ar_YE";
655 case SUBLANG_ARABIC_SYRIA
: return "ar_SY";
656 case SUBLANG_ARABIC_JORDAN
: return "ar_JO";
657 case SUBLANG_ARABIC_LEBANON
: return "ar_LB";
658 case SUBLANG_ARABIC_KUWAIT
: return "ar_KW";
659 case SUBLANG_ARABIC_UAE
: return "ar_AE";
660 case SUBLANG_ARABIC_BAHRAIN
: return "ar_BH";
661 case SUBLANG_ARABIC_QATAR
: return "ar_QA";
664 case LANG_ARMENIAN
: return "hy_AM";
665 case LANG_ASSAMESE
: return "as_IN";
669 /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
670 case SUBLANG_AZERI_LATIN
: return "az_AZ@latin";
671 case SUBLANG_AZERI_CYRILLIC
: return "az_AZ@cyrillic";
675 return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
676 case LANG_BELARUSIAN
: return "be_BY";
680 case SUBLANG_BENGALI_INDIA
: return "bn_IN";
681 case SUBLANG_BENGALI_BANGLADESH
: return "bn_BD";
684 case LANG_BULGARIAN
: return "bg_BG";
685 case LANG_BURMESE
: return "my_MM";
686 case LANG_CAMBODIAN
: return "km_KH";
687 case LANG_CATALAN
: return "ca_ES";
688 case LANG_CHEROKEE
: return "chr_US";
692 case SUBLANG_CHINESE_TRADITIONAL
: return "zh_TW";
693 case SUBLANG_CHINESE_SIMPLIFIED
: return "zh_CN";
694 case SUBLANG_CHINESE_HONGKONG
: return "zh_HK";
695 case SUBLANG_CHINESE_SINGAPORE
: return "zh_SG";
696 case SUBLANG_CHINESE_MACAU
: return "zh_MO";
699 case LANG_CROATIAN
: /* LANG_CROATIAN == LANG_SERBIAN
700 * What used to be called Serbo-Croatian
701 * should really now be two separate
702 * languages because of political reasons.
703 * (Says tml, who knows nothing about Serbian
705 * (I can feel those flames coming already.)
709 case SUBLANG_DEFAULT
: return "hr_HR";
710 case SUBLANG_SERBIAN_LATIN
: return "sr_CS";
711 case SUBLANG_SERBIAN_CYRILLIC
: return "sr_CS@cyrillic";
714 case LANG_CZECH
: return "cs_CZ";
715 case LANG_DANISH
: return "da_DK";
716 case LANG_DIVEHI
: return "div_MV";
720 case SUBLANG_DUTCH
: return "nl_NL";
721 case SUBLANG_DUTCH_BELGIAN
: /* FLEMISH, VLAAMS */ return "nl_BE";
724 case LANG_EDO
: return "bin_NG";
728 /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
729 * English was the language spoken in England.
732 case SUBLANG_ENGLISH_US
: return "en_US";
733 case SUBLANG_ENGLISH_UK
: return "en_GB";
734 case SUBLANG_ENGLISH_AUS
: return "en_AU";
735 case SUBLANG_ENGLISH_CAN
: return "en_CA";
736 case SUBLANG_ENGLISH_NZ
: return "en_NZ";
737 case SUBLANG_ENGLISH_EIRE
: return "en_IE";
738 case SUBLANG_ENGLISH_SOUTH_AFRICA
: return "en_ZA";
739 case SUBLANG_ENGLISH_JAMAICA
: return "en_JM";
740 case SUBLANG_ENGLISH_CARIBBEAN
: return "en_GD"; /* Grenada? */
741 case SUBLANG_ENGLISH_BELIZE
: return "en_BZ";
742 case SUBLANG_ENGLISH_TRINIDAD
: return "en_TT";
743 case SUBLANG_ENGLISH_ZIMBABWE
: return "en_ZW";
744 case SUBLANG_ENGLISH_PHILIPPINES
: return "en_PH";
745 case SUBLANG_ENGLISH_INDONESIA
: return "en_ID";
746 case SUBLANG_ENGLISH_HONGKONG
: return "en_HK";
747 case SUBLANG_ENGLISH_INDIA
: return "en_IN";
748 case SUBLANG_ENGLISH_MALAYSIA
: return "en_MY";
749 case SUBLANG_ENGLISH_SINGAPORE
: return "en_SG";
752 case LANG_ESTONIAN
: return "et_EE";
753 case LANG_FAEROESE
: return "fo_FO";
754 case LANG_FARSI
: return "fa_IR";
755 case LANG_FINNISH
: return "fi_FI";
759 case SUBLANG_FRENCH
: return "fr_FR";
760 case SUBLANG_FRENCH_BELGIAN
: /* WALLOON */ return "fr_BE";
761 case SUBLANG_FRENCH_CANADIAN
: return "fr_CA";
762 case SUBLANG_FRENCH_SWISS
: return "fr_CH";
763 case SUBLANG_FRENCH_LUXEMBOURG
: return "fr_LU";
764 case SUBLANG_FRENCH_MONACO
: return "fr_MC";
765 case SUBLANG_FRENCH_WESTINDIES
: return "fr"; /* Caribbean? */
766 case SUBLANG_FRENCH_REUNION
: return "fr_RE";
767 case SUBLANG_FRENCH_CONGO
: return "fr_CG";
768 case SUBLANG_FRENCH_SENEGAL
: return "fr_SN";
769 case SUBLANG_FRENCH_CAMEROON
: return "fr_CM";
770 case SUBLANG_FRENCH_COTEDIVOIRE
: return "fr_CI";
771 case SUBLANG_FRENCH_MALI
: return "fr_ML";
772 case SUBLANG_FRENCH_MOROCCO
: return "fr_MA";
773 case SUBLANG_FRENCH_HAITI
: return "fr_HT";
776 case LANG_FRISIAN
: return "fy_NL";
777 case LANG_FULFULDE
: return "ful_NG";
781 case 0x01: /* SCOTTISH */ return "gd_GB";
782 case 0x02: /* IRISH */ return "ga_IE";
785 case LANG_GALICIAN
: return "gl_ES";
786 case LANG_GEORGIAN
: return "ka_GE";
790 case SUBLANG_GERMAN
: return "de_DE";
791 case SUBLANG_GERMAN_SWISS
: return "de_CH";
792 case SUBLANG_GERMAN_AUSTRIAN
: return "de_AT";
793 case SUBLANG_GERMAN_LUXEMBOURG
: return "de_LU";
794 case SUBLANG_GERMAN_LIECHTENSTEIN
: return "de_LI";
797 case LANG_GREEK
: return "el_GR";
798 case LANG_GUARANI
: return "gn_PY";
799 case LANG_GUJARATI
: return "gu_IN";
800 case LANG_HAUSA
: return "ha_NG";
802 /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
803 or Hawaii Creole English ("cpe_US", 600000 speakers)? */
805 case LANG_HEBREW
: return "he_IL";
806 case LANG_HINDI
: return "hi_IN";
807 case LANG_HUNGARIAN
: return "hu_HU";
808 case LANG_IBIBIO
: return "nic_NG";
809 case LANG_ICELANDIC
: return "is_IS";
810 case LANG_IGBO
: return "ibo_NG";
811 case LANG_INDONESIAN
: return "id_ID";
812 case LANG_INUKTITUT
: return "iu_CA";
816 case SUBLANG_ITALIAN
: return "it_IT";
817 case SUBLANG_ITALIAN_SWISS
: return "it_CH";
820 case LANG_JAPANESE
: return "ja_JP";
821 case LANG_KANNADA
: return "kn_IN";
822 case LANG_KANURI
: return "kau_NG";
826 case SUBLANG_DEFAULT
: return "ks_PK";
827 case SUBLANG_KASHMIRI_INDIA
: return "ks_IN";
830 case LANG_KAZAK
: return "kk_KZ";
832 /* FIXME: Adjust this when such locales appear on Unix. */
834 case LANG_KOREAN
: return "ko_KR";
835 case LANG_KYRGYZ
: return "ky_KG";
836 case LANG_LAO
: return "lo_LA";
837 case LANG_LATIN
: return "la_VA";
838 case LANG_LATVIAN
: return "lv_LV";
839 case LANG_LITHUANIAN
: return "lt_LT";
840 case LANG_MACEDONIAN
: return "mk_MK";
844 case SUBLANG_MALAY_MALAYSIA
: return "ms_MY";
845 case SUBLANG_MALAY_BRUNEI_DARUSSALAM
: return "ms_BN";
848 case LANG_MALAYALAM
: return "ml_IN";
849 case LANG_MALTESE
: return "mt_MT";
851 /* FIXME: Adjust this when such locales appear on Unix. */
853 case LANG_MARATHI
: return "mr_IN";
855 return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
859 case SUBLANG_DEFAULT
: return "ne_NP";
860 case SUBLANG_NEPALI_INDIA
: return "ne_IN";
866 case SUBLANG_NORWEGIAN_BOKMAL
: return "no_NO";
867 case SUBLANG_NORWEGIAN_NYNORSK
: return "nn_NO";
870 case LANG_ORIYA
: return "or_IN";
871 case LANG_OROMO
: return "om_ET";
872 case LANG_PAPIAMENTU
: return "pap_AN";
874 return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
875 case LANG_POLISH
: return "pl_PL";
876 case LANG_PORTUGUESE
:
879 case SUBLANG_PORTUGUESE
: return "pt_PT";
880 /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
881 Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
882 case SUBLANG_PORTUGUESE_BRAZILIAN
: return "pt_BR";
888 case SUBLANG_PUNJABI_INDIA
: return "pa_IN"; /* Gurmukhi script */
891 case LANG_RHAETO_ROMANCE
: return "rm_CH";
895 case SUBLANG_ROMANIAN_ROMANIA
: return "ro_RO";
899 return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD". */
900 case LANG_SAAMI
: /* actually Northern Sami */ return "se_NO";
901 case LANG_SANSKRIT
: return "sa_IN";
905 case SUBLANG_SINDHI_INDIA
: return "sd_IN";
906 case SUBLANG_SINDHI_PAKISTAN
: return "sd_PK";
909 case LANG_SINHALESE
: return "si_LK";
910 case LANG_SLOVAK
: return "sk_SK";
911 case LANG_SLOVENIAN
: return "sl_SI";
912 case LANG_SOMALI
: return "so_SO";
914 /* FIXME: Adjust this when such locales appear on Unix. */
919 case SUBLANG_SPANISH
: return "es_ES";
920 case SUBLANG_SPANISH_MEXICAN
: return "es_MX";
921 case SUBLANG_SPANISH_MODERN
:
922 return "es_ES@modern"; /* not seen on Unix */
923 case SUBLANG_SPANISH_GUATEMALA
: return "es_GT";
924 case SUBLANG_SPANISH_COSTA_RICA
: return "es_CR";
925 case SUBLANG_SPANISH_PANAMA
: return "es_PA";
926 case SUBLANG_SPANISH_DOMINICAN_REPUBLIC
: return "es_DO";
927 case SUBLANG_SPANISH_VENEZUELA
: return "es_VE";
928 case SUBLANG_SPANISH_COLOMBIA
: return "es_CO";
929 case SUBLANG_SPANISH_PERU
: return "es_PE";
930 case SUBLANG_SPANISH_ARGENTINA
: return "es_AR";
931 case SUBLANG_SPANISH_ECUADOR
: return "es_EC";
932 case SUBLANG_SPANISH_CHILE
: return "es_CL";
933 case SUBLANG_SPANISH_URUGUAY
: return "es_UY";
934 case SUBLANG_SPANISH_PARAGUAY
: return "es_PY";
935 case SUBLANG_SPANISH_BOLIVIA
: return "es_BO";
936 case SUBLANG_SPANISH_EL_SALVADOR
: return "es_SV";
937 case SUBLANG_SPANISH_HONDURAS
: return "es_HN";
938 case SUBLANG_SPANISH_NICARAGUA
: return "es_NI";
939 case SUBLANG_SPANISH_PUERTO_RICO
: return "es_PR";
942 case LANG_SUTU
: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
943 case LANG_SWAHILI
: return "sw_KE";
947 case SUBLANG_DEFAULT
: return "sv_SE";
948 case SUBLANG_SWEDISH_FINLAND
: return "sv_FI";
951 case LANG_SYRIAC
: return "syr_TR"; /* An extinct language. */
952 case LANG_TAGALOG
: return "tl_PH";
953 case LANG_TAJIK
: return "tg_TJ";
957 /* FIXME: Adjust this when Tamazight locales appear on Unix. */
958 case SUBLANG_TAMAZIGHT_ARABIC
: return "ber_MA@arabic";
959 case SUBLANG_TAMAZIGHT_LATIN
: return "ber_MA@latin";
963 return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
964 case LANG_TATAR
: return "tt_RU";
965 case LANG_TELUGU
: return "te_IN";
966 case LANG_THAI
: return "th_TH";
967 case LANG_TIBETAN
: return "bo_CN";
971 case SUBLANG_TIGRINYA_ETHIOPIA
: return "ti_ET";
972 case SUBLANG_TIGRINYA_ERITREA
: return "ti_ER";
975 case LANG_TSONGA
: return "ts_ZA";
976 case LANG_TSWANA
: return "tn_BW";
977 case LANG_TURKISH
: return "tr_TR";
978 case LANG_TURKMEN
: return "tk_TM";
979 case LANG_UKRAINIAN
: return "uk_UA";
983 case SUBLANG_URDU_PAKISTAN
: return "ur_PK";
984 case SUBLANG_URDU_INDIA
: return "ur_IN";
990 case SUBLANG_UZBEK_LATIN
: return "uz_UZ";
991 case SUBLANG_UZBEK_CYRILLIC
: return "uz_UZ@cyrillic";
995 /* FIXME: It's not clear whether Venda has the ISO 639-2 two-letter code
997 http://www.loc.gov/standards/iso639-2/englangn.html has it, but
998 http://lcweb.loc.gov/standards/iso639-2/codechanges.html doesn't, */
999 return "ven_ZA"; /* or "ve_ZA"? */
1000 case LANG_VIETNAMESE
: return "vi_VN";
1001 case LANG_WELSH
: return "cy_GB";
1002 case LANG_XHOSA
: return "xh_ZA";
1003 case LANG_YI
: return "sit_CN";
1004 case LANG_YIDDISH
: return "yi_IL";
1005 case LANG_YORUBA
: return "yo_NG";
1006 case LANG_ZULU
: return "zu_ZA";
1007 default: return "C";
1011 /* localname.c from gettext END. */
1015 /* Support functions. */
1017 static __inline__
uint32_t
1018 do_swap_u32 (uint32_t i
)
1020 return (i
<< 24) | ((i
& 0xff00) << 8) | ((i
>> 8) & 0xff00) | (i
>> 24);
1023 #define SWAPIT(flag, data) ((flag) ? do_swap_u32(data) : (data))
1026 /* We assume to have `unsigned long int' value with at least 32 bits. */
1027 #define HASHWORDBITS 32
1029 /* The so called `hashpjw' function by P.J. Weinberger
1030 [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
1031 1986, 1987 Bell Telephone Laboratories, Inc.] */
1032 static __inline__
unsigned long
1033 hash_string( const char *str_param
)
1035 unsigned long int hval
, g
;
1036 const char *str
= str_param
;
1039 while (*str
!= '\0')
1042 hval
+= (unsigned long int) *str
++;
1043 g
= hval
& ((unsigned long int) 0xf << (HASHWORDBITS
- 4));
1046 hval
^= g
>> (HASHWORDBITS
- 8);
1054 /* my_xstrdup (const char *s) */
1056 /* size_t n = strlen (s) + 1; */
1057 /* char *p = jnlib_malloc (n); */
1060 /* strcpy (p, s); */
1066 /* Generic message catalog and gettext stuff. */
1068 /* The magic number of the GNU message catalog format. */
1069 #define MAGIC 0x950412de
1070 #define MAGIC_SWAPPED 0xde120495
1072 /* Revision number of the currently used .mo (binary) file format. */
1073 #define MO_REVISION_NUMBER 0
1076 /* Header for binary .mo file format. */
1077 struct mo_file_header
1079 /* The magic number. */
1081 /* The revision number of the file format. */
1083 /* The number of strings pairs. */
1085 /* Offset of table with start offsets of original strings. */
1086 uint32_t orig_tab_offset
;
1087 /* Offset of table with start offsets of translation strings. */
1088 uint32_t trans_tab_offset
;
1089 /* Size of hashing table. */
1090 uint32_t hash_tab_size
;
1091 /* Offset of first hashing entry. */
1092 uint32_t hash_tab_offset
;
1098 /* Length of addressed string. */
1100 /* Offset of string in file. */
1105 struct overflow_space_s
1107 struct overflow_space_s
*next
;
1113 struct loaded_domain
1116 char *data_native
; /* Data mapped to the native version of the
1117 string. (Allocated along with DATA). */
1120 uint32_t *mapped
; /* 0 := Not mapped (original utf8).
1121 1 := Mapped to native encoding in overflow space.
1122 >=2 := Mapped to native encoding. The values
1123 gives the length of the mapped string.
1124 becuase the 0 is included and an empty
1125 string is not allowed we will enver get
1127 struct overflow_space_s
*overflow_space
;
1128 struct string_desc
*orig_tab
;
1129 struct string_desc
*trans_tab
;
1135 /* The domain we use. We only support one domain at this point. This
1136 is why this implementation can not be shared. Bindtextdomain and
1137 dgettext will simply cheat and always use this one domain. */
1138 static struct loaded_domain
*the_domain
;
1140 /* Global flag to switch gettext into an utf8 mode. */
1141 static int want_utf8
;
1145 /* Free the domain data. */
1147 free_domain (struct loaded_domain
*domain
)
1149 struct overflow_space_s
*os
, *os2
;
1151 jnlib_free (domain
->data
);
1152 jnlib_free (domain
->mapped
);
1153 for (os
= domain
->overflow_space
; os
; os
= os2
)
1158 jnlib_free (domain
);
1162 static struct loaded_domain
*
1163 load_domain (const char *filename
)
1168 struct mo_file_header
*data
= NULL
;
1169 struct loaded_domain
*domain
= NULL
;
1173 fp
= fopen (filename
, "rb");
1177 /* Determine the file size. */
1178 if (fstat (fileno (fp
), &st
)
1179 || (size
= (size_t) st
.st_size
) != st
.st_size
1180 || size
< sizeof (struct mo_file_header
))
1186 data
= (2*size
<= size
)? NULL
: jnlib_malloc (2*size
);
1194 read_ptr
= (char *) data
;
1197 long int nb
= fread (read_ptr
, 1, to_read
, fp
);
1207 while (to_read
> 0);
1210 /* Using the magic number we can test whether it really is a message
1212 if (data
->magic
!= MAGIC
&& data
->magic
!= MAGIC_SWAPPED
)
1214 /* The magic number is wrong: not a message catalog file. */
1219 domain
= jnlib_calloc (1, sizeof *domain
);
1225 domain
->data
= (char *) data
;
1226 domain
->data_native
= (char *) data
+ size
;
1227 domain
->must_swap
= data
->magic
!= MAGIC
;
1229 /* Fill in the information about the available tables. */
1230 switch (SWAPIT (domain
->must_swap
, data
->revision
))
1232 case MO_REVISION_NUMBER
:
1233 domain
->nstrings
= SWAPIT (domain
->must_swap
, data
->nstrings
);
1234 domain
->orig_tab
= (struct string_desc
*)
1235 ((char *) data
+ SWAPIT (domain
->must_swap
, data
->orig_tab_offset
));
1236 domain
->trans_tab
= (struct string_desc
*)
1237 ((char *) data
+ SWAPIT (domain
->must_swap
, data
->trans_tab_offset
));
1238 domain
->hash_size
= SWAPIT (domain
->must_swap
, data
->hash_tab_size
);
1239 domain
->hash_tab
= (uint32_t *)
1240 ((char *) data
+ SWAPIT (domain
->must_swap
, data
->hash_tab_offset
));
1244 /* This is an invalid revision. */
1246 jnlib_free (domain
);
1250 /* Allocate an array to keep track of code page mappings. */
1251 domain
->mapped
= jnlib_calloc (domain
->nstrings
, sizeof *domain
->mapped
);
1252 if (!domain
->mapped
)
1255 jnlib_free (domain
);
1263 /* Return a malloced wide char string from an UTF-8 encoded input
1264 string STRING. Caller must free this value. On failure returns
1265 NULL. The result of calling this function with STRING set to NULL
1268 utf8_to_wchar (const char *string
, size_t length
, size_t *retlen
)
1274 n
= MultiByteToWideChar (CP_UTF8
, 0, string
, length
, NULL
, 0);
1275 if (n
< 0 || (n
+1) <= 0)
1278 nbytes
= (size_t)(n
+1) * sizeof(*result
);
1279 if (nbytes
/ sizeof(*result
) != (n
+1))
1284 result
= jnlib_malloc (nbytes
);
1288 n
= MultiByteToWideChar (CP_UTF8
, 0, string
, length
, result
, n
);
1291 jnlib_free (result
);
1299 /* Return a malloced string encoded in UTF-8 from the wide char input
1300 string STRING. Caller must free this value. On failure returns
1301 NULL. The result of calling this function with STRING set to NULL
1304 wchar_to_native (const wchar_t *string
, size_t length
, size_t *retlen
)
1309 n
= WideCharToMultiByte (CP_ACP
, 0, string
, length
, NULL
, 0, NULL
, NULL
);
1310 if (n
< 0 || (n
+1) <= 0)
1313 result
= jnlib_malloc (n
+1);
1317 n
= WideCharToMultiByte (CP_ACP
, 0, string
, length
, result
, n
, NULL
, NULL
);
1320 jnlib_free (result
);
1328 /* Convert UTF8 to the native codepage. Caller must free the return value. */
1330 utf8_to_native (const char *string
, size_t length
, size_t *retlen
)
1336 wstring
= utf8_to_wchar (string
, length
, &newlen
);
1339 result
= wchar_to_native (wstring
, newlen
, &newlen
);
1340 jnlib_free (wstring
);
1344 *retlen
= result
? newlen
: 0;
1351 /* Specify that the DOMAINNAME message catalog will be found
1352 in DIRNAME rather than in the system locale data base. */
1354 bindtextdomain (const char *domainname
, const char *dirname
)
1356 struct loaded_domain
*domain
= NULL
;
1357 const char *catval_full
;
1361 /* DOMAINNAME is ignored. We only support one domain. */
1363 /* DIRNAME is "$INSTALLDIR\share\locale". */
1365 /* First find out the category value. */
1367 catval_full
= my_nl_locale_name ("LC_MESSAGES");
1369 /* Normally, we would have to loop over all returned locales, and
1370 search for the right file. See gettext intl/dcigettext.c for all
1371 the gory details. Here, we only support the basic category, and
1372 ignore everything else. */
1377 catval
= jnlib_malloc (strlen (catval_full
) + 1);
1380 strcpy (catval
, catval_full
);
1381 p
= strchr (catval
, '_');
1389 /* Now build the filename string. The complete filename is this:
1390 DIRNAME + \ + CATVAL + \LC_MESSAGES\ + DOMAINNAME + .mo */
1392 int len
= strlen (dirname
) + 1 + strlen (catval
) + 13
1393 + strlen (domainname
) + 3 + 1;
1396 fname
= jnlib_malloc (len
);
1399 jnlib_free (catval
);
1404 strcpy (p
, dirname
);
1405 p
+= strlen (dirname
);
1408 p
+= strlen (catval
);
1409 strcpy (p
, "\\LC_MESSAGES\\");
1411 strcpy (p
, domainname
);
1412 p
+= strlen (domainname
);
1416 domain
= load_domain (fname
);
1417 jnlib_free (catval
);
1420 /* We should not be invoked twice, but this is how you would do
1421 it if it happened. */
1423 free_domain (the_domain
);
1424 the_domain
= domain
;
1426 /* For historic reasons we are not allowed to return a const char*. */
1427 return (char*)dirname
;
1434 get_plural (const char *data
, size_t datalen
, unsigned long nplural
)
1439 /* We only support the Germanic rule. */
1440 idx
= (nplural
== 1? 0 : 1);
1444 p
= strchr (data
, 0) + 1;
1445 if (p
>= data
+datalen
)
1446 return "ERROR in GETTEXT (bad plural entry)";
1447 datalen
-= (p
-data
);
1455 get_string (struct loaded_domain
*domain
, uint32_t idx
,
1456 int use_plural
, unsigned long nplural
)
1458 struct overflow_space_s
*os
;
1459 const char *trans
; /* Pointer to the translated entry. */
1460 size_t translen
; /* Length of that entry. */
1464 trans
= (domain
->data
1465 + SWAPIT(domain
->must_swap
, domain
->trans_tab
[idx
].offset
));
1466 translen
= SWAPIT(domain
->must_swap
, domain
->trans_tab
[idx
].length
);
1468 else if (!domain
->mapped
[idx
])
1470 /* Not yet mapped. Map from utf-8 to native encoding now. */
1472 size_t plen_utf8
, buflen
;
1475 p_utf8
= (domain
->data
1476 + SWAPIT(domain
->must_swap
, domain
->trans_tab
[idx
].offset
));
1477 plen_utf8
= SWAPIT(domain
->must_swap
, domain
->trans_tab
[idx
].length
);
1479 buf
= utf8_to_native (p_utf8
, plen_utf8
, &buflen
);
1482 trans
= "ERROR in GETTEXT MALLOC";
1485 else if (buflen
<= plen_utf8
&& buflen
> 1)
1487 /* Copy into the DATA_NATIVE area. */
1490 p_tmp
= (domain
->data_native
1491 + SWAPIT(domain
->must_swap
, domain
->trans_tab
[idx
].offset
));
1492 memcpy (p_tmp
, buf
, buflen
);
1493 domain
->mapped
[idx
] = buflen
;
1499 /* There is not enough space for the translation (or for
1500 whatever reason an empry string is used): Store it in the
1501 overflow_space and mark that in the mapped array.
1502 Because UTF-8 strings are in general longer than the
1503 Windows 2 byte encodings, we expect that this won't
1504 happen too often (if at all) and thus we use a linked
1505 list to manage this space. */
1506 os
= jnlib_malloc (sizeof *os
+ buflen
);
1510 memcpy (os
->d
, buf
, buflen
);
1511 os
->length
= buflen
;
1512 os
->next
= domain
->overflow_space
;
1513 domain
->overflow_space
= os
;
1514 domain
->mapped
[idx
] = 1;
1516 translen
= os
->length
;
1520 trans
= "ERROR in GETTEXT MALLOC";
1526 else if (domain
->mapped
[idx
] == 1)
1528 /* The translated string is in the overflow_space. */
1529 for (os
=domain
->overflow_space
; os
; os
= os
->next
)
1535 translen
= os
->length
;
1539 trans
= "ERROR in GETTEXT (overflow space)\n";
1545 trans
= (domain
->data_native
1546 + SWAPIT(domain
->must_swap
, domain
->trans_tab
[idx
].offset
));
1547 translen
= domain
->mapped
[idx
];
1550 if (use_plural
&& translen
)
1551 return get_plural (trans
, translen
, nplural
);
1558 do_gettext (const char *msgid
, const char *msgid2
, unsigned long nplural
)
1560 struct loaded_domain
*domain
;
1561 uint32_t top
, bottom
, nstr
;
1563 if (!(domain
= the_domain
))
1566 /* First try to use the hash table. */
1567 if (domain
->hash_size
> 2 && domain
->hash_tab
)
1569 /* Use the hashing table. */
1570 uint32_t len
= strlen (msgid
);
1571 uint32_t hash_val
= hash_string (msgid
);
1572 uint32_t idx
= hash_val
% domain
->hash_size
;
1573 uint32_t incr
= 1 + (hash_val
% (domain
->hash_size
- 2));
1575 while ( (nstr
= SWAPIT (domain
->must_swap
, domain
->hash_tab
[idx
])) )
1578 if (nstr
< domain
->nstrings
1579 && SWAPIT(domain
->must_swap
,
1580 domain
->orig_tab
[nstr
].length
) >= len
1581 && !strcmp (msgid
, (domain
->data
1582 + SWAPIT(domain
->must_swap
,
1583 domain
->orig_tab
[nstr
].offset
))))
1585 return get_string (domain
, nstr
, !!msgid2
, nplural
);
1588 if (idx
>= domain
->hash_size
- incr
)
1589 idx
-= domain
->hash_size
- incr
;
1595 /* Now we try the default method: binary search in the sorted array
1598 top
= domain
->nstrings
;
1599 while (bottom
< top
)
1603 nstr
= (bottom
+ top
) / 2;
1604 cmp_val
= strcmp (msgid
, (domain
->data
1605 + SWAPIT(domain
->must_swap
,
1606 domain
->orig_tab
[nstr
].offset
)));
1609 else if (cmp_val
> 0)
1612 return get_string (domain
, nstr
, !!msgid2
, nplural
);
1616 /* We use the standard Germanic rule if plural has been requested. */
1617 return msgid2
? (nplural
== 1? msgid
: msgid2
) : msgid
;
1622 textdomain (const char *domainname
)
1624 /* For now, support only one domain. */
1625 return (char*)domainname
;
1630 gettext (const char *msgid
)
1632 return do_gettext (msgid
, NULL
, 0);
1636 dgettext (const char *domainname
, const char *msgid
)
1640 /* For now, support only one domain. */
1641 return (char*)do_gettext (msgid
, NULL
, 0);
1645 ngettext (const char *msgid1
, const char *msgid2
, unsigned long int n
)
1647 /* We use the simple Germanic plural rule. */
1648 return do_gettext (msgid1
, msgid2
, n
);
1652 /* Return the locale name as used by gettext. The return value will
1655 gettext_localename (void)
1659 s
= my_nl_locale_name ("LC_MESSAGES");
1664 gettext_select_utf8 (int value
)
1672 main (int argc
, char **argv
)
1674 const char atext1
[] =
1675 "Warning: You have entered an insecure passphrase.%%0A"
1676 "A passphrase should be at least %u character long.";
1677 const char atext2
[] =
1678 "Warning: You have entered an insecure passphrase.%%0A"
1679 "A passphrase should be at least %u characters long.";
1687 bindtextdomain ("gnupg2", "c:/programme/gnu/gnupg/share/locale");
1689 printf ("locale is `%s'\n", gettext_localename ());
1690 fputs ("text with N=1:\n", stdout
);
1691 fputs (ngettext (atext1
, atext2
, 1), stdout
);
1692 fputs ("\n\ntext with N=2:\n", stdout
);
1693 fputs (ngettext (atext1
, atext2
, 2), stdout
);
1694 fputs ("\nready\n", stdout
);
1700 * compile-command: "i586-mingw32msvc-gcc -DTEST -Wall -g w32-gettext.c"