1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/intl.cpp 
   3 // Purpose:     Internationalization and localisation for wxWidgets 
   4 // Author:      Vadim Zeitlin 
   5 // Modified by: Michael N. Filippov <michael@idisys.iae.nsk.su> 
   6 //              (2003/09/30 - PluralForms support) 
   9 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 
  10 // Licence:     wxWindows licence 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 // ============================================================================ 
  15 // ============================================================================ 
  17 // ---------------------------------------------------------------------------- 
  19 // ---------------------------------------------------------------------------- 
  21 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  22     #pragma implementation "intl.h" 
  25 #if defined(__BORLAND__) && !defined(__WXDEBUG__) 
  26     // There's a bug in Borland's compiler that breaks wxLocale with -O2, 
  27     // so make sure that flag is not used for this file: 
  32 // The following define is needed by Innotek's libc to 
  33 // make the definition of struct localeconv available. 
  34 #define __INTERNAL_DEFS 
  37 // For compilers that support precompilation, includes "wx.h". 
  38 #include "wx/wxprec.h" 
  54 #ifdef HAVE_LANGINFO_H 
  60     #include "wx/string.h" 
  65     #include "wx/dynarray.h" 
  69     #include "wx/msw/private.h" 
  70 #elif defined(__UNIX_LIKE__) 
  71     #include "wx/fontmap.h"         // for CharsetToEncoding() 
  75 #include "wx/filename.h" 
  76 #include "wx/tokenzr.h" 
  77 #include "wx/module.h" 
  78 #include "wx/fontmap.h" 
  79 #include "wx/encconv.h" 
  80 #include "wx/hashmap.h" 
  81 #include "wx/ptr_scpd.h" 
  83 #include "wx/apptrait.h" 
  85 #if defined(__WXMAC__) 
  86   #include  "wx/mac/private.h"  // includes mac headers 
  89 // ---------------------------------------------------------------------------- 
  91 // ---------------------------------------------------------------------------- 
  93 // this should *not* be wxChar, this type must have exactly 8 bits! 
  94 typedef wxUint8 size_t8
; 
  95 typedef wxUint32 size_t32
; 
  97 // ---------------------------------------------------------------------------- 
  99 // ---------------------------------------------------------------------------- 
 101 // magic number identifying the .mo format file 
 102 const size_t32 MSGCATALOG_MAGIC    
= 0x950412de; 
 103 const size_t32 MSGCATALOG_MAGIC_SW 
= 0xde120495; 
 105 // the constants describing the format of lang_LANG locale string 
 106 static const size_t LEN_LANG 
= 2; 
 107 static const size_t LEN_SUBLANG 
= 2; 
 108 static const size_t LEN_FULL 
= LEN_LANG 
+ 1 + LEN_SUBLANG
; // 1 for '_' 
 110 // ---------------------------------------------------------------------------- 
 112 // ---------------------------------------------------------------------------- 
 116 // small class to suppress the translation erros until exit from current scope 
 120     NoTransErr() { ms_suppressCount
++; } 
 121    ~NoTransErr() { ms_suppressCount
--;  } 
 123    static bool Suppress() { return ms_suppressCount 
> 0; } 
 126    static size_t ms_suppressCount
; 
 129 size_t NoTransErr::ms_suppressCount 
= 0; 
 140 #endif // Debug/!Debug 
 142 static wxLocale 
*wxSetLocale(wxLocale 
*pLocale
); 
 144 // helper functions of GetSystemLanguage() 
 147 // get just the language part 
 148 static inline wxString 
ExtractLang(const wxString
& langFull
) 
 150     return langFull
.Left(LEN_LANG
); 
 153 // get everything else (including the leading '_') 
 154 static inline wxString 
ExtractNotLang(const wxString
& langFull
) 
 156     return langFull
.Mid(LEN_LANG
); 
 162 // ---------------------------------------------------------------------------- 
 163 // Plural forms parser 
 164 // ---------------------------------------------------------------------------- 
 170     LogicalOrExpression '?' Expression ':' Expression 
 174     LogicalAndExpression "||" LogicalOrExpression   // to (a || b) || c 
 177 LogicalAndExpression: 
 178     EqualityExpression "&&" LogicalAndExpression    // to (a && b) && c 
 182     RelationalExpression "==" RelationalExperession 
 183     RelationalExpression "!=" RelationalExperession 
 186 RelationalExpression: 
 187     MultiplicativeExpression '>' MultiplicativeExpression 
 188     MultiplicativeExpression '<' MultiplicativeExpression 
 189     MultiplicativeExpression ">=" MultiplicativeExpression 
 190     MultiplicativeExpression "<=" MultiplicativeExpression 
 191     MultiplicativeExpression 
 193 MultiplicativeExpression: 
 194     PmExpression '%' PmExpression 
 203 class wxPluralFormsToken
 
 208         T_ERROR
, T_EOF
, T_NUMBER
, T_N
, T_PLURAL
, T_NPLURALS
, T_EQUAL
, T_ASSIGN
, 
 209         T_GREATER
, T_GREATER_OR_EQUAL
, T_LESS
, T_LESS_OR_EQUAL
, 
 210         T_REMINDER
, T_NOT_EQUAL
, 
 211         T_LOGICAL_AND
, T_LOGICAL_OR
, T_QUESTION
, T_COLON
, T_SEMICOLON
, 
 212         T_LEFT_BRACKET
, T_RIGHT_BRACKET
 
 214     Type 
type() const { return m_type
; } 
 215     void setType(Type type
) { m_type 
= type
; } 
 218     Number 
number() const { return m_number
; } 
 219     void setNumber(Number num
) { m_number 
= num
; } 
 226 class wxPluralFormsScanner
 
 229     wxPluralFormsScanner(const char* s
); 
 230     const wxPluralFormsToken
& token() const { return m_token
; } 
 231     bool nextToken();  // returns false if error 
 234     wxPluralFormsToken m_token
; 
 237 wxPluralFormsScanner::wxPluralFormsScanner(const char* s
) : m_s(s
) 
 242 bool wxPluralFormsScanner::nextToken() 
 244     wxPluralFormsToken::Type type 
= wxPluralFormsToken::T_ERROR
; 
 245     while (isspace(*m_s
)) 
 251         type 
= wxPluralFormsToken::T_EOF
; 
 253     else if (isdigit(*m_s
)) 
 255         wxPluralFormsToken::Number number 
= *m_s
++ - '0'; 
 256         while (isdigit(*m_s
)) 
 258             number 
= number 
* 10 + (*m_s
++ - '0'); 
 260         m_token
.setNumber(number
); 
 261         type 
= wxPluralFormsToken::T_NUMBER
; 
 263     else if (isalpha(*m_s
)) 
 265         const char* begin 
= m_s
++; 
 266         while (isalnum(*m_s
)) 
 270         size_t size 
= m_s 
- begin
; 
 271         if (size 
== 1 && memcmp(begin
, "n", size
) == 0) 
 273             type 
= wxPluralFormsToken::T_N
; 
 275         else if (size 
== 6 && memcmp(begin
, "plural", size
) == 0) 
 277             type 
= wxPluralFormsToken::T_PLURAL
; 
 279         else if (size 
== 8 && memcmp(begin
, "nplurals", size
) == 0) 
 281             type 
= wxPluralFormsToken::T_NPLURALS
; 
 284     else if (*m_s 
== '=') 
 290             type 
= wxPluralFormsToken::T_EQUAL
; 
 294             type 
= wxPluralFormsToken::T_ASSIGN
; 
 297     else if (*m_s 
== '>') 
 303             type 
= wxPluralFormsToken::T_GREATER_OR_EQUAL
; 
 307             type 
= wxPluralFormsToken::T_GREATER
; 
 310     else if (*m_s 
== '<') 
 316             type 
= wxPluralFormsToken::T_LESS_OR_EQUAL
; 
 320             type 
= wxPluralFormsToken::T_LESS
; 
 323     else if (*m_s 
== '%') 
 326         type 
= wxPluralFormsToken::T_REMINDER
; 
 328     else if (*m_s 
== '!' && m_s
[1] == '=') 
 331         type 
= wxPluralFormsToken::T_NOT_EQUAL
; 
 333     else if (*m_s 
== '&' && m_s
[1] == '&') 
 336         type 
= wxPluralFormsToken::T_LOGICAL_AND
; 
 338     else if (*m_s 
== '|' && m_s
[1] == '|') 
 341         type 
= wxPluralFormsToken::T_LOGICAL_OR
; 
 343     else if (*m_s 
== '?') 
 346         type 
= wxPluralFormsToken::T_QUESTION
; 
 348     else if (*m_s 
== ':') 
 351         type 
