Exemple #1
0
	debuggeroutbuf<char>::int_type debuggeroutbuf<char>::overflow(int_type ch)
	{
		if(ch == traits_type::eof()) return traits_type::eof();
		*epptr() = ch;
		// SJIS?
		if(-1 == _ismbstrail((const unsigned char *)pbase(), (const unsigned char *)epptr())) {
			char *lbp;
			for(lbp = epptr()-1; lbp > pbase(); lbp--) {
				if(-1 == _ismbslead((const unsigned char *)pbase(), (const unsigned char *)lbp)) {
					break;
				}
			}
			int _ch = *lbp; *lbp = '\0';
			sync();
			sputc(_ch);
			for(lbp++; lbp <= epptr(); lbp++) {
				sputc(*lbp);
			}
			*epptr() = '\0';
		}
		else {
			*epptr() = '\0';
			sync();
			sputc(ch);
		}
		return traits_type::not_eof(ch);
	}
int FdoCommonOSUtil::ismbstrail(const unsigned char *string, const unsigned char *current)
{
#ifdef _WIN32
    return _ismbstrail(string, current);
#else // _WIN32
    return FdoCommonOSUtil::ismbslead(string, current)==-1 ? 0 : -1;
#endif
}
Exemple #3
0
char sjis_getlastchar(char *s)
{
	if (!s || !*s) {
		return 0;
	}
	if (!_ismbstrail((const unsigned char *)s, s + strlen(s) - 1)) {
		return s[strlen(s) - 1];
	}
	return 0;
}
Exemple #4
0
char* basename(const char* str)
{
	char*p = ((char*)str)+strlen(str)-1;
#ifdef SJIS
	while(p>str && (*p!='\\' || !_ismbstrail((unsigned char *)str, (unsigned char *)p)))
#else
	while(p>str && *p!='\\')
#endif
		p--;
	if(p>str) return (p+1);
	else return p;
}
Exemple #5
0
//
// 末尾に \ を追加
//
kjm::_tstring kjm::path::addBackslash(const kjm::_tstring& path) {

	// MAX_PATH を超えると PathAddBackslash が使えなくなるので、自作

	kjm::_tstring result = path;
#if defined(_MBCS)
	if (_ismbstrail((unsigned char *)&result[0], (unsigned char *)&result[result.length() - 1])) {
		result.push_back(_T('\\'));
	} else if (*result.rbegin() != _T('\\')) {
		result.push_back(_T('\\'));
	}
#else
	if (*result.rbegin() != _T('\\')) {
		result.push_back(_T('\\'));
	}
#endif
	return result;
}
void CEditView::DrawLine( int nLine, HDC hDC, int x, int y, int xDividerStart ) const
{
	int nLineLen = m_pBuffer->GetLineLength( nLine );
	BOOL bUseColor = ( m_pCtrl->UseColorSyntax() && ( nLineLen <= MAXCOL ) );

	int nViewCol = m_nLeftIndex;
	int nBuffColStart = m_pBuffer->ConvertViewColToBufferCol( nLine, nViewCol, FALSE );

	int xLeft = x;

	// highlight this line if appropriate
	BOOL bHighlight = m_pBuffer->IsHighlighted( nLine );
	if ( bHighlight )
	{
		// fill out the rest of the line with the highlight
		RECT rc = m_rcView;
		rc.left = x;
		rc.top = y;
		rc.bottom = y + m_cyLine;
		SetBkColor( hDC, m_pCtrl->GetHighlightedLineColor() );
		ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL );
	}

	BOOL bMBCS = DBCS_ACTIVE;

#ifdef _UNICODE
	int nRightIndex = m_nRightIndex;
#else
	int nRightIndex = m_nRightIndex + bMBCS * 2;	// always paint two more TCHARs so multibyte chars aren't truncated
