This patch is supposed to cleanup and improve the mbcs support in msvcrt: * adds include/msvcrt/mbctype.h and include/msvcrt/mbstring.h * fixes the function prototypes in dlls/msvcrt/mbcs.c (mostly char/unsigned char and int/MSVCRT_size_t mismatches) * fixes a couple of bugs, e.g. _mbsnccnt could lead to len<0 which since it's an unsigned int would be pretty bad * improves the support, e.g. _mbsicmp, _mbsnicmp, ... * and reorders functions a bit so that related functions are implemented next to each other: e.g. _mbscmp, _mbsicmp, _mbsncmp, _mbsnicmp * somewhat unrelated: implements putwc/putwchar by calling fputwc/fputwchar (AFAICT they are really identical) Changelog: François Gouget <fgouget@codeweavers.com> * include/msvcrt/mbctype.h, include/msvcrt/mbstring.h, include/Makefile.in, include/msvcrt/string.h, dlls/msvcrt/mbcs.c, dlls/msvcrt/msvcrt.spec Cleanup and improve the mbcs support Add mbctype.h and mbstring.h Implement putwc and putwchar -- François Gouget fgouget@codeweavers.com
--- /dev/null Fri Nov 16 17:06:31 2001 +++ include/msvcrt/mbctype.h Tue Dec 4 18:12:53 2001 @@ -0,0 +1,38 @@ +/* + * Multibyte char definitions + * + * Copyright 2001 Francois Gouget. + */ +#ifndef __WINE_MBCTYPE_H +#define __WINE_MBCTYPE_H +#define __WINE_USE_MSVCRT + + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned char* __p__mbctype(void); +#define _mbctype (__p__mbctype()) + +int _getmbcp(void); +int _ismbbalnum(unsigned int); +int _ismbbalpha(unsigned int); +int _ismbbgraph(unsigned int); +int _ismbbkalnum(unsigned int); +int _ismbbkana(unsigned int); +int _ismbbkprint(unsigned int); +int _ismbbkpunct(unsigned int); +int _ismbblead(unsigned int); +int _ismbbprint(unsigned int); +int _ismbbpunct(unsigned int); +int _ismbbtrail(unsigned int); +int _ismbslead(const unsigned char*,const unsigned char*); +int _ismbstrail(const unsigned char*,const unsigned char*); +int _setmbcp(int); + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_MBCTYPE_H */ --- /dev/null Fri Nov 16 17:06:31 2001 +++ include/msvcrt/mbstring.h Tue Dec 4 18:12:58 2001 @@ -0,0 +1,107 @@ +/* + * Multibyte string definitions + * + * Copyright 2001 Francois Gouget. + */ +#ifndef __WINE_MBSTRING_H +#define __WINE_MBSTRING_H +#define __WINE_USE_MSVCRT + +#include "msvcrt/mbctype.h" + +#ifdef USE_MSVCRT_PREFIX +#define MSVCRT(x) MSVCRT_##x +#else +#define MSVCRT(x) x +#endif + +#ifndef MSVCRT_SIZE_T_DEFINED +typedef unsigned int MSVCRT(size_t); +#define MSVCRT_SIZE_T_DEFINED +#endif + +#define _NLSCMPERROR ((unsigned int)0x7fffffff) + + +#ifdef __cplusplus +extern "C" { +#endif + +int _ismbcalnum(unsigned int); +int _ismbcalpha(unsigned int); +int _ismbcdigit(unsigned int); +int _ismbcgraph(unsigned int); +int _ismbchira(unsigned int); +int _ismbckata(unsigned int); +int _ismbcl0(unsigned int); +int _ismbcl1(unsigned int); +int _ismbcl2(unsigned int); +int _ismbclegal(unsigned int); +int _ismbclower(unsigned int); +int _ismbcprint(unsigned int); +int _ismbcpunct(unsigned int); +int _ismbcspace(unsigned int); +int _ismbcsymbol(unsigned int); +int _ismbcupper(unsigned int); +unsigned int _mbbtombc(unsigned int); +int _mbbtype(unsigned char,int); +#define _mbccmp(_cpc1,_cpc2) _mbsncmp((_cpc1),(_cpc2),1) +void _mbccpy(unsigned char*,const unsigned char*); +unsigned int _mbcjistojms(unsigned int); +unsigned int _mbcjmstojis(unsigned int); +MSVCRT(size_t) _mbclen(const unsigned char*); +unsigned int _mbctohira(unsigned int); +unsigned int _mbctokata(unsigned int); +unsigned int _mbctolower(unsigned int); +unsigned int _mbctombb(unsigned int); +unsigned int _mbctoupper(unsigned int); +int _mbsbtype(const unsigned char*,MSVCRT(size_t)); +unsigned char* _mbscat(unsigned char*,const unsigned char*); +unsigned char* _mbschr(const unsigned char*,unsigned int); +int _mbscmp(const unsigned char*,const unsigned char*); +int _mbscoll(const unsigned char*,const unsigned char*); +unsigned char* _mbscpy(unsigned char*,const unsigned char*); +MSVCRT(size_t) _mbscspn(const unsigned char*,const unsigned char*); +unsigned char* _mbsdec(const unsigned char*,const unsigned char*); +unsigned char* _mbsdup(const unsigned char*); +int _mbsicmp(const unsigned char*,const unsigned char*); +int _mbsicoll(const unsigned char*,const unsigned char*); +unsigned char* _mbsinc(const unsigned char*); +MSVCRT(size_t) _mbslen(const unsigned char*); +unsigned char* _mbslwr(unsigned char*); +unsigned char* _mbsnbcat(unsigned char*,const unsigned char*,MSVCRT(size_t)); +int _mbsnbcmp(const unsigned char*,const unsigned char*,MSVCRT(size_t)); +int _mbsnbcoll(const unsigned char*,const unsigned char*,MSVCRT(size_t)); +MSVCRT(size_t) _mbsnbcnt(const unsigned char*,MSVCRT(size_t)); +unsigned char* _mbsnbcpy(unsigned char*,const unsigned char* +,MSVCRT(size_t)); +int _mbsnbicmp(const unsigned char*,const unsigned char*,MSVCRT(size_t)); +int _mbsnbicoll(const unsigned char*,const unsigned char*,MSVCRT(size_t)); +unsigned char* _mbsnbset(unsigned char*,unsigned int,MSVCRT(size_t)) +; +unsigned char* _mbsncat(unsigned char*,const unsigned char*, + MSVCRT(size_t)); +MSVCRT(size_t) _mbsnccnt(const unsigned char*,MSVCRT(size_t)); +int _mbsncmp(const unsigned char*,const unsigned char*,MSVCRT(size_t)); +int _mbsncoll(const unsigned char*,const unsigned char*,MSVCRT(size_t)); +unsigned char* _mbsncpy(unsigned char*,const unsigned char*,MSVCRT(size_t)); +unsigned int _mbsnextc (const unsigned char*); +int _mbsnicmp(const unsigned char*,const unsigned char*,MSVCRT(size_t)); +int _mbsnicoll(const unsigned char*,const unsigned char*,MSVCRT(size_t)); +unsigned char* _mbsninc(const unsigned char*,MSVCRT(size_t)); +unsigned char* _mbsnset(unsigned char*,unsigned int,MSVCRT(size_t)); +unsigned char* _mbspbrk(const unsigned char*,const unsigned char*); +unsigned char* _mbsrchr(const unsigned char*,unsigned int); +unsigned char* _mbsrev(unsigned char*); +unsigned char* _mbsset(unsigned char*,unsigned int); +MSVCRT(size_t) _mbsspn(const unsigned char*,const unsigned char*); +unsigned char* _mbsspnp(const unsigned char*,const unsigned char*); +unsigned char* _mbsstr(const unsigned char*,const unsigned char*); +unsigned char* _mbstok(unsigned char*,const unsigned char*); +unsigned char* _mbsupr(unsigned char*); + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_MBSTRING_H */ Index: include/Makefile.in =================================================================== RCS file: /home/wine/wine/include/Makefile.in,v retrieving revision 1.35 diff -u -r1.35 Makefile.in --- include/Makefile.in 2001/11/14 21:26:24 1.35 +++ include/Makefile.in 2001/12/05 00:39:24 @@ -61,6 +61,8 @@ msvcrt/io.h \ msvcrt/locale.h \ msvcrt/malloc.h \ + msvcrt/mbctype.h \ + msvcrt/mbstring.h \ msvcrt/process.h \ msvcrt/search.h \ msvcrt/stddef.h \ Index: include/msvcrt/string.h =================================================================== RCS file: /home/wine/wine/include/msvcrt/string.h,v retrieving revision 1.3 diff -u -r1.3 string.h --- include/msvcrt/string.h 2001/10/22 18:59:23 1.3 +++ include/msvcrt/string.h 2001/12/05 00:35:02 @@ -28,9 +28,6 @@ extern "C" { #endif -unsigned char* _mbschr(const unsigned char*,unsigned int); -unsigned char* _mbsncat(unsigned char*,const unsigned char*,MSVCRT(size_t)); -unsigned char* _mbstok(unsigned char*,unsigned char*); void* _memccpy(void*,const void*,int,MSVCRT(size_t)); int _memicmp(const void*,const void*,MSVCRT(size_t)); int _strcmpi(const char*,const char*); Index: dlls/msvcrt/mbcs.c =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/mbcs.c,v retrieving revision 1.14 diff -u -r1.14 mbcs.c --- dlls/msvcrt/mbcs.c 2001/11/12 15:47:26 1.14 +++ dlls/msvcrt/mbcs.c 2001/12/05 00:44:48 @@ -11,6 +11,8 @@ #include "msvcrt.h" +#include "msvcrt/mbctype.h" +#include "msvcrt/mbstring.h" #include "msvcrt/stdlib.h" #include "msvcrt/string.h" #include "msvcrt/wctype.h" @@ -24,7 +26,7 @@ /********************************************************************* * __p__mbctype (MSVCRT.@) */ -unsigned char *__p__mbctype(void) +unsigned char* __p__mbctype(void) { return MSVCRT_mbctype; } @@ -32,7 +34,7 @@ /********************************************************************* * __p___mb_cur_max(MSVCRT.@) */ -int *__p___mb_cur_max(void) +int* __p___mb_cur_max(void) { return &MSVCRT___mb_cur_max; } @@ -40,7 +42,7 @@ /********************************************************************* * _mbsnextc(MSVCRT.@) */ -unsigned int _mbsnextc(const unsigned char *str) +unsigned int _mbsnextc(const unsigned char* str) { if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*str)) return *str << 8 | str[1]; @@ -48,9 +50,204 @@ } /********************************************************************* + * _mbctolower(MSVCRT.@) + */ +unsigned int _mbctolower(unsigned int c) +{ + if (MSVCRT_isleadbyte(c)) + { + FIXME("Handle MBC chars\n"); + return c; + } + return tolower(c); /* ASCII CP or SB char */ +} + +/********************************************************************* + * _mbctoupper(MSVCRT.@) + */ +unsigned int _mbctoupper(unsigned int c) +{ + if (MSVCRT_isleadbyte(c)) + { + FIXME("Handle MBC chars\n"); + return c; + } + return toupper(c); /* ASCII CP or SB char */ +} + +/********************************************************************* + * _mbsdec(MSVCRT.@) + */ +unsigned char* _mbsdec(const unsigned char* start, const unsigned char* cur) +{ + if(MSVCRT___mb_cur_max > 1) + return (char *)(_ismbstrail(start,cur-1) ? cur - 2 : cur -1); + + return (char *)cur - 1; /* ASCII CP or SB char */ +} + +/********************************************************************* + * _mbsinc(MSVCRT.@) + */ +unsigned char* _mbsinc(const unsigned char* str) +{ + if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*str)) + return (unsigned char*)str + 2; /* MB char */ + + return (unsigned char*)str + 1; /* ASCII CP or SB char */ +} + +/********************************************************************* + * _mbsninc(MSVCRT.@) + */ +unsigned char* _mbsninc(const unsigned char* str, MSVCRT_size_t num) +{ + if(!str || num < 1) + return NULL; + if(MSVCRT___mb_cur_max > 1) + { + while(num--) + str = _mbsinc(str); + return (unsigned char*)str; + } + return (unsigned char*)str + num; /* ASCII CP */ +} + +/********************************************************************* + * _mbclen(MSVCRT.@) + */ +unsigned int _mbclen(const unsigned char* str) +{ + return MSVCRT_isleadbyte(*str) ? 2 : 1; +} + +/********************************************************************* + * mblen(MSVCRT.@) + */ +int MSVCRT_mblen(const char* str, MSVCRT_size_t size) +{ + if (str && *str && size) + { + if(MSVCRT___mb_cur_max == 1) + return 1; /* ASCII CP */ + + return !MSVCRT_isleadbyte(*str) ? 1 : (size>1 ? 2 : -1); + } + return 0; +} + +/********************************************************************* + * _mbslen(MSVCRT.@) + */ +MSVCRT_size_t _mbslen(const unsigned char* str) +{ + if(MSVCRT___mb_cur_max > 1) + { + MSVCRT_size_t len = 0; + while(*str) + { + str += MSVCRT_isleadbyte(*str) ? 2 : 1; + len++; + } + return len; + } + return strlen(str); /* ASCII CP */ +} + +/********************************************************************* + * _mbstrlen(MSVCRT.@) + */ +MSVCRT_size_t _mbstrlen(const char* str) +{ + if(MSVCRT___mb_cur_max > 1) + { + MSVCRT_size_t len = 0; + while(*str) + { + /* FIXME: According to the documentation we are supposed to test for + * multi-byte character validity. Whatever that means + */ + str += MSVCRT_isleadbyte(*str) ? 2 : 1; + len++; + } + return len; + } + return strlen(str); /* ASCII CP */ +} + +/********************************************************************* + * _mbccpy(MSVCRT.@) + */ +void _mbccpy(unsigned char* dest, const unsigned char* src) +{ + *dest++ = *src; + if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*src)) + *dest = *++src; /* MB char */ + else + ERR("failure.. is this ok?\n"); +} + +/********************************************************************* + * _mbsncpy(MSVCRT.@) + */ +unsigned char* _mbsncpy(unsigned char* dst, const unsigned char* src, MSVCRT_size_t n) +{ + if(!n) + return dst; + if(MSVCRT___mb_cur_max > 1) + { + unsigned char* ret = dst; + while (*src && n--) + { + *dst++ = *src; + if (MSVCRT_isleadbyte(*src++)) + *dst++ = *src++; + } + while(n--) + *dst++ = '\0'; + return ret; + } + return strncpy(dst, src, n); /* ASCII CP */ +} + +/********************************************************************* + * _mbsnbcpy(MSVCRT.@) + */ +unsigned char* _mbsnbcpy(unsigned char* dst, const unsigned char* src, MSVCRT_size_t n) +{ + if(!n) + return dst; + if(MSVCRT___mb_cur_max > 1) + { + unsigned char* ret = dst; + while (*src && (n-- > 1)) + { + *dst++ = *src; + if (MSVCRT_isleadbyte(*src++)) + { + *dst++ = *src++; + n--; + } + } + if (*src && n && !MSVCRT_isleadbyte(*src)) + { + /* If the last character is a multi-byte character then + * we cannot copy it since we have only one byte left + */ + *dst++ = *src; + n--; + } + while (n--) + *dst++ = '\0'; + return ret; + } + return strncpy(dst, src, n); /* ASCII CP */ +} + +/********************************************************************* * _mbscmp(MSVCRT.@) */ -int _mbscmp(const char *str, const char *cmp) +int _mbscmp(const unsigned char* str, const unsigned char* cmp) { if(MSVCRT___mb_cur_max > 1) { @@ -72,29 +269,33 @@ } /********************************************************************* - * _mbscspn(MSVCRT.@) - */ -int _mbscspn(const char *str, const char *cmp) -{ - FIXME("don't handle double character case\n"); - return strcspn(str, cmp); -} - -/********************************************************************* * _mbsicmp(MSVCRT.@) */ -int _mbsicmp(const char *str, const char *cmp) +int _mbsicmp(const unsigned char* str, const unsigned char* cmp) { - /* FIXME: No tolower() for mb strings yet */ if(MSVCRT___mb_cur_max > 1) - return _mbscmp(str, cmp); + { + unsigned int strc, cmpc; + do { + if(!*str) + return *cmp ? -1 : 0; + if(!*cmp) + return 1; + strc = _mbctolower(_mbsnextc(str)); + cmpc = _mbctolower(_mbsnextc(cmp)); + if(strc != cmpc) + return strc < cmpc ? -1 : 1; + str +=(strc > 255) ? 2 : 1; + cmp +=(strc > 255) ? 2 : 1; /* equal, use same increment */ + } while(1); + } return strcasecmp(str, cmp); /* ASCII CP */ } /********************************************************************* - * _mbsncmp (MSVCRT.@) + * _mbsncmp(MSVCRT.@) */ -int _mbsncmp(const char *str, const char *cmp, unsigned int len) +int _mbsncmp(const unsigned char* str, const unsigned char* cmp, MSVCRT_size_t len) { if(!len) return 0; @@ -104,6 +305,7 @@ unsigned int strc, cmpc; while(len--) { + int inc; if(!*str) return *cmp ? -1 : 0; if(!*cmp) @@ -112,8 +314,9 @@ cmpc = _mbsnextc(cmp); if(strc != cmpc) return strc < cmpc ? -1 : 1; - str +=(strc > 255) ? 2 : 1; - cmp +=(strc > 255) ? 2 : 1; /* Equal, use same increment */ + inc=(strc > 255) ? 2 : 1; /* Equal, use same increment */ + str += inc; + cmp += inc; } return 0; /* Matched len chars */ } @@ -121,76 +324,127 @@ } /********************************************************************* - * _mbsnicmp(MSVCRT.@) - * - * Compare two multibyte strings case insensitively to 'len' characters. + * _mbsnbcmp(MSVCRT.@) */ -int _mbsnicmp(const char *str, const char *cmp, unsigned int len) +int _mbsnbcmp(const unsigned char* str, const unsigned char* cmp, MSVCRT_size_t len) { - /* FIXME: No tolower() for mb strings yet */ + if (!len) + return 0; if(MSVCRT___mb_cur_max > 1) - return _mbsncmp(str, cmp, len); - return strncasecmp(str, cmp, len); /* ASCII CP */ -} - -/********************************************************************* - * _mbsinc(MSVCRT.@) - */ -char *_mbsinc(const unsigned char *str) -{ - if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*str)) - return (char *)str + 2; /* MB char */ - - return (char *)str + 1; /* ASCII CP or SB char */ + { + unsigned int strc, cmpc; + while (len) + { + int clen; + if(!*str) + return *cmp ? -1 : 0; + if(!*cmp) + return 1; + if (MSVCRT_isleadbyte(*str)) + { + strc=(len>=2)?_mbsnextc(str):0; + clen=2; + } + else + { + strc=*str; + clen=1; + } + if (MSVCRT_isleadbyte(*cmp)) + cmpc=(len>=2)?_mbsnextc(cmp):0; + else + cmpc=*str; + if(strc != cmpc) + return strc < cmpc ? -1 : 1; + len -= clen; + str += clen; + cmp += clen; + } + return 0; /* Matched len chars */ + FIXME("%s %s %d\n",str,cmp,len); + } + return strncmp(str,cmp,len); } /********************************************************************* - * _mbsninc(MSVCRT.@) + * _mbsnicmp(MSVCRT.@) + * + * Compare two multibyte strings case insensitively to 'len' characters. */ -char *_mbsninc(const char *str, unsigned int num) +int _mbsnicmp(const unsigned char* str, const unsigned char* cmp, MSVCRT_size_t len) { - if(!str || num < 1) - return NULL; + /* FIXME: No tolower() for mb strings yet */ if(MSVCRT___mb_cur_max > 1) { - while(num--) - str = _mbsinc(str); - return (char *)str; + unsigned int strc, cmpc; + while(len--) + { + if(!*str) + return *cmp ? -1 : 0; + if(!*cmp) + return 1; + strc = _mbctolower(_mbsnextc(str)); + cmpc = _mbctolower(_mbsnextc(cmp)); + if(strc != cmpc) + return strc < cmpc ? -1 : 1; + str +=(strc > 255) ? 2 : 1; + cmp +=(strc > 255) ? 2 : 1; /* Equal, use same increment */ + } + return 0; /* Matched len chars */ } - return (char *)str + num; /* ASCII CP */ + return strncasecmp(str, cmp, len); /* ASCII CP */ } /********************************************************************* - * _mbslen(MSVCRT.@) + * _mbschr(MSVCRT.@) + * + * Find a multibyte character in a multibyte string. */ -int _mbslen(const unsigned char *str) +unsigned char* _mbschr(const unsigned char* s, unsigned int x) { if(MSVCRT___mb_cur_max > 1) { - int len = 0; - while(*str) + unsigned int c; + while (1) { - str += MSVCRT_isleadbyte(*str) ? 2 : 1; - len++; + c = _mbsnextc(s); + if (c == x) + return (unsigned char*)s; + if (!c) + return NULL; + s += c > 255 ? 2 : 1; } - return len; } - return strlen(str); /* ASCII CP */ + return strchr(s, x); /* ASCII CP */ } /********************************************************************* * _mbsrchr(MSVCRT.@) */ -char *_mbsrchr(const char *s,unsigned int x) +unsigned char* _mbsrchr(const unsigned char* s, unsigned int x) { - /* FIXME: handle multibyte strings */ + if(MSVCRT___mb_cur_max > 1) + { + unsigned int c; + unsigned char* match=NULL; + if(!s) + return NULL; + while (1) { + c = _mbsnextc(s); + if (c == x) + match=(unsigned char*)s; + if (!c) + return match; + s +=(c > 255) ? 2 : 1; + } + } return strrchr(s,x); } /********************************************************************* * mbtowc(MSVCRT.@) */ -int MSVCRT_mbtowc(WCHAR *dst, const char *str, unsigned int n) +int MSVCRT_mbtowc(WCHAR *dst, const char* str, MSVCRT_size_t n) { if(n <= 0 || !str) return 0; @@ -205,16 +459,6 @@ } /********************************************************************* - * _mbccpy(MSVCRT.@) - */ -void _mbccpy(char *dest, const unsigned char *src) -{ - *dest++ = *src; - if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*src)) - *dest = *++src; /* MB char */ -} - -/********************************************************************* * _mbbtombc(MSVCRT.@) */ unsigned int _mbbtombc(unsigned int c) @@ -230,14 +474,6 @@ } /********************************************************************* - * _mbclen(MSVCRT.@) - */ -unsigned int _mbclen(const unsigned char *str) -{ - return MSVCRT_isleadbyte(*str) ? 2 : 1; -} - -/********************************************************************* * _ismbbkana(MSVCRT.@) */ int _ismbbkana(unsigned int c) @@ -252,6 +488,32 @@ } /********************************************************************* + * _ismbcdigit(MSVCRT.@) + */ +int _ismbcdigit(unsigned int ch) +{ + if (ch <0x100) + return isdigit(ch); + else + { + FIXME("Handle MBC chars\n"); + return 0; + } +} + +/********************************************************************* + * _ismbcspace (MSVCRT.@) + */ +int _ismbcspace(unsigned int c) +{ + + if (c<0x100) + return isspace(c); + FIXME("%c\n",c); + return 0; +} + +/********************************************************************* * _ismbchira(MSVCRT.@) */ int _ismbchira(unsigned int c) @@ -303,7 +565,7 @@ /********************************************************************* * _ismbslead(MSVCRT.@) */ -int _ismbslead(const unsigned char *start, const unsigned char *str) +int _ismbslead(const unsigned char* start, const unsigned char* str) { /* Lead bytes can also be trail bytes if caller messed up * iterating through the string... @@ -322,29 +584,18 @@ /********************************************************************* * _ismbstrail(MSVCRT.@) */ -int _ismbstrail(const char *start, const unsigned char *str) +int _ismbstrail(const unsigned char* start, const unsigned char* str) { /* Must not be a lead, and must be preceeded by one */ return !_ismbslead(start, str) && MSVCRT_isleadbyte(str[-1]); } /********************************************************************* - * _mbsdec(MSVCRT.@) - */ -char *_mbsdec(const char *start, const char *cur) -{ - if(MSVCRT___mb_cur_max > 1) - return (char *)(_ismbstrail(start,cur-1) ? cur - 2 : cur -1); - - return (char *)cur - 1; /* ASCII CP or SB char */ -} - -/********************************************************************* * _mbsset(MSVCRT.@) */ -char *_mbsset(char *str, unsigned int c) +unsigned char* _mbsset(unsigned char* str, unsigned int c) { - char *ret = str; + unsigned char* ret = str; if(MSVCRT___mb_cur_max == 1 || c < 256) return _strset(str, c); /* ASCII CP or SB char */ @@ -365,9 +616,9 @@ /********************************************************************* * _mbsnset(MSVCRT.@) */ -char *_mbsnset(char *str, unsigned int c, unsigned int len) +unsigned char* _mbsnset(unsigned char* str, unsigned int c, MSVCRT_size_t len) { - char *ret = str; + unsigned char *ret = str; if(!len) return ret; @@ -389,117 +640,52 @@ } /********************************************************************* - * _mbstrlen(MSVCRT.@) - */ -MSVCRT_size_t _mbstrlen(const char *str) -{ - if(MSVCRT___mb_cur_max > 1) - { - int len = 0; - while(*str) - { - str += MSVCRT_isleadbyte(*str) ? 2 : 1; - len++; - } - return len; - } - return strlen(str); /* ASCII CP */ -} - -/********************************************************************* - * _mbsncpy(MSVCRT.@) - */ -char *_mbsncpy(char *dst, const char *src, unsigned int len) -{ - if(!len) - return dst; - if(MSVCRT___mb_cur_max > 1) - { - char *ret = dst; - while(src[0] && src[1] && len--) - { - *dst++ = *src++; - *dst++ = *src++; - } - if(len--) - { - *dst++ = *src++; /* Last char or '\0' */ - while(len--) - *dst++ = '\0'; - } - return ret; - } - return strncpy(dst, src, len); /* ASCII CP */ -} - -/********************************************************************* - * _mbschr(MSVCRT.@) - * - * Find a multibyte character in a multibyte string. - */ -unsigned char* _mbschr(const unsigned char* str, unsigned int c) -{ - if(MSVCRT___mb_cur_max > 1) - { - unsigned int next; - while((next = _mbsnextc(str))) - { - if(next == c) - return (char *)str; - str += next > 255 ? 2 : 1; - } - return c ? NULL :(char *)str; - } - return strchr(str, c); /* ASCII CP */ -} - -/********************************************************************* * _mbsnccnt(MSVCRT.@) * 'c' is for 'character'. */ -unsigned int _mbsnccnt(const unsigned char *str, unsigned int len) +MSVCRT_size_t _mbsnccnt(const unsigned char* str, MSVCRT_size_t len) { - int ret = 0; - + MSVCRT_size_t ret; if(MSVCRT___mb_cur_max > 1) { + ret=0; while(*str && len-- > 0) { if(MSVCRT_isleadbyte(*str)) { - str++; + if (!len) + break; len--; + str++; } - ret++; str++; + ret++; } return ret; } - return min(strlen(str), len); /* ASCII CP */ + ret=strlen(str); + return min(ret, len); /* ASCII CP */ } /********************************************************************* * _mbsnbcnt(MSVCRT.@) * 'b' is for byte count. */ -unsigned int _mbsnbcnt(const unsigned char *str, unsigned int len) +MSVCRT_size_t _mbsnbcnt(const unsigned char* str, MSVCRT_size_t len) { - const unsigned char *xstr = str; - + MSVCRT_size_t ret; if(MSVCRT___mb_cur_max > 1) { + const unsigned char* xstr = str; while(*xstr && len-- > 0) { - if(MSVCRT_isleadbyte(*xstr)) - { + if (MSVCRT_isleadbyte(*xstr++)) xstr++; - len--; - } - xstr++; } return xstr-str; } - return min(strlen(str), len); /* ASCII CP */ + ret=strlen(str); + return min(ret, len); /* ASCII CP */ } @@ -511,16 +697,18 @@ if(MSVCRT___mb_cur_max > 1) { char *res = dst; - dst += _mbslen(dst); - while(*src && len--) + while (*dst) { - *dst = *src; - if(MSVCRT_isleadbyte(*src)) - *++dst = *++src; - dst++; - src++; + if (MSVCRT_isleadbyte(*dst++)) + dst++; } - *dst++ = '\0'; + while (*src && len--) + { + *dst++ = *src; + if(MSVCRT_isleadbyte(*src++)) + *dst++ = *src++; + } + *dst = '\0'; return res; } return strncat(dst, src, len); /* ASCII CP */ @@ -528,98 +716,65 @@ /********************************************************************* - * _ismbcdigit(MSVCRT.@) - */ -int _ismbcdigit( unsigned int ch) -{ - if (ch <0x100) - return isdigit(ch); - else - { - FIXME("Handle MBC chars\n"); - return 0; - } -} - - -/********************************************************************* - * _mbsnbcmp(MSVCRT.@) - */ -int _mbsnbcmp( const unsigned char *str,const unsigned char *cmp, MSVCRT_size_t len ) -{ - if (!len) - return 0; - if(MSVCRT___mb_cur_max > 1) - { - FIXME("%s %s %d\n",str,cmp,len); - return 0; - } - return strncmp(str,cmp,len); -} - - -/********************************************************************* * _mbslwr(MSVCRT.@) */ -unsigned char * _mbslwr( unsigned char *string ) +unsigned char* _mbslwr(unsigned char* s) { - unsigned char *p; - - if(MSVCRT___mb_cur_max > 1) - { - FIXME("%s\n",string); - return string; - } - p = string; - while (*p) - { - *p= tolower(*p); - p++; + if (!s) + return NULL; + if (MSVCRT___mb_cur_max > 1) + { + unsigned int c; + unsigned char* p=s; + while (*s) + { + c = _mbctolower(_mbsnextc(s)); + /* Note that I assume that the size of the character is unchanged */ + if (c > 255) + { + *s++=(c>>8); + c=c & 0xff; + } + *s++=c; } - return string; + return p; + } + return _strlwr(s); } /********************************************************************* * _mbsupr(MSVCRT.@) */ -unsigned char * _mbsupr( unsigned char *string ) +unsigned char* _mbsupr(unsigned char* s) { - unsigned char *p; - - if(MSVCRT___mb_cur_max > 1) - { - FIXME("%s\n",string); - return string; - } - p = string; - while (*p) - { - *p= toupper(*p); - p++; - } - return string; -} - - -/********************************************************************* - * _mbsnbcpy(MSVCRT.@) - */ -unsigned char * _mbsnbcpy(unsigned char *dest,const unsigned char *src,MSVCRT_size_t n) -{ - if(MSVCRT___mb_cur_max > 1) - { - FIXME("%s %d\n",src,n); - return dest; + if (!s) + return NULL; + if (MSVCRT___mb_cur_max > 1) + { + unsigned int c; + unsigned char* p=s; + while (*s) + { + c = _mbctoupper(_mbsnextc(s)); + /* Note that I assume that the size of the character is unchanged */ + if (c > 255) + { + *s++=(c>>8); + c=c & 0xff; + } + *s++=c; } - return strncpy(dest, src, n); + return p; + } + return _strupr(s); } /********************************************************************* * _mbsspn (MSVCRT.@) */ -MSVCRT_size_t _mbsspn(const unsigned char *string, const unsigned char *set) +MSVCRT_size_t _mbsspn(const unsigned char* string, const unsigned char* set) { const unsigned char *p, *q; @@ -646,26 +801,23 @@ return p - string; } - /********************************************************************* - * _ismbcspace (MSVCRT.@) + * _mbscspn(MSVCRT.@) */ -int _ismbcspace( unsigned int c) +MSVCRT_size_t _mbscspn(const unsigned char* str, const unsigned char* cmp) { - - if (c <0x100) - return isspace(c); - FIXME("%c\n",c); - return 0; + if (MSVCRT___mb_cur_max > 1) + FIXME("don't handle double character case\n"); + return strcspn(str, cmp); } /********************************************************************* * _mbsrev (MSVCRT.@) */ -char *_mbsrev(char *str) +unsigned char* _mbsrev(unsigned char* str) { int i, len = _mbslen(str); - char *p, *temp=MSVCRT_malloc(len*2); + unsigned char *p, *temp=MSVCRT_malloc(len*2); if(!temp) return str; @@ -709,9 +861,9 @@ /********************************************************************* * _mbspbrk (MSVCRT.@) */ -const char *_mbspbrk(const char *str, const char *accept) +unsigned char* _mbspbrk(const unsigned char* str, const unsigned char* accept) { - const char *p; + const unsigned char* p; while(*str) { @@ -719,7 +871,7 @@ { if (*p == *str) if( !MSVCRT_isleadbyte(*p) || ( *(p+1) == *(str+1) ) ) - return str; + return (unsigned char*)str; } str += (MSVCRT_isleadbyte(*str)?2:1); } Index: dlls/msvcrt/msvcrt.spec =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/msvcrt.spec,v retrieving revision 1.25 diff -u -r1.25 msvcrt.spec --- dlls/msvcrt/msvcrt.spec 2001/11/12 15:47:26 1.25 +++ dlls/msvcrt/msvcrt.spec 2001/12/05 00:49:54 @@ -347,9 +347,9 @@ @ cdecl _mbclen(ptr) _mbclen @ stub _mbctohira #(long) @ stub _mbctokata #(long) -@ stub _mbctolower #(long) +@ cdecl _mbctolower(long) _mbctolower @ stub _mbctombb #(long) -@ stub _mbctoupper #(long) +@ cdecl _mbctoupper(long) _mbctoupper @ stub _mbctype @ stub _mbsbtype #(ptr long) @ cdecl _mbscat(str str) strcat @@ -667,7 +667,7 @@ @ cdecl log10(double) log10 @ cdecl longjmp(long long) MSVCRT_longjmp @ cdecl malloc(long) MSVCRT_malloc -@ stub mblen #(str long) +@ cdecl mblen(ptr long) MSVCRT_mblen @ forward -noimport mbstowcs ntdll.mbstowcs @ cdecl mbtowc(wstr str long) MSVCRT_mbtowc @ cdecl memchr(ptr long long) memchr @@ -683,8 +683,8 @@ @ cdecl putc(long ptr) MSVCRT_putc @ cdecl putchar(long) MSVCRT_putchar @ cdecl puts(str) MSVCRT_puts -@ stub putwc #(long ptr) -@ stub putwchar #(long) +@ cdecl putwc(long ptr) MSVCRT_fputwc +@ cdecl putwchar(long) _fputwchar @ cdecl qsort(ptr long long ptr) qsort @ stub raise #(long) @ cdecl rand() MSVCRT_rand