ReactOS  0.4.14-dev-98-gb0d4763
_setmbcp.c
Go to the documentation of this file.
1 /*
2  * msvcrt.dll mbcs functions
3  *
4  * Copyright 1999 Alexandre Julliard
5  * Copyright 2000 Jon Griffths
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  * FIXME
22  * Not currently binary compatible with win32. MSVCRT_mbctype must be
23  * populated correctly and the ismb* functions should reference it.
24  */
25 
26 #include <precomp.h>
27 
28 #include <mbctype.h>
29 
30 /* It seems that the data about valid trail bytes is not available from kernel32
31  * so we have to store is here. The format is the same as for lead bytes in CPINFO */
33 {
34  int cp;
36 };
37 
38 static struct cp_extra_info_t g_cpextrainfo[] =
39 {
40  {932, {0x40, 0x7e, 0x80, 0xfc, 0, 0}},
41  {936, {0x40, 0xfe, 0, 0}},
42  {949, {0x41, 0xfe, 0, 0}},
43  {950, {0x40, 0x7e, 0xa1, 0xfe, 0, 0}},
44  {1361, {0x31, 0x7e, 0x81, 0xfe, 0, 0}},
45  {20932, {1, 255, 0, 0}}, /* seems to give different results on different systems */
46  {0, {1, 255, 0, 0}} /* match all with FIXME */
47 };
48 
49 /*********************************************************************
50  * INTERNAL: _setmbcp_l
51  */
52 int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
53 {
54  const char format[] = ".%d";
55 
56  int newcp;
57  CPINFO cpi;
58  BYTE *bytes;
59  WORD chartypes[256];
60  char bufA[256];
61  WCHAR bufW[256];
62  int charcount;
63  int ret;
64  int i;
65 
66  if(!mbcinfo)
67  mbcinfo = get_mbcinfo();
68 
69  switch (cp)
70  {
71  case _MB_CP_ANSI:
72  newcp = GetACP();
73  break;
74  case _MB_CP_OEM:
75  newcp = GetOEMCP();
76  break;
77  case _MB_CP_LOCALE:
78  newcp = get_locinfo()->lc_codepage;
79  if(newcp)
80  break;
81  /* fall through (C locale) */
82  case _MB_CP_SBCS:
83  newcp = 20127; /* ASCII */
84  break;
85  default:
86  newcp = cp;
87  break;
88  }
89 
90  if(lcid == -1) {
91  sprintf(bufA, format, newcp);
92  mbcinfo->mblcid = MSVCRT_locale_to_LCID(bufA, NULL);
93  } else {
94  mbcinfo->mblcid = lcid;
95  }
96 
97  if(mbcinfo->mblcid == -1)
98  {
99  WARN("Can't assign LCID to codepage (%d)\n", mbcinfo->mblcid);
100  mbcinfo->mblcid = 0;
101  }
102 
103  if (!GetCPInfo(newcp, &cpi))
104  {
105  WARN("Codepage %d not found\n", newcp);
106  *_errno() = EINVAL;
107  return -1;
108  }
109 
110  /* setup the _mbctype */
111  memset(mbcinfo->mbctype, 0, sizeof(unsigned char[257]));
112  memset(mbcinfo->mbcasemap, 0, sizeof(unsigned char[256]));
113 
114  bytes = cpi.LeadByte;
115  while (bytes[0] || bytes[1])
116  {
117  for (i = bytes[0]; i <= bytes[1]; i++)
118  mbcinfo->mbctype[i + 1] |= _M1;
119  bytes += 2;
120  }
121 
122  if (cpi.MaxCharSize > 1)
123  {
124  /* trail bytes not available through kernel32 but stored in a structure in msvcrt */
125  struct cp_extra_info_t *cpextra = g_cpextrainfo;
126 
127  mbcinfo->ismbcodepage = 1;
128  while (TRUE)
129  {
130  if (cpextra->cp == 0 || cpextra->cp == newcp)
131  {
132  if (cpextra->cp == 0)
133  FIXME("trail bytes data not available for DBCS codepage %d - assuming all bytes\n", newcp);
134 
135  bytes = cpextra->TrailBytes;
136  while (bytes[0] || bytes[1])
137  {
138  for (i = bytes[0]; i <= bytes[1]; i++)
139  mbcinfo->mbctype[i + 1] |= _M2;
140  bytes += 2;
141  }
142  break;
143  }
144  cpextra++;
145  }
146  }
147  else
148  mbcinfo->ismbcodepage = 0;
149 
150  /* we can't use GetStringTypeA directly because we don't have a locale - only a code page
151  */
152  charcount = 0;
153  for (i = 0; i < 256; i++)
154  if (!(mbcinfo->mbctype[i + 1] & _M1))
155  bufA[charcount++] = i;
156 
157  ret = MultiByteToWideChar(newcp, 0, bufA, charcount, bufW, charcount);
158  if (ret != charcount)
159  ERR("MultiByteToWideChar of chars failed for cp %d, ret=%d (exp %d), error=%d\n", newcp, ret, charcount, GetLastError());
160 
161  GetStringTypeW(CT_CTYPE1, bufW, charcount, chartypes);
162 
163  charcount = 0;
164  for (i = 0; i < 256; i++)
165  if (!(mbcinfo->mbctype[i + 1] & _M1))
166  {
167  if (chartypes[charcount] & C1_UPPER)
168  {
169  mbcinfo->mbctype[i + 1] |= _SBUP;
170  bufW[charcount] = tolowerW(bufW[charcount]);
171  }
172  else if (chartypes[charcount] & C1_LOWER)
173  {
174  mbcinfo->mbctype[i + 1] |= _SBLOW;
175  bufW[charcount] = toupperW(bufW[charcount]);
176  }
177  charcount++;
178  }
179 
180  ret = WideCharToMultiByte(newcp, 0, bufW, charcount, bufA, charcount, NULL, NULL);
181  if (ret != charcount)
182  ERR("WideCharToMultiByte failed for cp %d, ret=%d (exp %d), error=%d\n", newcp, ret, charcount, GetLastError());
183 
184  charcount = 0;
185  for (i = 0; i < 256; i++)
186  {
187  if(!(mbcinfo->mbctype[i + 1] & _M1))
188  {
189  if(mbcinfo->mbctype[i] & (C1_UPPER|C1_LOWER))
190  mbcinfo->mbcasemap[i] = bufA[charcount];
191  charcount++;
192  }
193  }
194 
195  if (newcp == 932) /* CP932 only - set _MP and _MS */
196  {
197  /* On Windows it's possible to calculate the _MP and _MS from CT_CTYPE1
198  * and CT_CTYPE3. But as of Wine 0.9.43 we return wrong values what makes
199  * it hard. As this is set only for codepage 932 we hardcode it what gives
200  * also faster execution.
201  */
202  for (i = 161; i <= 165; i++)
203  mbcinfo->mbctype[i + 1] |= _MP;
204  for (i = 166; i <= 223; i++)
205  mbcinfo->mbctype[i + 1] |= _MS;
206  }
207 
208  mbcinfo->mbcodepage = newcp;
209  if(global_locale && mbcinfo == MSVCRT_locale->mbcinfo)
211 
212  return 0;
213 }
214 
215 /*********************************************************************
216  * _setmbcp (MSVCRT.@)
217  */
218 int CDECL _setmbcp(int cp)
219 {
220  return _setmbcp_l(cp, -1, NULL);
221 }
222 
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:1904
#define _MB_CP_OEM
Definition: msvcrt.h:829
#define TRUE
Definition: types.h:120
#define _M2
Definition: msvcrt.h:818
LCID MSVCRT_locale_to_LCID(const char *)
#define WideCharToMultiByte
Definition: compat.h:101
unsigned char mbctype[257]
Definition: msvcrt.h:143
Definition: arc.h:39
#define WARN(fmt,...)
Definition: debug.h:111
#define _MP
Definition: msvcrt.h:816
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
UINT MaxCharSize
Definition: winnls.h:578
DWORD LCID
Definition: nls.h:13
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define C1_LOWER
Definition: unicode.h:32
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define _MB_CP_SBCS
Definition: msvcrt.h:828
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned char mbcasemap[256]
Definition: msvcrt.h:144
#define _mbctype
Definition: mbctype.h:28
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
BYTE TrailBytes[MAX_LEADBYTES]
Definition: _setmbcp.c:35
#define FIXME(fmt,...)
Definition: debug.h:110
MSVCRT_pthreadmbcinfo mbcinfo
Definition: msvcrt.h:153
smooth NULL
Definition: ftsmooth.c:416
UINT WINAPI GetACP(VOID)
Definition: nls.c:2169
#define get_locinfo()
Definition: winesup.h:25
WINE_UNICODE_INLINE WCHAR toupperW(WCHAR ch)
Definition: unicode.h:141
#define MAX_LEADBYTES
Definition: winnls.h:14
__wchar_t WCHAR
Definition: xmlstorage.h:180
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:580
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: lang.c:1699
int CDECL _setmbcp(int cp)
Definition: _setmbcp.c:218
#define _MS
Definition: msvcrt.h:815
unsigned short WORD
Definition: ntddk_ex.h:93
WINE_UNICODE_INLINE WCHAR tolowerW(WCHAR ch)
Definition: unicode.h:135
#define for
Definition: utility.h:88
#define _SBUP
Definition: msvcrt.h:820
#define CT_CTYPE1
Definition: winnls.h:234
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:19
MSVCRT__locale_t global_locale
Definition: locale.c:1495
int ret
#define _MB_CP_LOCALE
Definition: msvcrt.h:831
#define C1_UPPER
Definition: unicode.h:31
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
MSVCRT_pthreadmbcinfo get_mbcinfo(void)
Definition: locale.c:364
#define ERR(fmt,...)
Definition: debug.h:109
MSVCRT__locale_t MSVCRT_locale
Definition: msvcrt.h:885
#define CDECL
Definition: compat.h:21
#define _MB_CP_ANSI
Definition: msvcrt.h:830
#define _SBLOW
Definition: msvcrt.h:821
#define MultiByteToWideChar
Definition: compat.h:100
static struct cp_extra_info_t g_cpextrainfo[]
Definition: _setmbcp.c:38
POINT cp
Definition: magnifier.c:59
#define memset(x, y, z)
Definition: compat.h:39
int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
Definition: _setmbcp.c:52
#define _M1
Definition: msvcrt.h:817
UINT WINAPI GetOEMCP(VOID)
Definition: nls.c:2184