home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / mbctype.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  27KB  |  899 lines

  1. /***
  2. *mbctype.c - MBCS table used by the functions that test for types of char
  3. *
  4. *       Copyright (c) 1985-1997, Microsoft Corporation.  All rights reserved.
  5. *
  6. *Purpose:
  7. *       table used to determine the type of char
  8. *
  9. *******************************************************************************/
  10.  
  11. #ifdef _MBCS
  12.  
  13. #if defined (_WIN32)
  14. #include <windows.h>
  15. #else  /* defined (_WIN32) */
  16. #include <fltintrn.h>
  17. #endif  /* defined (_WIN32) */
  18.  
  19. #include <mtdll.h>
  20. #include <cruntime.h>
  21. #include <mbdata.h>
  22. #include <mbctype.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <internal.h>
  26. #if defined (_WIN32)
  27. #include <setlocal.h>
  28. #endif  /* defined (_WIN32) */
  29. #if defined (_WIN32)
  30. #include <awint.h>
  31. #endif  /* defined (_WIN32) */
  32.  
  33. #ifdef _MAC
  34.  
  35. #include <macos\language.h>
  36. #include <macos\script.h>
  37.  
  38. void __cdecl __initmbctable(void);
  39.  
  40. #pragma data_seg(".CRT$XIC")
  41. const   PFV __pinitmbctable = __initmbctable;
  42. #pragma data_seg()
  43.  
  44. static short tmpScriptID;
  45. static short mbScriptID;
  46.  
  47. #endif  /* _MAC */
  48.  
  49. #ifndef CRTDLL
  50.  
  51. void __cdecl __initmbctable(void);
  52. /*
  53.  * Flag to ensure multibyte ctype table is only initialized once
  54.  */
  55. extern int __mbctype_initialized;
  56.  
  57. #pragma data_seg(".CRT$XIC")
  58. static _PVFV pinit = __initmbctable;
  59. #pragma data_seg()
  60.  
  61. #endif  /* CRTDLL */
  62.  
  63. #define _CHINESE_SIMP_CP    936
  64. #define _KOREAN_WANGSUNG_CP 949
  65. #define _CHINESE_TRAD_CP    950
  66. #define _KOREAN_JOHAB_CP    1361
  67.  
  68. #define NUM_CHARS 257 /* -1 through 255 */
  69.  
  70. #define NUM_CTYPES 4 /* table contains 4 types of info */
  71. #define MAX_RANGES 8 /* max number of ranges needed given languages so far */
  72.  
  73. /* character type info in ranges (pair of low/high), zeros indicate end */
  74. typedef struct
  75. {
  76.     int             code_page;
  77.     unsigned short  mbulinfo[NUM_ULINFO];
  78.     unsigned char   rgrange[NUM_CTYPES][MAX_RANGES];
  79. } code_page_info;
  80.  
  81.  
  82. /* MBCS ctype array */
  83. unsigned char _mbctype[NUM_CHARS];
  84. unsigned char _mbcasemap[256];
  85.  
  86. /* global variable to indicate current code page */
  87. int __mbcodepage;
  88.  
  89. /* global flag indicating if current code page is a multibyte code page */
  90. int __ismbcodepage;
  91.  
  92. #ifdef _WIN32
  93. /* global variable to indicate current LCID */
  94. int __mblcid;
  95. #endif  /* _WIN32 */
  96.  
  97. /* global variable to indicate current full-width-latin upper/lower info */
  98. unsigned short __mbulinfo[NUM_ULINFO];
  99.  
  100. static int fSystemSet;
  101.  
  102. static char __rgctypeflag[NUM_CTYPES] = { _MS, _MP, _M1, _M2 };
  103.  
  104. static code_page_info __rgcode_page_info[] =
  105. {
  106.     {
  107.       _KANJI_CP, /* Kanji (Japanese) Code Page */
  108.       { 0x8260, 0x8279,   /* Full-Width Latin Upper Range 1 */
  109.         0x8281 - 0x8260,  /* Full-Width Latin Case Difference 1 */
  110.  
  111.         0x0000, 0x0000,   /* Full-Width Latin Upper Range 2 */
  112.         0x0000            /* Full-Width Latin Case Difference 2 */
  113. #ifndef _WIN32
  114.         ,
  115.         0x8281, 0x829A,   /* Full-Width Latin Lower Range 1 */
  116.  
  117.         0x0000, 0x0000,   /* Full-Width Latin Lower Range 2 */
  118.  
  119.         0x824F, 0x8258    /* Full-Width Latin Digit Range */
  120. #endif  /* _WIN32 */
  121.       },
  122.       {
  123.         { 0xA6, 0xDF, 0,    0,    0,    0,    0, 0, }, /* Single Byte Ranges */
  124.         { 0xA1, 0xA5, 0,    0,    0,    0,    0, 0, }, /* Punctuation Ranges */
  125.         { 0x81, 0x9F, 0xE0, 0xFC, 0,    0,    0, 0, }, /* Lead Byte Ranges */
  126.         { 0x40, 0x7E, 0x80, 0xFC, 0,    0,    0, 0, }, /* Trail Byte Ranges */
  127.       }
  128.     },
  129.     {
  130.       _CHINESE_SIMP_CP, /* Chinese Simplified (PRC) Code Page */
  131.       { 0xA3C1, 0xA3DA,   /* Full-Width Latin Upper Range 1 */
  132.         0xA3E1 - 0xA3C1,  /* Full-Width Latin Case Difference 1 */
  133.  
  134.         0x0000, 0x0000,   /* Full-Width Latin Upper Range 2 */
  135.         0x0000            /* Full-Width Latin Case Difference 2 */
  136. #ifndef _WIN32
  137.         ,
  138.         0xA3E1, 0xA3FA,   /* Full-Width Latin Lower Range 1 */
  139.  
  140.         0x0000, 0x0000,   /* Full-Width Latin Lower Range 2 */
  141.  
  142.         0xA3B0, 0xA3B9    /* Full-Width Latin Digit Range */
  143. #endif  /* _WIN32 */
  144.       },
  145.       {
  146.         { 0,    0,    0,    0,    0,    0,    0, 0, }, /* Single Byte Ranges */
  147.         { 0,    0,    0,    0,    0,    0,    0, 0, }, /* Punctuation Ranges */
  148.         { 0x81, 0xFE, 0,    0,    0,    0,    0, 0, }, /* Lead Byte Ranges */
  149.         { 0x40, 0xFE, 0,    0,    0,    0,    0, 0, }, /* Trail Byte Ranges */
  150.       }
  151.     },
  152.     {
  153.       _KOREAN_WANGSUNG_CP, /* Wangsung (Korean) Code Page */
  154.       { 0xA3C1, 0xA3DA,   /* Full-Width Latin Upper Range 1 */
  155.         0xA3E1 - 0xA3C1,  /* Full-Width Latin Case Difference 1 */
  156.  
  157.         0x0000, 0x0000,   /* Full-Width Latin Upper Range 2 */
  158.         0x0000            /* Full-Width Latin Case Difference 2 */
  159. #ifndef _WIN32
  160.         ,
  161.         0xA3E1, 0xA3FA,   /* Full-Width Latin Lower Range 1 */
  162.  
  163.         0x0000, 0x0000,   /* Full-Width Latin Lower Range 2 */
  164.  
  165.         0xA3B0, 0xA3B9    /* Full-Width Latin Digit Range */
  166. #endif  /* _WIN32 */
  167.       },
  168.       {
  169.         { 0,    0,    0,    0,    0,    0,    0, 0, }, /* Single Byte Ranges */
  170.         { 0,    0,    0,    0,    0,    0,    0, 0, }, /* Punctuation Ranges */
  171.         { 0x81, 0xFE, 0,    0,    0,    0,    0, 0, }, /* Lead Byte Ranges */
  172.         { 0x41, 0xFE, 0,    0,    0,    0,    0, 0, }, /* Trail Byte Ranges */
  173.       }
  174.     },
  175.     {
  176.       _CHINESE_TRAD_CP, /* Chinese Traditional (Taiwan) Code Page */
  177.       { 0xA2CF, 0xA2E4,   /* Full-Width Latin Upper Range 1 */
  178.         0xA2E9 - 0xA2CF,  /* Full-Width Latin Case Difference 1 */
  179.  
  180.         0xA2E5, 0xA2E8,   /* Full-Width Latin Upper Range 2 */
  181.         0xA340 - 0XA2E5   /* Full-Width Latin Case Difference 2 */
  182. #ifndef _WIN32
  183.         ,
  184.         0xA2E9, 0xA2FE,   /* Full-Width Latin Lower Range 1 */
  185.  
  186.         0xA340, 0xA343,   /* Full-Width Latin Lower Range 2 */
  187.  
  188.         0xA2AF, 0xA2B8    /* Full-Width Latin Digit Range */
  189. #endif  /* _WIN32 */
  190.       },
  191.       {
  192.         { 0,    0,    0,    0,    0,    0,    0, 0, }, /* Single Byte Ranges */
  193.         { 0,    0,    0,    0,    0,    0,    0, 0, }, /* Punctuation Ranges */
  194.         { 0x81, 0xFE, 0,    0,    0,    0,    0, 0, }, /* Lead Byte Ranges */
  195.         { 0x40, 0x7E, 0xA1, 0xFE, 0,    0,    0, 0, }, /* Trail Byte Ranges */
  196.       }
  197.     },
  198.     {
  199.       _KOREAN_JOHAB_CP, /* Johab (Korean) Code Page */
  200.       { 0xDA51, 0xDA5E,   /* Full-Width Latin Upper Range 1 */
  201.         0xDA71 - 0xDA51,  /* Full-Width Latin Case Difference 1 */
  202.  
  203.         0xDA5F, 0xDA6A,   /* Full-Width Latin Upper Range 2 */
  204.         0xDA91 - 0xDA5F   /* Full-Width Latin Case Difference 2 */
  205. #ifndef _WIN32
  206.         ,
  207.         0xDA71, 0xDA7E,   /* Full-Width Latin Lower Range 1 */
  208.  
  209.         0xDA91, 0xDA9C,   /* Full-Width Latin Lower Range 2 */
  210.  
  211.         0xDA40, 0xDA49    /* Full-Width Latin Digit Range */
  212. #endif  /* _WIN32 */
  213.       },
  214.       {
  215.         { 0,    0,    0,    0,    0,    0,    0, 0, }, /* Single Byte Ranges */
  216.         { 0,    0,    0,    0,    0,    0,    0, 0, }, /* Punctuation Ranges */
  217.         { 0x81, 0xD3, 0xD8, 0xDE, 0xE0, 0xF9, 0, 0, }, /* Lead Byte Ranges */
  218.         { 0x31, 0x7E, 0x81, 0xFE, 0,    0,    0, 0, }, /* Trail Byte Ranges */
  219.       }
  220.     }
  221. };
  222.  
  223. /***
  224. *getSystemCP - Get system default CP if requested.
  225. *
  226. *Purpose:
  227. *       Get system default CP if requested.
  228. *
  229. *Entry:
  230. *       codepage - user requested code page/world script
  231. *Exit:
  232. *       requested code page
  233. *
  234. *Exceptions:
  235. *
  236. *******************************************************************************/
  237.  
  238. static int getSystemCP (int codepage)
  239. {
  240. #ifdef _WIN32
  241.     /* get system code page values if requested */
  242.  
  243.     fSystemSet = 0;
  244.  
  245.     if (codepage == _MB_CP_OEM)
  246.     {
  247.         fSystemSet = 1;
  248.         return GetOEMCP();
  249.     }
  250.  
  251.     else if (codepage == _MB_CP_ANSI)
  252.     {
  253.         fSystemSet = 1;
  254.         return GetACP();
  255.     }
  256.  
  257.     else
  258.     if (codepage == _MB_CP_LOCALE)
  259.     {
  260.         fSystemSet = 1;
  261.         return __lc_codepage;
  262.     }
  263.  
  264.     return codepage;
  265.  
  266. #endif  /* _WIN32 */
  267.  
  268. #ifdef _MAC
  269.  
  270.     tmpScriptID = 0;
  271.     fSystemSet = 0;
  272.  
  273.     /* get system Script ID */
  274.     if (codepage == _MB_CP_OEM || codepage == _MB_CP_ANSI)
  275.     {
  276.         fSystemSet = 1;
  277.         tmpScriptID = (short) GetEnvirons(smSysScript);
  278.     }
  279.  
  280.     /* or convert user Script ID */
  281.     else if (codepage > 0 && codepage < 32)
  282.         tmpScriptID = (short) codepage;
  283.  
  284.     if (tmpScriptID)
  285.     {
  286.         switch (tmpScriptID) {
  287.  
  288.             case smJapanese:
  289.                 return _KANJI_CP;
  290.  
  291.             case smKorean:
  292.                 return _KOREAN_WANGSUNG_CP;
  293.  
  294.             case smTradChinese:
  295.                 return _CHINESE_TRAD_CP;
  296.  
  297.             case smSimpChinese:
  298.                 return _CHINESE_SIMP_CP;
  299.  
  300.             default:
  301.                 tmpScriptID = 0;
  302.         }
  303.     }
  304.  
  305.     return codepage;
  306.  
  307. #endif  /* _MAC */
  308.  
  309. }
  310.  
  311.  
  312. #ifdef _WIN32
  313.  
  314. /***
  315. *CPtoLCID() - Code page to LCID.
  316. *
  317. *Purpose:
  318. *       Some API calls want an LCID, so convert MB CP to appropriate LCID,
  319. *       and then API converts back to ANSI CP for that LCID.
  320. *
  321. *Entry:
  322. *   codepage - code page to convert
  323. *Exit:
  324. *       returns appropriate LCID
  325. *
  326. *Exceptions:
  327. *
  328. *******************************************************************************/
  329.  
  330. static int CPtoLCID (int codepage)
  331. {
  332.     switch (codepage) {
  333.  
  334.     case 932:
  335.         return MAKELCID(MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT),
  336.                         SORT_DEFAULT);
  337.     case 936:
  338.         return MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),
  339.                         SORT_DEFAULT);
  340.     case 949:
  341.         return MAKELCID(MAKELANGID(LANG_KOREAN,SUBLANG_DEFAULT),
  342.                         SORT_DEFAULT);
  343.     case 950:
  344.         return MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL),
  345.                         SORT_DEFAULT);
  346.  
  347.     }
  348.  
  349.     return 0;
  350. }
  351.  
  352. #endif  /* _WIN32 */
  353.  
  354.  
  355. /***
  356. *setSBCS() - Set MB code page to SBCS.
  357. *
  358. *Purpose:
  359. *           Set MB code page to SBCS.
  360. *Entry:
  361. *
  362. *Exit:
  363. *
  364. *Exceptions:
  365. *
  366. *******************************************************************************/
  367.  
  368. static void setSBCS (void)
  369. {
  370.     int i;
  371.  
  372.     /* set for single-byte code page */
  373.     for (i = 0; i < NUM_CHARS; i++)
  374.         _mbctype[i] = 0;
  375.  
  376.     /* code page has changed, set global flag */
  377.     __mbcodepage = 0;
  378.  
  379.     /* clear flag to indicate single-byte code */
  380.     __ismbcodepage = 0;
  381.  
  382. #ifdef _WIN32
  383.     __mblcid = 0;
  384. #endif  /* _WIN32 */
  385.  
  386.     for (i = 0; i < NUM_ULINFO; i++)
  387.         __mbulinfo[i] = 0;
  388. }
  389.  
  390. /***
  391. *setSBUpLow() - Set single byte upper/lower mappings
  392. *
  393. *Purpose:
  394. *           Set single byte mapping for tolower/toupper.
  395. *Entry:
  396. *
  397. *Exit:
  398. *
  399. *Exceptions:
  400. *
  401. *******************************************************************************/
  402.  
  403. static void setSBUpLow (void)
  404. {
  405. #ifdef _WIN32
  406.     BYTE *  pbPair;
  407.     UINT    ich;
  408.     CPINFO  cpinfo;
  409.     UCHAR   sbVector[256];
  410.     UCHAR   upVector[256];
  411.     UCHAR   lowVector[256];
  412.     USHORT  wVector[256];
  413.  
  414.     //    test if codepage exists
  415.     if (GetCPInfo(__mbcodepage, &cpinfo) == TRUE)
  416.     {
  417.         //  if so, create vector 0-255
  418.         for (ich = 0; ich < 256; ich++)
  419.             sbVector[ich] = (UCHAR) ich;
  420.  
  421.         //  set byte 0 and any leading byte value to non-alpha char ' '
  422.         sbVector[0] = (UCHAR)' ';
  423.         for (pbPair = &cpinfo.LeadByte[0]; *pbPair; pbPair += 2)
  424.             for (ich = *pbPair; ich <= *(pbPair + 1); ich++)
  425.                 sbVector[ich] = (UCHAR)' ';
  426.  
  427.         //  get char type for character vector
  428.  
  429.         __crtGetStringTypeA(CT_CTYPE1, sbVector, 256, wVector,
  430.                             __mbcodepage, __mblcid, FALSE);
  431.  
  432.         //  get lower case mappings for character vector
  433.  
  434.         __crtLCMapStringA(__mblcid, LCMAP_LOWERCASE, sbVector, 256,
  435.                                     lowVector, 256, __mbcodepage, FALSE);
  436.  
  437.         //  get upper case mappings for character vector
  438.  
  439.         __crtLCMapStringA(__mblcid, LCMAP_UPPERCASE, sbVector, 256,
  440.                                     upVector, 256, __mbcodepage, FALSE);
  441.  
  442.         //  set _SBUP, _SBLOW in _mbctype if type is upper. lower
  443.         //  set mapping array with lower or upper mapping value
  444.  
  445.         for (ich = 0; ich < 256; ich++)
  446.             if (wVector[ich] & _UPPER)
  447.             {
  448.                 _mbctype[ich + 1] |= _SBUP;
  449.                 _mbcasemap[ich] = lowVector[ich];
  450.             }
  451.             else if (wVector[ich] & _LOWER)
  452.             {
  453.                 _mbctype[ich + 1] |= _SBLOW;
  454.                 _mbcasemap[ich] = upVector[ich];
  455.             }
  456.             else
  457.                 _mbcasemap[ich] = 0;
  458.     }
  459.     else
  460.     {
  461.         //  if no codepage, set 'A'-'Z' as upper, 'a'-'z' as lower
  462.  
  463.         for (ich = 0; ich < 256; ich++)
  464.             if (ich >= (UINT)'A' && ich <= (UINT)'Z')
  465.             {
  466.                 _mbctype[ich + 1] |= _SBUP;
  467.                 _mbcasemap[ich] = ich + ('a' - 'A');
  468.             }
  469.             else if (ich >= (UINT)'a' && ich <= (UINT)'z')
  470.             {
  471.                 _mbctype[ich + 1] |= _SBLOW;
  472.                 _mbcasemap[ich] = ich - ('a' - 'A');
  473.             }
  474.             else
  475.                 _mbcasemap[ich] = 0;
  476.     }
  477. #else  /* _WIN32 */
  478.     UINT ich;
  479.  
  480.     //  For MacOS, just define 'A'-'Z' as upper and 'a'-'z' as lower.
  481.  
  482.     for (ich = 0; ich < 256; ich++)
  483.         if (ich >= (UINT)'A' && ich <= (UINT)'Z')
  484.         {
  485.             _mbctype[ich + 1] |= _SBUP;
  486.             _mbcasemap[ich] = ich + ('a' - 'A');
  487.         }
  488.         else if (ich >= (UINT)'a' && ich <= (UINT)'z')
  489.         {
  490.             _mbctype[ich + 1] |= _SBLOW;
  491.             _mbcasemap[ich] = ich - ('a' - 'A');
  492.         }
  493.         else
  494.             _mbcasemap[ich] = 0;
  495. #endif  /* _WIN32 */
  496. }
  497.  
  498. /***
  499. *_setmbcp() - Set MBC data based on code page
  500. *
  501. *Purpose:
  502. *       Init MBC character type tables based on code page number. If
  503. *       given code page is supported, load that code page info into
  504. *       mbctype table. If not, query OS to find the information,
  505. *       otherwise set up table with single byte info.
  506. *Entry:
  507. *       codepage - code page to initialize MBC table
  508. *           _MB_CP_OEM = use system OEM code page
  509. *           _MB_CP_ANSI = use system ANSI code page
  510. *           _MB_CP_SBCS = set to single byte 'code page'
  511. *Exit:
  512. *        0 = Success
  513. *       -1 = Error, code page not changed.
  514. *
  515. *Exceptions:
  516. *
  517. *******************************************************************************/
  518.  
  519. int __cdecl _setmbcp (int codepage)
  520. {
  521.     unsigned int icp;
  522.     unsigned int irg;
  523.     unsigned int ich;
  524.     unsigned char *rgptr;
  525. #ifdef _WIN32
  526.     CPINFO cpinfo;
  527. #endif  /* _WIN32 */
  528.  
  529.     _mlock(_MB_CP_LOCK);
  530.  
  531.     codepage = getSystemCP(codepage);
  532.  
  533.     /* trivial case, request of current code page */
  534.     if (codepage == __mbcodepage)
  535.     {
  536.         /* return success */
  537. #ifdef _MAC
  538.         mbScriptID = tmpScriptID;
  539. #endif  /* _MAC */
  540.         _munlock(_MB_CP_LOCK);
  541.         return 0;
  542.     }
  543.  
  544.     /* user wants 'single-byte' MB code page */
  545.     if (codepage == _MB_CP_SBCS)
  546.     {
  547.         setSBCS();
  548.         setSBUpLow();
  549.         _munlock(_MB_CP_LOCK);
  550.         return 0;
  551.     }
  552.  
  553.     /* check for CRT code page info */
  554.     for (icp = 0;
  555.         icp < (sizeof(__rgcode_page_info) / sizeof(code_page_info));
  556.         icp++)
  557.     {
  558.         /* see if we have info for this code page */
  559.         if (__rgcode_page_info[icp].code_page == codepage)
  560.         {
  561.             /* clear the table */
  562.             for (ich = 0; ich < NUM_CHARS; ich++)
  563.                 _mbctype[ich] = 0;
  564.  
  565.             /* for each type of info, load table */
  566.             for (irg = 0; irg < NUM_CTYPES; irg++)
  567.             {
  568.                 /* go through all the ranges for each type of info */
  569.                 for (rgptr = (unsigned char *)__rgcode_page_info[icp].rgrange[irg];
  570.                     rgptr[0] && rgptr[1];
  571.                     rgptr += 2)
  572.                 {
  573.                     /* set the type for every character in range */
  574.                     for (ich = rgptr[0]; ich <= rgptr[1]; ich++)
  575.                         _mbctype[ich + 1] |= __rgctypeflag[irg];
  576.                 }
  577.             }
  578.             /* code page has changed */
  579.             __mbcodepage = codepage;
  580.             /* all the code pages we keep info for are truly multibyte */
  581.             __ismbcodepage = 1;
  582. #ifdef _WIN32
  583.             __mblcid = CPtoLCID(__mbcodepage);
  584. #endif  /* _WIN32 */
  585.             for (irg = 0; irg < NUM_ULINFO; irg++)
  586.                 __mbulinfo[irg] = __rgcode_page_info[icp].mbulinfo[irg];
  587.  
  588.             /* return success */
  589. #ifdef _MAC
  590.             mbScriptID = tmpScriptID;
  591. #endif  /* _MAC */
  592.             setSBUpLow();
  593.             _munlock(_MB_CP_LOCK);
  594.             return 0;
  595.         }
  596.     }
  597.  
  598. #if defined (_WIN32)
  599.  
  600.     /* code page not supported by CRT, try the OS */
  601.     if (GetCPInfo(codepage, &cpinfo) == TRUE) {
  602.         BYTE *lbptr;
  603.  
  604.         /* clear the table */
  605.         for (ich = 0; ich < NUM_CHARS; ich++)
  606.             _mbctype[ich] = 0;
  607.  
  608.         __mbcodepage = codepage;
  609.         __mblcid = 0;
  610.  
  611.         if (cpinfo.MaxCharSize > 1)
  612.         {
  613.             /* LeadByte range always terminated by two 0's */
  614.             for (lbptr = cpinfo.LeadByte; *lbptr && *(lbptr + 1); lbptr += 2)
  615.             {
  616.                 for (ich = *lbptr; ich <= *(lbptr + 1); ich++)
  617.                     _mbctype[ich + 1] |= _M1;
  618.             }
  619.  
  620.             /* All chars > 1 must be considered valid trail bytes */
  621.             for (ich = 0x01; ich < 0xFF; ich++)
  622.                 _mbctype[ich + 1] |= _M2;
  623.  
  624.             /* code page has changed */
  625.             __mblcid = CPtoLCID(__mbcodepage);
  626.  
  627.             /* really a multibyte code page */
  628.             __ismbcodepage = 1;
  629.         }
  630.         else
  631.             /* single-byte code page */
  632.             __ismbcodepage = 0;
  633.  
  634.         for (irg = 0; irg < NUM_ULINFO; irg++)
  635.             __mbulinfo[irg] = 0;
  636.  
  637.         setSBUpLow();
  638.         /* return success */
  639.         _munlock(_MB_CP_LOCK);
  640.         return 0;
  641.     }
  642.  
  643. #endif  /* defined (_WIN32) */
  644.  
  645.     /* If system default call, don't fail - set to SBCS */
  646.     if (fSystemSet)
  647.     {
  648.         setSBCS();
  649.         setSBUpLow();
  650.         _munlock(_MB_CP_LOCK);
  651.         return 0;
  652.     }
  653.  
  654.     /* return failure, code page not changed */
  655.     _munlock(_MB_CP_LOCK);
  656.     return -1;
  657. }
  658.  
  659. /***
  660. *_getmbcp() - Get the current MBC code page
  661. *
  662. *Purpose:
  663. *           Get code page value.
  664. *Entry:
  665. *       none.
  666. *Exit:
  667. *           return current MB codepage value.
  668. *
  669. *Exceptions:
  670. *
  671. *******************************************************************************/
  672.  
  673. int __cdecl _getmbcp (void)
  674. {
  675. #ifdef _MAC
  676.     if (mbScriptID)
  677.         return (int) mbScriptID;
  678. #endif  /* _MAC */
  679.  
  680.     if ( __ismbcodepage )
  681.         return __mbcodepage;
  682.     else
  683.         return 0;
  684. }
  685.  
  686.  
  687. /***
  688. *_initmbctable() - Set MB ctype table to initial default value.
  689. *
  690. *Purpose:
  691. *           Initialization.
  692. *Entry:
  693. *       none.
  694. *Exit:
  695. *           none.
  696. *Exceptions:
  697. *
  698. *******************************************************************************/
  699.  
  700. void __cdecl __initmbctable (void)
  701. {
  702. #ifdef CRTDLL
  703.  
  704.         _setmbcp(_MB_CP_ANSI);
  705.  
  706. #else  /* CRTDLL */
  707.  
  708.         /*
  709.          * Ensure we only initialize _mbctype[] once
  710.          */
  711.         if ( __mbctype_initialized == 0 ) {
  712.             _setmbcp(_MB_CP_ANSI);
  713.             __mbctype_initialized = 1;
  714.         }
  715.  
  716. #endif  /* CRTDLL */
  717. }
  718.  
  719. #endif  /* _MBCS */
  720.  
  721.  
  722. /************************ Code Page info from NT/Win95 ********************
  723.  
  724.  
  725. *** Code Page 932 ***
  726.  
  727. 0x824f  ;Fullwidth Digit Zero
  728. 0x8250  ;Fullwidth Digit One
  729. 0x8251  ;Fullwidth Digit Two
  730. 0x8252  ;Fullwidth Digit Three
  731. 0x8253  ;Fullwidth Digit Four
  732. 0x8254  ;Fullwidth Digit Five
  733. 0x8255  ;Fullwidth Digit Six
  734. 0x8256  ;Fullwidth Digit Seven
  735. 0x8257  ;Fullwidth Digit Eight
  736. 0x8258  ;Fullwidth Digit Nine
  737.  
  738. 0x8281  0x8260  ;Fullwidth Small A -> Fullwidth Capital A
  739. 0x8282  0x8261  ;Fullwidth Small B -> Fullwidth Capital B
  740. 0x8283  0x8262  ;Fullwidth Small C -> Fullwidth Capital C
  741. 0x8284  0x8263  ;Fullwidth Small D -> Fullwidth Capital D
  742. 0x8285  0x8264  ;Fullwidth Small E -> Fullwidth Capital E
  743. 0x8286  0x8265  ;Fullwidth Small F -> Fullwidth Capital F
  744. 0x8287  0x8266  ;Fullwidth Small G -> Fullwidth Capital G
  745. 0x8288  0x8267  ;Fullwidth Small H -> Fullwidth Capital H
  746. 0x8289  0x8268  ;Fullwidth Small I -> Fullwidth Capital I
  747. 0x828a  0x8269  ;Fullwidth Small J -> Fullwidth Capital J
  748. 0x828b  0x826a  ;Fullwidth Small K -> Fullwidth Capital K
  749. 0x828c  0x826b  ;Fullwidth Small L -> Fullwidth Capital L
  750. 0x828d  0x826c  ;Fullwidth Small M -> Fullwidth Capital M
  751. 0x828e  0x826d  ;Fullwidth Small N -> Fullwidth Capital N
  752. 0x828f  0x826e  ;Fullwidth Small O -> Fullwidth Capital O
  753. 0x8290  0x826f  ;Fullwidth Small P -> Fullwidth Capital P
  754. 0x8291  0x8270  ;Fullwidth Small Q -> Fullwidth Capital Q
  755. 0x8292  0x8271  ;Fullwidth Small R -> Fullwidth Capital R
  756. 0x8293  0x8272  ;Fullwidth Small S -> Fullwidth Capital S
  757. 0x8294  0x8273  ;Fullwidth Small T -> Fullwidth Capital T
  758. 0x8295  0x8274  ;Fullwidth Small U -> Fullwidth Capital U
  759. 0x8296  0x8275  ;Fullwidth Small V -> Fullwidth Capital V
  760. 0x8297  0x8276  ;Fullwidth Small W -> Fullwidth Capital W
  761. 0x8298  0x8277  ;Fullwidth Small X -> Fullwidth Capital X
  762. 0x8299  0x8278  ;Fullwidth Small Y -> Fullwidth Capital Y
  763. 0x829a  0x8279  ;Fullwidth Small Z -> Fullwidth Capital Z
  764.  
  765.  
  766. *** Code Page 936 ***
  767.  
  768. 0xa3b0  ;Fullwidth Digit Zero
  769. 0xa3b1  ;Fullwidth Digit One
  770. 0xa3b2  ;Fullwidth Digit Two
  771. 0xa3b3  ;Fullwidth Digit Three
  772. 0xa3b4  ;Fullwidth Digit Four
  773. 0xa3b5  ;Fullwidth Digit Five
  774. 0xa3b6  ;Fullwidth Digit Six
  775. 0xa3b7  ;Fullwidth Digit Seven
  776. 0xa3b8  ;Fullwidth Digit Eight
  777. 0xa3b9  ;Fullwidth Digit Nine
  778.  
  779. 0xa3e1  0xa3c1  ;Fullwidth Small A -> Fullwidth Capital A
  780. 0xa3e2  0xa3c2  ;Fullwidth Small B -> Fullwidth Capital B
  781. 0xa3e3  0xa3c3  ;Fullwidth Small C -> Fullwidth Capital C
  782. 0xa3e4  0xa3c4  ;Fullwidth Small D -> Fullwidth Capital D
  783. 0xa3e5  0xa3c5  ;Fullwidth Small E -> Fullwidth Capital E
  784. 0xa3e6  0xa3c6  ;Fullwidth Small F -> Fullwidth Capital F
  785. 0xa3e7  0xa3c7  ;Fullwidth Small G -> Fullwidth Capital G
  786. 0xa3e8  0xa3c8  ;Fullwidth Small H -> Fullwidth Capital H
  787. 0xa3e9  0xa3c9  ;Fullwidth Small I -> Fullwidth Capital I
  788. 0xa3ea  0xa3ca  ;Fullwidth Small J -> Fullwidth Capital J
  789. 0xa3eb  0xa3cb  ;Fullwidth Small K -> Fullwidth Capital K
  790. 0xa3ec  0xa3cc  ;Fullwidth Small L -> Fullwidth Capital L
  791. 0xa3ed  0xa3cd  ;Fullwidth Small M -> Fullwidth Capital M
  792. 0xa3ee  0xa3ce  ;Fullwidth Small N -> Fullwidth Capital N
  793. 0xa3ef  0xa3cf  ;Fullwidth Small O -> Fullwidth Capital O
  794. 0xa3f0  0xa3d0  ;Fullwidth Small P -> Fullwidth Capital P
  795. 0xa3f1  0xa3d1  ;Fullwidth Small Q -> Fullwidth Capital Q
  796. 0xa3f2  0xa3d2  ;Fullwidth Small R -> Fullwidth Capital R
  797. 0xa3f3  0xa3d3  ;Fullwidth Small S -> Fullwidth Capital S
  798. 0xa3f4  0xa3d4  ;Fullwidth Small T -> Fullwidth Capital T
  799. 0xa3f5  0xa3d5  ;Fullwidth Small U -> Fullwidth Capital U
  800. 0xa3f6  0xa3d6  ;Fullwidth Small V -> Fullwidth Capital V
  801. 0xa3f7  0xa3d7  ;Fullwidth Small W -> Fullwidth Capital W
  802. 0xa3f8  0xa3d8  ;Fullwidth Small X -> Fullwidth Capital X
  803. 0xa3f9  0xa3d9  ;Fullwidth Small Y -> Fullwidth Capital Y
  804. 0xa3fa  0xa3da  ;Fullwidth Small Z -> Fullwidth Capital Z
  805.  
  806.  
  807. *** Code Page 949 ***
  808.  
  809. 0xa3b0  ;Fullwidth Digit Zero
  810. 0xa3b1  ;Fullwidth Digit One
  811. 0xa3b2  ;Fullwidth Digit Two
  812. 0xa3b3  ;Fullwidth Digit Three
  813. 0xa3b4  ;Fullwidth Digit Four
  814. 0xa3b5  ;Fullwidth Digit Five
  815. 0xa3b6  ;Fullwidth Digit Six
  816. 0xa3b7  ;Fullwidth Digit Seven
  817. 0xa3b8  ;Fullwidth Digit Eight
  818. 0xa3b9  ;Fullwidth Digit Nine
  819.  
  820. 0xa3e1  0xa3c1  ;Fullwidth Small A -> Fullwidth Capital A
  821. 0xa3e2  0xa3c2  ;Fullwidth Small B -> Fullwidth Capital B
  822. 0xa3e3  0xa3c3  ;Fullwidth Small C -> Fullwidth Capital C
  823. 0xa3e4  0xa3c4  ;Fullwidth Small D -> Fullwidth Capital D
  824. 0xa3e5  0xa3c5  ;Fullwidth Small E -> Fullwidth Capital E
  825. 0xa3e6  0xa3c6  ;Fullwidth Small F -> Fullwidth Capital F
  826. 0xa3e7  0xa3c7  ;Fullwidth Small G -> Fullwidth Capital G
  827. 0xa3e8  0xa3c8  ;Fullwidth Small H -> Fullwidth Capital H
  828. 0xa3e9  0xa3c9  ;Fullwidth Small I -> Fullwidth Capital I
  829. 0xa3ea  0xa3ca  ;Fullwidth Small J -> Fullwidth Capital J
  830. 0xa3eb  0xa3cb  ;Fullwidth Small K -> Fullwidth Capital K
  831. 0xa3ec  0xa3cc  ;Fullwidth Small L -> Fullwidth Capital L
  832. 0xa3ed  0xa3cd  ;Fullwidth Small M -> Fullwidth Capital M
  833. 0xa3ee  0xa3ce  ;Fullwidth Small N -> Fullwidth Capital N
  834. 0xa3ef  0xa3cf  ;Fullwidth Small O -> Fullwidth Capital O
  835. 0xa3f0  0xa3d0  ;Fullwidth Small P -> Fullwidth Capital P
  836. 0xa3f1  0xa3d1  ;Fullwidth Small Q -> Fullwidth Capital Q
  837. 0xa3f2  0xa3d2  ;Fullwidth Small R -> Fullwidth Capital R
  838. 0xa3f3  0xa3d3  ;Fullwidth Small S -> Fullwidth Capital S
  839. 0xa3f4  0xa3d4  ;Fullwidth Small T -> Fullwidth Capital T
  840. 0xa3f5  0xa3d5  ;Fullwidth Small U -> Fullwidth Capital U
  841. 0xa3f6  0xa3d6  ;Fullwidth Small V -> Fullwidth Capital V
  842. 0xa3f7  0xa3d7  ;Fullwidth Small W -> Fullwidth Capital W
  843. 0xa3f8  0xa3d8  ;Fullwidth Small X -> Fullwidth Capital X
  844. 0xa3f9  0xa3d9  ;Fullwidth Small Y -> Fullwidth Capital Y
  845. 0xa3fa  0xa3da  ;Fullwidth Small Z -> Fullwidth Capital Z
  846.  
  847.  
  848. *** Code Page 950 ***
  849.  
  850. 0xa2af  ;Fullwidth Digit Zero
  851. 0xa2b0  ;Fullwidth Digit One
  852. 0xa2b1  ;Fullwidth Digit Two
  853. 0xa2b2  ;Fullwidth Digit Three
  854. 0xa2b3  ;Fullwidth Digit Four
  855. 0xa2b4  ;Fullwidth Digit Five
  856. 0xa2b5  ;Fullwidth Digit Six
  857. 0xa2b6  ;Fullwidth Digit Seven
  858. 0xa2b7  ;Fullwidth Digit Eight
  859. 0xa2b8  ;Fullwidth Digit Nine
  860.  
  861. 0xa2e9  0xa2cf  ;Fullwidth Small A -> Fullwidth Capital A
  862. 0xa2ea  0xa2d0  ;Fullwidth Small B -> Fullwidth Capital B
  863. 0xa2eb  0xa2d1  ;Fullwidth Small C -> Fullwidth Capital C
  864. 0xa2ec  0xa2d2  ;Fullwidth Small D -> Fullwidth Capital D
  865. 0xa2ed  0xa2d3  ;Fullwidth Small E -> Fullwidth Capital E
  866. 0xa2ee  0xa2d4  ;Fullwidth Small F -> Fullwidth Capital F
  867. 0xa2ef  0xa2d5  ;Fullwidth Small G -> Fullwidth Capital G
  868. 0xa2f0  0xa2d6  ;Fullwidth Small H -> Fullwidth Capital H
  869. 0xa2f1  0xa2d7  ;Fullwidth Small I -> Fullwidth Capital I
  870. 0xa2f2  0xa2d8  ;Fullwidth Small J -> Fullwidth Capital J
  871. 0xa2f3  0xa2d9  ;Fullwidth Small K -> Fullwidth Capital K
  872. 0xa2f4  0xa2da  ;Fullwidth Small L -> Fullwidth Capital L
  873. 0xa2f5  0xa2db  ;Fullwidth Small M -> Fullwidth Capital M
  874. 0xa2f6  0xa2dc  ;Fullwidth Small N -> Fullwidth Capital N
  875. 0xa2f7  0xa2dd  ;Fullwidth Small O -> Fullwidth Capital O
  876. 0xa2f8  0xa2de  ;Fullwidth Small P -> Fullwidth Capital P
  877. 0xa2f9  0xa2df  ;Fullwidth Small Q -> Fullwidth Capital Q
  878. 0xa2fa  0xa2e0  ;Fullwidth Small R -> Fullwidth Capital R
  879. 0xa2fb  0xa2e1  ;Fullwidth Small S -> Fullwidth Capital S
  880. 0xa2fc  0xa2e2  ;Fullwidth Small T -> Fullwidth Capital T
  881. 0xa2fd  0xa2e3  ;Fullwidth Small U -> Fullwidth Capital U
  882. 0xa2fe  0xa2e4  ;Fullwidth Small V -> Fullwidth Capital V
  883.  
  884. ...Note break in sequence...
  885.  
  886. 0xa340  0xa2e5  ;Fullwidth Small W -> Fullwidth Capital W
  887. 0xa341  0xa2e6  ;Fullwidth Small X -> Fullwidth Capital X
  888. 0xa342  0xa2e7  ;Fullwidth Small Y -> Fullwidth Capital Y
  889. 0xa343  0xa2e8  ;Fullwidth Small Z -> Fullwidth Capital Z
  890.  
  891.  
  892. *** Code Page 1361 ***
  893.  
  894. Not yet available (05/17/94)
  895.  
  896.  
  897.  
  898. ****************************************************************************/
  899.