= wxPluralFormsToken::T_COLON
; 
 352     } else if (*m_s 
== ';') { 
 354         type 
= wxPluralFormsToken::T_SEMICOLON
; 
 356     else if (*m_s 
== '(') 
 359         type 
= wxPluralFormsToken::T_LEFT_BRACKET
; 
 361     else if (*m_s 
== ')') 
 364         type 
= wxPluralFormsToken::T_RIGHT_BRACKET
; 
 366     m_token
.setType(type
); 
 367     return type 
!= wxPluralFormsToken::T_ERROR
; 
 370 class wxPluralFormsNode
; 
 372 // NB: Can't use wxDEFINE_SCOPED_PTR_TYPE because wxPluralFormsNode is not 
 373 //     fully defined yet: 
 374 class wxPluralFormsNodePtr
 
 377     wxPluralFormsNodePtr(wxPluralFormsNode 
*p 
= NULL
) : m_p(p
) {} 
 378     ~wxPluralFormsNodePtr(); 
 379     wxPluralFormsNode
& operator*() const { return *m_p
; } 
 380     wxPluralFormsNode
* operator->() const { return m_p
; } 
 381     wxPluralFormsNode
* get() const { return m_p
; } 
 382     wxPluralFormsNode
* release(); 
 383     void reset(wxPluralFormsNode 
*p
); 
 386     wxPluralFormsNode 
*m_p
; 
 389 class wxPluralFormsNode
 
 392     wxPluralFormsNode(const wxPluralFormsToken
& token
) : m_token(token
) {} 
 393     const wxPluralFormsToken
& token() const { return m_token
; } 
 394     const wxPluralFormsNode
* node(size_t i
) const 
 395         { return m_nodes
[i
].get(); } 
 396     void setNode(size_t i
, wxPluralFormsNode
* n
); 
 397     wxPluralFormsNode
* releaseNode(size_t i
); 
 398     wxPluralFormsToken::Number 
evaluate(wxPluralFormsToken::Number n
) const; 
 401     wxPluralFormsToken m_token
; 
 402     wxPluralFormsNodePtr m_nodes
[3]; 
 405 wxPluralFormsNodePtr::~wxPluralFormsNodePtr() 
 409 wxPluralFormsNode
* wxPluralFormsNodePtr::release() 
 411     wxPluralFormsNode 
*p 
= m_p
; 
 415 void wxPluralFormsNodePtr::reset(wxPluralFormsNode 
*p
) 
 425 void wxPluralFormsNode::setNode(size_t i
, wxPluralFormsNode
* n
) 
 430 wxPluralFormsNode
*  wxPluralFormsNode::releaseNode(size_t i
) 
 432     return m_nodes
[i
].release(); 
 435 wxPluralFormsToken::Number
 
 436 wxPluralFormsNode::evaluate(wxPluralFormsToken::Number n
) const 
 438     switch (token().type()) 
 441         case wxPluralFormsToken::T_NUMBER
: 
 442             return token().number(); 
 443         case wxPluralFormsToken::T_N
: 
 446         case wxPluralFormsToken::T_EQUAL
: 
 447             return node(0)->evaluate(n
) == node(1)->evaluate(n
); 
 448         case wxPluralFormsToken::T_NOT_EQUAL
: 
 449             return node(0)->evaluate(n
) != node(1)->evaluate(n
); 
 450         case wxPluralFormsToken::T_GREATER
: 
 451             return node(0)->evaluate(n
) > node(1)->evaluate(n
); 
 452         case wxPluralFormsToken::T_GREATER_OR_EQUAL
: 
 453             return node(0)->evaluate(n
) >= node(1)->evaluate(n
); 
 454         case wxPluralFormsToken::T_LESS
: 
 455             return node(0)->evaluate(n
) < node(1)->evaluate(n
); 
 456         case wxPluralFormsToken::T_LESS_OR_EQUAL
: 
 457             return node(0)->evaluate(n
) <= node(1)->evaluate(n
); 
 458         case wxPluralFormsToken::T_REMINDER
: 
 460                 wxPluralFormsToken::Number number 
= node(1)->evaluate(n
); 
 463                     return node(0)->evaluate(n
) % number
; 
 470         case wxPluralFormsToken::T_LOGICAL_AND
: 
 471             return node(0)->evaluate(n
) && node(1)->evaluate(n
); 
 472         case wxPluralFormsToken::T_LOGICAL_OR
: 
 473             return node(0)->evaluate(n
) || node(1)->evaluate(n
); 
 475         case wxPluralFormsToken::T_QUESTION
: 
 476             return node(0)->evaluate(n
) 
 477                 ? node(1)->evaluate(n
) 
 478                 : node(2)->evaluate(n
); 
 485 class wxPluralFormsCalculator
 
 488     wxPluralFormsCalculator() : m_nplurals(0), m_plural(0) {} 
 490     // input: number, returns msgstr index 
 491     int evaluate(int n
) const; 
 493     // input: text after "Plural-Forms:" (e.g. "nplurals=2; plural=(n != 1);"), 
 494     // if s == 0, creates default handler 
 495     // returns 0 if error 
 496     static wxPluralFormsCalculator
* make(const char* s 
= 0); 
 498     ~wxPluralFormsCalculator() {} 
 500     void  init(wxPluralFormsToken::Number nplurals
, wxPluralFormsNode
* plural
); 
 503     wxPluralFormsToken::Number m_nplurals
; 
 504     wxPluralFormsNodePtr m_plural
; 
 507 wxDEFINE_SCOPED_PTR_TYPE(wxPluralFormsCalculator
); 
 509 void wxPluralFormsCalculator::init(wxPluralFormsToken::Number nplurals
, 
 510                                    wxPluralFormsNode
* plural
) 
 512     m_nplurals 
= nplurals
; 
 513     m_plural
.reset(plural
); 
 516 int wxPluralFormsCalculator::evaluate(int n
) const 
 518     if (m_plural
.get() == 0) 
 522     wxPluralFormsToken::Number number 
= m_plural
->evaluate(n
); 
 523     if (number 
< 0 || number 
> m_nplurals
) 
 531 class wxPluralFormsParser
 
 534     wxPluralFormsParser(wxPluralFormsScanner
& scanner
) : m_scanner(scanner
) {} 
 535     bool parse(wxPluralFormsCalculator
& rCalculator
); 
 538     wxPluralFormsNode
* parsePlural(); 
 539     // stops at T_SEMICOLON, returns 0 if error 
 540     wxPluralFormsScanner
& m_scanner
; 
 541     const wxPluralFormsToken
& token() const; 
 544     wxPluralFormsNode
* expression(); 
 545     wxPluralFormsNode
* logicalOrExpression(); 
 546     wxPluralFormsNode
* logicalAndExpression(); 
 547     wxPluralFormsNode
* equalityExpression(); 
 548     wxPluralFormsNode
* multiplicativeExpression(); 
 549     wxPluralFormsNode
* relationalExpression(); 
 550     wxPluralFormsNode
* pmExpression(); 
 553 bool wxPluralFormsParser::parse(wxPluralFormsCalculator
& rCalculator
) 
 555     if (token().type() != wxPluralFormsToken::T_NPLURALS
) 
 559     if (token().type() != wxPluralFormsToken::T_ASSIGN
) 
 563     if (token().type() != wxPluralFormsToken::T_NUMBER
) 
 565     wxPluralFormsToken::Number nplurals 
= token().number(); 
 568     if (token().type() != wxPluralFormsToken::T_SEMICOLON
) 
 572     if (token().type() != wxPluralFormsToken::T_PLURAL
) 
 576     if (token().type() != wxPluralFormsToken::T_ASSIGN
) 
 580     wxPluralFormsNode
* plural 
= parsePlural(); 
 583     if (token().type() != wxPluralFormsToken::T_SEMICOLON
) 
 587     if (token().type() != wxPluralFormsToken::T_EOF
) 
 589     rCalculator
.init(nplurals
, plural
); 
 593 wxPluralFormsNode
* wxPluralFormsParser::parsePlural() 
 595     wxPluralFormsNode
* p 
= expression(); 
 600     wxPluralFormsNodePtr 
n(p
); 
 601     if (token().type() != wxPluralFormsToken::T_SEMICOLON
) 
 608 const wxPluralFormsToken
& wxPluralFormsParser::token() const 
 610     return m_scanner
.token(); 
 613 bool wxPluralFormsParser::nextToken() 
 615     if (!m_scanner
.nextToken()) 
 620 wxPluralFormsNode
* wxPluralFormsParser::expression() 
 622     wxPluralFormsNode
* p 
= logicalOrExpression(); 
 625     wxPluralFormsNodePtr 
n(p
); 
 626     if (token().type() == wxPluralFormsToken::T_QUESTION
) 
 628         wxPluralFormsNodePtr 
qn(new wxPluralFormsNode(token())); 
 639         if (token().type() != wxPluralFormsToken::T_COLON
) 
 653         qn
->setNode(0, n
.release()); 
 659 wxPluralFormsNode
*wxPluralFormsParser::logicalOrExpression() 
 661     wxPluralFormsNode
* p 
= logicalAndExpression(); 
 664     wxPluralFormsNodePtr 
ln(p
); 
 665     if (token().type() == wxPluralFormsToken::T_LOGICAL_OR
) 
 667         wxPluralFormsNodePtr 
un(new wxPluralFormsNode(token())); 
 672         p 
= logicalOrExpression(); 
 677         wxPluralFormsNodePtr 
rn(p
);    // right 
 678         if (rn
->token().type() == wxPluralFormsToken::T_LOGICAL_OR
) 
 680             // see logicalAndExpression comment 
 681             un
->setNode(0, ln
.release()); 
 682             un
->setNode(1, rn
->releaseNode(0)); 
 683             rn
->setNode(0, un
.release()); 
 688         un
->setNode(0, ln
.release()); 
 689         un
->setNode(1, rn
.release()); 
 695 wxPluralFormsNode
* wxPluralFormsParser::logicalAndExpression() 
 697     wxPluralFormsNode
* p 
= equalityExpression(); 
 700     wxPluralFormsNodePtr 
ln(p
);   // left 
 701     if (token().type() == wxPluralFormsToken::T_LOGICAL_AND
) 
 703         wxPluralFormsNodePtr 
un(new wxPluralFormsNode(token()));  // up 
 708         p 
= logicalAndExpression(); 
 713         wxPluralFormsNodePtr 
rn(p
);    // right 
 714         if (rn
->token().type() == wxPluralFormsToken::T_LOGICAL_AND
) 
 716 // transform 1 && (2 && 3) -> (1 && 2) && 3 
 720             un
->setNode(0, ln
.release()); 
 721             un
->setNode(1, rn
->releaseNode(0)); 
 722             rn
->setNode(0, un
.release()); 
 726         un
->setNode(0, ln
.release()); 
 727         un
->setNode(1, rn
.release()); 
 733 wxPluralFormsNode
* wxPluralFormsParser::equalityExpression() 
 735     wxPluralFormsNode
* p 
= relationalExpression(); 
 738     wxPluralFormsNodePtr 
n(p
); 
 739     if (token().type() == wxPluralFormsToken::T_EQUAL
 
 740         || token().type() == wxPluralFormsToken::T_NOT_EQUAL
) 
 742         wxPluralFormsNodePtr 
qn(new wxPluralFormsNode(token())); 
 747         p 
= relationalExpression(); 
 753         qn
->setNode(0, n
.release()); 
 759 wxPluralFormsNode
* wxPluralFormsParser::relationalExpression() 
 761     wxPluralFormsNode
* p 
= multiplicativeExpression(); 
 764     wxPluralFormsNodePtr 
n(p
); 
 765     if (token().type() == wxPluralFormsToken::T_GREATER
 
 766             || token().type() == wxPluralFormsToken::T_LESS
 
 767             || token().type() == wxPluralFormsToken::T_GREATER_OR_EQUAL
 
 768             || token().type() == wxPluralFormsToken::T_LESS_OR_EQUAL
) 
 770         wxPluralFormsNodePtr 
qn(new wxPluralFormsNode(token())); 
 775         p 
= multiplicativeExpression(); 
 781         qn
->setNode(0, n
.release()); 
 787 wxPluralFormsNode
* wxPluralFormsParser::multiplicativeExpression() 
 789     wxPluralFormsNode
* p 
= pmExpression(); 
 792     wxPluralFormsNodePtr 
n(p
); 
 793     if (token().type() == wxPluralFormsToken::T_REMINDER
) 
 795         wxPluralFormsNodePtr 
qn(new wxPluralFormsNode(token())); 
 806         qn
->setNode(0, n
.release()); 
 812 wxPluralFormsNode
* wxPluralFormsParser::pmExpression() 
 814     wxPluralFormsNodePtr n
; 
 815     if (token().type() == wxPluralFormsToken::T_N
 
 816         || token().type() == wxPluralFormsToken::T_NUMBER
) 
 818         n
.reset(new wxPluralFormsNode(token())); 
 824     else if (token().type() == wxPluralFormsToken::T_LEFT_BRACKET
) { 
 829         wxPluralFormsNode
* p 
= expression(); 
 835         if (token().type() != wxPluralFormsToken::T_RIGHT_BRACKET
) 
 851 wxPluralFormsCalculator
* wxPluralFormsCalculator::make(const char* s
) 
 853     wxPluralFormsCalculatorPtr 
calculator(new wxPluralFormsCalculator
); 
 856         wxPluralFormsScanner 
scanner(s
); 
 857         wxPluralFormsParser 
p(scanner
); 
 858         if (!p
.parse(*calculator
)) 
 863     return calculator
.release(); 
 869 // ---------------------------------------------------------------------------- 
 870 // wxMsgCatalogFile corresponds to one disk-file message catalog. 
 872 // This is a "low-level" class and is used only by wxMsgCatalog 
 873 // ---------------------------------------------------------------------------- 
 875 WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString
, wxMessagesHash
); 
 877 class wxMsgCatalogFile
 
 884     // load the catalog from disk (szDirPrefix corresponds to language) 
 885     bool Load(const wxChar 
*szDirPrefix
, const wxChar 
*szName
, 
 886               wxPluralFormsCalculatorPtr
& rPluralFormsCalculator
); 
 888     // fills the hash with string-translation pairs 
 889     void FillHash(wxMessagesHash
& hash
, const wxString
& msgIdCharset
, 
 890                   bool convertEncoding
) const; 
 893     // this implementation is binary compatible with GNU gettext() version 0.10 
 895     // an entry in the string table 
 896     struct wxMsgTableEntry
 
 898       size_t32   nLen
;           // length of the string 
 899       size_t32   ofsString
;      // pointer to the string 
 902     // header of a .mo file 
 903     struct wxMsgCatalogHeader
 
 905       size_t32  magic
,          // offset +00:  magic id 
 906                 revision
,       //        +04:  revision 
 907                 numStrings
;     //        +08:  number of strings in the file 
 908       size_t32  ofsOrigTable
,   //        +0C:  start of original string table 
 909                 ofsTransTable
;  //        +10:  start of translated string table 
 910       size_t32  nHashSize
,      //        +14:  hash table size 
 911                 ofsHashTable
;   //        +18:  offset of hash table start 
 914     // all data is stored here, NULL if no data loaded 
 917     // amount of memory pointed to by m_pData. 
 921     size_t32          m_numStrings
;   // number of strings in this domain 
 922     wxMsgTableEntry  
*m_pOrigTable
,   // pointer to original   strings 
 923                      *m_pTransTable
;  //            translated 
 927     // swap the 2 halves of 32 bit integer if needed 
 928     size_t32 
Swap(size_t32 ui
) const 
 930           return m_bSwapped 
? (ui 
<< 24) | ((ui 
& 0xff00) << 8) | 
 931                               ((ui 
>> 8) & 0xff00) | (ui 
>> 24) 
 935     const char *StringAtOfs(wxMsgTableEntry 
*pTable
, size_t32 n
) const 
 937         const wxMsgTableEntry 
* const ent 
= pTable 
+ n
; 
 939         // this check could fail for a corrupt message catalog 
 940         size_t32 ofsString 
= Swap(ent
->ofsString
); 
 941         if ( ofsString 
+ Swap(ent
->nLen
) > m_nSize
) 
 946         return (const char *)(m_pData 
+ ofsString
); 
 949     bool m_bSwapped
;   // wrong endianness? 
 951     DECLARE_NO_COPY_CLASS(wxMsgCatalogFile
) 
 955 // ---------------------------------------------------------------------------- 
 956 // wxMsgCatalog corresponds to one loaded message catalog. 
 958 // This is a "low-level" class and is used only by wxLocale (that's why 
 959 // it's designed to be stored in a linked list) 
 960 // ---------------------------------------------------------------------------- 
 965     // load the catalog from disk (szDirPrefix corresponds to language) 
 966     bool Load(const wxChar 
*szDirPrefix
, const wxChar 
*szName
, 
 967               const wxChar 
*msgIdCharset 
= NULL
, bool bConvertEncoding 
= false); 
 969     // get name of the catalog 
 970     wxString 
GetName() const { return m_name
; } 
 972     // get the translated string: returns NULL if not found 
 973     const wxChar 
*GetString(const wxChar 
*sz
, size_t n 
= size_t(-1)) const; 
 975     // public variable pointing to the next element in a linked list (or NULL) 
 976     wxMsgCatalog 
*m_pNext
; 
 979     wxMessagesHash  m_messages
; // all messages in the catalog 
 980     wxString        m_name
;     // name of the domain 
 981     wxPluralFormsCalculatorPtr  m_pluralFormsCalculator
; 
 984 // ---------------------------------------------------------------------------- 
 986 // ---------------------------------------------------------------------------- 
 988 // the list of the directories to search for message catalog files 
 989 static wxArrayString s_searchPrefixes
; 
 991 // ============================================================================ 
 993 // ============================================================================ 
 995 // ---------------------------------------------------------------------------- 
 996 // wxMsgCatalogFile class 
 997 // ---------------------------------------------------------------------------- 
 999 wxMsgCatalogFile::wxMsgCatalogFile() 
1005 wxMsgCatalogFile::~wxMsgCatalogFile() 
1010 // return all directories to search for given prefix 
1011 static wxString 
GetAllMsgCatalogSubdirs(const wxChar 
*prefix
, 
1014     wxString searchPath
; 
1016     // search first in prefix/fr/LC_MESSAGES, then in prefix/fr and finally in 
1017     // prefix (assuming the language is 'fr') 
1018     searchPath 
<< prefix 
<< wxFILE_SEP_PATH 
<< lang 
<< wxFILE_SEP_PATH
 
1019                          << wxT("LC_MESSAGES") << wxPATH_SEP
 
1020                << prefix 
<< wxFILE_SEP_PATH 
<< lang 
<< wxPATH_SEP
 
1021                << prefix 
<< wxPATH_SEP
; 
1026 // construct the search path for the given language 
1027 static wxString 
GetFullSearchPath(const wxChar 
*lang
) 
1029     wxString searchPath
; 
1031     // first take the entries explicitly added by the program 
1032     size_t count 
= s_searchPrefixes
.Count(); 
1033     for ( size_t n 
= 0; n 
< count
; n
++ ) 
1035         searchPath 
<< GetAllMsgCatalogSubdirs(s_searchPrefixes
[n
], lang
) 
1039     // TODO: use wxStandardPaths instead of all this mess!! 
1041     // LC_PATH is a standard env var containing the search path for the .mo 
1044     const wxChar 
*pszLcPath 
= wxGetenv(wxT("LC_PATH")); 
1045     if ( pszLcPath 
!= NULL 
) 
1046         searchPath 
<< GetAllMsgCatalogSubdirs(pszLcPath
, lang
); 
1050     // add some standard ones and the one in the tree where wxWin was installed: 
1052         << GetAllMsgCatalogSubdirs(wxString(wxGetInstallPrefix()) + wxT("/share/locale"), lang
) 
1053         << GetAllMsgCatalogSubdirs(wxT("/usr/share/locale"), lang
) 
1054         << GetAllMsgCatalogSubdirs(wxT("/usr/lib/locale"), lang
) 
1055         << GetAllMsgCatalogSubdirs(wxT("/usr/local/share/locale"), lang
); 
1058     // then take the current directory 
1059     // FIXME it should be the directory of the executable 
1060 #if defined(__WXMAC__) 
1061     searchPath 
<< GetAllMsgCatalogSubdirs(wxGetCwd(), lang
); 
1062     // generic search paths could be somewhere in the system folder preferences 
1063 #elif defined(__WXMSW__) 
1064     // look in the directory of the executable 
1066     wxSplitPath(wxGetFullModuleName(), &path
, NULL
, NULL
); 
1067     searchPath 
<< GetAllMsgCatalogSubdirs(path
, lang
); 
1069     searchPath 
<< GetAllMsgCatalogSubdirs(wxT("."), lang
); 
1075 // open disk file and read in it's contents 
1076 bool wxMsgCatalogFile::Load(const wxChar 
*szDirPrefix
, const wxChar 
*szName
, 
1077                             wxPluralFormsCalculatorPtr
& rPluralFormsCalculator
) 
1080      We need to handle locales like  de_AT.iso-8859-1 
1081      For this we first chop off the .CHARSET specifier and ignore it. 
1082      FIXME: UNICODE SUPPORT: must use CHARSET specifier! 
1085   wxString searchPath 
= GetFullSearchPath(szDirPrefix
); 
1086   const wxChar 
*sublocale 
= wxStrchr(szDirPrefix
, wxT('_')); 
1089       // also add just base locale name: for things like "fr_BE" (belgium 
1090       // french) we should use "fr" if no belgium specific message catalogs 
1092       searchPath 
<< GetFullSearchPath(wxString(szDirPrefix
). 
1093                                       Left((size_t)(sublocale 
- szDirPrefix
))) 
1097   // don't give translation errors here because the wxstd catalog might 
1098   // not yet be loaded (and it's normal) 
1100   // (we're using an object because we have several return paths) 
1102   NoTransErr noTransErr
; 
1103   wxLogVerbose(_("looking for catalog '%s' in path '%s'."), 
1104                szName
, searchPath
.c_str()); 
1106   wxFileName 
fn(szName
); 
1107   fn
.SetExt(_T("mo")); 
1108   wxString strFullName
; 
1109   if ( !wxFindFileInPath(&strFullName
, searchPath
, fn
.GetFullPath()) ) { 
1110     wxLogVerbose(_("catalog file for domain '%s' not found."), szName
); 
1115   wxLogVerbose(_("using catalog '%s' from '%s'."), szName
, strFullName
.c_str()); 
1117   wxFile 
fileMsg(strFullName
); 
1118   if ( !fileMsg
.IsOpened() ) 
1121   // get the file size (assume it is less than 4Gb...) 
1122   wxFileOffset nSize 
= fileMsg
.Length(); 
1123   if ( nSize 
== wxInvalidOffset 
) 
1126   // read the whole file in memory 
1127   m_pData 
= new size_t8
[nSize
]; 
1128   if ( fileMsg
.Read(m_pData
, (size_t)nSize
) != nSize 
) { 
1134   bool bValid 
= nSize 
+ (size_t)0 > sizeof(wxMsgCatalogHeader
); 
1136   wxMsgCatalogHeader 
*pHeader 
= (wxMsgCatalogHeader 
*)m_pData
; 
1138     // we'll have to swap all the integers if it's true 
1139     m_bSwapped 
= pHeader
->magic 
== MSGCATALOG_MAGIC_SW
; 
1141     // check the magic number 
1142     bValid 
= m_bSwapped 
|| pHeader
->magic 
== MSGCATALOG_MAGIC
; 
1146     // it's either too short or has incorrect magic number 
1147     wxLogWarning(_("'%s' is not a valid message catalog."), strFullName
.c_str()); 
1154   m_numStrings  
= Swap(pHeader
->numStrings
); 
1155   m_pOrigTable  
= (wxMsgTableEntry 
*)(m_pData 
+ 
1156                    Swap(pHeader
->ofsOrigTable
)); 
1157   m_pTransTable 
= (wxMsgTableEntry 
*)(m_pData 
+ 
1158                    Swap(pHeader
->ofsTransTable
)); 
1159   m_nSize 
= (size_t32
)nSize
; 
1161   // now parse catalog's header and try to extract catalog charset and 
1162   // plural forms formula from it: 
1164   const char* headerData 
= StringAtOfs(m_pOrigTable
, 0); 
1165   if (headerData 
&& headerData
[0] == 0) 
1167       // Extract the charset: 
1168       wxString header 
= wxString::FromAscii(StringAtOfs(m_pTransTable
, 0)); 
1169       int begin 
= header
.Find(wxT("Content-Type: text/plain; charset=")); 
1170       if (begin 
!= wxNOT_FOUND
) 
1172           begin 
+= 34; //strlen("Content-Type: text/plain; charset=") 
1173           size_t end 
= header
.find('\n', begin
); 
1174           if (end 
!= size_t(-1)) 
1176               m_charset
.assign(header
, begin
, end 
- begin
); 
1177               if (m_charset 
== wxT("CHARSET")) 
1179                   // "CHARSET" is not valid charset, but lazy translator 
1184       // else: incorrectly filled Content-Type header 
1186       // Extract plural forms: 
1187       begin 
= header
.Find(wxT("Plural-Forms:")); 
1188       if (begin 
!= wxNOT_FOUND
) 
1191           size_t end 
= header
.find('\n', begin
); 
1192           if (end 
!= size_t(-1)) 
1194               wxString 
pfs(header
, begin
, end 
- begin
); 
1195               wxPluralFormsCalculator
* pCalculator 
= wxPluralFormsCalculator
 
1196                   ::make(pfs
.ToAscii()); 
1197               if (pCalculator 
!= 0) 
1199                   rPluralFormsCalculator
.reset(pCalculator
); 
1203                    wxLogVerbose(_("Cannot parse Plural-Forms:'%s'"), 
1208       if (rPluralFormsCalculator
.get() == NULL
) 
1210           rPluralFormsCalculator
.reset(wxPluralFormsCalculator::make()); 
1214   // everything is fine 
1218 void wxMsgCatalogFile::FillHash(wxMessagesHash
& hash
, 
1219                                 const wxString
& msgIdCharset
, 
1220                                 bool convertEncoding
) const 
1223     // determine if we need any conversion at all 
1224     if ( convertEncoding 
) 
1226         wxFontEncoding encCat 
= wxFontMapperBase::GetEncodingFromName(m_charset
); 
1227         if ( encCat 
== wxLocale::GetSystemEncoding() ) 
1229             // no need to convert 
1230             convertEncoding 
= false; 
1233 #endif // wxUSE_FONTMAP 
1236     // conversion to use to convert catalog strings to the GUI encoding 
1237     wxMBConv 
*inputConv
, 
1238              *csConv 
= NULL
; // another ptr just to be able to delete it later 
1239     if ( convertEncoding 
) 
1241         if ( m_charset
.empty() ) 
1242             inputConv 
= wxConvCurrent
; 
1245             csConv 
= new wxCSConv(m_charset
); 
1247     else // no conversion needed 
1252     // conversion to apply to msgid strings before looking them up: we only 
1253     // need it if the msgids are neither in 7 bit ASCII nor in the same 
1254     // encoding as the catalog 
1255     wxCSConv 
*sourceConv 
= msgIdCharset
.empty() || (msgIdCharset 
== m_charset
) 
1257                             : new wxCSConv(msgIdCharset
); 
1260     wxASSERT_MSG( msgIdCharset 
== NULL
, 
1261                   _T("non-ASCII msgid languages only supported if wxUSE_WCHAR_T=1") ); 
1263     wxEncodingConverter converter
; 
1264     if ( convertEncoding 
) 
1266         wxFontEncoding targetEnc 
= wxFONTENCODING_SYSTEM
; 
1267         wxFontEncoding enc 
= wxFontMapperBase::Get()->CharsetToEncoding(m_charset
, false); 
1268         if ( enc 
== wxFONTENCODING_SYSTEM 
) 
1270             convertEncoding 
= false; // unknown encoding 
1274             targetEnc 
= wxLocale::GetSystemEncoding(); 
1275             if (targetEnc 
== wxFONTENCODING_SYSTEM
) 
1277                 wxFontEncodingArray a 
= wxEncodingConverter::GetPlatformEquivalents(enc
); 
1279                     // no conversion needed, locale uses native encoding 
1280                     convertEncoding 
= false; 
1281                 if (a
.GetCount() == 0) 
1282                     // we don't know common equiv. under this platform 
1283                     convertEncoding 
= false; 
1288         if ( convertEncoding 
) 
1290             converter
.Init(enc
, targetEnc
); 
1293 #endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T 
1294     (void)convertEncoding
; // get rid of warnings about unused parameter 
1296     for (size_t i 
= 0; i 
< m_numStrings
; i
++) 
1298         const char *data 
= StringAtOfs(m_pOrigTable
, i
); 
1300         wxString 
msgid(data
, *inputConv
); 
1304         if ( inputConv 
&& sourceConv 
) 
1305             msgid 
= wxString(inputConv
->cMB2WC(data
), *sourceConv
); 
1309 #endif // wxUSE_UNICODE 
1311         data 
= StringAtOfs(m_pTransTable
, i
); 
1312         size_t length 
= Swap(m_pTransTable
[i
].nLen
); 
1315         while (offset 
< length
) 
1320             msgstr 
= wxString(data 
+ offset
, *inputConv
); 
1323                 msgstr 
= wxString(inputConv
->cMB2WC(data 
+ offset
), wxConvLocal
); 
1325                 msgstr 
= wxString(data 
+ offset
); 
1327 #else // !wxUSE_WCHAR_T 
1329             if ( convertEncoding 
) 
1330                 msgstr 
= wxString(converter
.Convert(data 
+ offset
)); 
1333                 msgstr 
= wxString(data 
+ offset
); 
1334 #endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T 
1336             if ( !msgstr
.empty() ) 
1338                 hash
[index 
== 0 ? msgid 
: msgid 
+ wxChar(index
)] = msgstr
; 
1340             offset 
+= strlen(data 
+ offset
) + 1; 
1352 // ---------------------------------------------------------------------------- 
1353 // wxMsgCatalog class 
1354 // ---------------------------------------------------------------------------- 
1356 bool wxMsgCatalog::Load(const wxChar 
*szDirPrefix
, const wxChar 
*szName
, 
1357                         const wxChar 
*msgIdCharset
, bool bConvertEncoding
) 
1359     wxMsgCatalogFile file
; 
1363     if ( file
.Load(szDirPrefix
, szName
, m_pluralFormsCalculator
) ) 
1365         file
.FillHash(m_messages
, msgIdCharset
, bConvertEncoding
); 
1372 const wxChar 
*wxMsgCatalog::GetString(const wxChar 
*sz
, size_t n
) const 
1375     if (n 
!= size_t(-1)) 
1377         index 
= m_pluralFormsCalculator
->evaluate(n
); 
1379     wxMessagesHash::const_iterator i
; 
1382         i 
= m_messages
.find(wxString(sz
) + wxChar(index
));   // plural 
1386         i 
= m_messages
.find(sz
); 
1389     if ( i 
!= m_messages
.end() ) 
1391         return i
->second
.c_str(); 
1397 // ---------------------------------------------------------------------------- 
1399 // ---------------------------------------------------------------------------- 
1401 #include "wx/arrimpl.cpp" 
1402 WX_DECLARE_EXPORTED_OBJARRAY(wxLanguageInfo
, wxLanguageInfoArray
); 
1403 WX_DEFINE_OBJARRAY(wxLanguageInfoArray
); 
1405 wxLanguageInfoArray 
*wxLocale::ms_languagesDB 
= NULL
; 
1407 /*static*/ void wxLocale::CreateLanguagesDB() 
1409     if (ms_languagesDB 
== NULL
) 
1411         ms_languagesDB 
= new wxLanguageInfoArray
; 
1416 /*static*/ void wxLocale::DestroyLanguagesDB() 
1418     delete ms_languagesDB
; 
1419     ms_languagesDB 
= NULL
; 
1423 void wxLocale::DoCommonInit() 
1425   m_pszOldLocale 
= NULL
; 
1427   m_pOldLocale 
= wxSetLocale(this); 
1430   m_language 
= wxLANGUAGE_UNKNOWN
; 
1431   m_initialized 
= false; 
1434 // NB: this function has (desired) side effect of changing current locale 
1435 bool wxLocale::Init(const wxChar 
*szName
, 
1436                     const wxChar 
*szShort
, 
1437                     const wxChar 
*szLocale
, 
1439                     bool        bConvertEncoding
) 
1441   wxASSERT_MSG( !m_initialized
, 
1442                 _T("you can't call wxLocale::Init more than once") ); 
1444   m_initialized 
= true; 
1445   m_strLocale 
= szName
; 
1446   m_strShort 
= szShort
; 
1447   m_bConvertEncoding 
= bConvertEncoding
; 
1448   m_language 
= wxLANGUAGE_UNKNOWN
; 
1450   // change current locale (default: same as long name) 
1451   if ( szLocale 
== NULL 
) 
1453     // the argument to setlocale() 
1456     wxCHECK_MSG( szLocale
, false, _T("no locale to set in wxLocale::Init()") ); 
1460   // FIXME: I'm guessing here 
1461   wxChar localeName
[256]; 
1462   int ret 
= GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_SLANGUAGE
, localeName
, 
1466     m_pszOldLocale 
= wxStrdup(localeName
); 
1469     m_pszOldLocale 
= NULL
; 
1471   // TODO: how to find languageId 
1472   // SetLocaleInfo(languageId, SORT_DEFAULT, localeName); 
1474   wxMB2WXbuf oldLocale 
= wxSetlocale(LC_ALL
, szLocale
); 
1476       m_pszOldLocale 
= wxStrdup(oldLocale
); 
1478       m_pszOldLocale 
= NULL
; 
1481   if ( m_pszOldLocale 
== NULL 
) 
1482     wxLogError(_("locale '%s' can not be set."), szLocale
); 
1484   // the short name will be used to look for catalog files as well, 
1485   // so we need something here 
1486   if ( m_strShort
.empty() ) { 
1487     // FIXME I don't know how these 2 letter abbreviations are formed, 
1488     //       this wild guess is surely wrong 
1489     if ( szLocale 
&& szLocale
[0] ) 
1491         m_strShort 
+= (wxChar
)wxTolower(szLocale
[0]); 
1493             m_strShort 
+= (wxChar
)wxTolower(szLocale
[1]); 
1497   // load the default catalog with wxWidgets standard messages 
1502     bOk 
= AddCatalog(wxT("wxstd")); 
1504     // there may be a catalog with toolkit specific overrides, it is not 
1505     // an error if this does not exist 
1506     if ( bOk 
&& wxTheApp 
) 
1508       wxAppTraits 
*traits 
= wxTheApp
->GetTraits(); 
1510         AddCatalog(traits
->GetToolkitInfo().name
.BeforeFirst(wxT('/')).MakeLower()); 
1518 #if defined(__UNIX__) && wxUSE_UNICODE && !defined(__WXMAC__) 
1519 static wxWCharBuffer 
wxSetlocaleTryUTF(int c
, const wxChar 
*lc
) 
1521     wxMB2WXbuf l 
= wxSetlocale(c
, lc
); 
1522     if ( !l 
&& lc 
&& lc
[0] != 0 ) 
1526         buf2 
= buf 
+ wxT(".UTF-8"); 
1527         l 
= wxSetlocale(c
, buf2
.c_str()); 
1530             buf2 
= buf 
+ wxT(".utf-8"); 
1531             l 
= wxSetlocale(c
, buf2
.c_str()); 
1535             buf2 
= buf 
+ wxT(".UTF8"); 
1536             l 
= wxSetlocale(c
, buf2
.c_str()); 
1540             buf2 
= buf 
+ wxT(".utf8"); 
1541             l 
= wxSetlocale(c
, buf2
.c_str()); 
1547 #define wxSetlocaleTryUTF(c, lc)  wxSetlocale(c, lc) 
1550 bool wxLocale::Init(int language
, int flags
) 
1552     int lang 
= language
; 
1553     if (lang 
== wxLANGUAGE_DEFAULT
) 
1555         // auto detect the language 
1556         lang 
= GetSystemLanguage(); 
1559     // We failed to detect system language, so we will use English: 
1560     if (lang 
== wxLANGUAGE_UNKNOWN
) 
1565     const wxLanguageInfo 
*info 
= GetLanguageInfo(lang
); 
1567     // Unknown language: 
1570         wxLogError(wxT("Unknown language %i."), lang
); 
1574     wxString name 
= info
->Description
; 
1575     wxString canonical 
= info
->CanonicalName
; 
1579 #if defined(__UNIX__) && !defined(__WXMAC__) 
1580     if (language 
== wxLANGUAGE_DEFAULT
) 
1581         locale 
= wxEmptyString
; 
1583         locale 
= info
->CanonicalName
; 
1585     wxMB2WXbuf retloc 
= wxSetlocaleTryUTF(LC_ALL
, locale
); 
1589         // Some C libraries don't like xx_YY form and require xx only 
1590         retloc 
= wxSetlocaleTryUTF(LC_ALL
, locale
.Mid(0,2)); 
1594         // Some C libraries (namely glibc) still use old ISO 639, 
1595         // so will translate the abbrev for them 
1596         wxString mid 
= locale
.Mid(0,2); 
1597         if (mid 
== wxT("he")) 
1598             locale 
= wxT("iw") + locale
.Mid(3); 
1599         else if (mid 
== wxT("id")) 
1600             locale 
= wxT("in") + locale
.Mid(3); 
1601         else if (mid 
== wxT("yi")) 
1602             locale 
= wxT("ji") + locale
.Mid(3); 
1603         else if (mid 
== wxT("nb")) 
1604             locale 
= wxT("no_NO"); 
1605         else if (mid 
== wxT("nn")) 
1606             locale 
= wxT("no_NY"); 
1608         retloc 
= wxSetlocaleTryUTF(LC_ALL
, locale
); 
1612         // (This time, we changed locale in previous if-branch, so try again.) 
1613         // Some C libraries don't like xx_YY form and require xx only 
1614         retloc 
= wxSetlocaleTryUTF(LC_ALL
, locale
.Mid(0,2)); 
1618         wxLogError(wxT("Cannot set locale to '%s'."), locale
.c_str()); 
1621 #elif defined(__WIN32__) 
1623     #if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__)) 
1624         // NB: setlocale() from msvcrt.dll (used by VC++ and Mingw) 
1625         //     can't set locale to language that can only be written using 
1626         //     Unicode.  Therefore wxSetlocale call failed, but we don't want 
1627         //     to report it as an error -- so that at least message catalogs 
1628         //     can be used. Watch for code marked with 
1629         //     #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS bellow. 
1630         #define SETLOCALE_FAILS_ON_UNICODE_LANGS 
1636     wxMB2WXbuf retloc 
= wxT("C"); 
1637     if (language 
!= wxLANGUAGE_DEFAULT
) 
1639         if (info
->WinLang 
== 0) 
1641             wxLogWarning(wxT("Locale '%s' not supported by OS."), name
.c_str()); 
1642             // retloc already set to "C" 
1647                          #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS 
1651             wxUint32 lcid 
= MAKELCID(MAKELANGID(info
->WinLang
, info
->WinSublang
), 
1655             SetThreadLocale(lcid
); 
1657             // NB: we must translate LCID to CRT's setlocale string ourselves, 
1658             //     because SetThreadLocale does not modify change the 
1659             //     interpretation of setlocale(LC_ALL, "") call: 
1661             buffer
[0] = wxT('\0'); 
1662             GetLocaleInfo(lcid
, LOCALE_SENGLANGUAGE
, buffer
, 256); 
1664             if (GetLocaleInfo(lcid
, LOCALE_SENGCOUNTRY
, buffer
, 256) > 0) 
1665                 locale 
<< wxT("_") << buffer
; 
1666             if (GetLocaleInfo(lcid
, LOCALE_IDEFAULTANSICODEPAGE
, buffer
, 256) > 0) 
1668                 codepage 
= wxAtoi(buffer
); 
1670                     locale 
<< wxT(".") << buffer
; 
1674                 wxLogLastError(wxT("SetThreadLocale")); 
1675                 wxLogError(wxT("Cannot set locale to language %s."), name
.c_str()); 
1682                 retloc 
= wxSetlocale(LC_ALL
, locale
); 
1684 #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS 
1685                 if (codepage 
== 0 && (const wxChar
*)retloc 
== NULL
) 
1697         retloc 
= wxSetlocale(LC_ALL
, wxEmptyString
); 
1701 #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS 
1702         if ((const wxChar
*)retloc 
== NULL
) 
1705             if (GetLocaleInfo(LOCALE_USER_DEFAULT
, 
1706                               LOCALE_IDEFAULTANSICODEPAGE
, buffer
, 16) > 0 && 
1707                  wxStrcmp(buffer
, wxT("0")) == 0) 
1717         wxLogError(wxT("Cannot set locale to language %s."), name
.c_str()); 
1720 #elif defined(__WXMAC__) 
1721     if (lang 
== wxLANGUAGE_DEFAULT
) 
1722         locale 
= wxEmptyString
; 
1724         locale 
= info
->CanonicalName
; 
1726     wxMB2WXbuf retloc 
= wxSetlocale(LC_ALL
, locale
); 
1730         // Some C libraries don't like xx_YY form and require xx only 
1731         retloc 
= wxSetlocale(LC_ALL
, locale
.Mid(0,2)); 
1735         wxLogError(wxT("Cannot set locale to '%s'."), locale
.c_str()); 
1738 #elif defined(__WXPM__) 
1739     wxMB2WXbuf retloc 
= wxSetlocale(LC_ALL 
, wxEmptyString
); 
1742     #define WX_NO_LOCALE_SUPPORT 
1745 #ifndef WX_NO_LOCALE_SUPPORT 
1746     wxChar 
*szLocale 
= retloc 
? wxStrdup(retloc
) : NULL
; 
1747     bool ret 
= Init(name
, canonical
, retloc
, 
1748                     (flags 
& wxLOCALE_LOAD_DEFAULT
) != 0, 
1749                     (flags 
& wxLOCALE_CONV_ENCODING
) != 0); 
1752     if (IsOk()) // setlocale() succeeded 
1761 void wxLocale::AddCatalogLookupPathPrefix(const wxString
& prefix
) 
1763     if ( s_searchPrefixes
.Index(prefix
) == wxNOT_FOUND 
) 
1765         s_searchPrefixes
.Add(prefix
); 
1767     //else: already have it 
1770 /*static*/ int wxLocale::GetSystemLanguage() 
1772     CreateLanguagesDB(); 
1774     // init i to avoid compiler warning 
1776            count 
= ms_languagesDB
->GetCount(); 
1778 #if defined(__UNIX__) && !defined(__WXMAC__) 
1779     // first get the string identifying the language from the environment 
1781     if (!wxGetEnv(wxT("LC_ALL"), &langFull
) && 
1782         !wxGetEnv(wxT("LC_MESSAGES"), &langFull
) && 
1783         !wxGetEnv(wxT("LANG"), &langFull
)) 
1785         // no language specified, threat it as English 
1786         return wxLANGUAGE_ENGLISH
; 
1789     if ( langFull 
== _T("C") || langFull 
== _T("POSIX") ) 
1792         return wxLANGUAGE_ENGLISH
; 
1795     // the language string has the following form 
1797     //      lang[_LANG][.encoding][@modifier] 
1799     // (see environ(5) in the Open Unix specification) 
1801     // where lang is the primary language, LANG is a sublang/territory, 
1802     // encoding is the charset to use and modifier "allows the user to select 
1803     // a specific instance of localization data within a single category" 
1805     // for example, the following strings are valid: 
1810     //      de_DE.iso88591@euro 
1812     // for now we don't use the encoding, although we probably should (doing 
1813     // translations of the msg catalogs on the fly as required) (TODO) 
1815     // we don't use the modifiers neither but we probably should translate 
1816     // "euro" into iso885915 
1817     size_t posEndLang 
= langFull
.find_first_of(_T("@.")); 
1818     if ( posEndLang 
!= wxString::npos 
) 
1820         langFull
.Truncate(posEndLang
); 
1823     // in addition to the format above, we also can have full language names 
1824     // in LANG env var - for example, SuSE is known to use LANG="german" - so 
1827     // do we have just the language (or sublang too)? 
1828     bool justLang 
= langFull
.Len() == LEN_LANG
; 
1830          (langFull
.Len() == LEN_FULL 
&& langFull
[LEN_LANG
] == wxT('_')) ) 
1832         // 0. Make sure the lang is according to latest ISO 639 
1833         //    (this is necessary because glibc uses iw and in instead 
1834         //    of he and id respectively). 
1836         // the language itself (second part is the dialect/sublang) 
1837         wxString langOrig 
= ExtractLang(langFull
); 
1840         if ( langOrig 
== wxT("iw")) 
1842         else if (langOrig 
== wxT("in")) 
1844         else if (langOrig 
== wxT("ji")) 
1846         else if (langOrig 
== wxT("no_NO")) 
1847             lang 
= wxT("nb_NO"); 
1848         else if (langOrig 
== wxT("no_NY")) 
1849             lang 
= wxT("nn_NO"); 
1850         else if (langOrig 
== wxT("no")) 
1851             lang 
= wxT("nb_NO"); 
1855         // did we change it? 
1856         if ( lang 
!= langOrig 
) 
1858             langFull 
= lang 
+ ExtractNotLang(langFull
); 
1861         // 1. Try to find the language either as is: 
1862         for ( i 
= 0; i 
< count
; i
++ ) 
1864             if ( ms_languagesDB
->Item(i
).CanonicalName 
== langFull 
) 
1870         // 2. If langFull is of the form xx_YY, try to find xx: 
1871         if ( i 
== count 
&& !justLang 
) 
1873             for ( i 
= 0; i 
< count
; i
++ ) 
1875                 if ( ms_languagesDB
->Item(i
).CanonicalName 
== lang 
) 
1882         // 3. If langFull is of the form xx, try to find any xx_YY record: 
1883         if ( i 
== count 
&& justLang 
) 
1885             for ( i 
= 0; i 
< count
; i
++ ) 
1887                 if ( ExtractLang(ms_languagesDB
->Item(i
).CanonicalName
) 
1895     else // not standard format 
1897         // try to find the name in verbose description 
1898         for ( i 
= 0; i 
< count
; i
++ ) 
1900             if (ms_languagesDB
->Item(i
).Description
.CmpNoCase(langFull
) == 0) 
1906 #elif defined(__WXMAC__) 
1907     const wxChar 
* lc 
= NULL 
; 
1908     long lang 
= GetScriptVariable( smSystemScript
, smScriptLang
) ; 
1909     switch( GetScriptManagerVariable( smRegionCode 
) ) { 
1925       case verNetherlands 
: 
1980       // _CY is not part of wx, so we have to translate according to the system language 
1981         if ( lang 
== langGreek 
) { 
1984         else if ( lang 
== langTurkish 
) { 
1991       case verYugoCroatian
: 
1997       case verPakistanUrdu
: 
2000       case verTurkishModified
: 
2003       case verItalianSwiss
: 
2006       case verInternational
: 
2067       case verByeloRussian
: 
2089         lc 
= wxT("pt_BR ") ; 
2097       case verScottishGaelic
: 
2112       case verIrishGaelicScript
: 
2127       case verSpLatinAmerica
: 
2133       case verFrenchUniversal
: 
2184   for ( i 
= 0; i 
< count
; i
++ ) 
2186       if ( ms_languagesDB
->Item(i
).CanonicalName 
== lc 
) 
2192 #elif defined(__WIN32__) 
2193     LCID lcid 
= GetUserDefaultLCID(); 
2196         wxUint32 lang 
= PRIMARYLANGID(LANGIDFROMLCID(lcid
)); 
2197         wxUint32 sublang 
= SUBLANGID(LANGIDFROMLCID(lcid
)); 
2199         for ( i 
= 0; i 
< count
; i
++ ) 
2201             if (ms_languagesDB
->Item(i
).WinLang 
== lang 
&& 
2202                 ms_languagesDB
->Item(i
).WinSublang 
== sublang
) 
2208     //else: leave wxlang == wxLANGUAGE_UNKNOWN 
2209 #endif // Unix/Win32 
2213         // we did find a matching entry, use it 
2214         return ms_languagesDB
->Item(i
).Language
; 
2217     // no info about this language in the database 
2218     return wxLANGUAGE_UNKNOWN
; 
2221 // ---------------------------------------------------------------------------- 
2223 // ---------------------------------------------------------------------------- 
2225 // this is a bit strange as under Windows we get the encoding name using its 
2226 // numeric value and under Unix we do it the other way round, but this just 
2227 // reflects the way different systems provide the encoding info 
2230 wxString 
wxLocale::GetSystemEncodingName() 
2234 #if defined(__WIN32__) && !defined(__WXMICROWIN__) 
2235     // FIXME: what is the error return value for GetACP()? 
2236     UINT codepage 
= ::GetACP(); 
2237     encname
.Printf(_T("windows-%u"), codepage
); 
2238 #elif defined(__WXMAC__) 
2239     // default is just empty string, this resolves to the default system 
2241 #elif defined(__UNIX_LIKE__) 
2243 #if defined(HAVE_LANGINFO_H) && defined(CODESET) 
2244     // GNU libc provides current character set this way (this conforms 
2246     char *oldLocale 
= strdup(setlocale(LC_CTYPE
, NULL
)); 
2247     setlocale(LC_CTYPE
, ""); 
2248     const char *alang 
= nl_langinfo(CODESET
); 
2249     setlocale(LC_CTYPE
, oldLocale
); 
2254         // 7 bit ASCII encoding has several alternative names which we should 
2255         // recognize to avoid warnings about unrecognized encoding on each 
2258         // nl_langinfo() under Solaris returns 646 by default which stands for 
2259         // ISO-646, i.e. 7 bit ASCII 
2261         // and recent glibc call it ANSI_X3.4-1968... 
2263         // HP-UX uses HP-Roman8 cset which is not the same as ASCII (see RFC 
2264         // 1345 for its definition) but must be recognized as otherwise HP 
2265         // users get a warning about it on each program startup, so handle it 
2266         // here -- but it would be obviously better to add real supprot to it, 
2268         if ( strcmp(alang
, "646") == 0 
2269                 || strcmp(alang
, "ANSI_X3.4-1968") == 0 
2271                     || strcmp(alang
, "roman8") == 0 
2275             encname 
= _T("US-ASCII"); 
2279             encname 
= wxString::FromAscii( alang 
); 
2283 #endif // HAVE_LANGINFO_H 
2285         // if we can't get at the character set directly, try to see if it's in 
2286         // the environment variables (in most cases this won't work, but I was 
2288         char *lang 
= getenv( "LC_ALL"); 
2289         char *dot 
= lang 
? strchr(lang
, '.') : (char *)NULL
; 
2292             lang 
= getenv( "LC_CTYPE" ); 
2294                 dot 
= strchr(lang
, '.' ); 
2298             lang 
= getenv( "LANG"); 
2300                 dot 
= strchr(lang
, '.'); 
2305             encname 
= wxString::FromAscii( dot
+1 ); 
2308 #endif // Win32/Unix 
2314 wxFontEncoding 
wxLocale::GetSystemEncoding() 
2316 #if defined(__WIN32__) && !defined(__WXMICROWIN__) 
2317     UINT codepage 
= ::GetACP(); 
2319     // wxWidgets only knows about CP1250-1257, 874, 932, 936, 949, 950 
2320     if ( codepage 
>= 1250 && codepage 
<= 1257 ) 
2322         return (wxFontEncoding
)(wxFONTENCODING_CP1250 
+ codepage 
- 1250); 
2325     if ( codepage 
== 874 ) 
2327         return wxFONTENCODING_CP874
; 
2330     if ( codepage 
== 932 ) 
2332         return wxFONTENCODING_CP932
; 
2335     if ( codepage 
== 936 ) 
2337         return wxFONTENCODING_CP936
; 
2340     if ( codepage 
== 949 ) 
2342         return wxFONTENCODING_CP949
; 
2345     if ( codepage 
== 950 ) 
2347         return wxFONTENCODING_CP950
; 
2349 #elif defined(__WXMAC__) 
2350     TextEncoding encoding 
= 0 ; 
2352     encoding 
= CFStringGetSystemEncoding() ; 
2354     UpgradeScriptInfoToTextEncoding ( smSystemScript 
, kTextLanguageDontCare 
, kTextRegionDontCare 
, NULL 
, &encoding 
) ; 
2356     return wxMacGetFontEncFromSystemEnc( encoding 
) ; 
2357 #elif defined(__UNIX_LIKE__) && wxUSE_FONTMAP 
2358     wxString encname 
= GetSystemEncodingName(); 
2359     if ( !encname
.empty() ) 
2361         wxFontEncoding enc 
= (wxFontMapperBase::Get())-> 
2362             CharsetToEncoding(encname
, false /* not interactive */); 
2364         // on some modern Linux systems (RedHat 8) the default system locale 
2365         // is UTF8 -- but it isn't supported by wxGTK in ANSI build at all so 
2366         // don't even try to use it in this case 
2368         if ( enc 
== wxFONTENCODING_UTF8 
) 
2370             // the most similar supported encoding... 
2371             enc 
= wxFONTENCODING_ISO8859_1
; 
2373 #endif // !wxUSE_UNICODE 
2375         // this should probably be considered as a bug in CharsetToEncoding(): 
2376         // it shouldn't return wxFONTENCODING_DEFAULT at all - but it does it 
2377         // for US-ASCII charset 
2379         // we, OTOH, definitely shouldn't return it as it doesn't make sense at 
2380         // all (which encoding is it?) 
2381         if ( enc 
!= wxFONTENCODING_DEFAULT 
) 
2385         //else: return wxFONTENCODING_SYSTEM below 
2387 #endif // Win32/Unix 
2389     return wxFONTENCODING_SYSTEM
; 
2393 void wxLocale::AddLanguage(const wxLanguageInfo
& info
) 
2395     CreateLanguagesDB(); 
2396     ms_languagesDB
->Add(info
); 
2400 const wxLanguageInfo 
*wxLocale::GetLanguageInfo(int lang
) 
2402     CreateLanguagesDB(); 
2404     // calling GetLanguageInfo(wxLANGUAGE_DEFAULT) is a natural thing to do, so 
2406     if ( lang 
== wxLANGUAGE_DEFAULT 
) 
2407         lang 
= GetSystemLanguage(); 
2409     const size_t count 
= ms_languagesDB
->GetCount(); 
2410     for ( size_t i 
= 0; i 
< count
; i
++ ) 
2412         if ( ms_languagesDB
->Item(i
).Language 
== lang 
) 
2414             return &ms_languagesDB
->Item(i
); 
2422 wxString 
wxLocale::GetLanguageName(int lang
) 
2424     const wxLanguageInfo 
*info 
= GetLanguageInfo(lang
); 
2426         return wxEmptyString
; 
2428         return info
->Description
; 
2432 const wxLanguageInfo 
*wxLocale::FindLanguageInfo(const wxString
& locale
) 
2434     CreateLanguagesDB(); 
2436     const wxLanguageInfo 
*infoRet 
= NULL
; 
2438     const size_t count 
= ms_languagesDB
->GetCount(); 
2439     for ( size_t i 
= 0; i 
< count
; i
++ ) 
2441         const wxLanguageInfo 
*info 
= &ms_languagesDB
->Item(i
); 
2443         if ( wxStricmp(locale
, info
->CanonicalName
) == 0 || 
2444                 wxStricmp(locale
, info
->Description
) == 0 ) 
2446             // exact match, stop searching 
2451         if ( wxStricmp(locale
, info
->CanonicalName
.BeforeFirst(_T('_'))) == 0 ) 
2453             // a match -- but maybe we'll find an exact one later, so continue 
2456             // OTOH, maybe we had already found a language match and in this 
2457             // case don't overwrite it becauce the entry for the default 
2458             // country always appears first in ms_languagesDB 
2467 wxString 
wxLocale::GetSysName() const 
2471     return wxSetlocale(LC_ALL
, NULL
); 
2473     return wxEmptyString
; 
2478 wxLocale::~wxLocale() 
2481     wxMsgCatalog 
*pTmpCat
; 
2482     while ( m_pMsgCat 
!= NULL 
) { 
2483         pTmpCat 
= m_pMsgCat
; 
2484         m_pMsgCat 
= m_pMsgCat
->m_pNext
; 
2488     // restore old locale pointer 
2489     wxSetLocale(m_pOldLocale
); 
2493     wxSetlocale(LC_ALL
, m_pszOldLocale
); 
2495     free((wxChar 
*)m_pszOldLocale
);     // const_cast 
2498 // get the translation of given string in current locale 
2499 const wxChar 
*wxLocale::GetString(const wxChar 
*szOrigString
, 
2500                                   const wxChar 
*szDomain
) const 
2502     return GetString(szOrigString
, szOrigString
, size_t(-1), szDomain
); 
2505 const wxChar 
*wxLocale::GetString(const wxChar 
*szOrigString
, 
2506                                   const wxChar 
*szOrigString2
, 
2508                                   const wxChar 
*szDomain
) const 
2510     if ( wxIsEmpty(szOrigString
) ) 
2511         return wxEmptyString
; 
2513     const wxChar 
*pszTrans 
= NULL
; 
2514     wxMsgCatalog 
*pMsgCat
; 
2516     if ( szDomain 
!= NULL 
) 
2518         pMsgCat 
= FindCatalog(szDomain
); 
2520         // does the catalog exist? 
2521         if ( pMsgCat 
!= NULL 
) 
2522             pszTrans 
= pMsgCat
->GetString(szOrigString
, n
); 
2526         // search in all domains 
2527         for ( pMsgCat 
= m_pMsgCat
; pMsgCat 
!= NULL
; pMsgCat 
= pMsgCat
->m_pNext 
) 
2529             pszTrans 
= pMsgCat
->GetString(szOrigString
, n
); 
2530             if ( pszTrans 
!= NULL 
)   // take the first found 
2535     if ( pszTrans 
== NULL 
) 
2538         if ( !NoTransErr::Suppress() ) 
2540             NoTransErr noTransErr
; 
2542             if ( szDomain 
!= NULL 
) 
2544                 wxLogTrace(_T("i18n"), 
2545                            _T("string '%s'[%lu] not found in domain '%s' for locale '%s'."), 
2546                            szOrigString
, (unsigned long)n
, 
2547                            szDomain
, m_strLocale
.c_str()); 
2552                 wxLogTrace(_T("i18n"), 
2553                            _T("string '%s'[%lu] not found in locale '%s'."), 
2554                            szOrigString
, (unsigned long)n
, m_strLocale
.c_str()); 
2557 #endif // __WXDEBUG__ 
2559         if (n 
== size_t(-1)) 
2560             return szOrigString
; 
2562             return n 
== 1 ? szOrigString 
: szOrigString2
; 
2568 wxString 
wxLocale::GetHeaderValue( const wxChar
* szHeader
, 
2569                                    const wxChar
* szDomain 
) const 
2571     if ( wxIsEmpty(szHeader
) ) 
2572         return wxEmptyString
; 
2574     wxChar 
const * pszTrans 
= NULL
; 
2575     wxMsgCatalog 
*pMsgCat
; 
2577     if ( szDomain 
!= NULL 
) 
2579         pMsgCat 
= FindCatalog(szDomain
); 
2581         // does the catalog exist? 
2582         if ( pMsgCat 
== NULL 
) 
2583             return wxEmptyString
; 
2585         pszTrans 
= pMsgCat
->GetString(wxEmptyString
, (size_t)-1); 
2589         // search in all domains 
2590         for ( pMsgCat 
= m_pMsgCat
; pMsgCat 
!= NULL
; pMsgCat 
= pMsgCat
->m_pNext 
) 
2592             pszTrans 
= pMsgCat
->GetString(wxEmptyString
, (size_t)-1); 
2593             if ( pszTrans 
!= NULL 
)   // take the first found 
2598     if ( wxIsEmpty(pszTrans
) ) 
2599       return wxEmptyString
; 
2601     wxChar 
const * pszFound 
= wxStrstr(pszTrans
, szHeader
); 
2602     if ( pszFound 
== NULL 
) 
2603       return wxEmptyString
; 
2605     pszFound 
+= wxStrlen(szHeader
) + 2 /* ': ' */; 
2607     // Every header is separated by \n 
2609     wxChar 
const * pszEndLine 
= wxStrchr(pszFound
, wxT('\n')); 
2610     if ( pszEndLine 
== NULL 
) pszEndLine 
= pszFound 
+ wxStrlen(pszFound
); 
2613     // wxString( wxChar*, length); 
2614     wxString 
retVal( pszFound
, pszEndLine 
- pszFound 
); 
2620 // find catalog by name in a linked list, return NULL if !found 
2621 wxMsgCatalog 
*wxLocale::FindCatalog(const wxChar 
*szDomain
) const 
2623     // linear search in the linked list 
2624     wxMsgCatalog 
*pMsgCat
; 
2625     for ( pMsgCat 
= m_pMsgCat
; pMsgCat 
!= NULL
; pMsgCat 
= pMsgCat
->m_pNext 
) 
2627         if ( wxStricmp(pMsgCat
->GetName(), szDomain
) == 0 ) 
2634 // check if the given catalog is loaded 
2635 bool wxLocale::IsLoaded(const wxChar 
*szDomain
) const 
2637   return FindCatalog(szDomain
) != NULL
; 
2640 // add a catalog to our linked list 
2641 bool wxLocale::AddCatalog(const wxChar 
*szDomain
) 
2643     return AddCatalog(szDomain
, wxLANGUAGE_ENGLISH
, NULL
); 
2646 // add a catalog to our linked list 
2647 bool wxLocale::AddCatalog(const wxChar 
*szDomain
, 
2648                           wxLanguage    msgIdLanguage
, 
2649                           const wxChar 
*msgIdCharset
) 
2652   wxMsgCatalog 
*pMsgCat 
= new wxMsgCatalog
; 
2654   if ( pMsgCat
->Load(m_strShort
, szDomain
, msgIdCharset
, m_bConvertEncoding
) ) { 
2655     // add it to the head of the list so that in GetString it will 
2656     // be searched before the catalogs added earlier 
2657     pMsgCat
->m_pNext 
= m_pMsgCat
; 
2658     m_pMsgCat 
= pMsgCat
; 
2663     // don't add it because it couldn't be loaded anyway 
2666     // It is OK to not load catalog if the msgid language and m_language match, 
2667     // in which case we can directly display the texts embedded in program's 
2669     if (m_language 
== msgIdLanguage
) 
2672     // If there's no exact match, we may still get partial match where the 
2673     // (basic) language is same, but the country differs. For example, it's 
2674     // permitted to use en_US strings from sources even if m_language is en_GB: 
2675     const wxLanguageInfo 
*msgIdLangInfo 
= GetLanguageInfo(msgIdLanguage
); 
2676     if ( msgIdLangInfo 
&& 
2677          msgIdLangInfo
->CanonicalName
.Mid(0, 2) == m_strShort
.Mid(0, 2) ) 
2686 // ---------------------------------------------------------------------------- 
2687 // accessors for locale-dependent data 
2688 // ---------------------------------------------------------------------------- 
2693 wxString 
wxLocale::GetInfo(wxLocaleInfo index
, wxLocaleCategory 
WXUNUSED(cat
)) 
2698     buffer
[0] = wxT('\0'); 
2701         case wxLOCALE_DECIMAL_POINT
: 
2702             count 
= ::GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_SDECIMAL
, buffer
, 256); 
2709         case wxSYS_LIST_SEPARATOR
: 
2710             count 
= ::GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_SLIST
, buffer
, 256); 
2716         case wxSYS_LEADING_ZERO
: // 0 means no leading zero, 1 means leading zero 
2717             count 
= ::GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_ILZERO
, buffer
, 256); 
2725             wxFAIL_MSG(wxT("Unknown System String !")); 
2733 wxString 
wxLocale::GetInfo(wxLocaleInfo index
, wxLocaleCategory cat
) 
2735     struct lconv 
*locale_info 
= localeconv(); 
2738         case wxLOCALE_CAT_NUMBER
: 
2741                 case wxLOCALE_THOUSANDS_SEP
: 
2742                     return wxString(locale_info
->thousands_sep
, 
2744                 case wxLOCALE_DECIMAL_POINT
: 
2745                     return wxString(locale_info
->decimal_point
, 
2748                     return wxEmptyString
; 
2750         case wxLOCALE_CAT_MONEY
: 
2753                 case wxLOCALE_THOUSANDS_SEP
: 
2754                     return wxString(locale_info
->mon_thousands_sep
, 
2756                 case wxLOCALE_DECIMAL_POINT
: 
2757                     return wxString(locale_info
->mon_decimal_point
, 
2760                     return wxEmptyString
; 
2763             return wxEmptyString
; 
2767 #endif // __WXMSW__/!__WXMSW__ 
2769 // ---------------------------------------------------------------------------- 
2770 // global functions and variables 
2771 // ---------------------------------------------------------------------------- 
2773 // retrieve/change current locale 
2774 // ------------------------------ 
2776 // the current locale object 
2777 static wxLocale 
*g_pLocale 
= NULL
; 
2779 wxLocale 
*wxGetLocale() 
2784 wxLocale 
*wxSetLocale(wxLocale 
*pLocale
) 
2786   wxLocale 
*pOld 
= g_pLocale
; 
2787   g_pLocale 
= pLocale
; 
2793 // ---------------------------------------------------------------------------- 
2794 // wxLocale module (for lazy destruction of languagesDB) 
2795 // ---------------------------------------------------------------------------- 
2797 class wxLocaleModule
: public wxModule
 
2799     DECLARE_DYNAMIC_CLASS(wxLocaleModule
) 
2802         bool OnInit() { return true; } 
2803         void OnExit() { wxLocale::DestroyLanguagesDB(); } 
2806 IMPLEMENT_DYNAMIC_CLASS(wxLocaleModule
, wxModule
) 
2810 // ---------------------------------------------------------------------------- 
2811 // default languages table & initialization 
2812 // ---------------------------------------------------------------------------- 
2816 // --- --- --- generated code begins here --- --- --- 
2818 // This table is generated by misc/languages/genlang.py 
2819 // When making changes, please put them into misc/languages/langtabl.txt 
2821 #if !defined(__WIN32__) || defined(__WXMICROWIN__) 
2823 #define SETWINLANG(info,lang,sublang) 
2827 #define SETWINLANG(info,lang,sublang) \ 
2828     info.WinLang = lang, info.WinSublang = sublang; 
2830 #ifndef LANG_AFRIKAANS 
2831 #define LANG_AFRIKAANS (0) 
2833 #ifndef LANG_ALBANIAN 
2834 #define LANG_ALBANIAN (0) 
2837 #define LANG_ARABIC (0) 
2839 #ifndef LANG_ARMENIAN 
2840 #define LANG_ARMENIAN (0) 
2842 #ifndef LANG_ASSAMESE 
2843 #define LANG_ASSAMESE (0) 
2846 #define LANG_AZERI (0) 
2849 #define LANG_BASQUE (0) 
2851 #ifndef LANG_BELARUSIAN 
2852 #define LANG_BELARUSIAN (0) 
2854 #ifndef LANG_BENGALI 
2855 #define LANG_BENGALI (0) 
2857 #ifndef LANG_BULGARIAN 
2858 #define LANG_BULGARIAN (0) 
2860 #ifndef LANG_CATALAN 
2861 #define LANG_CATALAN (0) 
2863 #ifndef LANG_CHINESE 
2864 #define LANG_CHINESE (0) 
2866 #ifndef LANG_CROATIAN 
2867 #define LANG_CROATIAN (0) 
2870 #define LANG_CZECH (0) 
2873 #define LANG_DANISH (0) 
2876 #define LANG_DUTCH (0) 
2878 #ifndef LANG_ENGLISH 
2879 #define LANG_ENGLISH (0) 
2881 #ifndef LANG_ESTONIAN 
2882 #define LANG_ESTONIAN (0) 
2884 #ifndef LANG_FAEROESE 
2885 #define LANG_FAEROESE (0) 
2888 #define LANG_FARSI (0) 
2890 #ifndef LANG_FINNISH 
2891 #define LANG_FINNISH (0) 
2894 #define LANG_FRENCH (0) 
2896 #ifndef LANG_GEORGIAN 
2897 #define LANG_GEORGIAN (0) 
2900 #define LANG_GERMAN (0) 
2903 #define LANG_GREEK (0) 
2905 #ifndef LANG_GUJARATI 
2906 #define LANG_GUJARATI (0) 
2909 #define LANG_HEBREW (0) 
2912 #define LANG_HINDI (0) 
2914 #ifndef LANG_HUNGARIAN 
2915 #define LANG_HUNGARIAN (0) 
2917 #ifndef LANG_ICELANDIC 
2918 #define LANG_ICELANDIC (0) 
2920 #ifndef LANG_INDONESIAN 
2921 #define LANG_INDONESIAN (0) 
2923 #ifndef LANG_ITALIAN 
2924 #define LANG_ITALIAN (0) 
2926 #ifndef LANG_JAPANESE 
2927 #define LANG_JAPANESE (0) 
2929 #ifndef LANG_KANNADA 
2930 #define LANG_KANNADA (0) 
2932 #ifndef LANG_KASHMIRI 
2933 #define LANG_KASHMIRI (0) 
2936 #define LANG_KAZAK (0) 
2938 #ifndef LANG_KONKANI 
2939 #define LANG_KONKANI (0) 
2942 #define LANG_KOREAN (0) 
2944 #ifndef LANG_LATVIAN 
2945 #define LANG_LATVIAN (0) 
2947 #ifndef LANG_LITHUANIAN 
2948 #define LANG_LITHUANIAN (0) 
2950 #ifndef LANG_MACEDONIAN 
2951 #define LANG_MACEDONIAN (0) 
2954 #define LANG_MALAY (0) 
2956 #ifndef LANG_MALAYALAM 
2957 #define LANG_MALAYALAM (0) 
2959 #ifndef LANG_MANIPURI 
2960 #define LANG_MANIPURI (0) 
2962 #ifndef LANG_MARATHI 
2963 #define LANG_MARATHI (0) 
2966 #define LANG_NEPALI (0) 
2968 #ifndef LANG_NORWEGIAN 
2969 #define LANG_NORWEGIAN (0) 
2972 #define LANG_ORIYA (0) 
2975 #define LANG_POLISH (0) 
2977 #ifndef LANG_PORTUGUESE 
2978 #define LANG_PORTUGUESE (0) 
2980 #ifndef LANG_PUNJABI 
2981 #define LANG_PUNJABI (0) 
2983 #ifndef LANG_ROMANIAN 
2984 #define LANG_ROMANIAN (0) 
2986 #ifndef LANG_RUSSIAN 
2987 #define LANG_RUSSIAN (0) 
2989 #ifndef LANG_SANSKRIT 
2990 #define LANG_SANSKRIT (0) 
2992 #ifndef LANG_SERBIAN 
2993 #define LANG_SERBIAN (0) 
2996 #define LANG_SINDHI (0) 
2999 #define LANG_SLOVAK (0) 
3001 #ifndef LANG_SLOVENIAN 
3002 #define LANG_SLOVENIAN (0) 
3004 #ifndef LANG_SPANISH 
3005 #define LANG_SPANISH (0) 
3007 #ifndef LANG_SWAHILI 
3008 #define LANG_SWAHILI (0) 
3010 #ifndef LANG_SWEDISH 
3011 #define LANG_SWEDISH (0) 
3014 #define LANG_TAMIL (0) 
3017 #define LANG_TATAR (0) 
3020 #define LANG_TELUGU (0) 
3023 #define LANG_THAI (0) 
3025 #ifndef LANG_TURKISH 
3026 #define LANG_TURKISH (0) 
3028 #ifndef LANG_UKRAINIAN 
3029 #define LANG_UKRAINIAN (0) 
3032 #define LANG_URDU (0) 
3035 #define LANG_UZBEK (0) 
3037 #ifndef LANG_VIETNAMESE 
3038 #define LANG_VIETNAMESE (0) 
3040 #ifndef SUBLANG_ARABIC_ALGERIA 
3041 #define SUBLANG_ARABIC_ALGERIA SUBLANG_DEFAULT 
3043 #ifndef SUBLANG_ARABIC_BAHRAIN 
3044 #define SUBLANG_ARABIC_BAHRAIN SUBLANG_DEFAULT 
3046 #ifndef SUBLANG_ARABIC_EGYPT 
3047 #define SUBLANG_ARABIC_EGYPT SUBLANG_DEFAULT 
3049 #ifndef SUBLANG_ARABIC_IRAQ 
3050 #define SUBLANG_ARABIC_IRAQ SUBLANG_DEFAULT 
3052 #ifndef SUBLANG_ARABIC_JORDAN 
3053 #define SUBLANG_ARABIC_JORDAN SUBLANG_DEFAULT 
3055 #ifndef SUBLANG_ARABIC_KUWAIT 
3056 #define SUBLANG_ARABIC_KUWAIT SUBLANG_DEFAULT 
3058 #ifndef SUBLANG_ARABIC_LEBANON 
3059 #define SUBLANG_ARABIC_LEBANON SUBLANG_DEFAULT 
3061 #ifndef SUBLANG_ARABIC_LIBYA 
3062 #define SUBLANG_ARABIC_LIBYA SUBLANG_DEFAULT 
3064 #ifndef SUBLANG_ARABIC_MOROCCO 
3065 #define SUBLANG_ARABIC_MOROCCO SUBLANG_DEFAULT 
3067 #ifndef SUBLANG_ARABIC_OMAN 
3068 #define SUBLANG_ARABIC_OMAN SUBLANG_DEFAULT 
3070 #ifndef SUBLANG_ARABIC_QATAR 
3071 #define SUBLANG_ARABIC_QATAR SUBLANG_DEFAULT 
3073 #ifndef SUBLANG_ARABIC_SAUDI_ARABIA 
3074 #define SUBLANG_ARABIC_SAUDI_ARABIA SUBLANG_DEFAULT 
3076 #ifndef SUBLANG_ARABIC_SYRIA 
3077 #define SUBLANG_ARABIC_SYRIA SUBLANG_DEFAULT 
3079 #ifndef SUBLANG_ARABIC_TUNISIA 
3080 #define SUBLANG_ARABIC_TUNISIA SUBLANG_DEFAULT 
3082 #ifndef SUBLANG_ARABIC_UAE 
3083 #define SUBLANG_ARABIC_UAE SUBLANG_DEFAULT 
3085 #ifndef SUBLANG_ARABIC_YEMEN 
3086 #define SUBLANG_ARABIC_YEMEN SUBLANG_DEFAULT 
3088 #ifndef SUBLANG_AZERI_CYRILLIC 
3089 #define SUBLANG_AZERI_CYRILLIC SUBLANG_DEFAULT 
3091 #ifndef SUBLANG_AZERI_LATIN 
3092 #define SUBLANG_AZERI_LATIN SUBLANG_DEFAULT 
3094 #ifndef SUBLANG_CHINESE_SIMPLIFIED 
3095 #define SUBLANG_CHINESE_SIMPLIFIED SUBLANG_DEFAULT 
3097 #ifndef SUBLANG_CHINESE_TRADITIONAL 
3098 #define SUBLANG_CHINESE_TRADITIONAL SUBLANG_DEFAULT 
3100 #ifndef SUBLANG_CHINESE_HONGKONG 
3101 #define SUBLANG_CHINESE_HONGKONG SUBLANG_DEFAULT 
3103 #ifndef SUBLANG_CHINESE_MACAU 
3104 #define SUBLANG_CHINESE_MACAU SUBLANG_DEFAULT 
3106 #ifndef SUBLANG_CHINESE_SINGAPORE 
3107 #define SUBLANG_CHINESE_SINGAPORE SUBLANG_DEFAULT 
3109 #ifndef SUBLANG_DUTCH 
3110 #define SUBLANG_DUTCH SUBLANG_DEFAULT 
3112 #ifndef SUBLANG_DUTCH_BELGIAN 
3113 #define SUBLANG_DUTCH_BELGIAN SUBLANG_DEFAULT 
3115 #ifndef SUBLANG_ENGLISH_UK 
3116 #define SUBLANG_ENGLISH_UK SUBLANG_DEFAULT 
3118 #ifndef SUBLANG_ENGLISH_US 
3119 #define SUBLANG_ENGLISH_US SUBLANG_DEFAULT 
3121 #ifndef SUBLANG_ENGLISH_AUS 
3122 #define SUBLANG_ENGLISH_AUS SUBLANG_DEFAULT 
3124 #ifndef SUBLANG_ENGLISH_BELIZE 
3125 #define SUBLANG_ENGLISH_BELIZE SUBLANG_DEFAULT 
3127 #ifndef SUBLANG_ENGLISH_CAN 
3128 #define SUBLANG_ENGLISH_CAN SUBLANG_DEFAULT 
3130 #ifndef SUBLANG_ENGLISH_CARIBBEAN 
3131 #define SUBLANG_ENGLISH_CARIBBEAN SUBLANG_DEFAULT 
3133 #ifndef SUBLANG_ENGLISH_EIRE 
3134 #define SUBLANG_ENGLISH_EIRE SUBLANG_DEFAULT 
3136 #ifndef SUBLANG_ENGLISH_JAMAICA 
3137 #define SUBLANG_ENGLISH_JAMAICA SUBLANG_DEFAULT 
3139 #ifndef SUBLANG_ENGLISH_NZ 
3140 #define SUBLANG_ENGLISH_NZ SUBLANG_DEFAULT 
3142 #ifndef SUBLANG_ENGLISH_PHILIPPINES 
3143 #define SUBLANG_ENGLISH_PHILIPPINES SUBLANG_DEFAULT 
3145 #ifndef SUBLANG_ENGLISH_SOUTH_AFRICA 
3146 #define SUBLANG_ENGLISH_SOUTH_AFRICA SUBLANG_DEFAULT 
3148 #ifndef SUBLANG_ENGLISH_TRINIDAD 
3149 #define SUBLANG_ENGLISH_TRINIDAD SUBLANG_DEFAULT 
3151 #ifndef SUBLANG_ENGLISH_ZIMBABWE 
3152 #define SUBLANG_ENGLISH_ZIMBABWE SUBLANG_DEFAULT 
3154 #ifndef SUBLANG_FRENCH 
3155 #define SUBLANG_FRENCH SUBLANG_DEFAULT 
3157 #ifndef SUBLANG_FRENCH_BELGIAN 
3158 #define SUBLANG_FRENCH_BELGIAN SUBLANG_DEFAULT 
3160 #ifndef SUBLANG_FRENCH_CANADIAN 
3161 #define SUBLANG_FRENCH_CANADIAN SUBLANG_DEFAULT 
3163 #ifndef SUBLANG_FRENCH_LUXEMBOURG 
3164 #define SUBLANG_FRENCH_LUXEMBOURG SUBLANG_DEFAULT 
3166 #ifndef SUBLANG_FRENCH_MONACO 
3167 #define SUBLANG_FRENCH_MONACO SUBLANG_DEFAULT 
3169 #ifndef SUBLANG_FRENCH_SWISS 
3170 #define SUBLANG_FRENCH_SWISS SUBLANG_DEFAULT 
3172 #ifndef SUBLANG_GERMAN 
3173 #define SUBLANG_GERMAN SUBLANG_DEFAULT 
3175 #ifndef SUBLANG_GERMAN_AUSTRIAN 
3176 #define SUBLANG_GERMAN_AUSTRIAN SUBLANG_DEFAULT 
3178 #ifndef SUBLANG_GERMAN_LIECHTENSTEIN 
3179 #define SUBLANG_GERMAN_LIECHTENSTEIN SUBLANG_DEFAULT 
3181 #ifndef SUBLANG_GERMAN_LUXEMBOURG 
3182 #define SUBLANG_GERMAN_LUXEMBOURG SUBLANG_DEFAULT 
3184 #ifndef SUBLANG_GERMAN_SWISS 
3185 #define SUBLANG_GERMAN_SWISS SUBLANG_DEFAULT 
3187 #ifndef SUBLANG_ITALIAN 
3188 #define SUBLANG_ITALIAN SUBLANG_DEFAULT 
3190 #ifndef SUBLANG_ITALIAN_SWISS 
3191 #define SUBLANG_ITALIAN_SWISS SUBLANG_DEFAULT 
3193 #ifndef SUBLANG_KASHMIRI_INDIA 
3194 #define SUBLANG_KASHMIRI_INDIA SUBLANG_DEFAULT 
3196 #ifndef SUBLANG_KOREAN 
3197 #define SUBLANG_KOREAN SUBLANG_DEFAULT 
3199 #ifndef SUBLANG_LITHUANIAN 
3200 #define SUBLANG_LITHUANIAN SUBLANG_DEFAULT 
3202 #ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM 
3203 #define SUBLANG_MALAY_BRUNEI_DARUSSALAM SUBLANG_DEFAULT 
3205 #ifndef SUBLANG_MALAY_MALAYSIA 
3206 #define SUBLANG_MALAY_MALAYSIA SUBLANG_DEFAULT 
3208 #ifndef SUBLANG_NEPALI_INDIA 
3209 #define SUBLANG_NEPALI_INDIA SUBLANG_DEFAULT 
3211 #ifndef SUBLANG_NORWEGIAN_BOKMAL 
3212 #define SUBLANG_NORWEGIAN_BOKMAL SUBLANG_DEFAULT 
3214 #ifndef SUBLANG_NORWEGIAN_NYNORSK 
3215 #define SUBLANG_NORWEGIAN_NYNORSK SUBLANG_DEFAULT 
3217 #ifndef SUBLANG_PORTUGUESE 
3218 #define SUBLANG_PORTUGUESE SUBLANG_DEFAULT 
3220 #ifndef SUBLANG_PORTUGUESE_BRAZILIAN 
3221 #define SUBLANG_PORTUGUESE_BRAZILIAN SUBLANG_DEFAULT 
3223 #ifndef SUBLANG_SERBIAN_CYRILLIC 
3224 #define SUBLANG_SERBIAN_CYRILLIC SUBLANG_DEFAULT 
3226 #ifndef SUBLANG_SERBIAN_LATIN 
3227 #define SUBLANG_SERBIAN_LATIN SUBLANG_DEFAULT 
3229 #ifndef SUBLANG_SPANISH 
3230 #define SUBLANG_SPANISH SUBLANG_DEFAULT 
3232 #ifndef SUBLANG_SPANISH_ARGENTINA 
3233 #define SUBLANG_SPANISH_ARGENTINA SUBLANG_DEFAULT 
3235 #ifndef SUBLANG_SPANISH_BOLIVIA 
3236 #define SUBLANG_SPANISH_BOLIVIA SUBLANG_DEFAULT 
3238 #ifndef SUBLANG_SPANISH_CHILE 
3239 #define SUBLANG_SPANISH_CHILE SUBLANG_DEFAULT 
3241 #ifndef SUBLANG_SPANISH_COLOMBIA 
3242 #define SUBLANG_SPANISH_COLOMBIA SUBLANG_DEFAULT 
3244 #ifndef SUBLANG_SPANISH_COSTA_RICA 
3245 #define SUBLANG_SPANISH_COSTA_RICA SUBLANG_DEFAULT 
3247 #ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC 
3248 #define SUBLANG_SPANISH_DOMINICAN_REPUBLIC SUBLANG_DEFAULT 
3250 #ifndef SUBLANG_SPANISH_ECUADOR 
3251 #define SUBLANG_SPANISH_ECUADOR SUBLANG_DEFAULT 
3253 #ifndef SUBLANG_SPANISH_EL_SALVADOR 
3254 #define SUBLANG_SPANISH_EL_SALVADOR SUBLANG_DEFAULT 
3256 #ifndef SUBLANG_SPANISH_GUATEMALA 
3257 #define SUBLANG_SPANISH_GUATEMALA SUBLANG_DEFAULT 
3259 #ifndef SUBLANG_SPANISH_HONDURAS 
3260 #define SUBLANG_SPANISH_HONDURAS SUBLANG_DEFAULT 
3262 #ifndef SUBLANG_SPANISH_MEXICAN 
3263 #define SUBLANG_SPANISH_MEXICAN SUBLANG_DEFAULT 
3265 #ifndef SUBLANG_SPANISH_MODERN 
3266 #define SUBLANG_SPANISH_MODERN SUBLANG_DEFAULT 
3268 #ifndef SUBLANG_SPANISH_NICARAGUA 
3269 #define SUBLANG_SPANISH_NICARAGUA SUBLANG_DEFAULT 
3271 #ifndef SUBLANG_SPANISH_PANAMA 
3272 #define SUBLANG_SPANISH_PANAMA SUBLANG_DEFAULT 
3274 #ifndef SUBLANG_SPANISH_PARAGUAY 
3275 #define SUBLANG_SPANISH_PARAGUAY SUBLANG_DEFAULT 
3277 #ifndef SUBLANG_SPANISH_PERU 
3278 #define SUBLANG_SPANISH_PERU SUBLANG_DEFAULT 
3280 #ifndef SUBLANG_SPANISH_PUERTO_RICO 
3281 #define SUBLANG_SPANISH_PUERTO_RICO SUBLANG_DEFAULT 
3283 #ifndef SUBLANG_SPANISH_URUGUAY 
3284 #define SUBLANG_SPANISH_URUGUAY SUBLANG_DEFAULT 
3286 #ifndef SUBLANG_SPANISH_VENEZUELA 
3287 #define SUBLANG_SPANISH_VENEZUELA SUBLANG_DEFAULT 
3289 #ifndef SUBLANG_SWEDISH 
3290 #define SUBLANG_SWEDISH SUBLANG_DEFAULT 
3292 #ifndef SUBLANG_SWEDISH_FINLAND 
3293 #define SUBLANG_SWEDISH_FINLAND SUBLANG_DEFAULT 
3295 #ifndef SUBLANG_URDU_INDIA 
3296 #define SUBLANG_URDU_INDIA SUBLANG_DEFAULT 
3298 #ifndef SUBLANG_URDU_PAKISTAN 
3299 #define SUBLANG_URDU_PAKISTAN SUBLANG_DEFAULT 
3301 #ifndef SUBLANG_UZBEK_CYRILLIC 
3302 #define SUBLANG_UZBEK_CYRILLIC SUBLANG_DEFAULT 
3304 #ifndef SUBLANG_UZBEK_LATIN 
3305 #define SUBLANG_UZBEK_LATIN SUBLANG_DEFAULT 
3311 #define LNG(wxlang, canonical, winlang, winsublang, desc) \ 
3312     info.Language = wxlang;                               \ 
3313     info.CanonicalName = wxT(canonical);                  \ 
3314     info.Description = wxT(desc);                         \ 
3315     SETWINLANG(info, winlang, winsublang)                 \ 
3318 void wxLocale::InitLanguagesDB() 
3320    wxLanguageInfo info
; 
3321    wxStringTokenizer tkn
; 
3323    LNG(wxLANGUAGE_ABKHAZIAN
,                  "ab"   , 0              , 0                                 , "Abkhazian") 
3324    LNG(wxLANGUAGE_AFAR
,                       "aa"   , 0              , 0                                 , "Afar") 
3325    LNG(wxLANGUAGE_AFRIKAANS
,                  "af_ZA", LANG_AFRIKAANS 
, SUBLANG_DEFAULT                   
, "Afrikaans") 
3326    LNG(wxLANGUAGE_ALBANIAN
,                   "sq_AL", LANG_ALBANIAN  
, SUBLANG_DEFAULT                   
, "Albanian") 
3327    LNG(wxLANGUAGE_AMHARIC
,                    "am"   , 0              , 0                                 , "Amharic") 
3328    LNG(wxLANGUAGE_ARABIC
,                     "ar"   , LANG_ARABIC    
, SUBLANG_DEFAULT                   
, "Arabic") 
3329    LNG(wxLANGUAGE_ARABIC_ALGERIA
,             "ar_DZ", LANG_ARABIC    
, SUBLANG_ARABIC_ALGERIA            
, "Arabic (Algeria)") 
3330    LNG(wxLANGUAGE_ARABIC_BAHRAIN
,             "ar_BH", LANG_ARABIC    
, SUBLANG_ARABIC_BAHRAIN            
, "Arabic (Bahrain)") 
3331    LNG(wxLANGUAGE_ARABIC_EGYPT
,               "ar_EG", LANG_ARABIC    
, SUBLANG_ARABIC_EGYPT              
, "Arabic (Egypt)") 
3332    LNG(wxLANGUAGE_ARABIC_IRAQ
,                "ar_IQ", LANG_ARABIC    
, SUBLANG_ARABIC_IRAQ               
, "Arabic (Iraq)") 
3333    LNG(wxLANGUAGE_ARABIC_JORDAN
,              "ar_JO", LANG_ARABIC    
, SUBLANG_ARABIC_JORDAN             
, "Arabic (Jordan)") 
3334    LNG(wxLANGUAGE_ARABIC_KUWAIT
,              "ar_KW", LANG_ARABIC    
, SUBLANG_ARABIC_KUWAIT             
, "Arabic (Kuwait)") 
3335    LNG(wxLANGUAGE_ARABIC_LEBANON
,             "ar_LB", LANG_ARABIC    
, SUBLANG_ARABIC_LEBANON            
, "Arabic (Lebanon)") 
3336    LNG(wxLANGUAGE_ARABIC_LIBYA
,               "ar_LY", LANG_ARABIC    
, SUBLANG_ARABIC_LIBYA              
, "Arabic (Libya)") 
3337    LNG(wxLANGUAGE_ARABIC_MOROCCO
,             "ar_MA", LANG_ARABIC    
, SUBLANG_ARABIC_MOROCCO            
, "Arabic (Morocco)") 
3338    LNG(wxLANGUAGE_ARABIC_OMAN
,                "ar_OM", LANG_ARABIC    
, SUBLANG_ARABIC_OMAN               
, "Arabic (Oman)") 
3339    LNG(wxLANGUAGE_ARABIC_QATAR
,               "ar_QA", LANG_ARABIC    
, SUBLANG_ARABIC_QATAR              
, "Arabic (Qatar)") 
3340    LNG(wxLANGUAGE_ARABIC_SAUDI_ARABIA
,        "ar_SA", LANG_ARABIC    
, SUBLANG_ARABIC_SAUDI_ARABIA       
, "Arabic (Saudi Arabia)") 
3341    LNG(wxLANGUAGE_ARABIC_SUDAN
,               "ar_SD", 0              , 0                                 , "Arabic (Sudan)") 
3342    LNG(wxLANGUAGE_ARABIC_SYRIA
,               "ar_SY", LANG_ARABIC    
, SUBLANG_ARABIC_SYRIA              
, "Arabic (Syria)") 
3343    LNG(wxLANGUAGE_ARABIC_TUNISIA
,             "ar_TN", LANG_ARABIC    
, SUBLANG_ARABIC_TUNISIA            
, "Arabic (Tunisia)") 
3344    LNG(wxLANGUAGE_ARABIC_UAE
,                 "ar_AE", LANG_ARABIC    
, SUBLANG_ARABIC_UAE                
, "Arabic (Uae)") 
3345    LNG(wxLANGUAGE_ARABIC_YEMEN
,               "ar_YE", LANG_ARABIC    
, SUBLANG_ARABIC_YEMEN              
, "Arabic (Yemen)") 
3346    LNG(wxLANGUAGE_ARMENIAN
,                   "hy"   , LANG_ARMENIAN  
, SUBLANG_DEFAULT                   
, "Armenian") 
3347    LNG(wxLANGUAGE_ASSAMESE
,                   "as"   , LANG_ASSAMESE  
, SUBLANG_DEFAULT                   
, "Assamese") 
3348    LNG(wxLANGUAGE_AYMARA
,                     "ay"   , 0              , 0                                 , "Aymara") 
3349    LNG(wxLANGUAGE_AZERI
,                      "az"   , LANG_AZERI     
, SUBLANG_DEFAULT                   
, "Azeri") 
3350    LNG(wxLANGUAGE_AZERI_CYRILLIC
,             "az"   , LANG_AZERI     
, SUBLANG_AZERI_CYRILLIC            
, "Azeri (Cyrillic)") 
3351    LNG(wxLANGUAGE_AZERI_LATIN
,                "az"   , LANG_AZERI     
, SUBLANG_AZERI_LATIN               
, "Azeri (Latin)") 
3352    LNG(wxLANGUAGE_BASHKIR
,                    "ba"   , 0              , 0                                 , "Bashkir") 
3353    LNG(wxLANGUAGE_BASQUE
,                     "eu_ES", LANG_BASQUE    
, SUBLANG_DEFAULT                   
, "Basque") 
3354    LNG(wxLANGUAGE_BELARUSIAN
,                 "be_BY", LANG_BELARUSIAN
, SUBLANG_DEFAULT                   
, "Belarusian") 
3355    LNG(wxLANGUAGE_BENGALI
,                    "bn"   , LANG_BENGALI   
, SUBLANG_DEFAULT                   
, "Bengali") 
3356    LNG(wxLANGUAGE_BHUTANI
,                    "dz"   , 0              , 0                                 , "Bhutani") 
3357    LNG(wxLANGUAGE_BIHARI
,                     "bh"   , 0              , 0                                 , "Bihari") 
3358    LNG(wxLANGUAGE_BISLAMA
,                    "bi"   , 0              , 0                                 , "Bislama") 
3359    LNG(wxLANGUAGE_BRETON
,                     "br"   , 0              , 0                                 , "Breton") 
3360    LNG(wxLANGUAGE_BULGARIAN
,                  "bg_BG", LANG_BULGARIAN 
, SUBLANG_DEFAULT                   
, "Bulgarian") 
3361    LNG(wxLANGUAGE_BURMESE
,                    "my"   , 0              , 0                                 , "Burmese") 
3362    LNG(wxLANGUAGE_CAMBODIAN
,                  "km"   , 0              , 0                                 , "Cambodian") 
3363    LNG(wxLANGUAGE_CATALAN
,                    "ca_ES", LANG_CATALAN   
, SUBLANG_DEFAULT                   
, "Catalan") 
3364    LNG(wxLANGUAGE_CHINESE
,                    "zh_TW", LANG_CHINESE   
, SUBLANG_DEFAULT                   
, "Chinese") 
3365    LNG(wxLANGUAGE_CHINESE_SIMPLIFIED
,         "zh_CN", LANG_CHINESE   
, SUBLANG_CHINESE_SIMPLIFIED        
, "Chinese (Simplified)") 
3366    LNG(wxLANGUAGE_CHINESE_TRADITIONAL
,        "zh_TW", LANG_CHINESE   
, SUBLANG_CHINESE_TRADITIONAL       
, "Chinese (Traditional)") 
3367    LNG(wxLANGUAGE_CHINESE_HONGKONG
,           "zh_HK", LANG_CHINESE   
, SUBLANG_CHINESE_HONGKONG          
, "Chinese (Hongkong)") 
3368    LNG(wxLANGUAGE_CHINESE_MACAU
,              "zh_MO", LANG_CHINESE   
, SUBLANG_CHINESE_MACAU             
, "Chinese (Macau)") 
3369    LNG(wxLANGUAGE_CHINESE_SINGAPORE
,          "zh_SG", LANG_CHINESE   
, SUBLANG_CHINESE_SINGAPORE         
, "Chinese (Singapore)") 
3370    LNG(wxLANGUAGE_CHINESE_TAIWAN
,             "zh_TW", LANG_CHINESE   
, SUBLANG_CHINESE_TRADITIONAL       
, "Chinese (Taiwan)") 
3371    LNG(wxLANGUAGE_CORSICAN
,                   "co"   , 0              , 0                                 , "Corsican") 
3372    LNG(wxLANGUAGE_CROATIAN
,                   "hr_HR", LANG_CROATIAN  
, SUBLANG_DEFAULT                   
, "Croatian") 
3373    LNG(wxLANGUAGE_CZECH
,                      "cs_CZ", LANG_CZECH     
, SUBLANG_DEFAULT                   
, "Czech") 
3374    LNG(wxLANGUAGE_DANISH
,                     "da_DK", LANG_DANISH    
, SUBLANG_DEFAULT                   
, "Danish") 
3375    LNG(wxLANGUAGE_DUTCH
,                      "nl_NL", LANG_DUTCH     
, SUBLANG_DUTCH                     
, "Dutch") 
3376    LNG(wxLANGUAGE_DUTCH_BELGIAN
,              "nl_BE", LANG_DUTCH     
, SUBLANG_DUTCH_BELGIAN             
, "Dutch (Belgian)") 
3377    LNG(wxLANGUAGE_ENGLISH
,                    "en_GB", LANG_ENGLISH   
, SUBLANG_ENGLISH_UK                
, "English") 
3378    LNG(wxLANGUAGE_ENGLISH_UK
,                 "en_GB", LANG_ENGLISH   
, SUBLANG_ENGLISH_UK                
, "English (U.K.)") 
3379    LNG(wxLANGUAGE_ENGLISH_US
,                 "en_US", LANG_ENGLISH   
, SUBLANG_ENGLISH_US                
, "English (U.S.)") 
3380    LNG(wxLANGUAGE_ENGLISH_AUSTRALIA
,          "en_AU", LANG_ENGLISH   
, SUBLANG_ENGLISH_AUS               
, "English (Australia)") 
3381    LNG(wxLANGUAGE_ENGLISH_BELIZE
,             "en_BZ", LANG_ENGLISH   
, SUBLANG_ENGLISH_BELIZE            
, "English (Belize)") 
3382    LNG(wxLANGUAGE_ENGLISH_BOTSWANA
,           "en_BW", 0              , 0                                 , "English (Botswana)") 
3383    LNG(wxLANGUAGE_ENGLISH_CANADA
,             "en_CA", LANG_ENGLISH   
, SUBLANG_ENGLISH_CAN               
, "English (Canada)") 
3384    LNG(wxLANGUAGE_ENGLISH_CARIBBEAN
,          "en_CB", LANG_ENGLISH   
, SUBLANG_ENGLISH_CARIBBEAN         
, "English (Caribbean)") 
3385    LNG(wxLANGUAGE_ENGLISH_DENMARK
,            "en_DK", 0              , 0                                 , "English (Denmark)") 
3386    LNG(wxLANGUAGE_ENGLISH_EIRE
,               "en_IE", LANG_ENGLISH   
, SUBLANG_ENGLISH_EIRE              
, "English (Eire)") 
3387    LNG(wxLANGUAGE_ENGLISH_JAMAICA
,            "en_JM", LANG_ENGLISH   
, SUBLANG_ENGLISH_JAMAICA           
, "English (Jamaica)") 
3388    LNG(wxLANGUAGE_ENGLISH_NEW_ZEALAND
,        "en_NZ", LANG_ENGLISH   
, SUBLANG_ENGLISH_NZ                
, "English (New Zealand)") 
3389    LNG(wxLANGUAGE_ENGLISH_PHILIPPINES
,        "en_PH", LANG_ENGLISH   
, SUBLANG_ENGLISH_PHILIPPINES       
, "English (Philippines)") 
3390    LNG(wxLANGUAGE_ENGLISH_SOUTH_AFRICA
,       "en_ZA", LANG_ENGLISH   
, SUBLANG_ENGLISH_SOUTH_AFRICA      
, "English (South Africa)") 
3391    LNG(wxLANGUAGE_ENGLISH_TRINIDAD
,           "en_TT", LANG_ENGLISH   
, SUBLANG_ENGLISH_TRINIDAD          
, "English (Trinidad)") 
3392    LNG(wxLANGUAGE_ENGLISH_ZIMBABWE
,           "en_ZW", LANG_ENGLISH   
, SUBLANG_ENGLISH_ZIMBABWE          
, "English (Zimbabwe)") 
3393    LNG(wxLANGUAGE_ESPERANTO
,                  "eo"   , 0              , 0                                 , "Esperanto") 
3394    LNG(wxLANGUAGE_ESTONIAN
,                   "et_EE", LANG_ESTONIAN  
, SUBLANG_DEFAULT                   
, "Estonian") 
3395    LNG(wxLANGUAGE_FAEROESE
,                   "fo_FO", LANG_FAEROESE  
, SUBLANG_DEFAULT                   
, "Faeroese") 
3396    LNG(wxLANGUAGE_FARSI
,                      "fa_IR", LANG_FARSI     
, SUBLANG_DEFAULT                   
, "Farsi") 
3397    LNG(wxLANGUAGE_FIJI
,                       "fj"   , 0              , 0                                 , "Fiji") 
3398    LNG(wxLANGUAGE_FINNISH
,                    "fi_FI", LANG_FINNISH   
, SUBLANG_DEFAULT                   
, "Finnish") 
3399    LNG(wxLANGUAGE_FRENCH
,                     "fr_FR", LANG_FRENCH    
, SUBLANG_FRENCH                    
, "French") 
3400    LNG(wxLANGUAGE_FRENCH_BELGIAN
,             "fr_BE", LANG_FRENCH    
, SUBLANG_FRENCH_BELGIAN            
, "French (Belgian)") 
3401    LNG(wxLANGUAGE_FRENCH_CANADIAN
,            "fr_CA", LANG_FRENCH    
, SUBLANG_FRENCH_CANADIAN           
, "French (Canadian)") 
3402    LNG(wxLANGUAGE_FRENCH_LUXEMBOURG
,          "fr_LU", LANG_FRENCH    
, SUBLANG_FRENCH_LUXEMBOURG         
, "French (Luxembourg)") 
3403    LNG(wxLANGUAGE_FRENCH_MONACO
,              "fr_MC", LANG_FRENCH    
, SUBLANG_FRENCH_MONACO             
, "French (Monaco)") 
3404    LNG(wxLANGUAGE_FRENCH_SWISS
,               "fr_CH", LANG_FRENCH    
, SUBLANG_FRENCH_SWISS              
, "French (Swiss)") 
3405    LNG(wxLANGUAGE_FRISIAN
,                    "fy"   , 0              , 0                                 , "Frisian") 
3406    LNG(wxLANGUAGE_GALICIAN
,                   "gl_ES", 0              , 0                                 , "Galician") 
3407    LNG(wxLANGUAGE_GEORGIAN
,                   "ka"   , LANG_GEORGIAN  
, SUBLANG_DEFAULT                   
, "Georgian") 
3408    LNG(wxLANGUAGE_GERMAN
,                     "de_DE", LANG_GERMAN    
, SUBLANG_GERMAN                    
, "German") 
3409    LNG(wxLANGUAGE_GERMAN_AUSTRIAN
,            "de_AT", LANG_GERMAN    
, SUBLANG_GERMAN_AUSTRIAN           
, "German (Austrian)") 
3410    LNG(wxLANGUAGE_GERMAN_BELGIUM
,             "de_BE", 0              , 0                                 , "German (Belgium)") 
3411    LNG(wxLANGUAGE_GERMAN_LIECHTENSTEIN
,       "de_LI", LANG_GERMAN    
, SUBLANG_GERMAN_LIECHTENSTEIN      
, "German (Liechtenstein)") 
3412    LNG(wxLANGUAGE_GERMAN_LUXEMBOURG
,          "de_LU", LANG_GERMAN    
, SUBLANG_GERMAN_LUXEMBOURG         
, "German (Luxembourg)") 
3413    LNG(wxLANGUAGE_GERMAN_SWISS
,               "de_CH", LANG_GERMAN    
, SUBLANG_GERMAN_SWISS              
, "German (Swiss)") 
3414    LNG(wxLANGUAGE_GREEK
,                      "el_GR", LANG_GREEK     
, SUBLANG_DEFAULT                   
, "Greek") 
3415    LNG(wxLANGUAGE_GREENLANDIC
,                "kl_GL", 0              , 0                                 , "Greenlandic") 
3416    LNG(wxLANGUAGE_GUARANI
,                    "gn"   , 0              , 0                                 , "Guarani") 
3417    LNG(wxLANGUAGE_GUJARATI
,                   "gu"   , LANG_GUJARATI  
, SUBLANG_DEFAULT                   
, "Gujarati") 
3418    LNG(wxLANGUAGE_HAUSA
,                      "ha"   , 0              , 0                                 , "Hausa") 
3419    LNG(wxLANGUAGE_HEBREW
,                     "he_IL", LANG_HEBREW    
, SUBLANG_DEFAULT                   
, "Hebrew") 
3420    LNG(wxLANGUAGE_HINDI
,                      "hi_IN", LANG_HINDI     
, SUBLANG_DEFAULT                   
, "Hindi") 
3421    LNG(wxLANGUAGE_HUNGARIAN
,                  "hu_HU", LANG_HUNGARIAN 
, SUBLANG_DEFAULT                   
, "Hungarian") 
3422    LNG(wxLANGUAGE_ICELANDIC
,                  "is_IS", LANG_ICELANDIC 
, SUBLANG_DEFAULT                   
, "Icelandic") 
3423    LNG(wxLANGUAGE_INDONESIAN
,                 "id_ID", LANG_INDONESIAN
, SUBLANG_DEFAULT                   
, "Indonesian") 
3424    LNG(wxLANGUAGE_INTERLINGUA
,                "ia"   , 0              , 0                                 , "Interlingua") 
3425    LNG(wxLANGUAGE_INTERLINGUE
,                "ie"   , 0              , 0                                 , "Interlingue") 
3426    LNG(wxLANGUAGE_INUKTITUT
,                  "iu"   , 0              , 0                                 , "Inuktitut") 
3427    LNG(wxLANGUAGE_INUPIAK
,                    "ik"   , 0              , 0                                 , "Inupiak") 
3428    LNG(wxLANGUAGE_IRISH
,                      "ga_IE", 0              , 0                                 , "Irish") 
3429    LNG(wxLANGUAGE_ITALIAN
,                    "it_IT", LANG_ITALIAN   
, SUBLANG_ITALIAN                   
, "Italian") 
3430    LNG(wxLANGUAGE_ITALIAN_SWISS
,              "it_CH", LANG_ITALIAN   
, SUBLANG_ITALIAN_SWISS             
, "Italian (Swiss)") 
3431    LNG(wxLANGUAGE_JAPANESE
,                   "ja_JP", LANG_JAPANESE  
, SUBLANG_DEFAULT                   
, "Japanese") 
3432    LNG(wxLANGUAGE_JAVANESE
,                   "jw"   , 0              , 0                                 , "Javanese") 
3433    LNG(wxLANGUAGE_KANNADA
,                    "kn"   , LANG_KANNADA   
, SUBLANG_DEFAULT                   
, "Kannada") 
3434    LNG(wxLANGUAGE_KASHMIRI
,                   "ks"   , LANG_KASHMIRI  
, SUBLANG_DEFAULT                   
, "Kashmiri") 
3435    LNG(wxLANGUAGE_KASHMIRI_INDIA
,             "ks_IN", LANG_KASHMIRI  
, SUBLANG_KASHMIRI_INDIA            
, "Kashmiri (India)") 
3436    LNG(wxLANGUAGE_KAZAKH
,                     "kk"   , LANG_KAZAK     
, SUBLANG_DEFAULT                   
, "Kazakh") 
3437    LNG(wxLANGUAGE_KERNEWEK
,                   "kw_GB", 0              , 0                                 , "Kernewek") 
3438    LNG(wxLANGUAGE_KINYARWANDA
,                "rw"   , 0              , 0                                 , "Kinyarwanda") 
3439    LNG(wxLANGUAGE_KIRGHIZ
,                    "ky"   , 0              , 0                                 , "Kirghiz") 
3440    LNG(wxLANGUAGE_KIRUNDI
,                    "rn"   , 0              , 0                                 , "Kirundi") 
3441    LNG(wxLANGUAGE_KONKANI
,                    ""     , LANG_KONKANI   
, SUBLANG_DEFAULT                   
, "Konkani") 
3442    LNG(wxLANGUAGE_KOREAN
,                     "ko_KR", LANG_KOREAN    
, SUBLANG_KOREAN                    
, "Korean") 
3443    LNG(wxLANGUAGE_KURDISH
,                    "ku"   , 0              , 0                                 , "Kurdish") 
3444    LNG(wxLANGUAGE_LAOTHIAN
,                   "lo"   , 0              , 0                                 , "Laothian") 
3445    LNG(wxLANGUAGE_LATIN
,                      "la"   , 0              , 0                                 , "Latin") 
3446    LNG(wxLANGUAGE_LATVIAN
,                    "lv_LV", LANG_LATVIAN   
, SUBLANG_DEFAULT                   
, "Latvian") 
3447    LNG(wxLANGUAGE_LINGALA
,                    "ln"   , 0              , 0                                 , "Lingala") 
3448    LNG(wxLANGUAGE_LITHUANIAN
,                 "lt_LT", LANG_LITHUANIAN
, SUBLANG_LITHUANIAN                
, "Lithuanian") 
3449    LNG(wxLANGUAGE_MACEDONIAN
,                 "mk_MK", LANG_MACEDONIAN
, SUBLANG_DEFAULT                   
, "Macedonian") 
3450    LNG(wxLANGUAGE_MALAGASY
,                   "mg"   , 0              , 0                                 , "Malagasy") 
3451    LNG(wxLANGUAGE_MALAY
,                      "ms_MY", LANG_MALAY     
, SUBLANG_DEFAULT                   
, "Malay") 
3452    LNG(wxLANGUAGE_MALAYALAM
,                  "ml"   , LANG_MALAYALAM 
, SUBLANG_DEFAULT                   
, "Malayalam") 
3453    LNG(wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM
,    "ms_BN", LANG_MALAY     
, SUBLANG_MALAY_BRUNEI_DARUSSALAM   
, "Malay (Brunei Darussalam)") 
3454    LNG(wxLANGUAGE_MALAY_MALAYSIA
,             "ms_MY", LANG_MALAY     
, SUBLANG_MALAY_MALAYSIA            
, "Malay (Malaysia)") 
3455    LNG(wxLANGUAGE_MALTESE
,                    "mt_MT", 0              , 0                                 , "Maltese") 
3456    LNG(wxLANGUAGE_MANIPURI
,                   ""     , LANG_MANIPURI  
, SUBLANG_DEFAULT                   
, "Manipuri") 
3457    LNG(wxLANGUAGE_MAORI
,                      "mi"   , 0              , 0                                 , "Maori") 
3458    LNG(wxLANGUAGE_MARATHI
,                    "mr_IN", LANG_MARATHI   
, SUBLANG_DEFAULT                   
, "Marathi") 
3459    LNG(wxLANGUAGE_MOLDAVIAN
,                  "mo"   , 0              , 0                                 , "Moldavian") 
3460    LNG(wxLANGUAGE_MONGOLIAN
,                  "mn"   , 0              , 0                                 , "Mongolian") 
3461    LNG(wxLANGUAGE_NAURU
,                      "na"   , 0              , 0                                 , "Nauru") 
3462    LNG(wxLANGUAGE_NEPALI
,                     "ne"   , LANG_NEPALI    
, SUBLANG_DEFAULT                   
, "Nepali") 
3463    LNG(wxLANGUAGE_NEPALI_INDIA
,               "ne_IN", LANG_NEPALI    
, SUBLANG_NEPALI_INDIA              
, "Nepali (India)") 
3464    LNG(wxLANGUAGE_NORWEGIAN_BOKMAL
,           "nb_NO", LANG_NORWEGIAN 
, SUBLANG_NORWEGIAN_BOKMAL          
, "Norwegian (Bokmal)") 
3465    LNG(wxLANGUAGE_NORWEGIAN_NYNORSK
,          "nn_NO", LANG_NORWEGIAN 
, SUBLANG_NORWEGIAN_NYNORSK         
, "Norwegian (Nynorsk)") 
3466    LNG(wxLANGUAGE_OCCITAN
,                    "oc"   , 0              , 0                                 , "Occitan") 
3467    LNG(wxLANGUAGE_ORIYA
,                      "or"   , LANG_ORIYA     
, SUBLANG_DEFAULT                   
, "Oriya") 
3468    LNG(wxLANGUAGE_OROMO
,                      "om"   , 0              , 0                                 , "(Afan) Oromo") 
3469    LNG(wxLANGUAGE_PASHTO
,                     "ps"   , 0              , 0                                 , "Pashto, Pushto") 
3470    LNG(wxLANGUAGE_POLISH
,                     "pl_PL", LANG_POLISH    
, SUBLANG_DEFAULT                   
, "Polish") 
3471    LNG(wxLANGUAGE_PORTUGUESE
,                 "pt_PT", LANG_PORTUGUESE
, SUBLANG_PORTUGUESE                
, "Portuguese") 
3472    LNG(wxLANGUAGE_PORTUGUESE_BRAZILIAN
,       "pt_BR", LANG_PORTUGUESE
, SUBLANG_PORTUGUESE_BRAZILIAN      
, "Portuguese (Brazilian)") 
3473    LNG(wxLANGUAGE_PUNJABI
,                    "pa"   , LANG_PUNJABI   
, SUBLANG_DEFAULT                   
, "Punjabi") 
3474    LNG(wxLANGUAGE_QUECHUA
,                    "qu"   , 0              , 0                                 , "Quechua") 
3475    LNG(wxLANGUAGE_RHAETO_ROMANCE
,             "rm"   , 0              , 0                                 , "Rhaeto-Romance") 
3476    LNG(wxLANGUAGE_ROMANIAN
,                   "ro_RO", LANG_ROMANIAN  
, SUBLANG_DEFAULT                   
, "Romanian") 
3477    LNG(wxLANGUAGE_RUSSIAN
,                    "ru_RU", LANG_RUSSIAN   
, SUBLANG_DEFAULT                   
, "Russian") 
3478    LNG(wxLANGUAGE_RUSSIAN_UKRAINE
,            "ru_UA", 0              , 0                                 , "Russian (Ukraine)") 
3479    LNG(wxLANGUAGE_SAMOAN
,                     "sm"   , 0              , 0                                 , "Samoan") 
3480    LNG(wxLANGUAGE_SANGHO
,                     "sg"   , 0              , 0                                 , "Sangho") 
3481    LNG(wxLANGUAGE_SANSKRIT
,                   "sa"   , LANG_SANSKRIT  
, SUBLANG_DEFAULT                   
, "Sanskrit") 
3482    LNG(wxLANGUAGE_SCOTS_GAELIC
,               "gd"   , 0              , 0                                 , "Scots Gaelic") 
3483    LNG(wxLANGUAGE_SERBIAN
,                    "sr_YU", LANG_SERBIAN   
, SUBLANG_DEFAULT                   
, "Serbian") 
3484    LNG(wxLANGUAGE_SERBIAN_CYRILLIC
,           "sr_YU", LANG_SERBIAN   
, SUBLANG_SERBIAN_CYRILLIC          
, "Serbian (Cyrillic)") 
3485    LNG(wxLANGUAGE_SERBIAN_LATIN
,              "sr_YU", LANG_SERBIAN   
, SUBLANG_SERBIAN_LATIN             
, "Serbian (Latin)") 
3486    LNG(wxLANGUAGE_SERBO_CROATIAN
,             "sh"   , 0              , 0                                 , "Serbo-Croatian") 
3487    LNG(wxLANGUAGE_SESOTHO
,                    "st"   , 0              , 0                                 , "Sesotho") 
3488    LNG(wxLANGUAGE_SETSWANA
,                   "tn"   , 0              , 0                                 , "Setswana") 
3489    LNG(wxLANGUAGE_SHONA
,                      "sn"   , 0              , 0                                 , "Shona") 
3490    LNG(wxLANGUAGE_SINDHI
,                     "sd"   , LANG_SINDHI    
, SUBLANG_DEFAULT                   
, "Sindhi") 
3491    LNG(wxLANGUAGE_SINHALESE
,                  "si"   , 0              , 0                                 , "Sinhalese") 
3492    LNG(wxLANGUAGE_SISWATI
,                    "ss"   , 0              , 0                                 , "Siswati") 
3493    LNG(wxLANGUAGE_SLOVAK
,                     "sk_SK", LANG_SLOVAK    
, SUBLANG_DEFAULT                   
, "Slovak") 
3494    LNG(wxLANGUAGE_SLOVENIAN
,                  "sl_SI", LANG_SLOVENIAN 
, SUBLANG_DEFAULT                   
, "Slovenian") 
3495    LNG(wxLANGUAGE_SOMALI
,                     "so"   , 0              , 0                                 , "Somali") 
3496    LNG(wxLANGUAGE_SPANISH
,                    "es_ES", LANG_SPANISH   
, SUBLANG_SPANISH                   
, "Spanish") 
3497    LNG(wxLANGUAGE_SPANISH_ARGENTINA
,          "es_AR", LANG_SPANISH   
, SUBLANG_SPANISH_ARGENTINA         
, "Spanish (Argentina)") 
3498    LNG(wxLANGUAGE_SPANISH_BOLIVIA
,            "es_BO", LANG_SPANISH   
, SUBLANG_SPANISH_BOLIVIA           
, "Spanish (Bolivia)") 
3499    LNG(wxLANGUAGE_SPANISH_CHILE
,              "es_CL", LANG_SPANISH   
, SUBLANG_SPANISH_CHILE             
, "Spanish (Chile)") 
3500    LNG(wxLANGUAGE_SPANISH_COLOMBIA
,           "es_CO", LANG_SPANISH   
, SUBLANG_SPANISH_COLOMBIA          
, "Spanish (Colombia)") 
3501    LNG(wxLANGUAGE_SPANISH_COSTA_RICA
,         "es_CR", LANG_SPANISH   
, SUBLANG_SPANISH_COSTA_RICA        
, "Spanish (Costa Rica)") 
3502    LNG(wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC
, "es_DO", LANG_SPANISH   
, SUBLANG_SPANISH_DOMINICAN_REPUBLIC
, "Spanish (Dominican republic)") 
3503    LNG(wxLANGUAGE_SPANISH_ECUADOR
,            "es_EC", LANG_SPANISH   
, SUBLANG_SPANISH_ECUADOR           
, "Spanish (Ecuador)") 
3504    LNG(wxLANGUAGE_SPANISH_EL_SALVADOR
,        "es_SV", LANG_SPANISH   
, SUBLANG_SPANISH_EL_SALVADOR       
, "Spanish (El Salvador)") 
3505    LNG(wxLANGUAGE_SPANISH_GUATEMALA
,          "es_GT", LANG_SPANISH   
, SUBLANG_SPANISH_GUATEMALA         
, "Spanish (Guatemala)") 
3506    LNG(wxLANGUAGE_SPANISH_HONDURAS
,           "es_HN", LANG_SPANISH   
, SUBLANG_SPANISH_HONDURAS          
, "Spanish (Honduras)") 
3507    LNG(wxLANGUAGE_SPANISH_MEXICAN
,            "es_MX", LANG_SPANISH   
, SUBLANG_SPANISH_MEXICAN           
, "Spanish (Mexican)") 
3508    LNG(wxLANGUAGE_SPANISH_MODERN
,             "es_ES", LANG_SPANISH   
, SUBLANG_SPANISH_MODERN            
, "Spanish (Modern)") 
3509    LNG(wxLANGUAGE_SPANISH_NICARAGUA
,          "es_NI", LANG_SPANISH   
, SUBLANG_SPANISH_NICARAGUA         
, "Spanish (Nicaragua)") 
3510    LNG(wxLANGUAGE_SPANISH_PANAMA
,             "es_PA", LANG_SPANISH   
, SUBLANG_SPANISH_PANAMA            
, "Spanish (Panama)") 
3511    LNG(wxLANGUAGE_SPANISH_PARAGUAY
,           "es_PY", LANG_SPANISH   
, SUBLANG_SPANISH_PARAGUAY          
, "Spanish (Paraguay)") 
3512    LNG(wxLANGUAGE_SPANISH_PERU
,               "es_PE", LANG_SPANISH   
, SUBLANG_SPANISH_PERU              
, "Spanish (Peru)") 
3513    LNG(wxLANGUAGE_SPANISH_PUERTO_RICO
,        "es_PR", LANG_SPANISH   
, SUBLANG_SPANISH_PUERTO_RICO       
, "Spanish (Puerto Rico)") 
3514    LNG(wxLANGUAGE_SPANISH_URUGUAY
,            "es_UY", LANG_SPANISH   
, SUBLANG_SPANISH_URUGUAY           
, "Spanish (Uruguay)") 
3515    LNG(wxLANGUAGE_SPANISH_US
,                 "es_US", 0              , 0                                 , "Spanish (U.S.)") 
3516    LNG(wxLANGUAGE_SPANISH_VENEZUELA
,          "es_VE", LANG_SPANISH   
, SUBLANG_SPANISH_VENEZUELA         
, "Spanish (Venezuela)") 
3517    LNG(wxLANGUAGE_SUNDANESE
,                  "su"   , 0              , 0                                 , "Sundanese") 
3518    LNG(wxLANGUAGE_SWAHILI
,                    "sw_KE", LANG_SWAHILI   
, SUBLANG_DEFAULT                   
, "Swahili") 
3519    LNG(wxLANGUAGE_SWEDISH
,                    "sv_SE", LANG_SWEDISH   
, SUBLANG_SWEDISH                   
, "Swedish") 
3520    LNG(wxLANGUAGE_SWEDISH_FINLAND
,            "sv_FI", LANG_SWEDISH   
, SUBLANG_SWEDISH_FINLAND           
, "Swedish (Finland)") 
3521    LNG(wxLANGUAGE_TAGALOG
,                    "tl_PH", 0              , 0                                 , "Tagalog") 
3522    LNG(wxLANGUAGE_TAJIK
,                      "tg"   , 0              , 0                                 , "Tajik") 
3523    LNG(wxLANGUAGE_TAMIL
,                      "ta"   , LANG_TAMIL     
, SUBLANG_DEFAULT                   
, "Tamil") 
3524    LNG(wxLANGUAGE_TATAR
,                      "tt"   , LANG_TATAR     
, SUBLANG_DEFAULT                   
, "Tatar") 
3525    LNG(wxLANGUAGE_TELUGU
,                     "te"   , LANG_TELUGU    
, SUBLANG_DEFAULT                   
, "Telugu") 
3526    LNG(wxLANGUAGE_THAI
,                       "th_TH", LANG_THAI      
, SUBLANG_DEFAULT                   
, "Thai") 
3527    LNG(wxLANGUAGE_TIBETAN
,                    "bo"   , 0              , 0                                 , "Tibetan") 
3528    LNG(wxLANGUAGE_TIGRINYA
,                   "ti"   , 0              , 0                                 , "Tigrinya") 
3529    LNG(wxLANGUAGE_TONGA
,                      "to"   , 0              , 0                                 , "Tonga") 
3530    LNG(wxLANGUAGE_TSONGA
,                     "ts"   , 0              , 0                                 , "Tsonga") 
3531    LNG(wxLANGUAGE_TURKISH
,                    "tr_TR", LANG_TURKISH   
, SUBLANG_DEFAULT                   
, "Turkish") 
3532    LNG(wxLANGUAGE_TURKMEN
,                    "tk"   , 0              , 0                                 , "Turkmen") 
3533    LNG(wxLANGUAGE_TWI
,                        "tw"   , 0              , 0                                 , "Twi") 
3534    LNG(wxLANGUAGE_UIGHUR
,                     "ug"   , 0              , 0                                 , "Uighur") 
3535    LNG(wxLANGUAGE_UKRAINIAN
,                  "uk_UA", LANG_UKRAINIAN 
, SUBLANG_DEFAULT                   
, "Ukrainian") 
3536    LNG(wxLANGUAGE_URDU
,                       "ur"   , LANG_URDU      
, SUBLANG_DEFAULT                   
, "Urdu") 
3537    LNG(wxLANGUAGE_URDU_INDIA
,                 "ur_IN", LANG_URDU      
, SUBLANG_URDU_INDIA                
, "Urdu (India)") 
3538    LNG(wxLANGUAGE_URDU_PAKISTAN
,              "ur_PK", LANG_URDU      
, SUBLANG_URDU_PAKISTAN             
, "Urdu (Pakistan)") 
3539    LNG(wxLANGUAGE_UZBEK
,                      "uz"   , LANG_UZBEK     
, SUBLANG_DEFAULT                   
, "Uzbek") 
3540    LNG(wxLANGUAGE_UZBEK_CYRILLIC
,             "uz"   , LANG_UZBEK     
, SUBLANG_UZBEK_CYRILLIC            
, "Uzbek (Cyrillic)") 
3541    LNG(wxLANGUAGE_UZBEK_LATIN
,                "uz"   , LANG_UZBEK     
, SUBLANG_UZBEK_LATIN               
, "Uzbek (Latin)") 
3542    LNG(wxLANGUAGE_VIETNAMESE
,                 "vi_VN", LANG_VIETNAMESE
, SUBLANG_DEFAULT                   
, "Vietnamese") 
3543    LNG(wxLANGUAGE_VOLAPUK
,                    "vo"   , 0              , 0                                 , "Volapuk") 
3544    LNG(wxLANGUAGE_WELSH
,                      "cy"   , 0              , 0                                 , "Welsh") 
3545    LNG(wxLANGUAGE_WOLOF
,                      "wo"   , 0              , 0                                 , "Wolof") 
3546    LNG(wxLANGUAGE_XHOSA
,                      "xh"   , 0              , 0                                 , "Xhosa") 
3547    LNG(wxLANGUAGE_YIDDISH
,                    "yi"   , 0              , 0                                 , "Yiddish") 
3548    LNG(wxLANGUAGE_YORUBA
,                     "yo"   , 0              , 0                                 , "Yoruba") 
3549    LNG(wxLANGUAGE_ZHUANG
,                     "za"   , 0              , 0                                 , "Zhuang") 
3550    LNG(wxLANGUAGE_ZULU
,                       "zu"   , 0              , 0                                 , "Zulu") 
3555 // --- --- --- generated code ends here --- --- --- 
3557 #endif // wxUSE_INTL