source: trunk/src/msvcrt/mbcs.c@ 10005

Last change on this file since 10005 was 10005, checked in by sandervl, 22 years ago

PF: MSVCRT update

File size: 27.2 KB
Line 
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "msvcrt.h"
27
28#include "msvcrt/mbctype.h"
29#include "msvcrt/mbstring.h"
30#include "msvcrt/stdlib.h"
31#include "msvcrt/string.h"
32#include "msvcrt/wctype.h"
33
34#include "wine/unicode.h"
35#include "wine/debug.h"
36
37#include <string.h>
38#include <ctype.h>
39
40WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
41
42unsigned char MSVCRT_mbctype[257];
43int MSVCRT___mb_cur_max = 1;
44
45static MSVCRT_wchar_t msvcrt_mbc_to_wc(unsigned int ch)
46{
47 MSVCRT_wchar_t chW;
48 char mbch[2];
49 int n_chars;
50
51 if (ch <= 0xff) {
52 mbch[0] = ch;
53 n_chars = 1;
54 } else {
55 mbch[0] = (ch >> 8) & 0xff;
56 mbch[1] = ch & 0xff;
57 n_chars = 2;
58 }
59 if (!MultiByteToWideChar(MSVCRT_current_lc_all_cp, 0, mbch, n_chars, &chW, 1))
60 {
61 WARN("MultiByteToWideChar failed on %x\n", ch);
62 return 0;
63 }
64 return chW;
65}
66
67/*********************************************************************
68 * __p__mbctype (MSVCRT.@)
69 */
70unsigned char* __p__mbctype(void)
71{
72 dprintf(("MSVCRT: Query for __p__mbctype"));
73 return MSVCRT_mbctype;
74}
75
76/*********************************************************************
77 * __p___mb_cur_max(MSVCRT.@)
78 */
79int* __p___mb_cur_max(void)
80{
81 dprintf(("MSVCRT: Query for __p__mb_cur_max"));
82 return &MSVCRT___mb_cur_max;
83}
84
85/*********************************************************************
86 * _mbsnextc(MSVCRT.@)
87 */
88unsigned int _mbsnextc(const unsigned char* str)
89{
90 dprintf(("MSVCRT: _mbsnextc"));
91 if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*str))
92 return *str << 8 | str[1];
93 return *str; /* ASCII CP or SB char */
94}
95
96/*********************************************************************
97 * _mbctolower(MSVCRT.@)
98 */
99unsigned int _mbctolower(unsigned int c)
100{
101 dprintf(("MSVCRT: _mbctolower"));
102 if (MSVCRT_isleadbyte(c))
103 {
104 FIXME("Handle MBC chars\n");
105 return c;
106 }
107 return tolower(c); /* ASCII CP or SB char */
108}
109
110/*********************************************************************
111 * _mbctoupper(MSVCRT.@)
112 */
113unsigned int _mbctoupper(unsigned int c)
114{
115 dprintf(("MSVCRT: _mbctoupper"));
116 if (MSVCRT_isleadbyte(c))
117 {
118 FIXME("Handle MBC chars\n");
119 return c;
120 }
121 return toupper(c); /* ASCII CP or SB char */
122}
123
124/*********************************************************************
125 * _mbsdec(MSVCRT.@)
126 */
127unsigned char* _mbsdec(const unsigned char* start, const unsigned char* cur)
128{
129 dprintf(("MSVCRT: _mbsdec"));
130 if(MSVCRT___mb_cur_max > 1)
131 return (char *)(_ismbstrail(start,cur-1) ? cur - 2 : cur -1);
132
133 return (char *)cur - 1; /* ASCII CP or SB char */
134}
135
136/*********************************************************************
137 * _mbsinc(MSVCRT.@)
138 */
139unsigned char* _mbsinc(const unsigned char* str)
140{
141 dprintf(("MSVCRT: _mbsinc"));
142 if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*str))
143 return (unsigned char*)str + 2; /* MB char */
144
145 return (unsigned char*)str + 1; /* ASCII CP or SB char */
146}
147
148/*********************************************************************
149 * _mbsninc(MSVCRT.@)
150 */
151unsigned char* _mbsninc(const unsigned char* str, MSVCRT_size_t num)
152{
153 dprintf(("MSVCRT: _mbsninc"));
154 if(!str || num < 1)
155 return NULL;
156 if(MSVCRT___mb_cur_max > 1)
157 {
158 while(num--)
159 str = _mbsinc(str);
160 return (unsigned char*)str;
161 }
162 return (unsigned char*)str + num; /* ASCII CP */
163}
164
165/*********************************************************************
166 * _mbclen(MSVCRT.@)
167 */
168unsigned int _mbclen(const unsigned char* str)
169{
170 dprintf(("MSVCRT: _mbclen"));
171 return MSVCRT_isleadbyte(*str) ? 2 : 1;
172}
173
174/*********************************************************************
175 * mblen(MSVCRT.@)
176 */
177int MSVCRT_mblen(const char* str, MSVCRT_size_t size)
178{
179 dprintf(("MSVCRT: mblen"));
180 if (str && *str && size)
181 {
182 if(MSVCRT___mb_cur_max == 1)
183 return 1; /* ASCII CP */
184
185 return !MSVCRT_isleadbyte(*str) ? 1 : (size>1 ? 2 : -1);
186 }
187 return 0;
188}
189
190/*********************************************************************
191 * _mbslen(MSVCRT.@)
192 */
193MSVCRT_size_t _mbslen(const unsigned char* str)
194{
195 dprintf(("MSVCRT: _mbslen"));
196 if(MSVCRT___mb_cur_max > 1)
197 {
198 MSVCRT_size_t len = 0;
199 while(*str)
200 {
201 str += MSVCRT_isleadbyte(*str) ? 2 : 1;
202 len++;
203 }
204 return len;
205 }
206 return strlen(str); /* ASCII CP */
207}
208
209/*********************************************************************
210 * _mbstrlen(MSVCRT.@)
211 */
212MSVCRT_size_t _mbstrlen(const char* str)
213{
214 dprintf(("MSVCRT: _mbstrlen"));
215 if(MSVCRT___mb_cur_max > 1)
216 {
217 MSVCRT_size_t len = 0;
218 while(*str)
219 {
220 /* FIXME: According to the documentation we are supposed to test for
221 * multi-byte character validity. Whatever that means
222 */
223 str += MSVCRT_isleadbyte(*str) ? 2 : 1;
224 len++;
225 }
226 return len;
227 }
228 return strlen(str); /* ASCII CP */
229}
230
231/*********************************************************************
232 * _mbccpy(MSVCRT.@)
233 */
234void _mbccpy(unsigned char* dest, const unsigned char* src)
235{
236 dprintf(("MSVCRT: _mbccpy"));
237 *dest++ = *src;
238 if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*src))
239 *dest = *++src; /* MB char */
240 else
241 ERR("failure.. is this ok?\n");
242}
243
244/*********************************************************************
245 * _mbsncpy(MSVCRT.@)
246 */
247unsigned char* _mbsncpy(unsigned char* dst, const unsigned char* src, MSVCRT_size_t n)
248{
249 dprintf(("MSVCRT: _mbsncpy"));
250 if(!n)
251 return dst;
252 if(MSVCRT___mb_cur_max > 1)
253 {
254 unsigned char* ret = dst;
255 while (*src && n--)
256 {
257 *dst++ = *src;
258 if (MSVCRT_isleadbyte(*src++))
259 *dst++ = *src++;
260 }
261 while(n--)
262 *dst++ = '\0';
263 return ret;
264 }
265 return strncpy(dst, src, n); /* ASCII CP */
266}
267
268/*********************************************************************
269 * _mbsnbcpy(MSVCRT.@)
270 */
271unsigned char* _mbsnbcpy(unsigned char* dst, const unsigned char* src, MSVCRT_size_t n)
272{
273 dprintf(("MSVCRT: _mbsnbcpy"));
274 if(!n)
275 return dst;
276 if(MSVCRT___mb_cur_max > 1)
277 {
278 unsigned char* ret = dst;
279 while (*src && (n-- > 1))
280 {
281 *dst++ = *src;
282 if (MSVCRT_isleadbyte(*src++))
283 {
284 *dst++ = *src++;
285 n--;
286 }
287 }
288 if (*src && n && !MSVCRT_isleadbyte(*src))
289 {
290 /* If the last character is a multi-byte character then
291 * we cannot copy it since we have only one byte left
292 */
293 *dst++ = *src;
294 n--;
295 }
296 while (n--)
297 *dst++ = '\0';
298 return ret;
299 }
300 return strncpy(dst, src, n); /* ASCII CP */
301}
302
303/*********************************************************************
304 * _mbscmp(MSVCRT.@)
305 */
306int _mbscmp(const unsigned char* str, const unsigned char* cmp)
307{
308 dprintf(("MSVCRT: _mbscmp"));
309 if(MSVCRT___mb_cur_max > 1)
310 {
311 unsigned int strc, cmpc;
312 do {
313 if(!*str)
314 return *cmp ? -1 : 0;
315 if(!*cmp)
316 return 1;
317 strc = _mbsnextc(str);
318 cmpc = _mbsnextc(cmp);
319 if(strc != cmpc)
320 return strc < cmpc ? -1 : 1;
321 str +=(strc > 255) ? 2 : 1;
322 cmp +=(strc > 255) ? 2 : 1; /* equal, use same increment */
323 } while(1);
324 }
325 return strcmp(str, cmp); /* ASCII CP */
326}
327
328/*********************************************************************
329 * _mbsicoll(MSVCRT.@)
330 * FIXME: handle locales.
331 */
332int _mbsicoll(const unsigned char* str, const unsigned char* cmp)
333{
334 if(MSVCRT___mb_cur_max > 1)
335 {
336 unsigned int strc, cmpc;
337 do {
338 if(!*str)
339 return *cmp ? -1 : 0;
340 if(!*cmp)
341 return 1;
342 strc = _mbctolower(_mbsnextc(str));
343 cmpc = _mbctolower(_mbsnextc(cmp));
344 if(strc != cmpc)
345 return strc < cmpc ? -1 : 1;
346 str +=(strc > 255) ? 2 : 1;
347 cmp +=(strc > 255) ? 2 : 1; /* equal, use same increment */
348 } while(1);
349 }
350 return strcasecmp(str, cmp); /* ASCII CP */
351}
352
353/*********************************************************************
354 * _mbsicmp(MSVCRT.@)
355 */
356int _mbsicmp(const unsigned char* str, const unsigned char* cmp)
357{
358 dprintf(("MSVCRT: _mbsicmp"));
359 if(MSVCRT___mb_cur_max > 1)
360 {
361 unsigned int strc, cmpc;
362 do {
363 if(!*str)
364 return *cmp ? -1 : 0;
365 if(!*cmp)
366 return 1;
367 strc = _mbctolower(_mbsnextc(str));
368 cmpc = _mbctolower(_mbsnextc(cmp));
369 if(strc != cmpc)
370 return strc < cmpc ? -1 : 1;
371 str +=(strc > 255) ? 2 : 1;
372 cmp +=(strc > 255) ? 2 : 1; /* equal, use same increment */
373 } while(1);
374 }
375 return _stricmp(str, cmp); /* ASCII CP */
376}
377
378/*********************************************************************
379 * _mbsncmp(MSVCRT.@)
380 */
381int _mbsncmp(const unsigned char* str, const unsigned char* cmp, MSVCRT_size_t len)
382{
383 dprintf(("MSVCRT: _mbsncmp"));
384 if(!len)
385 return 0;
386
387 if(MSVCRT___mb_cur_max > 1)
388 {
389 unsigned int strc, cmpc;
390 while(len--)
391 {
392 int inc;
393 if(!*str)
394 return *cmp ? -1 : 0;
395 if(!*cmp)
396 return 1;
397 strc = _mbsnextc(str);
398 cmpc = _mbsnextc(cmp);
399 if(strc != cmpc)
400 return strc < cmpc ? -1 : 1;
401 inc=(strc > 255) ? 2 : 1; /* Equal, use same increment */
402 str += inc;
403 cmp += inc;
404 }
405 return 0; /* Matched len chars */
406 }
407 return strncmp(str, cmp, len); /* ASCII CP */
408}
409
410/*********************************************************************
411 * _mbsnbcmp(MSVCRT.@)
412 */
413int _mbsnbcmp(const unsigned char* str, const unsigned char* cmp, MSVCRT_size_t len)
414{
415 dprintf(("MSVCRT: _mbsnbcmp"));
416 if (!len)
417 return 0;
418 if(MSVCRT___mb_cur_max > 1)
419 {
420 unsigned int strc, cmpc;
421 while (len)
422 {
423 int clen;
424 if(!*str)
425 return *cmp ? -1 : 0;
426 if(!*cmp)
427 return 1;
428 if (MSVCRT_isleadbyte(*str))
429 {
430 strc=(len>=2)?_mbsnextc(str):0;
431 clen=2;
432 }
433 else
434 {
435 strc=*str;
436 clen=1;
437 }
438 if (MSVCRT_isleadbyte(*cmp))
439 cmpc=(len>=2)?_mbsnextc(cmp):0;
440 else
441 cmpc=*str;
442 if(strc != cmpc)
443 return strc < cmpc ? -1 : 1;
444 len -= clen;
445 str += clen;
446 cmp += clen;
447 }
448 return 0; /* Matched len chars */
449 FIXME("%s %s %d\n",str,cmp,len);
450 }
451 return strncmp(str,cmp,len);
452}
453
454/*********************************************************************
455 * _mbsnicmp(MSVCRT.@)
456 *
457 * Compare two multibyte strings case insensitively to 'len' characters.
458 */
459int _mbsnicmp(const unsigned char* str, const unsigned char* cmp, MSVCRT_size_t len)
460{
461 dprintf(("MSVCRT: _mbsnicmp"));
462 /* FIXME: No tolower() for mb strings yet */
463 if(MSVCRT___mb_cur_max > 1)
464 {
465 unsigned int strc, cmpc;
466 while(len--)
467 {
468 if(!*str)
469 return *cmp ? -1 : 0;
470 if(!*cmp)
471 return 1;
472 strc = _mbctolower(_mbsnextc(str));
473 cmpc = _mbctolower(_mbsnextc(cmp));
474 if(strc != cmpc)
475 return strc < cmpc ? -1 : 1;
476 str +=(strc > 255) ? 2 : 1;
477 cmp +=(strc > 255) ? 2 : 1; /* Equal, use same increment */
478 }
479 return 0; /* Matched len chars */
480 }
481 return strncasecmp(str, cmp, len); /* ASCII CP */
482}
483
484/*********************************************************************
485 * _mbsnbicmp(MSVCRT.@)
486 */
487int _mbsnbicmp(const unsigned char* str, const unsigned char* cmp, MSVCRT_size_t len)
488{
489 dprintf(("MSVCRT: _mbsnbicmp"));
490 if (!len)
491 return 0;
492 if(MSVCRT___mb_cur_max > 1)
493 {
494 unsigned int strc, cmpc;
495 while (len)
496 {
497 int clen;
498 if(!*str)
499 return *cmp ? -1 : 0;
500 if(!*cmp)
501 return 1;
502 if (MSVCRT_isleadbyte(*str))
503 {
504 strc=(len>=2)?_mbsnextc(str):0;
505 clen=2;
506 }
507 else
508 {
509 strc=*str;
510 clen=1;
511 }
512 if (MSVCRT_isleadbyte(*cmp))
513 cmpc=(len>=2)?_mbsnextc(cmp):0;
514 else
515 cmpc=*str;
516 strc = _mbctolower(strc);
517 cmpc = _mbctolower(cmpc);
518 if(strc != cmpc)
519 return strc < cmpc ? -1 : 1;
520 len -= clen;
521 str += clen;
522 cmp += clen;
523 }
524 return 0; /* Matched len bytes */
525 FIXME("%s %s %d\n",str,cmp,len);
526 }
527 return strncmp(str,cmp,len);
528}
529
530/*********************************************************************
531 * _mbschr(MSVCRT.@)
532 *
533 * Find a multibyte character in a multibyte string.
534 */
535unsigned char* _mbschr(const unsigned char* s, unsigned int x)
536{
537 dprintf(("MSVCRT: _mbschr"));
538 if(MSVCRT___mb_cur_max > 1)
539 {
540 unsigned int c;
541 while (1)
542 {
543 c = _mbsnextc(s);
544 if (c == x)
545 return (unsigned char*)s;
546 if (!c)
547 return NULL;
548 s += c > 255 ? 2 : 1;
549 }
550 }
551 return strchr(s, x); /* ASCII CP */
552}
553
554/*********************************************************************
555 * _mbsrchr(MSVCRT.@)
556 */
557unsigned char* _mbsrchr(const unsigned char* s, unsigned int x)
558{
559 dprintf(("MSVCRT: _mbsrchr"));
560 if(MSVCRT___mb_cur_max > 1)
561 {
562 unsigned int c;
563 unsigned char* match=NULL;
564 if(!s)
565 return NULL;
566 while (1) {
567 c = _mbsnextc(s);
568 if (c == x)
569 match=(unsigned char*)s;
570 if (!c)
571 return match;
572 s +=(c > 255) ? 2 : 1;
573 }
574 }
575 return strrchr(s,x);
576}
577
578/*********************************************************************
579 * _mbstok(MSVCRT.@)
580 *
581 * Find and extract tokens from strings
582 */
583unsigned char* _mbstok(unsigned char *str, const unsigned char *delim)
584{
585 MSVCRT_thread_data *data = msvcrt_get_thread_data();
586 char *ret;
587
588 if(MSVCRT___mb_cur_max > 1)
589 {
590 unsigned int c;
591
592 if (!str)
593 if (!(str = data->mbstok_next)) return NULL;
594
595 while ((c = _mbsnextc(str)) && _mbschr(delim, c)) {
596 str += c > 255 ? 2 : 1;
597 }
598 if (!*str) return NULL;
599 ret = str++;
600 while ((c = _mbsnextc(str)) && !_mbschr(delim, c)) {
601 str += c > 255 ? 2 : 1;
602 }
603 if (*str) {
604 *str++ = 0;
605 if (c > 255) *str++ = 0;
606 }
607 data->mbstok_next = str;
608 return ret;
609 }
610 return strtok(str, delim); /* ASCII CP */
611}
612
613/*********************************************************************
614 * mbtowc(MSVCRT.@)
615 */
616int MSVCRT_mbtowc(MSVCRT_wchar_t *dst, const char* str, MSVCRT_size_t n)
617{
618 dprintf(("MSVCRT: _mbtowc"));
619 if(n <= 0 || !str)
620 return 0;
621 if(!MultiByteToWideChar(CP_ACP, 0, str, n, dst, 1))
622 return 0;
623 /* return the number of bytes from src that have been used */
624 if(!*str)
625 return 0;
626 if(n >= 2 && MSVCRT_isleadbyte(*str) && str[1])
627 return 2;
628 return 1;
629}
630
631/*********************************************************************
632 * _mbbtombc(MSVCRT.@)
633 */
634unsigned int _mbbtombc(unsigned int c)
635{
636 dprintf(("MSVCRT: _mbbtombc"));
637 if(MSVCRT___mb_cur_max > 1 &&
638 ((c >= 0x20 && c <=0x7e) ||(c >= 0xa1 && c <= 0xdf)))
639 {
640 /* FIXME: I can't get this function to return anything
641 * different to what I pass it...
642 */
643 }
644 return c; /* ASCII CP or no MB char */
645}
646
647/*********************************************************************
648 * _ismbbkana(MSVCRT.@)
649 */
650int _ismbbkana(unsigned int c)
651{
652 dprintf(("MSVCRT: _ismbbkana"));
653 /* FIXME: use lc_ctype when supported, not lc_all */
654 if(MSVCRT_current_lc_all_cp == 932)
655 {
656 /* Japanese/Katakana, CP 932 */
657 return (c >= 0xa1 && c <= 0xdf);
658 }
659 return 0;
660}
661
662/*********************************************************************
663 * _ismbcdigit(MSVCRT.@)
664 */
665int _ismbcdigit(unsigned int ch)
666{
667 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
668 dprintf(("MSVCRT: _ismbcdigit"));
669 return (get_char_typeW( wch ) & C1_DIGIT);
670}
671
672/*********************************************************************
673 * _ismbcgraph(MSVCRT.@)
674 */
675int _ismbcgraph(unsigned int ch)
676{
677 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
678 return (get_char_typeW( wch ) & (C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_ALPHA));
679}
680
681/*********************************************************************
682 * _ismbcalpha (MSVCRT.@)
683 */
684int _ismbcalpha(unsigned int ch)
685{
686 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
687 return (get_char_typeW( wch ) & C1_ALPHA);
688}
689
690/*********************************************************************
691 * _ismbclower (MSVCRT.@)
692 */
693int _ismbclower(unsigned int ch)
694{
695 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
696 return (get_char_typeW( wch ) & C1_UPPER);
697}
698
699/*********************************************************************
700 * _ismbcupper (MSVCRT.@)
701 */
702int _ismbcupper(unsigned int ch)
703{
704 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
705 return (get_char_typeW( wch ) & C1_LOWER);
706}
707
708/*********************************************************************
709 * _ismbcsymbol(MSVCRT.@)
710 */
711int _ismbcsymbol(unsigned int ch)
712{
713 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
714 WORD ctype;
715 if (!GetStringTypeW(CT_CTYPE3, &wch, 1, &ctype))
716 {
717 WARN("GetStringTypeW failed on %x\n", ch);
718 return 0;
719 }
720 return ((ctype & C3_SYMBOL) != 0);
721}
722
723/*********************************************************************
724 * _ismbcalnum (MSVCRT.@)
725 */
726int _ismbcalnum(unsigned int ch)
727{
728 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
729 return (get_char_typeW( wch ) & (C1_ALPHA | C1_DIGIT));
730}
731
732/*********************************************************************
733 * _ismbcspace (MSVCRT.@)
734 */
735int _ismbcspace(unsigned int ch)
736{
737 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
738 return (get_char_typeW( wch ) & C1_SPACE);
739}
740
741/*********************************************************************
742 * _ismbcprint (MSVCRT.@)
743 */
744int _ismbcprint(unsigned int ch)
745{
746 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
747 return (get_char_typeW( wch ) & (C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_ALPHA | C1_SPACE));
748}
749
750/*********************************************************************
751 * _ismbcpunct(MSVCRT.@)
752 */
753int _ismbcpunct(unsigned int ch)
754{
755 MSVCRT_wchar_t wch = msvcrt_mbc_to_wc( ch );
756 return (get_char_typeW( wch ) & C1_PUNCT);
757}
758
759/*********************************************************************
760 * _ismbchira(MSVCRT.@)
761 */
762int _ismbchira(unsigned int c)
763{
764 /* FIXME: use lc_ctype when supported, not lc_all */
765 if(MSVCRT_current_lc_all_cp == 932)
766 {
767 /* Japanese/Hiragana, CP 932 */
768 return (c >= 0x829f && c <= 0x82f1);
769 }
770 return 0;
771}
772
773/*********************************************************************
774 * _ismbckata(MSVCRT.@)
775 */
776int _ismbckata(unsigned int c)
777{
778 /* FIXME: use lc_ctype when supported, not lc_all */
779 if(MSVCRT_current_lc_all_cp == 932)
780 {
781 if(c < 256)
782 return _ismbbkana(c);
783 /* Japanese/Katakana, CP 932 */
784 return (c >= 0x8340 && c <= 0x8396 && c != 0x837f);
785 }
786 return 0;
787}
788
789/*********************************************************************
790 * _ismbblead(MSVCRT.@)
791 */
792int _ismbblead(unsigned int c)
793{
794 /* FIXME: should reference MSVCRT_mbctype */
795 return MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(c);
796}
797
798
799/*********************************************************************
800 * _ismbbtrail(MSVCRT.@)
801 */
802int _ismbbtrail(unsigned int c)
803{
804 /* FIXME: should reference MSVCRT_mbctype */
805 return !_ismbblead(c);
806}
807
808/*********************************************************************
809 * _ismbslead(MSVCRT.@)
810 */
811int _ismbslead(const unsigned char* start, const unsigned char* str)
812{
813 /* Lead bytes can also be trail bytes if caller messed up
814 * iterating through the string...
815 */
816 if(MSVCRT___mb_cur_max > 1)
817 {
818 while(start < str)
819 start += MSVCRT_isleadbyte(*str) ? 2 : 1;
820
821 if(start == str)
822 return MSVCRT_isleadbyte(*str);
823 }
824 return 0; /* Must have been a trail, we skipped it */
825}
826
827/*********************************************************************
828 * _ismbstrail(MSVCRT.@)
829 */
830int _ismbstrail(const unsigned char* start, const unsigned char* str)
831{
832 /* Must not be a lead, and must be preceeded by one */
833 return !_ismbslead(start, str) && MSVCRT_isleadbyte(str[-1]);
834}
835
836/*********************************************************************
837 * _mbsset(MSVCRT.@)
838 */
839unsigned char* _mbsset(unsigned char* str, unsigned int c)
840{
841 unsigned char* ret = str;
842
843 if(MSVCRT___mb_cur_max == 1 || c < 256)
844 return MSVCRT__strset(str, c); /* ASCII CP or SB char */
845
846 c &= 0xffff; /* Strip high bits */
847
848 while(str[0] && str[1])
849 {
850 *str++ = c >> 8;
851 *str++ = c & 0xff;
852 }
853 if(str[0])
854 str[0] = '\0'; /* FIXME: OK to shorten? */
855
856 return ret;
857}
858
859/*********************************************************************
860 * _mbsnbset(MSVCRT.@)
861 */
862unsigned char* _mbsnbset(unsigned char *str, unsigned int c, MSVCRT_size_t len)
863{
864 unsigned char *ret = str;
865
866 if(!len)
867 return ret;
868
869 if(MSVCRT___mb_cur_max == 1 || c < 256)
870 return _strnset(str, c, len); /* ASCII CP or SB char */
871
872 c &= 0xffff; /* Strip high bits */
873
874 while(str[0] && str[1] && (len > 1))
875 {
876 *str++ = c >> 8;
877 len--;
878 *str++ = c & 0xff;
879 len--;
880 }
881 if(len && str[0]) {
882 /* as per msdn pad with a blank character */
883 str[0] = ' ';
884 }
885
886 return ret;
887}
888
889/*********************************************************************
890 * _mbsnset(MSVCRT.@)
891 */
892unsigned char* _mbsnset(unsigned char* str, unsigned int c, MSVCRT_size_t len)
893{
894 unsigned char *ret = str;
895
896 if(!len)
897 return ret;
898
899 if(MSVCRT___mb_cur_max == 1 || c < 256)
900 return MSVCRT__strnset(str, c, len); /* ASCII CP or SB char */
901
902 c &= 0xffff; /* Strip high bits */
903
904 while(str[0] && str[1] && len--)
905 {
906 *str++ = c >> 8;
907 *str++ = c & 0xff;
908 }
909 if(len && str[0])
910 str[0] = '\0'; /* FIXME: OK to shorten? */
911
912 return ret;
913}
914
915/*********************************************************************
916 * _mbsnccnt(MSVCRT.@)
917 * 'c' is for 'character'.
918 */
919MSVCRT_size_t _mbsnccnt(const unsigned char* str, MSVCRT_size_t len)
920{
921 MSVCRT_size_t ret;
922 if(MSVCRT___mb_cur_max > 1)
923 {
924 ret=0;
925 while(*str && len-- > 0)
926 {
927 if(MSVCRT_isleadbyte(*str))
928 {
929 if (!len)
930 break;
931 len--;
932 str++;
933 }
934 str++;
935 ret++;
936 }
937 return ret;
938 }
939 ret=strlen(str);
940 return min(ret, len); /* ASCII CP */
941}
942
943/*********************************************************************
944 * _mbsnbcnt(MSVCRT.@)
945 * 'b' is for byte count.
946 */
947MSVCRT_size_t _mbsnbcnt(const unsigned char* str, MSVCRT_size_t len)
948{
949 MSVCRT_size_t ret;
950 if(MSVCRT___mb_cur_max > 1)
951 {
952 const unsigned char* xstr = str;
953 while(*xstr && len-- > 0)
954 {
955 if (MSVCRT_isleadbyte(*xstr++))
956 xstr++;
957 }
958 return xstr-str;
959 }
960 ret=strlen(str);
961 return min(ret, len); /* ASCII CP */
962}
963
964
965/*********************************************************************
966 * _mbsnbcat(MSVCRT.@)
967 */
968unsigned char* _mbsnbcat(unsigned char* dst, const unsigned char* src, MSVCRT_size_t len)
969{
970 if(MSVCRT___mb_cur_max > 1)
971 {
972 char *res = dst;
973 while (*dst) {
974 if (MSVCRT_isleadbyte(*dst++)) {
975 if (*dst) {
976 dst++;
977 } else {
978 /* as per msdn overwrite the lead byte in front of '\0' */
979 dst--;
980 break;
981 }
982 }
983 }
984 while (*src && len--) *dst++ = *src++;
985 *dst = '\0';
986 return res;
987 }
988 return strncat(dst, src, len); /* ASCII CP */
989}
990
991/*********************************************************************
992 * _mbsncat(MSVCRT.@)
993 */
994unsigned char* _mbsncat(unsigned char* dst, const unsigned char* src, MSVCRT_size_t len)
995{
996 if(MSVCRT___mb_cur_max > 1)
997 {
998 char *res = dst;
999 while (*dst)
1000 {
1001 if (MSVCRT_isleadbyte(*dst++))
1002 dst++;
1003 }
1004 while (*src && len--)
1005 {
1006 *dst++ = *src;
1007 if(MSVCRT_isleadbyte(*src++))
1008 *dst++ = *src++;
1009 }
1010 *dst = '\0';
1011 return res;
1012 }
1013 return strncat(dst, src, len); /* ASCII CP */
1014}
1015
1016
1017/*********************************************************************
1018 * _mbslwr(MSVCRT.@)
1019 */
1020unsigned char* _mbslwr(unsigned char* s)
1021{
1022 if (!s)
1023 return NULL;
1024 if (MSVCRT___mb_cur_max > 1)
1025 {
1026 unsigned int c;
1027 unsigned char* p=s;
1028 while (*s)
1029 {
1030 c = _mbctolower(_mbsnextc(s));
1031 /* Note that I assume that the size of the character is unchanged */
1032 if (c > 255)
1033 {
1034 *s++=(c>>8);
1035 c=c & 0xff;
1036 }
1037 *s++=c;
1038 }
1039 return p;
1040 }
1041 return _strlwr(s);
1042}
1043
1044
1045/*********************************************************************
1046 * _mbsupr(MSVCRT.@)
1047 */
1048unsigned char* _mbsupr(unsigned char* s)
1049{
1050 if (!s)
1051 return NULL;
1052 if (MSVCRT___mb_cur_max > 1)
1053 {
1054 unsigned int c;
1055 unsigned char* p=s;
1056 while (*s)
1057 {
1058 c = _mbctoupper(_mbsnextc(s));
1059 /* Note that I assume that the size of the character is unchanged */
1060 if (c > 255)
1061 {
1062 *s++=(c>>8);
1063 c=c & 0xff;
1064 }
1065 *s++=c;
1066 }
1067 return p;
1068 }
1069 return _strupr(s);
1070}
1071
1072
1073/*********************************************************************
1074 * _mbsspn (MSVCRT.@)
1075 */
1076MSVCRT_size_t _mbsspn(const unsigned char* string, const unsigned char* set)
1077{
1078 const unsigned char *p, *q;
1079
1080 for (p = string; *p; p++)
1081 {
1082 if (MSVCRT_isleadbyte(*p))
1083 {
1084 for (q = set; *q; q++)
1085 {
1086 if (!q[1])
1087 break;
1088 if ((*p == *q) && (p[1] == q[1]))
1089 break;
1090 q++;
1091 }
1092 if (*++p == '\0')
1093 break;
1094 }
1095 else
1096 for (q = set; *q; q++)
1097 if (*p == *q)
1098 break;
1099 }
1100 return p - string;
1101}
1102
1103/*********************************************************************
1104 * _mbscspn(MSVCRT.@)
1105 */
1106MSVCRT_size_t _mbscspn(const unsigned char* str, const unsigned char* cmp)
1107{
1108 if (MSVCRT___mb_cur_max > 1)
1109 FIXME("don't handle double character case\n");
1110 return strcspn(str, cmp);
1111}
1112
1113/*********************************************************************
1114 * _mbsrev (MSVCRT.@)
1115 */
1116unsigned char* _mbsrev(unsigned char* str)
1117{
1118 int i, len = _mbslen(str);
1119 unsigned char *p, *temp=MSVCRT_malloc(len*2);
1120
1121 if(!temp)
1122 return str;
1123
1124 /* unpack multibyte string to temp buffer */
1125 p=str;
1126 for(i=0; i<len; i++)
1127 {
1128 if (MSVCRT_isleadbyte(*p))
1129 {
1130 temp[i*2]=*p++;
1131 temp[i*2+1]=*p++;
1132 }
1133 else
1134 {
1135 temp[i*2]=*p++;
1136 temp[i*2+1]=0;
1137 }
1138 }
1139
1140 /* repack it in the reverse order */
1141 p=str;
1142 for(i=len-1; i>=0; i--)
1143 {
1144 if(MSVCRT_isleadbyte(temp[i*2]))
1145 {
1146 *p++=temp[i*2];
1147 *p++=temp[i*2+1];
1148 }
1149 else
1150 {
1151 *p++=temp[i*2];
1152 }
1153 }
1154
1155 MSVCRT_free(temp);
1156
1157 return str;
1158}
1159
1160/*********************************************************************
1161 * _mbspbrk (MSVCRT.@)
1162 */
1163unsigned char* _mbspbrk(const unsigned char* str, const unsigned char* accept)
1164{
1165 const unsigned char* p;
1166
1167 while(*str)
1168 {
1169 for(p = accept; *p; p += (MSVCRT_isleadbyte(*p)?2:1) )
1170 {
1171 if (*p == *str)
1172 if( !MSVCRT_isleadbyte(*p) || ( *(p+1) == *(str+1) ) )
1173 return (unsigned char*)str;
1174 }
1175 str += (MSVCRT_isleadbyte(*str)?2:1);
1176 }
1177 return NULL;
1178}
Note: See TracBrowser for help on using the repository browser.