#endif

	if ( nBuffColStart < nLineLen )	// else nothing to draw
	{
		// wait for nLine to become available (in case of background syntax parsing)
		m_pBuffer->WaitForLine( nLine );

		LPCTSTR pszLineStart = m_pBuffer->GetLineText( nLine );
		register LPCTSTR psz = pszLineStart + nBuffColStart;
		LPCTSTR pszStart = psz;
		
		//////////////////////////////////////////////////////////////////////////
		// Step 1: Expand tabs
		//
		BOOL bViewWhitespace = m_pCtrl->DisplayWhitespace();
		TCHAR szLine[ 1000 ];  CharFill( szLine, _T(' '), ARRAY_SIZE( szLine ) );
		int cbTab = m_pBuffer->GetTabSize();
		LPTSTR pszBuff = szLine;
		TCHAR chTab, chSpace;
		if ( bMBCS )
			{ chTab = _T('^'); chSpace = _T('`'); }
		else
			{ chTab = _T('»'); chSpace = _T('·'); }

		while ( *psz && ( nViewCol <= nRightIndex ) )
		{
			if ( *psz == _T('\t') )
			{
				int nSpaces = ( ( nViewCol / cbTab ) * cbTab ) + cbTab - nViewCol;
				if ( nSpaces )
				{
					if ( bViewWhitespace )
					{
						if ( psz != pszStart || m_nLeftIndex == m_pBuffer->ConvertBufferColToViewCol( nLine, nBuffColStart ) )
						{
							*pszBuff = chTab;
						}
					}
					pszBuff += nSpaces;
					nViewCol += nSpaces;
				}
			}
			else
			{
				if ( bViewWhitespace && *psz == _T(' ') )
				{
					*pszBuff++ = chSpace;
				}
				else
				{
					*pszBuff++ = *psz;
				}
				nViewCol++;
			}
			psz++;
		}
		//////////////////////////////////////////////////////////////////////////
		// Step 2: Parse the line and assign colors to everything
		//
		DWORD clrLine[ 100 ]; // hiword = token, loword = token offset in szLine
		int nColors = 0;

		if ( bUseColor )
		{
			psz = pszLineStart;
			int nParseLen = m_pBuffer->ConvertViewColToBufferCol( nLine, nRightIndex ) + 20; // +20 is a reasonable max token length
			nParseLen = min( nParseLen, nLineLen );
			nViewCol = 0;
			int nBuffCol = 0;
			int nFirstColorViewCol = m_nLeftIndex;
			BOOL bColorIsVisible = nViewCol >= nFirstColorViewCol;

			CLineParser Parser( m_pBuffer, nLine, nParseLen );

			// pick up where the last line left off -- in a multi-line comment block (or not)
			clrLine[ nColors++ ] = MAKELPARAM( 0, ( WORD ) ( Parser.m_bInComment ? CBuffer::eMultiLineCommentStart : 
			                                               ( Parser.m_bInString ?  CBuffer::eStringDelim :
			                                               ( Parser.m_bInTag ?     CBuffer::eTagText :
														                           CBuffer::eText ) ) ) );

			while ( Parser.MoreComing() )
			{
				Parser.AcceptToken();

				int nTokenStartCol = nViewCol;
				nBuffCol += Parser.m_nTokenLen;
				if ( Parser.m_bHasTab )
				{
					ASSERT( Parser.m_eToken == CBuffer::eText || Parser.m_eToken == CBuffer::eTagText || Parser.m_eToken == CBuffer::eStringDelim || Parser.m_eToken == CBuffer::eSingleLineComment );
					nViewCol = m_pBuffer->ConvertBufferColToViewCol( nLine, nBuffCol );
				}
				else
				{
					nViewCol += Parser.m_nTokenLen;
				}
				if ( !bColorIsVisible )
				{
					// Assume this token (unless in a comment) will be the first token to cross the left edge 
					clrLine[ 0 ] = MAKELPARAM( 0, ( WORD )( Parser.m_bInComment ? CBuffer::eMultiLineCommentStart : 
																		 ( Parser.m_bInString ? CBuffer::eStringDelim : Parser.m_eToken ) ) );

					if ( nViewCol > nFirstColorViewCol )
					{
						//////////////////////////
						// token is now in view
						//
						bColorIsVisible = TRUE;
						nTokenStartCol = nFirstColorViewCol;
					}
				}

				// record the token position
				if ( nTokenStartCol > nRightIndex )
				{
					break;
				}

				if ( bColorIsVisible &&
				     !Parser.m_bWasInComment && !Parser.m_bIsCommentEndToken &&
					 !Parser.m_bWasInString && !Parser.m_bIsStringEndToken )
				{
					clrLine[ nColors++ ] = MAKELPARAM( nTokenStartCol - m_nLeftIndex, ( WORD ) Parser.m_eToken );
				}

				clrLine[ nColors ] = MAKELPARAM( ( nViewCol > m_nLeftIndex ? nViewCol : nRightIndex ) - m_nLeftIndex, ( WORD ) Parser.m_eToken );

				// don't blow past the local array and corrupt the stack!
				if ( nColors >= ARRAY_SIZE( clrLine ) - 1 )
				{
					nColors = 0;
					goto no_color;
				}

			}
		}
		else
		{
			no_color:

			clrLine[ nColors++ ] = MAKELPARAM( 0, ( WORD ) CBuffer::eText );
			// draw text only as far as is necessary.  We don't want to paint extra characters that aren't
			// in the buffer.  If underline font used on plain text, the underline will extend to the edge of the window.
			// we don't want that.
			int nViewColEnd = m_pBuffer->ConvertBufferColToViewCol( nLine, nLineLen );
			nViewColEnd = min( nRightIndex, nViewColEnd );
			nViewColEnd = max( m_nLeftIndex, nViewColEnd );

			clrLine[ nColors ] = MAKELPARAM( nViewColEnd - m_nLeftIndex, ( WORD ) CBuffer::eText );
		}

		//////////////////////////////////////////////////////////////////////////
		// Step 3: Output the line
		//
		ASSERT( nColors );
		BOOL bFirstToken = TRUE;

		for ( int i = 0; i < nColors; i++ )
		{
			DWORD dwColorInfo = clrLine[ i ];
			CBuffer::LangToken eToken = ( CBuffer::LangToken ) HIWORD( dwColorInfo );
			SetTextColor( hDC, m_pCtrl->GetTokenColor( eToken, TRUE ) );
			COLORREF crBk = bHighlight ? m_pCtrl->GetHighlightedLineColor() : m_pCtrl->GetTokenColor( eToken, FALSE );
			if ( crBk != CLR_INVALID )
			{
				SetBkColor( hDC, crBk );
				SetBkMode( hDC, OPAQUE );
			}
			else
			{
				SetBkMode( hDC, TRANSPARENT );
			}

			long cxExtraSpacing, cyDescentShift;
			SelectObject( hDC, m_pCtrl->GetTokenFont( eToken, cxExtraSpacing, cyDescentShift, m_pCtrl->m_font ) );
			SetTextCharacterExtra( hDC, cxExtraSpacing );

			int nTokenStart = LOWORD( dwColorInfo );
			int nTokenNext = LOWORD( clrLine[ i + 1 ] );
			int cbToken = nTokenNext - nTokenStart;
			if ( cbToken )
			{
				#ifndef _UNICODE
				// The first visible token on the left of the line might be cutoff right
				// in the middle of a multi-byte char.  We need to account for this by not
				// rendering the character (just leave whitespace).
				if ( bFirstToken && _ismbstrail( ( const unsigned char * ) pszLineStart, ( const unsigned char * ) pszStart ) )
				{
					// scan backwards to the lead byte
					LPCTSTR pszLead = pszStart;
					while ( _ismbstrail( ( const unsigned char * ) pszLineStart, ( const unsigned char * ) --pszLead ) )
						;
					int cbChar = pszStart - pszLead;
					nTokenStart += cbChar;
					cbToken -= cbChar;
					x += ( cbChar * m_cxChar );
				}
				#endif
				bFirstToken = FALSE;
				ExtTextOut( hDC, x, y - cyDescentShift, 0, NULL, szLine + nTokenStart, cbToken, NULL );
				x += ( cbToken * m_cxChar );
			}
			// don't worry about deselecting the font -- it will be cleaned up by any
			// calling method (as an optimization)
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// Step 4: give the parent window a crack at painting, too.
	//
	DWORD dwStyle = m_pBuffer->GetLineStyle( nLine );
	if ( HAS_FLAG( dwStyle, CML_OWNERDRAW ) )
	{
		CM_DRAWLINEDATA dld;
		dld.hDC = hDC;
		dld.rcLine.left = xLeft;
		dld.rcLine.top = y;
		dld.rcLine.right = m_rcView.right;
		dld.rcLine.bottom = y + m_cyLine;
		dld.nLine = nLine;
		dld.nLeftCol = m_nLeftIndex; 
		dld.nRightCol = m_nRightIndex; 
		dld.lParam = m_pBuffer->GetItemData( nLine );
		dld.dwStyle = dwStyle;
		m_pCtrl->NotifyParent( CMN_DRAWLINE, ( NMHDR * ) &dld );
	}

	// Draw divider line underneath the line if appropriate
	if ( m_pBuffer->HasDivider( nLine ) )
	{
		COLORREF crDividerLine = m_pCtrl->GetHDividerLineColor();
		COLORREF crWindow = m_pCtrl->GetWindowColor( TRUE );
		// if line will blend in with the background, make it visible (opposite of window color).
		if ( crDividerLine == CLR_INVALID || crDividerLine == crWindow )
			crDividerLine = ( ~crWindow & 0x00ffffff );

		HPEN hPen = CreatePen( PS_SOLID, CY_DIVIDERLINE, crDividerLine );
		HPEN hPenOld = ( HPEN ) SelectObject( hDC, hPen );
		int yLine = y + m_cyLine - 1;
		MoveToEx( hDC, xDividerStart, yLine, NULL );
		LineTo( hDC, m_rcView.right, yLine );
		SelectObject( hDC, hPenOld );
		DeleteObject( hPen );
	}
}
Exemple #7
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");
    }