home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / src / c_locale_win32 / c_locale_win32.c
C/C++ Source or Header  |  2001-06-19  |  49KB  |  1,736 lines

  1. /*
  2.  * Copyright (c) 1999
  3.  * Silicon Graphics Computer Systems, Inc.
  4.  *
  5.  * Copyright (c) 1999
  6.  * Boris Fomitchev
  7.  *
  8.  * Written 2000
  9.  * Anton Lapach
  10.  *
  11.  * This material is provided "as is", with absolutely no warranty expressed
  12.  * or implied. Any use is at your own risk.
  13.  *
  14.  * Permission to use or copy this software for any purpose is hereby granted
  15.  * without fee, provided the above notices are retained on all copies.
  16.  * Permission to modify the code and to distribute modified code is granted,
  17.  * provided the above notices are retained, and a notice that the code was
  18.  * modified is included with the above copyright notice.
  19.  *
  20.  */
  21.  
  22. #include <windows.h>
  23. #include <limits.h>
  24. #if defined (_STLP_MSVC) || defined (__ICL) || defined (__BORLANDC__)
  25. # include <memory.h>
  26. #endif
  27. #include <string.h>
  28. #include <locale.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31.  
  32. #ifdef __cplusplus
  33. // _STLP_BEGIN_NAMESPACE
  34. extern "C" {
  35. #endif
  36.  
  37. /* Framework functions */
  38. /*
  39.   locale :: "lang[_country[.code_page]]"
  40.   | ".code_page"
  41.   | ""
  42.   | NULL
  43.  
  44. */
  45.  
  46. #ifndef _LEADBYTE
  47. /* multibyte leadbyte */
  48. #define _LEADBYTE       0x8000
  49. #endif
  50.  
  51. typedef struct _LOCALECONV
  52. {
  53.   const char* name;
  54.   const char* abbrev;
  55. } LOCALECONV;
  56.  
  57. #define MAX_LANG_LEN        64  /* max language name length */
  58. #define MAX_CTRY_LEN        64  /* max country name length */
  59. #define MAX_MODIFIER_LEN    0   /* max modifier name length - n/a */
  60. #define MAX_LC_LEN          (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3)
  61.                                 /* max entire locale string length */
  62. #define MAX_CP_LEN          5   /* max code page name length */
  63.  
  64.  
  65. // Metrowerks has different define here
  66. #if !defined (LC_MAX)
  67. # if defined (LC_LAST)
  68. #  define LC_MAX LC_LAST
  69. # endif
  70. #endif
  71.  
  72. //  non-NLS language string table
  73. static LOCALECONV __rg_language[] =
  74. {
  75.   {"american",                    "ENU"},
  76.   {"american english",            "ENU"},
  77.   {"american-english",            "ENU"},
  78.   {"australian",                  "ENA"},
  79.   {"belgian",                     "NLB"},
  80.   {"canadian",                    "ENC"},
  81.   {"chh",                         "ZHH"},
  82.   {"chi",                         "ZHI"},
  83.   {"chinese",                     "CHS"},
  84.   {"chinese-hongkong",            "ZHH"},
  85.   {"chinese-simplified",          "CHS"},
  86.   {"chinese-singapore",           "ZHI"},
  87.   {"chinese-traditional",         "CHT"},
  88.   {"dutch-belgian",               "NLB"},
  89.   {"english-american",            "ENU"},
  90.   {"english-aus",                 "ENA"},
  91.   {"english-belize",              "ENL"},
  92.   {"english-can",                 "ENC"},
  93.   {"english-caribbean",           "ENB"},
  94.   {"english-ire",                 "ENI"},
  95.   {"english-jamaica",             "ENJ"},
  96.   {"english-nz",                  "ENZ"},
  97.   {"english-south africa",        "ENS"},
  98.   {"english-trinidad y tobago",   "ENT"},
  99.   {"english-uk",                  "ENG"},
  100.   {"english-us",                  "ENU"},
  101.   {"english-usa",                 "ENU"},
  102.   {"french-belgian",              "FRB"},
  103.   {"french-canadian",             "FRC"},
  104.   {"french-luxembourg",           "FRL"},
  105.   {"french-swiss",                "FRS"},
  106.   {"german-austrian",             "DEA"},
  107.   {"german-lichtenstein",         "DEC"},
  108.   {"german-luxembourg",           "DEL"},
  109.   {"german-swiss",                "DES"},
  110.   {"irish-english",               "ENI"},
  111.   {"italian-swiss",               "ITS"},
  112.   {"norwegian",                   "NOR"},
  113.   {"norwegian-bokmal",            "NOR"},
  114.   {"norwegian-nynorsk",           "NON"},
  115.   {"portuguese-brazilian",        "PTB"},
  116.   {"spanish-argentina",           "ESS"},
  117.   {"spanish-bolivia",             "ESB"},
  118.   {"spanish-chile",               "ESL"},
  119.   {"spanish-colombia",            "ESO"},
  120.   {"spanish-costa rica",          "ESC"},
  121.   {"spanish-dominican republic",  "ESD"},
  122.   {"spanish-ecuador",             "ESF"},
  123.   {"spanish-el salvador",         "ESE"},
  124.   {"spanish-guatemala",           "ESG"},
  125.   {"spanish-honduras",            "ESH"},
  126.   {"spanish-mexican",             "ESM"},
  127.   {"spanish-modern",              "ESN"},
  128.   {"spanish-nicaragua",           "ESI"},
  129.   {"spanish-panama",              "ESA"},
  130.   {"spanish-paraguay",            "ESZ"},
  131.   {"spanish-peru",                "ESR"},
  132.   {"spanish-puerto rico",         "ESU"},
  133.   {"spanish-uruguay",             "ESY"},
  134.   {"spanish-venezuela",           "ESV"},
  135.   {"swedish-finland",             "SVF"},
  136.   {"swiss",                       "DES"},
  137.   {"uk",                          "ENG"},
  138.   {"us",                          "ENU"},
  139.   {"usa",                         "ENU"}
  140. };
  141.  
  142. //  non-NLS country string table
  143. static LOCALECONV __rg_country[] =
  144. {
  145.   {"america",                     "USA"},
  146.   {"britain",                     "GBR"},
  147.   {"china",                       "CHN"},
  148.   {"czech",                       "CZE"},
  149.   {"england",                     "GBR"},
  150.   {"great britain",               "GBR"},
  151.   {"holland",                     "NLD"},
  152.   {"hong-kong",                   "HKG"},
  153.   {"new-zealand",                 "NZL"},
  154.   {"nz",                          "NZL"},
  155.   {"pr china",                    "CHN"},
  156.   {"pr-china",                    "CHN"},
  157.   {"puerto-rico",                 "PRI"},
  158.   {"slovak",                      "SVK"},
  159.   {"south africa",                "ZAF"},
  160.   {"south korea",                 "KOR"},
  161.   {"south-africa",                "ZAF"},
  162.   {"south-korea",                 "KOR"},
  163.   {"trinidad & tobago",           "TTO"},
  164.   {"uk",                          "GBR"},
  165.   {"united-kingdom",              "GBR"},
  166.   {"united-states",               "USA"},
  167.   {"us",                          "USA"},
  168. };
  169.  
  170. typedef struct _Locale_ctype {
  171.   LCID lcid;
  172.   UINT cp;
  173.   unsigned int ctable[257];
  174. } _Locale_ctype_t;
  175.  
  176. typedef struct _Locale_numeric    {
  177.   LCID lcid;
  178.   char cp[MAX_CP_LEN+1];
  179.   char decimal_point[4];
  180.   char thousands_sep[4];
  181.   char *grouping;
  182. } _Locale_numeric_t;
  183.  
  184. typedef struct _Locale_time    {
  185.   LCID lcid;
  186.   char cp[MAX_CP_LEN+1];
  187.   char *month[12];
  188.   char *abbrev_month[12];
  189.   char *dayofweek[7];
  190.   char *abbrev_dayofweek[7];
  191. } _Locale_time_t;
  192.  
  193. typedef struct _Locale_collate    {
  194.   LCID lcid;
  195.   char cp[MAX_CP_LEN+1];
  196. } _Locale_collate_t;
  197.  
  198. typedef struct _Locale_monetary    {
  199.   LCID lcid;
  200.   char cp[MAX_CP_LEN+1];
  201.   char decimal_point[4];
  202.   char thousands_sep[4];
  203.   char *grouping;
  204.   char int_curr_symbol[5]; // 3+1+1
  205.   char curr_symbol[6];
  206.   char negative_sign[5];
  207.   char positive_sign[5];
  208.   int frac_digits;
  209.   int int_frac_digits;
  210. } _Locale_monetary_t;
  211.  
  212. typedef struct _Locale_messages    {
  213.   LCID lcid;
  214.   char cp[MAX_CP_LEN+1];
  215. } _Locale_messages_t;
  216.  
  217. /* Internal function */
  218. static void __FixGrouping(char *grouping);
  219. static const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize);
  220. static int __ParseLocaleString(const char* lname, char* lang, char* ctry, char* page);
  221. static int __GetLCID(const char* lang, const char* ctry, LCID* lcid);
  222. static int __GetLCIDFromName(const char* lname, LCID* lcid, char *cp);
  223. static char* __GetLocaleName(LCID lcid, const char* cp, char* buf);
  224. static char* __Extract_locale_name(const char* loc, int category, char* buf);
  225. static char* __TranslateToSystem(const char* lname, char* buf);
  226. static void __ConvertFromACP(char* buf, int buf_size, const char* cp);
  227. static int __intGetACP(LCID lcid);
  228. static int __intGetOCP(LCID lcid);
  229. static int __GetDefaultCP(LCID lcid);
  230. static char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size);
  231. static void my_ltoa(long __x, char* buf) ;
  232.  
  233. void my_ltoa(long __x, char* buf) 
  234.   char rbuf[64];
  235.   char* ptr = rbuf; 
  236.  
  237.   if (__x == 0)
  238.     *ptr++ = '0';
  239.   else {
  240.     for (; __x != 0; __x /= 10)
  241.       *ptr++ = (int)(__x % 10) + '0';
  242.   }
  243.   while(ptr > rbuf) *buf++ = *--ptr;
  244.   //psw
  245.   *buf = '\0';
  246.  
  247. # ifdef __cplusplus
  248. _STLP_BEGIN_NAMESPACE
  249. extern "C" {
  250. # endif
  251.  
  252.   void* _Locale_ctype_create(const char * name)
  253.   {
  254.     char cname[_Locale_MAX_SIMPLE_NAME];
  255.     char cp_name[MAX_CP_LEN+1];
  256.     int NativeCP;
  257.     unsigned char Buffer[256];
  258.     unsigned char *ptr;
  259.     unsigned short ctable[256];
  260.     CPINFO CPInfo;
  261.     int i;
  262.     wchar_t *wbuffer;
  263.     int BufferSize;
  264.  
  265.     _Locale_ctype_t *ltype=(_Locale_ctype_t*)malloc(sizeof(_Locale_ctype_t));
  266.     if(!ltype) return ltype;
  267.     memset(ltype, 0, sizeof(_Locale_ctype_t));
  268.  
  269.     __Extract_locale_name(name, LC_CTYPE, cname);
  270.  
  271.     if(__GetLCIDFromName(cname, <ype->lcid, cp_name)==-1)
  272.       { free(ltype); return NULL; }
  273.     ltype->cp = atoi(cp_name);
  274.  
  275.     NativeCP=__intGetACP(ltype->lcid);
  276.     if(NativeCP == 0)
  277.       NativeCP=__intGetOCP(ltype->lcid);
  278.  
  279.     /* Make table with all characters. */
  280.     for(i = 0; i < 256; i++) Buffer[i] = i;
  281.  
  282.     if(!GetCPInfo(NativeCP, &CPInfo)) { free(ltype); return NULL; }
  283.  
  284.     if(CPInfo.MaxCharSize > 1)
  285.       for(ptr=(unsigned char*)CPInfo.LeadByte; *ptr && *(ptr+1); ptr+=2)
  286.     for(i=*ptr; i <= *(ptr+1); i++) Buffer[i] = 0;
  287.  
  288.     if(NativeCP != ltype->cp)
  289.       {
  290.         OSVERSIONINFO ver_info;
  291.         ver_info.dwOSVersionInfoSize = sizeof(ver_info);
  292.         GetVersionEx(&ver_info);
  293.         if(ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT)
  294.       {
  295.         // Convert character sequence to Unicode.
  296.         BufferSize = MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0);
  297.         wbuffer = (wchar_t*)malloc(BufferSize*sizeof(wchar_t));
  298.         if(!MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize))
  299.           { free(wbuffer); free(ltype); return NULL; }
  300.  
  301.         GetStringTypeW(CT_CTYPE1, wbuffer, 256, ctable);
  302.  
  303.         for(i = 0; i < 256; ++i)
  304.           ltype->ctable[i+1]=(unsigned int)ctable[i];
  305.  
  306.         if(CPInfo.MaxCharSize > 1)
  307.           for(ptr=(unsigned char*)CPInfo.LeadByte; *ptr && *(ptr+1); ptr+=2)
  308.         for(i=*ptr; i <= *(ptr+1); i++) ltype->ctable[i+1] = _LEADBYTE;
  309.  
  310.         free(wbuffer);
  311.       }
  312.         else
  313.       {
  314.         unsigned char TargetBuffer[256];
  315.         GetStringTypeA(ltype->lcid, CT_CTYPE1, (const char*)Buffer, 256, ctable);
  316.  
  317.         // Convert character sequence to target code page.
  318.         BufferSize = MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0);
  319.         wbuffer = (wchar_t*)malloc(BufferSize*sizeof(wchar_t));
  320.         if(!MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize))
  321.           { free(wbuffer); free(ltype); return NULL; }
  322.         if(!WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, BufferSize, (char*)TargetBuffer, 256, NULL, FALSE))
  323.           { free(wbuffer); free(ltype); return NULL; }
  324.  
  325.         free(wbuffer);
  326.  
  327.         // Translate ctype table.
  328.         for(i = 0; i < 256; ++i)
  329.           {
  330.         if(!TargetBuffer[i]) continue;
  331.         ltype->ctable[TargetBuffer[i]+1] = ctable[i];
  332.           }
  333.         ltype->ctable[0] = 0; // EOF
  334.  
  335.         // Mark lead byte.
  336.         if(!GetCPInfo(ltype->cp, &CPInfo)) { free(ltype); return NULL; }
  337.         if(CPInfo.MaxCharSize > 1)
  338.           for(ptr=(unsigned char*)CPInfo.LeadByte; *ptr && *(ptr+1); ptr+=2)
  339.         for(i=*ptr; i <= *(ptr+1); i++) ltype->ctable[i+1] = _LEADBYTE;
  340.       }
  341.       }
  342.     else
  343.       {
  344.     GetStringTypeA(ltype->lcid, CT_CTYPE1, (const char*)Buffer, 256, ctable);
  345.     for(i = 0; i < 256; ++i)
  346.       ltype->ctable[i+1]=(unsigned int)ctable[i];
  347.  
  348.         if(CPInfo.MaxCharSize > 1)
  349.       for(ptr=(unsigned char*)CPInfo.LeadByte; *ptr && *(ptr+1); ptr+=2)
  350.         for(i=*ptr; i <= *(ptr+1); i++) ltype->ctable[i+1] = _LEADBYTE;
  351.       }
  352.     ltype->ctable[0] = 0; // EOF
  353.  
  354.     return ltype;
  355.   }
  356.  
  357.   void* _Locale_numeric_create(const char * name)
  358.   {
  359.     char *GroupingBuffer;
  360.     char cname[_Locale_MAX_SIMPLE_NAME];
  361.     int BufferSize;
  362.     _Locale_numeric_t *lnum=(_Locale_numeric_t*)malloc(sizeof(_Locale_numeric_t));
  363.     if(!lnum) return lnum; // MS normal behavior for 'new'
  364.  
  365.     __Extract_locale_name(name, LC_NUMERIC, cname);
  366.  
  367.     if(__GetLCIDFromName(cname, &lnum->lcid, lnum->cp)==-1)
  368.       { free(lnum); return NULL; }
  369.  
  370.     GetLocaleInfoA(lnum->lcid, LOCALE_SDECIMAL, lnum->decimal_point, 4);
  371.     __ConvertFromACP(lnum->decimal_point, 4, lnum->cp);
  372.     GetLocaleInfoA(lnum->lcid, LOCALE_STHOUSAND, lnum->thousands_sep, 4);
  373.     __ConvertFromACP(lnum->thousands_sep, 4, lnum->cp);
  374.  
  375.     BufferSize=GetLocaleInfoA(lnum->lcid, LOCALE_SGROUPING, NULL, 0);
  376.     GroupingBuffer=(char*)malloc(BufferSize);
  377.     if(!GroupingBuffer) { lnum->grouping=NULL; return lnum; }
  378.     GetLocaleInfoA(lnum->lcid, LOCALE_SGROUPING, GroupingBuffer, BufferSize);
  379.     __FixGrouping(GroupingBuffer);
  380.     lnum->grouping=GroupingBuffer;
  381.  
  382.     return lnum;
  383.   }
  384.  
  385.   void* _Locale_time_create(const char * name)
  386.   {
  387.     int size, month, dayofweek;
  388.     char cname[_Locale_MAX_SIMPLE_NAME];
  389.  
  390.     _Locale_time_t *ltime=(_Locale_time_t*)malloc(sizeof(_Locale_time_t));;
  391.     if(!ltime) return ltime;
  392.     memset(ltime, 0, sizeof(_Locale_time_t));
  393.  
  394.     __Extract_locale_name(name, LC_TIME, cname);
  395.  
  396.     if(__GetLCIDFromName(cname, <ime->lcid, ltime->cp)==-1)
  397.       { free(ltime); return NULL; }
  398.  
  399.     for(month=LOCALE_SMONTHNAME1; month<=LOCALE_SMONTHNAME12; month++) // Small hack :-)
  400.       {
  401.     size=GetLocaleInfoA(ltime->lcid, month, NULL, 0);
  402.         ltime->month[month-LOCALE_SMONTHNAME1]=(char*)malloc(size);
  403.         if(!ltime->month[month-LOCALE_SMONTHNAME1]) { _Locale_time_destroy(ltime); return NULL; }
  404.     GetLocaleInfoA(ltime->lcid, month, ltime->month[month-LOCALE_SMONTHNAME1], size);
  405.         __ConvertFromACP(ltime->month[month-LOCALE_SMONTHNAME1], size, ltime->cp);
  406.       }
  407.  
  408.     for(month=LOCALE_SABBREVMONTHNAME1; month<=LOCALE_SABBREVMONTHNAME12; month++)
  409.       {
  410.     size=GetLocaleInfoA(ltime->lcid, month, NULL, 0);
  411.     ltime->abbrev_month[month-LOCALE_SABBREVMONTHNAME1]=(char*)malloc(size);
  412.     if(!ltime->abbrev_month[month-LOCALE_SABBREVMONTHNAME1]) { _Locale_time_destroy(ltime); return NULL; }
  413.     GetLocaleInfoA(ltime->lcid, month, ltime->abbrev_month[month-LOCALE_SABBREVMONTHNAME1], size);
  414.     __ConvertFromACP(ltime->abbrev_month[month-LOCALE_SABBREVMONTHNAME1], size, ltime->cp);
  415.       }
  416.  
  417.     for(dayofweek=LOCALE_SDAYNAME1; dayofweek<=LOCALE_SDAYNAME7; dayofweek++)
  418.       {
  419.     int dayindex= ( dayofweek != LOCALE_SDAYNAME7 ) ?
  420.       dayofweek-LOCALE_SDAYNAME1+1 : 0;
  421.     size=GetLocaleInfoA(ltime->lcid, dayofweek, NULL, 0);
  422.     ltime->dayofweek[dayindex]=(char*)malloc(size);
  423.     if(!ltime->dayofweek[dayindex] ) { _Locale_time_destroy(ltime); return NULL; }
  424.     GetLocaleInfoA(ltime->lcid, dayofweek, ltime->dayofweek[dayindex], size);
  425.     __ConvertFromACP(ltime->dayofweek[dayindex], size, ltime->cp);
  426.       }
  427.  
  428.     for(dayofweek=LOCALE_SABBREVDAYNAME1; dayofweek<=LOCALE_SABBREVDAYNAME7; dayofweek++)
  429.       {
  430.     int dayindex= ( dayofweek != LOCALE_SABBREVDAYNAME7 ) ?
  431.       dayofweek-LOCALE_SABBREVDAYNAME1+1 : 0;
  432.     size=GetLocaleInfoA(ltime->lcid, dayofweek, NULL, 0);
  433.     ltime->abbrev_dayofweek[dayindex]=(char*)malloc(size);
  434.     if(!ltime->abbrev_dayofweek[dayindex]) { _Locale_time_destroy(ltime); return NULL; }
  435.     GetLocaleInfoA(ltime->lcid, dayofweek, ltime->abbrev_dayofweek[dayindex], size);
  436.     __ConvertFromACP(ltime->abbrev_dayofweek[dayindex], size, ltime->cp);
  437.       }
  438.  
  439.     return ltime;
  440.   }
  441.  
  442.   void* _Locale_collate_create(const char * name)
  443.   {
  444.     char cname[_Locale_MAX_SIMPLE_NAME];
  445.  
  446.     _Locale_collate_t *lcol=(_Locale_collate_t*)malloc(sizeof(_Locale_collate_t));
  447.     if(!lcol) return lcol;
  448.     memset(lcol, 0, sizeof(_Locale_collate_t));
  449.  
  450.     __Extract_locale_name(name, LC_COLLATE, cname);
  451.  
  452.     if(__GetLCIDFromName(cname, &lcol->lcid, lcol->cp)==-1)
  453.       { free(lcol); return NULL; }
  454.  
  455.     return lcol;
  456.   }
  457.  
  458.   void* _Locale_monetary_create(const char * name)
  459.   {
  460.     char cname[_Locale_MAX_SIMPLE_NAME];
  461.     char *GroupingBuffer;
  462.     int BufferSize;
  463.     char FracDigits[3];
  464.  
  465.     _Locale_monetary_t *lmon=(_Locale_monetary_t*)malloc(sizeof(_Locale_monetary_t));
  466.     if(!lmon) return lmon;
  467.     memset(lmon, 0, sizeof(_Locale_monetary_t));
  468.  
  469.     __Extract_locale_name(name, LC_MONETARY, cname);
  470.  
  471.     if(__GetLCIDFromName(cname, &lmon->lcid, lmon->cp)==-1)
  472.       { free(lmon); return NULL; }
  473.  
  474.     // Extract information about monetary system
  475.     GetLocaleInfoA(lmon->lcid, LOCALE_SDECIMAL, lmon->decimal_point, 4);
  476.     __ConvertFromACP(lmon->decimal_point, 4, lmon->cp);
  477.     GetLocaleInfoA(lmon->lcid, LOCALE_STHOUSAND, lmon->thousands_sep, 4);
  478.     __ConvertFromACP(lmon->thousands_sep, 4, lmon->cp);
  479.  
  480.     BufferSize=GetLocaleInfoA(lmon->lcid, LOCALE_SGROUPING, NULL, 0);
  481.     GroupingBuffer=(char*)malloc(BufferSize);
  482.     if(!GroupingBuffer) { lmon->grouping=NULL; return lmon; }
  483.     GetLocaleInfoA(lmon->lcid, LOCALE_SGROUPING, GroupingBuffer, BufferSize);
  484.     __FixGrouping(GroupingBuffer);
  485.     lmon->grouping=GroupingBuffer;
  486.  
  487.     GetLocaleInfoA(lmon->lcid, LOCALE_SCURRENCY, lmon->curr_symbol, 6);
  488.     __ConvertFromACP(lmon->curr_symbol, 6, lmon->cp);
  489.  
  490.     GetLocaleInfoA(lmon->lcid, LOCALE_SNEGATIVESIGN, lmon->negative_sign, 5);
  491.     __ConvertFromACP(lmon->negative_sign, 5, lmon->cp);
  492.  
  493.     GetLocaleInfoA(lmon->lcid, LOCALE_SPOSITIVESIGN, lmon->positive_sign, 5);
  494.     __ConvertFromACP(lmon->positive_sign, 5, lmon->cp);
  495.  
  496.     GetLocaleInfoA(lmon->lcid, LOCALE_ICURRDIGITS, FracDigits, 3);
  497.     lmon->frac_digits=atoi(FracDigits);
  498.  
  499.     GetLocaleInfoA(lmon->lcid, LOCALE_IINTLCURRDIGITS, FracDigits, 3);
  500.     lmon->int_frac_digits=atoi(FracDigits);
  501.  
  502.     GetLocaleInfoA(lmon->lcid, LOCALE_SINTLSYMBOL, lmon->int_curr_symbol, 5);
  503.  
  504.     return lmon;
  505.   }
  506.  
  507.   void* _Locale_messages_create(const char *name)
  508.   {
  509.     _Locale_messages_t *lmes=(_Locale_messages_t*)malloc(sizeof(_Locale_messages_t));
  510.     if(!lmes) return lmes;
  511.     memset(lmes, 0, sizeof(_Locale_messages_t));
  512.  
  513.     return lmes;
  514.   }
  515.  
  516.   const char* _Locale_common_default(char* buf)
  517.   {
  518.     char cp[MAX_CP_LEN+1];
  519.     int CodePage=__intGetACP(LOCALE_USER_DEFAULT);
  520.     if(!CodePage) CodePage=__intGetOCP(LOCALE_USER_DEFAULT);
  521.     my_ltoa(CodePage, cp);
  522.     return __GetLocaleName(LOCALE_USER_DEFAULT, cp, buf);
  523.   }
  524.  
  525.   const char* _Locale_ctype_default(char* buf)
  526.   {
  527.     return  _Locale_common_default(buf);
  528.   }
  529.  
  530.   const char* _Locale_numeric_default(char * buf)
  531.   {
  532.     return  _Locale_common_default(buf);
  533.   }
  534.  
  535.   const char* _Locale_time_default(char* buf)
  536.   {
  537.     return  _Locale_common_default(buf);
  538.   }
  539.  
  540.   const char* _Locale_collate_default(char* buf)
  541.   {
  542.     return  _Locale_common_default(buf);
  543.   }
  544.  
  545.   const char* _Locale_monetary_default(char* buf)
  546.   {
  547.     return  _Locale_common_default(buf);
  548.   }
  549.  
  550.   const char* _Locale_messages_default(char* buf)
  551.   {
  552.     return  _Locale_common_default(buf);
  553.   }
  554.  
  555.   char* _Locale_ctype_name(const void* loc, char* buf)
  556.   {
  557.     char cp_buf[MAX_CP_LEN+1];
  558.     _Locale_ctype_t* ltype=(_Locale_ctype_t*)loc;
  559.     my_ltoa(ltype->cp, cp_buf);
  560.     return __GetLocaleName(ltype->lcid, cp_buf, buf);
  561.   }
  562.  
  563.   char* _Locale_numeric_name(const void* loc, char* buf)
  564.   {
  565.     _Locale_numeric_t* lnum=(_Locale_numeric_t*)loc;
  566.     return __GetLocaleName(lnum->lcid, lnum->cp, buf);
  567.   }
  568.  
  569.   char* _Locale_time_name(const void* loc, char* buf)
  570.   {
  571.     _Locale_time_t* ltime=(_Locale_time_t*)loc;
  572.     return __GetLocaleName(ltime->lcid, ltime->cp, buf);
  573.   }
  574.  
  575.   char* _Locale_collate_name(const void* loc, char* buf)
  576.   {
  577.     _Locale_collate_t* lcol=(_Locale_collate_t*)loc;
  578.     return __GetLocaleName(lcol->lcid, lcol->cp, buf);
  579.   }
  580.  
  581.   char* _Locale_monetary_name(const void* loc, char* buf)
  582.   {
  583.     _Locale_monetary_t* lmon=(_Locale_monetary_t*)loc;
  584.     return __GetLocaleName(lmon->lcid, lmon->cp, buf);
  585.   }
  586.  
  587.   char* _Locale_messages_name(const void* loc, char* buf)
  588.   {
  589.     _Locale_messages_t* lmes=(_Locale_messages_t*)loc;
  590.     return __GetLocaleName(lmes->lcid, lmes->cp, buf);
  591.   }
  592.  
  593.   void _Locale_ctype_destroy(void* loc)
  594.   {
  595.     _Locale_ctype_t *ltype=(_Locale_ctype_t*)loc;
  596.     if(!ltype) return;
  597.  
  598.     free(ltype);
  599.   }
  600.  
  601.   void _Locale_numeric_destroy(void* loc)
  602.   {
  603.     _Locale_numeric_t *lnum=(_Locale_numeric_t *)loc;
  604.     if(!lnum) return;
  605.  
  606.     if(lnum->grouping) free(lnum->grouping);
  607.     free(lnum);
  608.   }
  609.  
  610.   void _Locale_time_destroy(void* loc)
  611.   {
  612.     int i;
  613.     _Locale_time_t* ltime=(_Locale_time_t*)loc;
  614.     if(!ltime) return;
  615.  
  616.     for(i=0; i<12; i++)
  617.       {
  618.         if(ltime->month[i]) free(ltime->month[i]);
  619.         if(ltime->abbrev_month[i]) free(ltime->abbrev_month[i]);
  620.       }
  621.  
  622.     for(i=0; i<7; i++)
  623.       {
  624.         if(ltime->dayofweek[i]) free(ltime->dayofweek[i]);
  625.         if(ltime->abbrev_dayofweek[i]) free(ltime->abbrev_dayofweek[i]);
  626.       }
  627.  
  628.     free(ltime);
  629.   }
  630.  
  631.   void _Locale_collate_destroy(void* loc)
  632.   {
  633.     _Locale_collate_t* lcol=(_Locale_collate_t*)loc;
  634.     if(!lcol) return;
  635.  
  636.     free(lcol);
  637.   }
  638.  
  639.   void _Locale_monetary_destroy(void* loc)
  640.   {
  641.     struct _Locale_monetary *lmon=(struct _Locale_monetary *)loc;
  642.     if(!lmon) return;
  643.  
  644.     if(lmon->grouping) free(lmon->grouping);
  645.     free(lmon);
  646.   }
  647.  
  648.   void _Locale_messages_destroy(void* loc)
  649.   {
  650.     _Locale_messages_t* lmes=(_Locale_messages_t*)loc;
  651.     if(!lmes) return;
  652.  
  653.     free(lmes);
  654.   }
  655.  
  656.   char* _Locale_extract_ctype_name(const char* cname, char* buf) 
  657.   {
  658.     char lname[_Locale_MAX_SIMPLE_NAME];
  659.     __Extract_locale_name(cname, LC_CTYPE, lname);
  660.     if(lname[0] == 'C' && lname[1] == 0) return strcpy(buf, lname);
  661.     return __TranslateToSystem(lname, buf);
  662.   }
  663.  
  664.   char* _Locale_extract_numeric_name(const char* cname, char* buf) 
  665.   {
  666.     char lname[_Locale_MAX_SIMPLE_NAME];
  667.     __Extract_locale_name(cname, LC_NUMERIC, lname);
  668.     if(lname[0] == 'C' && lname[1] == 0) return strcpy(buf, lname);
  669.     return __TranslateToSystem(lname, buf);
  670.   }
  671.  
  672.   char* _Locale_extract_time_name(const char* cname, char* buf) 
  673.   {
  674.     char lname[_Locale_MAX_SIMPLE_NAME];
  675.     __Extract_locale_name(cname, LC_TIME, lname);
  676.     if(lname[0] == 'C' && lname[1] == 0) return strcpy(buf, lname);
  677.     return __TranslateToSystem(lname, buf);
  678.   }
  679.  
  680.   char* _Locale_extract_collate_name(const char* cname, char* buf) 
  681.   {
  682.     char lname[_Locale_MAX_SIMPLE_NAME];
  683.     __Extract_locale_name(cname, LC_COLLATE, lname);
  684.     if(lname[0] == 'C' && lname[1] == 0) return strcpy(buf, lname);
  685.     return __TranslateToSystem(lname, buf);
  686.   }
  687.  
  688.   char* _Locale_extract_monetary_name(const char* cname, char* buf) 
  689.   {
  690.     char lname[_Locale_MAX_SIMPLE_NAME];
  691.     __Extract_locale_name(cname, LC_MONETARY, lname);
  692.     if(lname[0] == 'C' && lname[1] == 0) return strcpy(buf, lname);
  693.     return __TranslateToSystem(lname, buf);
  694.   }
  695.  
  696.   char* _Locale_extract_messages_name(const char* cname, char* buf) 
  697.   {
  698.     if(cname[0] == 'L' && cname[1] == 'C' && cname[2] == '_')
  699.       return strcpy(buf, "C");
  700.     return strcpy(buf, cname);
  701.   }
  702.  
  703.   char* _Locale_compose_name(char* buf,
  704.                  const char* _ctype, const char* numeric,
  705.                  const char* time, const char* _collate,
  706.                  const char* monetary, const char* messages)
  707.   {
  708.     if(!strcmp(_ctype, numeric) &&\
  709.        !strcmp(_ctype, time) &&\
  710.        !strcmp(_ctype, _collate) &&\
  711.        !strcmp(_ctype, monetary) &&\
  712.        !strcmp(_ctype, messages))
  713.       return strcpy(buf, _ctype);
  714.  
  715.     strcpy(buf, "LC_CTYPE="); strcat(buf, _ctype); strcat(buf, ";");
  716.     strcat(buf, "LC_TIME="); strcat(buf, time); strcat(buf, ";");
  717.     strcat(buf, "LC_NUMERIC="); strcat(buf, numeric); strcat(buf, ";");
  718.     strcat(buf, "LC_COLLATE="); strcat(buf, _collate); strcat(buf, ";");
  719.     strcat(buf, "LC_MONETARY="); strcat(buf, monetary); strcat(buf, ";");
  720.     strcat(buf, "LC_MESSAGES="); strcat(buf, messages); strcat(buf, ";");
  721.  
  722.     return buf;
  723.   }
  724.  
  725.   /* ctype */
  726.  
  727.   _Locale_mask_t* _Locale_ctype_table(struct _Locale_ctype* ltype)
  728.   {
  729.     return (_Locale_mask_t*)ltype->ctable;
  730.   }
  731.  
  732.   int _Locale_toupper(struct _Locale_ctype* ltype, int c)
  733.   {
  734.     char buf[2], out_buf[2];;
  735.     buf[0] = (char)c; buf[1] = 0;
  736.     if(__GetDefaultCP(ltype->lcid) == ltype->cp)
  737.       {
  738.     LCMapStringA(ltype->lcid, LCMAP_LINGUISTIC_CASING | LCMAP_UPPERCASE, buf, 2, out_buf, 2);
  739.     return out_buf[0];
  740.       }
  741.     else
  742.       {
  743.     wchar_t wbuf[2];
  744.         MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, buf, 2, wbuf, 2);
  745.     WideCharToMultiByte(__GetDefaultCP(ltype->lcid), WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, buf, 2, NULL, FALSE);
  746.  
  747.     LCMapStringA(ltype->lcid, LCMAP_LINGUISTIC_CASING | LCMAP_UPPERCASE, buf, 2, out_buf, 2);
  748.  
  749.         MultiByteToWideChar(__GetDefaultCP(ltype->lcid), MB_PRECOMPOSED, out_buf, 2, wbuf, 2);
  750.     WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, out_buf, 2, NULL, FALSE);
  751.     return out_buf[0];
  752.       }
  753.   }
  754.  
  755.   int _Locale_tolower(struct _Locale_ctype* ltype, int c)
  756.   {
  757.     char buf[2], out_buf[2];;
  758.     buf[0] = (char)c; buf[1] = 0;
  759.     if(__GetDefaultCP(ltype->lcid) == ltype->cp)
  760.       {
  761.     LCMapStringA(ltype->lcid, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, buf, 2, out_buf, 2);
  762.     return out_buf[0];
  763.       }
  764.     else
  765.       {
  766.     wchar_t wbuf[2];
  767.         MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, buf, 2, wbuf, 2);
  768.     WideCharToMultiByte(__GetDefaultCP(ltype->lcid), WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, buf, 2, NULL, FALSE);
  769.  
  770.     LCMapStringA(ltype->lcid, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, buf, 2, out_buf, 2);
  771.  
  772.         MultiByteToWideChar(__GetDefaultCP(ltype->lcid), MB_PRECOMPOSED, out_buf, 2, wbuf, 2);
  773.     WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, out_buf, 2, NULL, FALSE);
  774.     return out_buf[0];
  775.       }
  776.   }
  777.  
  778. # ifndef _STLP_NO_WCHAR_T
  779.   _Locale_mask_t _Locale_wchar_ctype(struct _Locale_ctype* ltype, wint_t c)
  780.   {
  781.     wchar_t buf[2];
  782.     WORD out[2];
  783.     buf[0] = c; buf[1] = 0;
  784.     GetStringTypeW(CT_CTYPE1, buf, -1, out);
  785.  
  786.     return (_Locale_mask_t)out[0];
  787.     //    ltype;
  788.   }
  789.  
  790.   wint_t _Locale_wchar_tolower(struct _Locale_ctype* ltype, wint_t c)
  791.   {
  792.     wint_t res;
  793.  
  794.     LCMapStringW(ltype->lcid, LCMAP_LOWERCASE, &c, 1, &res, 1);
  795.     return res;
  796.   }
  797.  
  798.   wint_t _Locale_wchar_toupper(struct _Locale_ctype* ltype, wint_t c)
  799.   {
  800.     wint_t res;
  801.  
  802.     LCMapStringW(ltype->lcid, LCMAP_UPPERCASE, &c, 1, &res, 1);
  803.     return res;
  804.   }
  805. # endif
  806.  
  807. # ifndef _STLP_NO_MBSTATE_T
  808.  
  809.   int _Locale_mb_cur_max (struct _Locale_ctype * ltype)
  810.   {
  811.     CPINFO CPInfo;
  812.     if(!GetCPInfo(ltype->cp, &CPInfo)) return 0;
  813.     return CPInfo.MaxCharSize;
  814.   }
  815.  
  816.   int _Locale_mb_cur_min (struct _Locale_ctype *dummy)
  817.   { return 1; }
  818.  
  819.   int _Locale_is_stateless (struct _Locale_ctype * ltype)
  820.   {
  821.     CPINFO CPInfo;
  822.     GetCPInfo(ltype->cp, &CPInfo);
  823.     return (CPInfo.MaxCharSize == 1) ? 1 : 0;
  824.   }
  825.  
  826.   wint_t _Locale_btowc(struct _Locale_ctype * ltype, int c)
  827.   {
  828.     wchar_t wc;
  829.     if(c == EOF) return WEOF;
  830.  
  831.     MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (char*)&c, 1, &wc, 1);
  832.  
  833.     return (wint_t)wc;
  834.   }
  835.  
  836.   int _Locale_wctob(struct _Locale_ctype * ltype, wint_t wc)
  837.   {
  838.     char c;
  839.  
  840.     if(WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_DEFAULTCHAR, (wchar_t*)&wc, 1, &c, 1, NULL, NULL) == 0)
  841.       return WEOF; // Not single byte or error conversion.
  842.  
  843.     return (int)c;
  844.   }
  845.  
  846.   static int __isleadbyte(int c, unsigned int *ctable)
  847.   {
  848.     return (ctable[(unsigned char)(c)] & _LEADBYTE);
  849.   }
  850.  
  851.   static size_t __mbtowc(struct _Locale_ctype *l, wchar_t *dst, char src, mbstate_t *shift_state)
  852.   {
  853.     int result;
  854.  
  855.     if(*shift_state == 0)
  856.       {
  857.     if(__isleadbyte(src, l->ctable))
  858.       {
  859.         ((unsigned char*)shift_state)[0] = src;
  860.         return (size_t)-2;
  861.       }
  862.     else
  863.       {
  864.         result = MultiByteToWideChar(l->cp, MB_PRECOMPOSED, &src, 1, dst, 1);
  865.         if(result == 0) return (size_t)-1;
  866.  
  867.         return 1;
  868.       }
  869.       }
  870.     else
  871.       {
  872.     ((unsigned char*)shift_state)[1] = src;
  873.     result = MultiByteToWideChar(l->cp, MB_PRECOMPOSED, (const char*)shift_state, 2, dst, 1);
  874.     *shift_state = 0;
  875.     if(result == 0) return (size_t)-1;
  876.  
  877.     return 1;
  878.       }
  879.   }
  880.  
  881.   size_t _Locale_mbtowc(struct _Locale_ctype *ltype,
  882.             wchar_t *to,
  883.             const char *from, size_t n,
  884.             mbstate_t *shift_state)
  885.   {
  886.     CPINFO ci;
  887.     int result;
  888.  
  889.     GetCPInfo(ltype->cp, &ci);
  890.     if(ci.MaxCharSize == 1) // Single byte encoding.
  891.       {
  892.     *shift_state = (mbstate_t)0;
  893.     result = MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, from, 1, to, 1);
  894.     if(result == 0) return (size_t)-1;
  895.     return result;
  896.       }
  897.     else // Multi byte encoding.
  898.       {
  899.         size_t retval, count = 0;
  900.         while(n--)
  901.       {
  902.         retval = __mbtowc(ltype, to, *from, shift_state);
  903.         if(retval == -2) { from++; count++; }
  904.         else if(retval == -1) return -1;
  905.         else return count+retval;
  906.       }
  907.         if(retval == -2) return (size_t)-2;
  908.  
  909.         return n;
  910.       }
  911.   }
  912.  
  913.   size_t _Locale_wctomb(struct _Locale_ctype *ltype,
  914.             char *to, size_t n,
  915.             const wchar_t c,
  916.             mbstate_t *shift_state)
  917.   {
  918.     int size = \
  919.       WideCharToMultiByte(ltype->cp,  WC_COMPOSITECHECK | WC_SEPCHARS, &c, 1, NULL, 0, NULL, NULL);
  920.  
  921.     if(size > n) return (size_t)-2;
  922.  
  923.     size = \
  924.       WideCharToMultiByte(ltype->cp,  WC_COMPOSITECHECK | WC_SEPCHARS, &c, 1, to, n, NULL, NULL);
  925.  
  926.     if(size == 0) return (size_t)-1;
  927.  
  928.     return (size_t)size;
  929.   }
  930.  
  931.   size_t _Locale_unshift(struct _Locale_ctype *ltype,
  932.              mbstate_t *st,
  933.              char *buf, size_t n, char **next)
  934.   {
  935.     if(*st == 0)
  936.       {
  937.     *next = buf;
  938.     return 0;
  939.       }
  940.     else
  941.       {
  942.     if(n < 1) { *next = buf; return (size_t)-2; }
  943.  
  944.     *next = buf + 1;
  945.     return 1;
  946.       }
  947.   }
  948.  
  949. # endif /*  _STLP_NO_MBSTATE_T */
  950.  
  951.  
  952. # ifndef CSTR_EQUAL /* VC5SP3*/
  953. # define CSTR_EQUAL 2
  954. # endif
  955. # ifndef CSTR_LESS_THAN /* VC5SP3 */
  956. # define CSTR_LESS_THAN 1
  957. # endif
  958.  
  959.   /* Collate */
  960.   int _Locale_strcmp(struct _Locale_collate* lcol,
  961.              const char* s1, size_t n1,
  962.              const char* s2, size_t n2)
  963.   {
  964.     int result;
  965.     if(__GetDefaultCP(lcol->lcid) == atoi(lcol->cp))
  966.       {
  967.     result=CompareStringA(lcol->lcid, 0, s1, n1, s2, n2);
  968.       }
  969.     else
  970.       {
  971.     char *buf1, *buf2;
  972.     size_t size1, size2;
  973.     buf1 = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lcid), s1, n1, &size1);
  974.     buf2 = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lcid), s2, n2, &size2);
  975.  
  976.     result=CompareStringA(lcol->lcid, 0, buf1, size1, buf2, size2);
  977.     free(buf1); free(buf2);
  978.       }
  979.     return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1;
  980.   }
  981.  
  982. # ifndef _STLP_NO_WCHAR_T
  983.  
  984.   int _Locale_strwcmp(struct _Locale_collate* lcol,
  985.               const wchar_t* s1, size_t n1,
  986.               const wchar_t* s2, size_t n2)
  987.   {
  988.     int result;
  989.     result=CompareStringW(lcol->lcid, 0, s1, n1, s2, n2);
  990.     return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1;
  991.   }
  992.  
  993. # endif
  994.  
  995.   size_t _Locale_strxfrm(struct _Locale_collate* lcol,
  996.              char* dst, size_t dst_size,
  997.              const char* src, size_t src_size)
  998.   {
  999.     if(__GetDefaultCP(lcol->lcid) == atoi(lcol->cp))
  1000.       return LCMapStringA(lcol->lcid, LCMAP_SORTKEY, src, src_size, dst, dst_size);
  1001.     else
  1002.       {
  1003.     int result;
  1004.     char *buf;
  1005.     size_t size;
  1006.     buf = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lcid), src, src_size, &size);
  1007.  
  1008.     result=LCMapStringA(lcol->lcid, LCMAP_SORTKEY, buf, size, dst, dst_size);
  1009.     free(buf);
  1010.     return result;
  1011.       }
  1012.   }
  1013.  
  1014. # ifndef _STLP_NO_WCHAR_T
  1015.  
  1016.   size_t _Locale_strwxfrm(struct _Locale_collate* lcol,
  1017.                           wchar_t* dst, size_t dst_size,
  1018.                           const wchar_t* src, size_t src_size)
  1019.   {
  1020.     return LCMapStringW(lcol->lcid, LCMAP_SORTKEY, src, src_size, dst, dst_size);
  1021.   }
  1022.  
  1023. # endif
  1024.  
  1025.   /* Numeric */
  1026.  
  1027.   static const char* __true_name="true";
  1028.   static const char* __false_name="false";
  1029.  
  1030.   char _Locale_decimal_point(struct _Locale_numeric* lnum)
  1031.   {
  1032.     return lnum->decimal_point[0];
  1033.   }
  1034.  
  1035.   char _Locale_thousands_sep(struct _Locale_numeric* lnum)
  1036.   {
  1037.     return lnum->thousands_sep[0];
  1038.   }
  1039.  
  1040.   const char* _Locale_grouping(struct _Locale_numeric * lnum)
  1041.   {
  1042.     if(!lnum->grouping) return "";
  1043.     else return lnum->grouping;
  1044.   }
  1045.  
  1046.   const char * _Locale_true(struct _Locale_numeric * lnum)
  1047.   {
  1048.     return __true_name; // NT does't provide information about this
  1049.   }
  1050.  
  1051.   const char * _Locale_false(struct _Locale_numeric * lnum)
  1052.   {
  1053.     return __false_name; // NT does't provide information about this
  1054.   }
  1055.  
  1056.  
  1057.   /* Monetary */
  1058.  
  1059.   const char* _Locale_int_curr_symbol(struct _Locale_monetary * lmon)
  1060.   {
  1061.     return lmon->int_curr_symbol;
  1062.   }
  1063.  
  1064.   const char* _Locale_currency_symbol(struct _Locale_monetary * lmon)
  1065.   {
  1066.     return lmon->curr_symbol;
  1067.   }
  1068.  
  1069.   char        _Locale_mon_decimal_point(struct _Locale_monetary * lmon)
  1070.   {
  1071.     return lmon->decimal_point[0];
  1072.   }
  1073.  
  1074.   char        _Locale_mon_thousands_sep(struct _Locale_monetary * lmon)
  1075.   {
  1076.     return lmon->thousands_sep[0];
  1077.   }
  1078.  
  1079.   const char* _Locale_mon_grouping(struct _Locale_monetary * lmon)
  1080.   {
  1081.     if(!lmon->grouping) return "";
  1082.     else return lmon->grouping;
  1083.   }
  1084.  
  1085.   const char* _Locale_positive_sign(struct _Locale_monetary * lmon)
  1086.   {
  1087.     return lmon->positive_sign;
  1088.   }
  1089.  
  1090.   const char* _Locale_negative_sign(struct _Locale_monetary * lmon)
  1091.   {
  1092.     return lmon->negative_sign;
  1093.   }
  1094.  
  1095.   char        _Locale_int_frac_digits(struct _Locale_monetary * lmon)
  1096.   {
  1097.     return (char)lmon->int_frac_digits;
  1098.   }
  1099.  
  1100.   char        _Locale_frac_digits(struct _Locale_monetary * lmon)
  1101.   {
  1102.     return (char)lmon->frac_digits;
  1103.   }
  1104.  
  1105.   int         _Locale_p_cs_precedes(struct _Locale_monetary * lmon)
  1106.   {
  1107.     char loc_data[2];
  1108.     GetLocaleInfoA(lmon->lcid, LOCALE_IPOSSYMPRECEDES, loc_data, 2);
  1109.     if(loc_data[0]=='0') return 0;
  1110.     else if(loc_data[0]=='1') return 1;
  1111.     else return -1;
  1112.   }
  1113.  
  1114.   int         _Locale_p_sep_by_space(struct _Locale_monetary * lmon)
  1115.   {
  1116.     char loc_data[2];
  1117.     GetLocaleInfoA(lmon->lcid, LOCALE_IPOSSEPBYSPACE, loc_data, 2);
  1118.     if(loc_data[0]=='0') return 0;
  1119.     else if(loc_data[0]=='1') return 1;
  1120.     else return -1;
  1121.   }
  1122.  
  1123.   int         _Locale_p_sign_posn(struct _Locale_monetary * lmon)
  1124.   {
  1125.     char loc_data[2];
  1126.     GetLocaleInfoA(lmon->lcid, LOCALE_IPOSSIGNPOSN, loc_data, 2);
  1127.     return atoi(loc_data);
  1128.   }
  1129.  
  1130.   int         _Locale_n_cs_precedes(struct _Locale_monetary * lmon)
  1131.   {
  1132.     char loc_data[2];
  1133.     GetLocaleInfoA(lmon->lcid, LOCALE_INEGSYMPRECEDES, loc_data, 2);
  1134.     if(loc_data[0]=='0') return 0;
  1135.     else if(loc_data[0]=='1') return 1;
  1136.     else return -1;
  1137.   }
  1138.  
  1139.   int          _Locale_n_sep_by_space(struct _Locale_monetary * lmon)
  1140.   {
  1141.     char loc_data[2];
  1142.     GetLocaleInfoA(lmon->lcid, LOCALE_INEGSEPBYSPACE, loc_data, 2);
  1143.     if(loc_data[0]=='0') return 0;
  1144.     else if(loc_data[0]=='1') return 1;
  1145.     else return -1;
  1146.   }
  1147.  
  1148.   int          _Locale_n_sign_posn(struct _Locale_monetary * lmon)
  1149.   {
  1150.     char loc_data[2];
  1151.     GetLocaleInfoA(lmon->lcid, LOCALE_INEGSIGNPOSN, loc_data, 2);
  1152.     return atoi(loc_data);
  1153.   }
  1154.  
  1155.  
  1156.   /* Time */
  1157.   const char ** _Locale_full_monthname(struct _Locale_time * ltime)
  1158.   {
  1159.     return (const char**)ltime->month;
  1160.   }
  1161.  
  1162.   const char ** _Locale_abbrev_monthname(struct _Locale_time * ltime)
  1163.   {
  1164.     return (const char**)ltime->abbrev_month;
  1165.   }
  1166.  
  1167.   const char ** _Locale_full_dayofweek(struct _Locale_time * ltime)
  1168.   {
  1169.     return (const char**)ltime->dayofweek;
  1170.   }
  1171.  
  1172.   const char ** _Locale_abbrev_dayofweek(struct _Locale_time * ltime)
  1173.   {
  1174.     return (const char**)ltime->abbrev_dayofweek;
  1175.   }
  1176.  
  1177.   const char* _Locale_d_t_fmt(struct _Locale_time* ltime)
  1178.   {
  1179.     // NT doesn't provide this information, and must simulate.
  1180.     static char buffer[MAX_PATH];
  1181.     strcpy(buffer, _Locale_d_fmt(ltime));
  1182.     strcat(buffer, " ");
  1183.     strcat(buffer, _Locale_t_fmt(ltime));
  1184.     return buffer;
  1185.   }
  1186.  
  1187.   const char* _Locale_long_d_t_fmt(struct _Locale_time* ltime)
  1188.   {
  1189.     // NT doesn't provide this information, and must simulate.
  1190.     static char buffer[MAX_PATH];
  1191.     strcpy(buffer, _Locale_long_d_fmt(ltime));
  1192.     strcat(buffer, " ");
  1193.     strcat(buffer, _Locale_t_fmt(ltime));
  1194.     return buffer;
  1195.   }
  1196.  
  1197.   const char* __ConvertDate(const char* NTTime)
  1198.   {
  1199.     static char ansi_date_fmt[MAX_PATH]; // Hack
  1200.     const char *cur_char;
  1201.     char *cur_output;
  1202.  
  1203.     // Correct time format.
  1204.     cur_char=NTTime;
  1205.     cur_output=ansi_date_fmt;
  1206.     while(*cur_char)
  1207.       {
  1208.         switch(*cur_char)
  1209.       {
  1210.       case 'd':
  1211.             {
  1212.           if(*(cur_char+1)=='d')
  1213.                 {
  1214.           if(*(cur_char+2)=='d')
  1215.             {
  1216.               if(*(cur_char+3)=='d')
  1217.             { *(cur_output++)='%'; *(cur_output++)='A';  cur_char+=3; }
  1218.               else
  1219.             { *(cur_output++)='%'; *(cur_output++)='a';  cur_char+=2; }
  1220.             }
  1221.           else
  1222.             { *(cur_output++)='%'; *(cur_output++)='d';  cur_char++; }
  1223.                 }
  1224.           else
  1225.         { *(cur_output++)='%'; *(cur_output++)='#'; *(cur_output++)='d'; }
  1226.             }
  1227.             break;
  1228.  
  1229.       case 'M':
  1230.             {
  1231.           if(*(cur_char+1)=='M')
  1232.                 {
  1233.           if(*(cur_char+2)=='M')
  1234.             {
  1235.               if(*(cur_char+3)=='M')
  1236.             { *(cur_output++)='%'; *(cur_output++)='B';  cur_char+=3; }
  1237.               else
  1238.             { *(cur_output++)='%'; *(cur_output++)='b';  cur_char+=2; }
  1239.             }
  1240.           else
  1241.             { *(cur_output++)='%'; *(cur_output++)='m';  cur_char++; }
  1242.                 }
  1243.           else
  1244.         { *(cur_output++)='%'; *(cur_output++)='#'; *(cur_output++)='m'; }
  1245.             }
  1246.             break;
  1247.  
  1248.       case 'y':
  1249.             {
  1250.           if(*(cur_char+1)=='y')
  1251.                 {
  1252.           if(*(cur_char+2)=='y' && *(cur_char+3)=='y')
  1253.             { *(cur_output++)='%'; *(cur_output++)='Y';  cur_char+=3; }
  1254.           else
  1255.             { *(cur_output++)='%'; *(cur_output++)='y';  cur_char++; }
  1256.                 }
  1257.           else
  1258.         { *(cur_output++)='%'; *(cur_output++)='#'; *(cur_output++)='y'; }
  1259.             }
  1260.             break;
  1261.  
  1262.       case '%':
  1263.         {
  1264.           *(cur_output++)='%'; *(cur_output++)='%';
  1265.             }
  1266.             break;
  1267.  
  1268.       case '\'':
  1269.         {
  1270.           cur_char++;
  1271.           while(*cur_char!='\'' && *cur_char!=0) *cur_output++=*cur_char++;
  1272.         }
  1273.         break;
  1274.  
  1275.       default:
  1276.         {
  1277.           *(cur_output++)=*cur_char;
  1278.             }
  1279.             break;
  1280.       }
  1281.         if(*cur_char==0) break;
  1282.         cur_char++;
  1283.       }
  1284.  
  1285.     *cur_output=0;
  1286.     return ansi_date_fmt;
  1287.   }
  1288.  
  1289.   const char* _Locale_d_fmt(struct _Locale_time* ltime)
  1290.   {
  1291.     static char date_fmt[80];
  1292.     GetLocaleInfoA(ltime->lcid, LOCALE_SSHORTDATE, date_fmt, MAX_PATH);
  1293.     __ConvertFromACP(date_fmt, 80, ltime->cp);
  1294.  
  1295.     return __ConvertDate(date_fmt);
  1296.   }
  1297.  
  1298.   const char* _Locale_long_d_fmt(struct _Locale_time* ltime)
  1299.   {
  1300.     static char date_fmt[80];
  1301.     GetLocaleInfoA(ltime->lcid, LOCALE_SLONGDATE, date_fmt, MAX_PATH);
  1302.     __ConvertFromACP(date_fmt, 80, ltime->cp);
  1303.  
  1304.     return __ConvertDate(date_fmt);
  1305.   }
  1306.  
  1307.   const char* _Locale_t_fmt(struct _Locale_time* ltime)
  1308.   {
  1309.     char time_fmt[80];
  1310.     static char ansi_time_fmt[MAX_PATH]; // Hack
  1311.     char *cur_char, *cur_output;
  1312.     GetLocaleInfoA(ltime->lcid, LOCALE_STIMEFORMAT, time_fmt, MAX_PATH);
  1313.     __ConvertFromACP(time_fmt, 80, ltime->cp);
  1314.  
  1315.     // Correct time format.
  1316.     cur_char=time_fmt;
  1317.     cur_output=ansi_time_fmt;
  1318.     while(*cur_char)
  1319.       {
  1320.         switch(*cur_char)
  1321.       {
  1322.       case 'h':
  1323.             {
  1324.           if(*(cur_char+1)=='h')
  1325.         { *(cur_output++)='%'; *(cur_output++)='I';  cur_char++; }
  1326.           else
  1327.         { *(cur_output++)='%'; *(cur_output++)='#'; *(cur_output++)='I'; }
  1328.             }
  1329.             break;
  1330.  
  1331.       case 'H':
  1332.         if(*(cur_char+1)=='H')
  1333.           { *(cur_output++)='%'; *(cur_output++)='H'; cur_char++; }
  1334.         else
  1335.           { *(cur_output++)='%'; *(cur_output++)='#'; *(cur_output++)='H'; }
  1336.         break;
  1337.  
  1338.       case 'm':
  1339.             {
  1340.           if(*(cur_char+1)=='m')
  1341.         { *(cur_output++)='%'; *(cur_output++)='M';  cur_char++; }
  1342.           else
  1343.         { *(cur_output++)='%'; *(cur_output++)='#'; *(cur_output++)='M'; }
  1344.             }
  1345.             break;
  1346.  
  1347.       case 's':
  1348.             {
  1349.           if(*(cur_char+1)=='s')
  1350.         { *(cur_output++)='%'; *(cur_output++)='S';  cur_char++; }
  1351.           else
  1352.         { *(cur_output++)='%'; *(cur_output++)='#'; *(cur_output++)='S'; }
  1353.             }
  1354.             break;
  1355.  
  1356.       case 't':
  1357.             {
  1358.           if(*(cur_char+1)=='t')
  1359.         cur_char++;
  1360.  
  1361.           *(cur_output++)='%'; *(cur_output++)='p';
  1362.             }
  1363.             break;
  1364.  
  1365.       case '%':
  1366.         {
  1367.           *(cur_output++)='%'; *(cur_output++)='%';
  1368.             }
  1369.             break;
  1370.  
  1371.       case '\'':
  1372.         {
  1373.           cur_char++;
  1374.           while(*cur_char!='\'' && *cur_char!=0) *cur_output++=*cur_char++;
  1375.         }
  1376.         break;
  1377.  
  1378.       default:
  1379.         {
  1380.           *(cur_output++)=*cur_char;
  1381.             }
  1382.             break;
  1383.       }
  1384.         if(*cur_char==0) break;
  1385.         cur_char++;
  1386.       }
  1387.  
  1388.     *cur_output=0;
  1389.     return ansi_time_fmt;
  1390.   }
  1391.  
  1392.   const char* _Locale_am_str(struct _Locale_time* ltime)
  1393.   {
  1394.     static char buffer[9];
  1395.     GetLocaleInfoA(ltime->lcid, LOCALE_S1159, buffer, 9);
  1396.     __ConvertFromACP(buffer, 9, ltime->cp);
  1397.     return buffer;
  1398.   }
  1399.  
  1400.   const char* _Locale_pm_str(struct _Locale_time* ltime)
  1401.   {
  1402.     static char buffer[9];
  1403.     GetLocaleInfoA(ltime->lcid, LOCALE_S2359, buffer, 9);
  1404.     __ConvertFromACP(buffer, 9, ltime->cp);
  1405.     return buffer;
  1406.   }
  1407.  
  1408.   const char* _Locale_t_fmt_ampm(struct _Locale_time* ltime)
  1409.   {
  1410.     char time_sep[4];
  1411.     static char buffer[17];
  1412.     GetLocaleInfoA(ltime->lcid, LOCALE_STIME, time_sep, 4);
  1413.     __ConvertFromACP(time_sep, 4, ltime->cp);
  1414.     strcpy(buffer, "%H"); strcat(buffer, time_sep);
  1415.     strcat(buffer, "%M"); strcat(buffer, time_sep);
  1416.     strcat(buffer, "%S %p");
  1417.     return buffer;
  1418.   }
  1419.  
  1420.   /* Messages */
  1421.  
  1422.   int _Locale_catopen(struct _Locale_messages* __DUMMY_PAR1, const char* __DUMMY_PAR)
  1423.   { return -1; }
  1424.   void _Locale_catclose(struct _Locale_messages* __DUMMY_PAR1, int __DUMMY_PAR) {}
  1425.   const char* _Locale_catgets(struct _Locale_messages* __DUMMY_PAR1, int __DUMMY_PAR2,
  1426.                   int __DUMMY_PAR3, int __DUMMY_PAR4,
  1427.                   const char *dfault)
  1428.   { return dfault; }
  1429.  
  1430. #ifdef __cplusplus    
  1431. } /* extern C */
  1432. _STLP_END_NAMESPACE
  1433. #endif
  1434.  
  1435. void __FixGrouping(char *grouping)
  1436. {
  1437.   /* This converts NT version which uses '0' instead of 0, etc ; to ANSI */
  1438.   while (*grouping) {
  1439.     if (*grouping >= '0' && *grouping <= '9') {
  1440.       *grouping = *grouping - '0'; 
  1441.       grouping++;
  1442.     } else if (*grouping == ';') {
  1443.       char *tmp = grouping;
  1444.       /* remove ':' */
  1445.       for (tmp = grouping; *tmp; tmp++)
  1446.         *tmp = *(tmp+1);
  1447.     } else
  1448.       grouping++;
  1449.   } 
  1450. }
  1451.  
  1452. const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize)
  1453. {
  1454.   int     i;
  1455.   int     cmp = 1;
  1456.   int     low = 0;
  1457.   int        high=TableSize-1;
  1458.  
  1459.   //  typical binary search - do until no more to search or match
  1460.   while (low <= high)
  1461.     {
  1462.       i = (low + high) / 2;
  1463.  
  1464.       if ((cmp=lstrcmpiA(lname, (*(ConvTable + i)).name))==0)
  1465.     return (*(ConvTable + i)).abbrev;
  1466.       else if (cmp < 0)
  1467.     high = i - 1;
  1468.       else
  1469.     low = i + 1;
  1470.     }
  1471.   return lname;
  1472. }
  1473.  
  1474. int __ParseLocaleString(const char* lname, char* lang, char* ctry,
  1475. char* page)
  1476. {
  1477.   int param=0;
  1478.   size_t len=0;
  1479.   char ch=lname[0];
  1480.  
  1481.   if(ch==0)
  1482.      return 0;
  1483.     
  1484.   else if(ch=='.') // Only code page provided
  1485.     {
  1486.       if(strlen(lname+1)>MAX_CP_LEN) return -1; // CP number too long
  1487.       strcpy(page, lname+1);
  1488.       lang[0] = 0; ctry[0] = 0;  //necessary? calling function does this too
  1489.       return 0;
  1490.     }
  1491.  
  1492.   while (ch!=0) // Parse string
  1493.     {
  1494.       len=strcspn(lname, "_.,"); // ',' for compability with POSIX
  1495.  
  1496.       ch=lname[len];
  1497.       if((param==0) && (len<MAX_LANG_LEN))
  1498.         {
  1499.           if (ch!='.') // hence '_', ',' or '/0'
  1500.                 strncpy(lang, lname, len);
  1501.           else  // no ctry, read lang and skip ctry on next pass
  1502.             {
  1503.               ctry[0]=0;  
  1504.               strncpy(lang, lname, len);
  1505.               param++;    
  1506.              }
  1507.          }
  1508.       else if(param==1 && len<MAX_CTRY_LEN && ch!='_')
  1509.             strncpy(ctry, lname, len);
  1510.       else if(param==2 && len<MAX_CP_LEN && (ch==0 || ch==','))
  1511.             strncpy(page, lname, len);
  1512.       else
  1513.         return -1;
  1514.       if(ch==',') break; // Modifier found. In NT not used.
  1515.       param++;
  1516.       lname+=(len+1);
  1517.     }
  1518.   return 0;
  1519. }
  1520.  
  1521. /* Data necesary for find LCID*/
  1522. static int __FindFlag;
  1523. static LCID __FndLCID;
  1524. static const char* __FndLang;
  1525. static const char* __FndCtry;
  1526.  
  1527. static LCID LocaleFromHex(const char* locale)
  1528. {
  1529.   unsigned long result=0;
  1530.   int digit;
  1531.   while(*locale)
  1532.     {
  1533.       result<<=4;
  1534.       digit=(*locale>='0' && *locale<='9')? *locale-'0':
  1535.     (*locale>='A' && *locale<='F')?(*locale-'A')+10:(*locale-'a')+10;
  1536.       result+=digit;
  1537.       locale++;
  1538.     }
  1539.   return (LCID)result;
  1540. }
  1541.  
  1542. static BOOL CALLBACK EnumLocalesProcA(LPSTR locale)
  1543. {
  1544.   LCID lcid=LocaleFromHex(locale);
  1545.   int LangFlag=0, CtryFlag=!__FndCtry;
  1546.   static char Lang[MAX_LANG_LEN], Ctry[MAX_CTRY_LEN];
  1547.  
  1548.   GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, Lang, MAX_LANG_LEN);
  1549.   if(lstrcmpiA(Lang, __FndLang)!=0)
  1550.     {
  1551.       GetLocaleInfoA(lcid, LOCALE_SABBREVLANGNAME, Lang, MAX_LANG_LEN);
  1552.       if(lstrcmpiA(Lang, __FndLang)==0) LangFlag=1;
  1553.     }
  1554.   else LangFlag=1;
  1555.  
  1556.   if(__FndCtry)
  1557.     {
  1558.       GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, Ctry, MAX_CTRY_LEN);
  1559.       if(lstrcmpiA(Ctry, __FndCtry)!=0)
  1560.     {
  1561.       GetLocaleInfoA(lcid, LOCALE_SABBREVCTRYNAME, Ctry, MAX_CTRY_LEN);
  1562.       if(lstrcmpiA(Ctry, __FndCtry)==0) CtryFlag=1;
  1563.     }
  1564.       else CtryFlag=1;
  1565.     }
  1566.  
  1567.   if(LangFlag && CtryFlag)
  1568.     {
  1569.       __FindFlag=1;
  1570.       __FndLCID=lcid;
  1571.       return FALSE;
  1572.     }
  1573.  
  1574.   return TRUE;
  1575. }
  1576.  
  1577. int __GetLCID(const char* lang, const char* ctry, LCID* lcid)
  1578. {
  1579.   __FindFlag=0;
  1580.   __FndLang=lang;
  1581.   __FndCtry=ctry;
  1582.   EnumSystemLocalesA(EnumLocalesProcA, LCID_INSTALLED);
  1583.  
  1584.   if(__FindFlag==0) return -1;
  1585.  
  1586.   *lcid=__FndLCID;
  1587.   return 0;
  1588. }
  1589.  
  1590. int __GetLCIDFromName(const char* lname, LCID* lcid, char* cp)
  1591. {
  1592.   char lang[MAX_LANG_LEN+1], ctry[MAX_CTRY_LEN+1], page[MAX_CP_LEN+1];
  1593.   int result = 0;
  1594.   if(lname==NULL || lname[0]==0)
  1595.     {
  1596.       *lcid=LOCALE_USER_DEFAULT;
  1597.       return 0;
  1598.     }
  1599.  
  1600.   memset(lang, 0, MAX_LANG_LEN+1);
  1601.   memset(ctry, 0, MAX_CTRY_LEN+1);
  1602.   memset(page, 0, MAX_CP_LEN+1);
  1603.   if(__ParseLocaleString(lname, lang, ctry, page)==-1) return -1;
  1604.  
  1605.   if(lang[0] == 0 && ctry[0] == 0)
  1606.     *lcid = LOCALE_USER_DEFAULT; // Only code page given.
  1607.   else
  1608.     {
  1609.       if(ctry[0] == 0)
  1610.     result = __GetLCID(__ConvertName(lang, __rg_language, sizeof(__rg_language)/sizeof(LOCALECONV)), NULL, lcid);
  1611.       else
  1612.     result = __GetLCID(
  1613.                __ConvertName(lang, __rg_language, sizeof(__rg_language)/sizeof(LOCALECONV)),
  1614.                __ConvertName(ctry, __rg_country, sizeof(__rg_country)/sizeof(LOCALECONV)),
  1615.                lcid);
  1616.     }
  1617.  
  1618.   if(result==0)
  1619.     {
  1620.       // Handling code page
  1621.       if(lstrcmpiA(page, "ACP")==0 || page[0]==0)
  1622.     my_ltoa(__intGetACP(*lcid), cp);
  1623.       else if(lstrcmpiA(page, "OCP")==0)
  1624.     my_ltoa(__intGetOCP(*lcid), cp);
  1625.       else strncpy(cp, page, 5);
  1626.     }
  1627.   return result;
  1628. }
  1629.  
  1630. char* __GetLocaleName(LCID lcid, const char* cp, char* buf)
  1631. {
  1632.   char lang[MAX_LANG_LEN+1], ctry[MAX_CTRY_LEN+1];
  1633.   GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, lang, MAX_LANG_LEN);
  1634.   GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, ctry, MAX_CTRY_LEN);
  1635.   strcpy(buf, lang); strcat(buf, "_");
  1636.   strcat(buf, ctry); strcat(buf, ".");
  1637.   return strcat(buf, cp);
  1638. }
  1639.  
  1640. static const char* __loc_categories[]=
  1641. {
  1642.   "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", "LC_TIME"
  1643.     };
  1644.  
  1645. char* __Extract_locale_name(const char* loc, int category, char* buf)
  1646. {
  1647.   char *expr;
  1648.   size_t len_name;
  1649.   buf[0] = 0;
  1650.   if(category < LC_ALL || category > LC_MAX) return NULL;
  1651.  
  1652.   if(loc[0]=='L' && loc[1]=='C' && loc[2]=='_')
  1653.     {
  1654.       expr=strstr((char*)loc, __loc_categories[category]);
  1655.       if(expr==NULL) return NULL; // Category not found.
  1656.       expr=strchr(expr, '=');
  1657.       if(expr==NULL) return NULL;
  1658.       expr++;
  1659.       len_name=strcspn(expr, ";");
  1660.       len_name=len_name>_Locale_MAX_SIMPLE_NAME?\
  1661.     _Locale_MAX_SIMPLE_NAME:len_name;
  1662.       strncpy(buf, expr, len_name);        buf[len_name]=0;
  1663.       return buf;
  1664.     }
  1665.   else
  1666.     return strncpy(buf, loc, _Locale_MAX_SIMPLE_NAME);
  1667. }
  1668.  
  1669. char* __TranslateToSystem(const char* lname, char* buf)
  1670. {
  1671.   LCID lcid;
  1672.   char cp[MAX_CP_LEN+1];
  1673.   if(__GetLCIDFromName(lname, &lcid, cp)!=0) return NULL;
  1674.  
  1675.   return __GetLocaleName(lcid, cp, buf);
  1676. }
  1677.  
  1678. void __ConvertFromACP(char* buf, int buf_size, const char* cp)
  1679. {
  1680.   wchar_t *Buffer;
  1681.   int BufferSize=MultiByteToWideChar(CP_ACP, 0, buf, -1, NULL, 0);
  1682.   Buffer=(wchar_t*)malloc(sizeof(wchar_t)*(BufferSize+1));
  1683.   MultiByteToWideChar(CP_ACP, 0, buf, -1, Buffer, BufferSize);
  1684.   WideCharToMultiByte(atoi(cp), 0, Buffer, -1, buf, buf_size, NULL, NULL);
  1685.   free(Buffer);
  1686. }
  1687.  
  1688. /* Return 0 if ANSI code page not used */
  1689. int __intGetACP(LCID lcid)
  1690. {
  1691.   char cp[6];
  1692.   GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, cp, 6);
  1693.   return atoi(cp);
  1694. }
  1695.  
  1696. /* Return 1 if OEM code page not used */
  1697. int __intGetOCP(LCID lcid)
  1698. {
  1699.   char cp[6];
  1700.   GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE, cp, 6);
  1701.   return atoi(cp);
  1702. }
  1703.  
  1704. int __GetDefaultCP(LCID lcid)
  1705. {
  1706.   int cp = __intGetACP(lcid);
  1707.   if(cp == 0) return __intGetOCP(lcid);
  1708.   else return cp;
  1709. }
  1710.  
  1711. char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size)
  1712. {
  1713.   int wbuffer_size, buffer_size;
  1714.   wchar_t *wbuffer;
  1715.   char* buffer;
  1716.  
  1717.   wbuffer_size = MultiByteToWideChar(from_cp, MB_PRECOMPOSED, from, size, NULL, 0);
  1718.   wbuffer = (wchar_t*)malloc(sizeof(wchar_t)*wbuffer_size);
  1719.   MultiByteToWideChar(from_cp, MB_PRECOMPOSED, from, size, wbuffer, wbuffer_size);
  1720.  
  1721.   buffer_size = WideCharToMultiByte(to_cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, wbuffer_size, NULL, 0, NULL, FALSE);
  1722.   buffer = (char*)malloc(buffer_size);
  1723.   WideCharToMultiByte(to_cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, wbuffer_size, buffer, buffer_size, NULL, FALSE);
  1724.  
  1725.   free(wbuffer);
  1726.   *ret_buf_size = buffer_size;
  1727.   return buffer;
  1728. }
  1729.  
  1730. #ifdef __cplusplus
  1731. }
  1732. // _STLP_END_NAMESPACE
  1733. #endif
  1734.