Beispiel #1
0
void main()
  {
    int     i;

    _setmbcp( 932 );
    for( i = 0; i < SIZE; i++ )
      printf( "%s\n", types[ 1+_mbsbtype( chars, i ) ] );
  }
Beispiel #2
0
//---------------------------------------------------------------------------
void __fastcall CMBCS::Create(void)
{
//	FILE *fp = fopen("DbgLog.txt", "wt");
	if( !m_pLead ) m_pLead = new BYTE[256];
    for( int i = 0; i < 256; i++ ){
		m_pLead[i] = (_mbsbtype((unsigned char *)&i, 0) == _MBC_LEAD);
//        fprintf(fp, "%02X:%d\n", i, m_pLead[i]);
    }
//    fclose(fp);
}
Beispiel #3
0
///----------------------------------------------------------------
///  デリミッタ分解を行う
///
LPSTR __fastcall StrDlm(LPSTR &t, LPSTR p, char c)
{
	int		f, k;
	LPSTR	d1=NULL;
	LPSTR	d2=NULL;

	t = p;
	f = k = 0;
	while(*p){
		if( k ){															// 漢字2バイト目
			if( (c == -1) && !sys.m_MsgEng ){
				k |= *p & 0x00ff;
                if( k == 0x8140 ){
					p--;
					*p = 0;
					p+=2;
					break;
                }
            }
			k = 0;
		}
		else if(  _mbsbtype((const unsigned char *)p, 0) == _MBC_LEAD ){	// 漢字1バイト目
			k = *p & 0x00ff;
            k = k << 8;
		}
		else if( *p == 0x22 ){
			if( !f ){
				if( d1 == NULL ) d1 = p+1;
				f++;
			}
			else {
				d2 = p;
				f--;
			}
		}
		else if( !f && ((*p == c) || ((c == -1) && strchr(" /,;;.", *p))) ){
			*p = 0;
			p++;
			break;
		}
		p++;
	}
	if( (d1!=NULL)&&(d2!=NULL) ){
		if( ((t+1)==d1) && ( ((p-2)==d2)||((p-1)==d2) ) ){
			t = d1;
			*d2 = 0;
		}
	}
	return(p);
}
Beispiel #4
0
static  int DotFound(_TCHAR *pB)
#endif
{
#if defined(_MBCS) && !defined(_UNICODE)
        if (*(pB-1) == _TEXT('.') && _mbsbtype(baseP, (pB-1)-baseP) == _MBC_SINGLE)
                pB--;
        if (_mbsbtype(baseP, (pB-1)-baseP) == _MBC_TRAIL)
                return 0;
#else
        if (*(pB-1) == _TEXT('.'))
                pB--;
#endif
        switch (*--pB) {
        case _TEXT(':')  :
                if (*(pB-2) != _TEXT('\0'))
                        break;
        case _TEXT('/')  :
        case _TEXT('\\') :
        case _TEXT('\0') :
                return 1;
        }
        return 0;
}
Beispiel #5
0
const char *__fastcall StrDlmCpyK(char *t, const char *p, char Dlm, int len)
{
	const char _tt1[]="[{(「<";
	const char _tt2[]="]})」>";
	const char	*pp;
	int			r = FALSE;

	char	Key;
	if( (pp = strchr(_tt2, Dlm))!=NULL ){
		Key = _tt1[pp - _tt2];
	}
	else {
		Key = 0;
	}
	int	f, k;
	for( f = k = 0; *p;  p++ ){
		if( k ){															// 漢字2バイト目
			k = 0;
		}
		else if(  _mbsbtype((const unsigned char *)p, 0) == _MBC_LEAD ){	// 漢字1バイト目
			k = 1;
		}
		else if( (pp = strchr(_tt1, *p))!=NULL ){
			Key = _tt2[pp - _tt1];
			f++;
		}
		else if( f && (*p == Key) ){
			f--;
			Key = 0;
		}
		else if( *p == Dlm ){
			if( !f ){
				r = TRUE;
				p++;
				break;
			}
		}
		if( len ){
			*t++ = *p;
			len--;
		}
	}
	*t = 0;
	return (r == TRUE) ? p : NULL;
}
Beispiel #6
0
LPUSTR __fastcall jstrlwr(LPUSTR s)
{
	LPUSTR	p = s;
	int kf;

	for( kf = 0; *p; p++ ){
		if( kf ){
			kf = 0;
		}
		else if( _mbsbtype((unsigned char *)p, 0) == _MBC_LEAD ){
			kf = 1;
		}
		else {
			*p = (unsigned char)tolower(*p);
		}
	}
	return s;
}
Beispiel #7
0
int _RTLENTRY _EXPFUNC _tfnsplit(const _TCHAR *pathP, _TCHAR *driveP, _TCHAR *dirP,
                         _TCHAR *nameP, _TCHAR *extP)
{
        register _TCHAR   *pB;
        register int    Wrk;
        int     Ret;

        _TCHAR buf[ MAXPATH+2 ];

        /*
          Set all string to default value zero
        */
        Ret = 0;
        if (driveP)
                *driveP = 0;
        if (dirP)
                *dirP = 0;
        if (nameP)
                *nameP = 0;
        if (extP)
                *extP = 0;

        /*
          Copy filename into template up to MAXPATH characters
        */
        pB = buf;
        if ((Wrk = _tcslen(pathP)) > MAXPATH)
                Wrk = MAXPATH;
        *pB++ = 0;
        _tcsncpy(pB, pathP, Wrk);
        *(pB += Wrk) = 0;

        /*
          Split the filename and fill corresponding nonzero pointers
        */
        Wrk = 0;
        for (; ; ) {
#if defined(_MBCS) && !defined(_UNICODE)
                if (_mbsbtype(buf+1, (pB-1) - (buf+1)) == _MBC_TRAIL) {
                        pB -= 2;
                        continue;
                }
#endif
                switch (*--pB) {
                case _TEXT('.')  :
                        if (!Wrk && (*(pB+1) == _TEXT('\0')))
#if defined(_MBCS) && !defined(_UNICODE)
                                Wrk = DotFound(buf+1, pB);
#else
                                Wrk = DotFound(pB);
#endif
                        if ((!Wrk) && ((Ret & EXTENSION) == 0)) {
                                Ret |= EXTENSION;
                                CopyIt(extP, pB, MAXEXT - 1);
                                *pB = 0;
                        }
                        continue;
                case _TEXT(':')  :
                        if (pB != &buf[2])
                                continue;
                case _TEXT('\0') :
                        if (Wrk) {
                                if (*++pB)
                                        Ret |= DIRECTORY;
                                CopyIt(dirP, pB, MAXDIR - 1);
                                *pB-- = 0;
                                break;
                        }
                case _TEXT('/')  :
                case _TEXT('\\') :
                        if (!Wrk) {
                                Wrk++;
                                if (*++pB)
                                        Ret |= FILENAME;
                                CopyIt(nameP, pB, MAXFILE - 1);
                                *pB-- = 0;
                                if (*pB == 0 || (*pB == _TEXT(':') && pB == &buf[2]))
                                        break;
                        }
                        continue;
                case _TEXT('*')  :
                case _TEXT('?')  :
                        if (!Wrk)
                                Ret |= WILDCARDS;
                default :
                        continue;
                }
                break;
        }
        if (*pB == _TEXT(':')) {
                if (buf[1])
                        Ret |= DRIVE;
                CopyIt(driveP, &buf[1], MAXDRIVE - 1);
        }

        return (Ret);
}
Beispiel #8
0
//パスに共通する部分を取り出し、基底パスを取り出す
void UtilGetBaseDirectory(CString &BasePath,const std::list<CString> &PathList)
{
	bool bFirst=true;
	size_t ElementsCount=0;	//共通項目数
	std::vector<CString> PathElements;	//共通項目の配列

	std::list<CString>::const_iterator ite,end;
	end=PathList.end();
	for(ite=PathList.begin();ite!=end;++ite){
		if(!bFirst&&0==ElementsCount){
			//既に共通している要素が配列内に存在しないとき
			break;
		}

		//親ディレクトリまでで終わるパスを作る
		TCHAR Path[_MAX_PATH+1];
		FILL_ZERO(Path);
		_tcsncpy_s(Path,*ite,_MAX_PATH);
		PathRemoveFileSpec(Path);
		PathAddBackslash(Path);

		CString buffer;
		size_t iElement=0;	//一致しているパスの要素のカウント用(ループ内)
		size_t iIndex=0;	//パス内の文字のインデックス
		const size_t Length=_tcslen(Path);
		for(;iIndex<Length;iIndex++){
#if !defined(_UNICODE)&&!defined(UNICODE)
			if(_MBC_SINGLE==_mbsbtype((const unsigned char *)Path,iIndex)){
#endif
				if(_T('\\')==Path[iIndex]){
					//初回ならパスを詰め込み、そうでなければ要素を比較
					if(bFirst){
						PathElements.push_back(buffer);
						buffer.Empty();
						continue;
					}
					else{
						//大文字小文字区別せずに比較
						if(0==PathElements[iElement].CompareNoCase(buffer)){
							//要素が共通しているうちはOK
							iElement++;
							if(iElement>=ElementsCount)break;
							else{
								buffer.Empty();
								continue;
							}
						}
						else
						{
							//要素数を減らす
							//0オリジンのi番目で不一致ならばi個まで一致
							ElementsCount=iElement;
							break;
						}
					}
				}
#if !defined(_UNICODE)&&!defined(UNICODE)
			}
#endif
			buffer+=Path[iIndex];
		}
		if(bFirst){
			bFirst=false;
			ElementsCount=PathElements.size();
		}
		else if(ElementsCount>iElement){
			//パスが短かった場合、不一致なしのまま処理が終了する場合がある
			ElementsCount=iElement;
		}
	}

	BasePath.Empty();
	for(size_t i=0;i<ElementsCount;i++){
		BasePath+=PathElements[i];
		BasePath+=_T("\\");
	}
	TRACE(_T("BasePath=%s\n"),BasePath);
}
Beispiel #9
0
//=============================================================
// SevenZipGetFileName()の出力結果を基に、格納されたファイルが
// パス情報を持っているかどうか判別し、二重フォルダ作成を防ぐ
//=============================================================
bool CArchiver7ZIP::ExamineArchive(LPCTSTR ArcFileName,CConfigManager& ConfMan,bool bSkipDir,bool &bInFolder,bool &bSafeArchive,CString &BaseDir,CString &strErr)
{
	//UNICODE文字が安全かどうか判定する
	ASSERT(IsOK());
	if(!IsOK()){
		return false;
	}

	if(!InspectArchiveBegin(ArcFileName,ConfMan)){
		strErr.Format(IDS_ERROR_OPEN_ARCHIVE,ArcFileName);
		return false;
	}

	bInFolder=true;
	bool bSureDir=false;	//BaseDirに入っている文字列が確かにフォルダであるならtrue
	TRACE(_T("========\n"));

	while(InspectArchiveNext()){
		CString Buffer;
		InspectArchiveGetFileName(Buffer);
		Buffer.Replace(_T('\\'),_T('/'));		//パス区切り文字の置き換え
		TRACE(_T("%s\n"),Buffer);

		/*
		Separator('/' or '\')は格納ファイルの先頭にいくら含まれていても無視すべきであるので、
		格納ファイル名の先頭にいくらSeparatorがあってもフォルダに格納された状態とは見なさない。
		SeparatorがMaxRepeatより多いと不正とする
		ただし、MaxRepeatが-1のときはエラーとはしない
		*/
		const int Length=Buffer.GetLength();
		int StartIndex=0;
		for(;StartIndex<Length;StartIndex++){
			//先頭の'/'をとばしていく
#if defined(_UNICODE)||defined(UNICODE)
			if(_T('/')!=Buffer[StartIndex])break;
#else
			if(_MBC_SINGLE==_mbsbtype((const unsigned char *)(LPCTSTR)Buffer,StartIndex)){
				if(_T('/')!=Buffer[StartIndex])break;
			}
			else{	//全角文字なら'/'であるはずがない
				break;
			}
#endif//defined(_UNICODE)||defined(UNICODE)
		}
		if(!UtilIsSafeUnicode((LPCTSTR)Buffer+StartIndex)){	//危険なUNICODE指定が見つかれば、危険なファイルと見なす
			//監査終了
			InspectArchiveEnd();
			bSafeArchive=false;
			bInFolder=false;
			return true;
		}

		//ここからは二重ディレクトリ判定
		//すでに二重ディレクトリ判定が付いている場合は安全判定のみに徹する

		int FoundIndex=0;
		while(bInFolder){
			FoundIndex=Buffer.Find(_T('/'),StartIndex);
			if(-1==FoundIndex){	//'/'が格納ファイル名の先頭以外に含まれない場合
				if(!BaseDir.IsEmpty()&&BaseDir==Buffer){
					bSureDir=true;	//BaseDirがフォルダであると確認された
					break;
				}
				else if(BaseDir.IsEmpty()){
					//フォルダ名の後ろに'/'が付かないアーカイバもある
					//そういうものが最初に出てきたときは、フォルダ名と仮定する
					BaseDir=Buffer;
					bSureDir=false;
					break;
				}
			}
			CString Dir=Buffer.Mid(StartIndex,FoundIndex-StartIndex);	//Separatorの前までの文字列(ディレクトリに相当)を抜き出してくる
			//これまでの調べでDirはEmptyではないことが保証されている
			//また、危険ではないことも分かっている
			TRACE(_T("Base=%s,Dir=%s\n"),BaseDir,Dir);

			if(_T('.')==Dir){	//./があればディレクトリ指定としては無視する
				StartIndex=FoundIndex+1;
				continue;
			}
			if(BaseDir.IsEmpty()){
				BaseDir=Dir;
				bSureDir=true;
			}
			else if(BaseDir!=Dir){
				bInFolder=false;
			}
			else bSureDir=true;	//BaseDirがディレクトリと確認された
			break;
		}
	}
	TRACE(_T("========\n"));

	InspectArchiveEnd();
	bSafeArchive=true;

	//フォルダに入っているようではあるが、ディレクトリと仮定されただけの場合
	if(bInFolder&&!bSureDir)bInFolder=false;
	return true;
}
Beispiel #10
0
//---------------------------------------------------------------------------
void __fastcall TCodeView::PBoxPaint(TObject *Sender)
{
	if( !m_pFont ) return;

	CWaitCursor w;
	Graphics::TBitmap *pBmp = new Graphics::TBitmap;
    pBmp->Width = PBox->Width;
    pBmp->Height = PBox->Height;
	TCanvas *pCanvas = pBmp->Canvas;
	BOOL eud = SBOut->Down;
	if( !m_Base && !eud ) memset(m_tPfx, 0, sizeof(m_tPfx));
	SetPBoxFont(pCanvas);
	if( !eud ) SetMBCP(m_pFont->Charset);
	int x, y, xx, yy, fw, fh;
    char bf[16];
	int c = 0;
	for( y = 0; y < 16; y++ ){
		for( x = 0; x < 16; x++ ){
			if( eud ){
				DrawChar(pCanvas, c, FALSE);
            }
            else {
				if( !m_Base && (_mbsbtype((const unsigned char *)&c, 0) == _MBC_LEAD) ){
					m_tPfx[c] = TRUE;
    	        	DrawCursor(pCanvas, c, FALSE);
        	    }
            	else {
					DrawChar(pCanvas, c, FALSE);
            	}
            }
           	c++;
        }
    }
	pCanvas->Font = Font;
    pCanvas->Pen->Color = clBlack;
	::SetBkMode(pCanvas->Handle, TRANSPARENT);
    for( y = 0; y < 16; y++ ){
		wsprintf(bf, "%X", y);
		fw = pCanvas->TextWidth(bf);
        fh = pCanvas->TextHeight(bf);
        xx = m_XW1 + y*m_XW + (m_XW-fw)/2;
        yy = (m_YW1-fh)/2;
        pCanvas->TextOut(xx, yy, bf);

		if( eud ){
			c = GetEUDC(y, 1) & 0xfff0;
            if( c ){
		        wsprintf(bf, "%04x", c);
            }
            else {
				bf[0] = 0;
            }
        }
		else if( m_Base ){
	        wsprintf(bf, "%04x", y*16 + m_Base);
        }
        else {
	        wsprintf(bf, "%02X", y*16);
        }
		fw = pCanvas->TextWidth(bf);
        fh = pCanvas->TextHeight(bf);
        xx = (m_XW1-fw)/2;
        yy = m_YW1 + y*m_YW + (m_YW-fh)/2;
        pCanvas->TextOut(xx, yy, bf);

		pCanvas->Pen->Width = y ? 1 : 2;
		pCanvas->MoveTo(0, m_YW1 + y*m_YW);
        pCanvas->LineTo(PBox->Width, m_YW1 + y*m_YW);
		pCanvas->MoveTo(m_XW1 + y*m_XW, 0);
        pCanvas->LineTo(m_XW1 + y*m_XW, PBox->Height);
    }
    PBox->Canvas->Draw(0, 0, pBmp);
    delete pBmp;
	m_pfxCount = 0;
    for( x = 0; x < 256; x++ ){
		if( m_tPfx[x] ){
			m_tPfxIdx[m_pfxCount] = x;
        	m_pfxCount++;
        }
    }
	if( m_pfxCount != UDMB->Max ) UDMB->Max = short(m_pfxCount - 1);
}
Beispiel #11
0
static void test_mbcp(void)
{
    int mb_orig_max = *p__mb_cur_max;
    int curr_mbcp = _getmbcp();
    unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2 \xb3\xb4 \xb5"; /* incorrect string */
    unsigned char *mbstring2 = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5"; /* correct string */
    unsigned char *mbsonlylead = (unsigned char *)"\xb0\0\xb1\xb2 \xb3";
    unsigned char buf[16];
    int step;

    /* _mbtype tests */

    /* An SBCS codepage test. The ctype of characters on e.g. CP1252 or CP1250 differs slightly
     * between versions of Windows. Also Windows 9x seems to ignore the codepage and always uses
     * CP1252 (or the ACP?) so we test only a few ASCII characters */
    _setmbcp(1252);
    expect_eq(p_mbctype[10], 0, char, "%x");
    expect_eq(p_mbctype[50], 0, char, "%x");
    expect_eq(p_mbctype[66], _SBUP, char, "%x");
    expect_eq(p_mbctype[100], _SBLOW, char, "%x");
    expect_eq(p_mbctype[128], 0, char, "%x");
    _setmbcp(1250);
    expect_eq(p_mbctype[10], 0, char, "%x");
    expect_eq(p_mbctype[50], 0, char, "%x");
    expect_eq(p_mbctype[66], _SBUP, char, "%x");
    expect_eq(p_mbctype[100], _SBLOW, char, "%x");
    expect_eq(p_mbctype[128], 0, char, "%x");

    /* double byte code pages */
    test_codepage(932);
    test_codepage(936);
    test_codepage(949);
    test_codepage(950);

    _setmbcp(936);
    ok(*p__mb_cur_max == mb_orig_max, "__mb_cur_max shouldn't be updated (is %d != %d)\n", *p__mb_cur_max, mb_orig_max);
    ok(_ismbblead('\354'), "\354 should be a lead byte\n");
    ok(_ismbblead(' ') == FALSE, "' ' should not be a lead byte\n");
    ok(_ismbblead(0x1234b0), "0x1234b0 should not be a lead byte\n");
    ok(_ismbblead(0x123420) == FALSE, "0x123420 should not be a lead byte\n");
    ok(_ismbbtrail('\xb0'), "\xa0 should be a trail byte\n");
    ok(_ismbbtrail(' ') == FALSE, "' ' should not be a trail byte\n");

    /* _ismbslead */
    expect_eq(_ismbslead(mbstring, &mbstring[0]), -1, int, "%d");
    expect_eq(_ismbslead(mbstring, &mbstring[1]), FALSE, int, "%d");
    expect_eq(_ismbslead(mbstring, &mbstring[2]), -1, int, "%d");
    expect_eq(_ismbslead(mbstring, &mbstring[3]), FALSE, int, "%d");
    expect_eq(_ismbslead(mbstring, &mbstring[4]), -1, int, "%d");
    expect_eq(_ismbslead(mbstring, &mbstring[5]), FALSE, int, "%d");
    expect_eq(_ismbslead(mbstring, &mbstring[6]), FALSE, int, "%d");
    expect_eq(_ismbslead(mbstring, &mbstring[7]), -1, int, "%d");
    expect_eq(_ismbslead(mbstring, &mbstring[8]), FALSE, int, "%d");

    expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[0]), -1, int, "%d");
    expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[1]), FALSE, int, "%d");
    expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[2]), FALSE, int, "%d");
    expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[5]), FALSE, int, "%d");

    /* _ismbstrail */
    expect_eq(_ismbstrail(mbstring, &mbstring[0]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbstring, &mbstring[1]), -1, int, "%d");
    expect_eq(_ismbstrail(mbstring, &mbstring[2]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbstring, &mbstring[3]), -1, int, "%d");
    expect_eq(_ismbstrail(mbstring, &mbstring[4]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbstring, &mbstring[5]), -1, int, "%d");
    expect_eq(_ismbstrail(mbstring, &mbstring[6]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbstring, &mbstring[7]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbstring, &mbstring[8]), -1, int, "%d");

    expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[0]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[1]), -1, int, "%d");
    expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[2]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[3]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[4]), FALSE, int, "%d");
    expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[5]), FALSE, int, "%d");

    /* _mbsbtype */
    expect_eq(_mbsbtype(mbstring, 0), _MBC_LEAD, int, "%d");
    expect_eq(_mbsbtype(mbstring, 1), _MBC_TRAIL, int, "%d");
    expect_eq(_mbsbtype(mbstring, 2), _MBC_LEAD, int, "%d");
    expect_eq(_mbsbtype(mbstring, 3), _MBC_ILLEGAL, int, "%d");
    expect_eq(_mbsbtype(mbstring, 4), _MBC_LEAD, int, "%d");
    expect_eq(_mbsbtype(mbstring, 5), _MBC_TRAIL, int, "%d");
    expect_eq(_mbsbtype(mbstring, 6), _MBC_SINGLE, int, "%d");
    expect_eq(_mbsbtype(mbstring, 7), _MBC_LEAD, int, "%d");
    expect_eq(_mbsbtype(mbstring, 8), _MBC_ILLEGAL, int, "%d");

    expect_eq(_mbsbtype(mbsonlylead, 0), _MBC_LEAD, int, "%d");
    expect_eq(_mbsbtype(mbsonlylead, 1), _MBC_ILLEGAL, int, "%d");
    expect_eq(_mbsbtype(mbsonlylead, 2), _MBC_ILLEGAL, int, "%d");
    expect_eq(_mbsbtype(mbsonlylead, 3), _MBC_ILLEGAL, int, "%d");
    expect_eq(_mbsbtype(mbsonlylead, 4), _MBC_ILLEGAL, int, "%d");
    expect_eq(_mbsbtype(mbsonlylead, 5), _MBC_ILLEGAL, int, "%d");

    /* _mbsnextc */
    expect_eq(_mbsnextc(mbstring), 0xb0b1, int, "%x");
    expect_eq(_mbsnextc(&mbstring[2]), 0xb220, int, "%x");  /* lead + invalid tail */
    expect_eq(_mbsnextc(&mbstring[3]), 0x20, int, "%x");    /* single char */

    /* _mbclen/_mbslen */
    expect_eq(_mbclen(mbstring), 2, int, "%d");
    expect_eq(_mbclen(&mbstring[2]), 2, int, "%d");
    expect_eq(_mbclen(&mbstring[3]), 1, int, "%d");
    expect_eq(_mbslen(mbstring2), 4, int, "%d");
    expect_eq(_mbslen(mbsonlylead), 0, int, "%d");          /* lead + NUL not counted as character */
    expect_eq(_mbslen(mbstring), 4, int, "%d");             /* lead + invalid trail counted */

    /* _mbccpy/_mbsncpy */
    memset(buf, 0xff, sizeof(buf));
    _mbccpy(buf, mbstring);
    expect_bin(buf, "\xb0\xb1\xff", 3);

    memset(buf, 0xff, sizeof(buf));
    _mbsncpy(buf, mbstring, 1);
    expect_bin(buf, "\xb0\xb1\xff", 3);
    memset(buf, 0xff, sizeof(buf));
    _mbsncpy(buf, mbstring, 2);
    expect_bin(buf, "\xb0\xb1\xb2 \xff", 5);
    memset(buf, 0xff, sizeof(buf));
    _mbsncpy(buf, mbstring, 3);
    expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4\xff", 7);
    memset(buf, 0xff, sizeof(buf));
    _mbsncpy(buf, mbstring, 4);
    expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4 \xff", 8);
    memset(buf, 0xff, sizeof(buf));
    _mbsncpy(buf, mbstring, 5);
    expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4 \0\0\xff", 10);
    memset(buf, 0xff, sizeof(buf));
    _mbsncpy(buf, mbsonlylead, 6);
    expect_bin(buf, "\0\0\0\0\0\0\0\xff", 8);

    memset(buf, 0xff, sizeof(buf));
    _mbsnbcpy(buf, mbstring2, 2);
    expect_bin(buf, "\xb0\xb1\xff", 3);
    _mbsnbcpy(buf, mbstring2, 3);
    expect_bin(buf, "\xb0\xb1\0\xff", 4);
    _mbsnbcpy(buf, mbstring2, 4);
    expect_bin(buf, "\xb0\xb1\xb2\xb3\xff", 5);
    memset(buf, 0xff, sizeof(buf));
    _mbsnbcpy(buf, mbsonlylead, 5);
    expect_bin(buf, "\0\0\0\0\0\xff", 6);

    /* _mbsinc/mbsdec */
    step = _mbsinc(mbstring) - mbstring;
    ok(step == 2, "_mbsinc adds %d (exp. 2)\n", step);
    step = _mbsinc(&mbstring[2]) - &mbstring[2];  /* lead + invalid tail */
    ok(step == 2, "_mbsinc adds %d (exp. 2)\n", step);

    step = _mbsninc(mbsonlylead, 1) - mbsonlylead;
    ok(step == 0, "_mbsninc adds %d (exp. 0)\n", step);
    step = _mbsninc(mbsonlylead, 2) - mbsonlylead;  /* lead + NUL byte + lead + char */
    ok(step == 0, "_mbsninc adds %d (exp. 0)\n", step);
    step = _mbsninc(mbstring2, 0) - mbstring2;
    ok(step == 0, "_mbsninc adds %d (exp. 2)\n", step);
    step = _mbsninc(mbstring2, 1) - mbstring2;
    ok(step == 2, "_mbsninc adds %d (exp. 2)\n", step);
    step = _mbsninc(mbstring2, 2) - mbstring2;
    ok(step == 4, "_mbsninc adds %d (exp. 4)\n", step);
    step = _mbsninc(mbstring2, 3) - mbstring2;
    ok(step == 5, "_mbsninc adds %d (exp. 5)\n", step);
    step = _mbsninc(mbstring2, 4) - mbstring2;
    ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step);
    step = _mbsninc(mbstring2, 5) - mbstring2;
    ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step);
    step = _mbsninc(mbstring2, 17) - mbstring2;
    ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step);

    /* functions that depend on locale codepage, not mbcp.
     * we hope the current locale to be SBCS because setlocale(LC_ALL, ".1252") seems not to work yet
     * (as of Wine 0.9.43)
     */
    if (*p__mb_cur_max == 1)
    {
        expect_eq(mblen((char *)mbstring, 3), 1, int, "%x");
        expect_eq(_mbstrlen((char *)mbstring2), 7, int, "%d");
    }