2 * msvcrt.dll mbcs functions
4 * Copyright 1999 Alexandre Julliard
5 * Copyright 2000 Jon Griffths
8 * Not currently binary compatable with win32. MSVCRT_mbctype must be
9 * populated correctly and the ismb* functions should reference it.
13 DEFAULT_DEBUG_CHANNEL(msvcrt);
15 unsigned char MSVCRT_mbctype[257];
16 int MSVCRT___mb_cur_max = 1;
18 int __cdecl MSVCRT_isleadbyte(int);
19 char *__cdecl MSVCRT__strset(char *, int);
20 char *__cdecl MSVCRT__strnset(char *, int, unsigned int);
21 extern unsigned int MSVCRT_current_lc_all_cp;
24 /*********************************************************************
25 * __p__mbctype (MSVCRT.@)
27 unsigned char *__cdecl MSVCRT___p__mbctype(void)
29 return MSVCRT_mbctype;
32 /*********************************************************************
33 * __p___mb_cur_max(MSVCRT.@)
35 int *__cdecl MSVCRT___p___mb_cur_max(void)
37 return &MSVCRT___mb_cur_max;
40 /*********************************************************************
43 unsigned int __cdecl MSVCRT__mbsnextc(const char *str)
45 if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*str))
46 return *str << 8 | str[1];
47 return *str; /* ASCII CP or SB char */
50 /*********************************************************************
53 int __cdecl MSVCRT__mbscmp(const char *str, const char *cmp)
55 if(MSVCRT___mb_cur_max > 1)
57 unsigned int strc, cmpc;
63 strc = MSVCRT__mbsnextc(str);
64 cmpc = MSVCRT__mbsnextc(cmp);
66 return strc < cmpc ? -1 : 1;
67 str +=(strc > 255) ? 2 : 1;
68 cmp +=(strc > 255) ? 2 : 1; /* equal, use same increment */
71 return strcmp(str, cmp); /* ASCII CP */
74 /*********************************************************************
77 int __cdecl MSVCRT__mbsicmp(const char *str, const char *cmp)
79 /* FIXME: No tolower() for mb strings yet */
80 if(MSVCRT___mb_cur_max > 1)
81 return MSVCRT__mbscmp(str, cmp);
82 return strcasecmp(str, cmp); /* ASCII CP */
85 /*********************************************************************
88 int __cdecl MSVCRT__mbsncmp(const char *str, const char *cmp, unsigned int len)
93 if(MSVCRT___mb_cur_max > 1)
95 unsigned int strc, cmpc;
102 strc = MSVCRT__mbsnextc(str);
103 cmpc = MSVCRT__mbsnextc(cmp);
105 return strc < cmpc ? -1 : 1;
106 str +=(strc > 255) ? 2 : 1;
107 cmp +=(strc > 255) ? 2 : 1; /* Equal, use same increment */
109 return 0; /* Matched len chars */
111 return strncmp(str, cmp, len); /* ASCII CP */
114 /*********************************************************************
115 * _mbsnicmp(MSVCRT.@)
117 * Compare two multibyte strings case insensitively to 'len' characters.
119 int __cdecl MSVCRT__mbsnicmp(const char *str, const char *cmp, unsigned int len)
121 /* FIXME: No tolower() for mb strings yet */
122 if(MSVCRT___mb_cur_max > 1)
123 return MSVCRT__mbsncmp(str, cmp, len);
124 return strncasecmp(str, cmp, len); /* ASCII CP */
127 /*********************************************************************
130 char *__cdecl MSVCRT__mbsinc(const char *str)
132 if(MSVCRT___mb_cur_max > 1 &&
133 MSVCRT_isleadbyte(*str))
134 return(char *)str + 2; /* MB char */
136 return(char *)str + 1; /* ASCII CP or SB char */
139 /*********************************************************************
142 char *MSVCRT__mbsninc(const char *str, unsigned int num)
146 if(MSVCRT___mb_cur_max > 1)
149 str = MSVCRT__mbsinc(str);
152 return(char *)str + num; /* ASCII CP */
155 /*********************************************************************
156 * _mbslen(MSVCRT.206)
158 int __cdecl MSVCRT__mbslen(const char *str)
160 if(MSVCRT___mb_cur_max > 1)
165 str += MSVCRT_isleadbyte(*str) ? 2 : 1;
170 return strlen(str); /* ASCII CP */
173 /*********************************************************************
176 char *__cdecl MSVCRT__mbsrchr(const char *s,unsigned int x)
178 /* FIXME: handle multibyte strings */
182 /*********************************************************************
185 int __cdecl MSVCRT_mbtowc(WCHAR *dst, const char *str, unsigned int n)
189 if(!MultiByteToWideChar(CP_ACP, 0, str, n, dst, 1))
191 /* return the number of bytes from src that have been used */
194 if(n >= 2 && MSVCRT_isleadbyte(*str) && str[1])
199 /*********************************************************************
202 void __cdecl MSVCRT__mbccpy(char *dest, char *src)
205 if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*src))
206 *dest = *++src; /* MB char */
209 /*********************************************************************
210 * _mbbtombc(MSVCRT.@)
212 unsigned int __cdecl MSVCRT__mbbtombc(unsigned int c)
214 if(MSVCRT___mb_cur_max > 1 &&
215 ((c >= 0x20 && c <=0x7e) ||(c >= 0xa1 && c <= 0xdf)))
217 /* FIXME: I can't get this function to return anything
218 * different to what I pass it...
221 return c; /* ASCII CP or no MB char */
224 /*********************************************************************
227 unsigned int __cdecl MSVCRT__mbclen(const char *str)
229 return MSVCRT_isleadbyte(*str) ? 2 : 1;
232 /*********************************************************************
233 * _ismbbkana(MSVCRT.@)
235 int __cdecl MSVCRT__ismbbkana(unsigned int c)
237 /* FIXME: use lc_ctype when supported, not lc_all */
238 if(MSVCRT_current_lc_all_cp == 932)
240 /* Japanese/Katakana, CP 932 */
241 return(c >= 0xa1 && c <= 0xdf);
246 /*********************************************************************
247 * _ismbchira(MSVCRT.@)
249 int __cdecl MSVCRT__ismbchira(unsigned int c)
251 /* FIXME: use lc_ctype when supported, not lc_all */
252 if(MSVCRT_current_lc_all_cp == 932)
254 /* Japanese/Hiragana, CP 932 */
255 return(c >= 0x829f && c <= 0x82f1);
260 /*********************************************************************
261 * _ismbckata(MSVCRT.@)
263 int __cdecl MSVCRT__ismbckata(unsigned int c)
265 /* FIXME: use lc_ctype when supported, not lc_all */
266 if(MSVCRT_current_lc_all_cp == 932)
269 return MSVCRT__ismbbkana(c);
270 /* Japanese/Katakana, CP 932 */
271 return(c >= 0x8340 && c <= 0x8396 && c != 0x837f);
276 /*********************************************************************
277 * _ismbblead(MSVCRT.@)
279 int __cdecl MSVCRT__ismbblead(unsigned int c)
281 /* FIXME: should reference MSVCRT_mbctype */
282 return MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(c);
286 /*********************************************************************
287 * _ismbbtrail(MSVCRT.@)
289 int __cdecl MSVCRT__ismbbtrail(unsigned int c)
291 /* FIXME: should reference MSVCRT_mbctype */
292 return !MSVCRT__ismbblead(c);
295 /*********************************************************************
296 * _ismbslead(MSVCRT.@)
298 int __cdecl MSVCRT__ismbslead(const char *start, const char *str)
300 /* Lead bytes can also be trail bytes if caller messed up
301 * iterating through the string...
303 if(MSVCRT___mb_cur_max > 1)
306 start += MSVCRT_isleadbyte(*str) ? 2 : 1;
309 return MSVCRT_isleadbyte(*str);
311 return 0; /* Must have been a trail, we skipped it */
314 /*********************************************************************
315 * _ismbstrail(MSVCRT.@)
317 int __cdecl MSVCRT__ismbstrail(const char *start, const char *str)
319 /* Must not be a lead, and must be preceeded by one */
320 return !MSVCRT__ismbslead(start, str) && MSVCRT_isleadbyte(str[-1]);
323 /*********************************************************************
326 char *__cdecl MSVCRT__mbsdec(const char *start, const char *cur)
328 if(MSVCRT___mb_cur_max > 1)
329 return(char *)(MSVCRT__ismbstrail(start,cur-1) ? cur - 2 : cur -1);
331 return(char *)cur - 1; /* ASCII CP or SB char */
334 /*********************************************************************
337 char *__cdecl MSVCRT__mbsset(char *str, unsigned int c)
341 if(MSVCRT___mb_cur_max == 1 || c < 256)
342 return MSVCRT__strset(str, c); /* ASCII CP or SB char */
344 c &= 0xffff; /* Strip high bits */
346 while(str[0] && str[1])
352 str[0] = '\0'; /* FIXME: OK to shorten? */
357 /*********************************************************************
360 char *__cdecl MSVCRT__mbsnset(char *str, unsigned int c, unsigned int len)
367 if(MSVCRT___mb_cur_max == 1 || c < 256)
368 return MSVCRT__strnset(str, c, len); /* ASCII CP or SB char */
370 c &= 0xffff; /* Strip high bits */
372 while(str[0] && str[1] && len--)
378 str[0] = '\0'; /* FIXME: OK to shorten? */
383 /*********************************************************************
384 * _mbstrlen(MSVCRT.@)
386 int __cdecl MSVCRT__mbstrlen(const char *str)
388 if(MSVCRT___mb_cur_max > 1)
393 str += MSVCRT_isleadbyte(*str) ? 2 : 1;
398 return strlen(str); /* ASCII CP */
401 /*********************************************************************
404 char *__cdecl MSVCRT__mbsncpy(char *dst, const char *src, unsigned int len)
408 if(MSVCRT___mb_cur_max > 1)
411 while(src[0] && src[1] && len--)
418 *dst++ = *src++; /* Last char or '\0' */
424 return strncpy(dst, src, len); /* ASCII CP */
427 /*********************************************************************
430 * Find a multibyte character in a multibyte string.
432 char *__cdecl MSVCRT__mbschr(const char *str, unsigned int c)
434 if(MSVCRT___mb_cur_max > 1)
437 while((next = MSVCRT__mbsnextc(str)))
441 str += next > 255 ? 2 : 1;
443 return c ? NULL :(char *)str;
445 return strchr(str, c); /* ASCII CP */
448 /*********************************************************************
449 * _mbsnccnt(MSVCRT.@)
451 unsigned int __cdecl MSVCRT__mbsnccnt(const char *str, unsigned int len)
455 if(MSVCRT___mb_cur_max > 1)
457 while(*str && len-- > 0)
459 if(MSVCRT_isleadbyte(*str))
469 return min(strlen(str), len); /* ASCII CP */
473 /*********************************************************************
476 char *__cdecl MSVCRT__mbsncat(char *dst, const char *src, unsigned int len)
478 if(MSVCRT___mb_cur_max > 1)
481 dst += MSVCRT__mbslen(dst);
485 if(MSVCRT_isleadbyte(*src))
493 return strncat(dst, src, len); /* ASCII CP */