diff --git a/bld/wipfc/cpp/acvwport.cpp b/bld/wipfc/cpp/acvwport.cpp index 44cfcf19e3..8d64368be8 100644 --- a/bld/wipfc/cpp/acvwport.cpp +++ b/bld/wipfc/cpp/acvwport.cpp @@ -234,26 +234,29 @@ void AcViewport::buildText( Cell* cell ) esc.push_back( static_cast< STD1::uint8_t >( objectName.size() + 1 ) ); if( !objectName.empty() ) { std::string buffer; - wtombstring( objectName, buffer ); + wtomb_string( objectName, buffer ); std::size_t bytes( buffer.size() ); - for( std::size_t count1 = 0; count1 < bytes; ++count1 ) + for( std::size_t count1 = 0; count1 < bytes; ++count1 ) { esc.push_back( static_cast< STD1::uint8_t >( buffer[ count1 ] ) ); + } } esc.push_back( static_cast< STD1::uint8_t >( dll.size() + 1 ) ); if( !dll.empty() ) { std::string buffer; - wtombstring( dll, buffer ); + wtomb_string( dll, buffer ); std::size_t bytes( buffer.size() ); - for( std::size_t count1 = 0; count1 < bytes; ++count1 ) + for( std::size_t count1 = 0; count1 < bytes; ++count1 ) { esc.push_back( static_cast< STD1::uint8_t >( buffer[ count1 ] ) ); + } } esc.push_back( static_cast< STD1::uint8_t >( objectInfo.size() + 1 ) ); if( !objectInfo.empty() ) { std::string buffer; - wtombstring( objectInfo, buffer ); + wtomb_string( objectInfo, buffer ); std::size_t bytes( buffer.size() ); - for( std::size_t count1 = 0; count1 < bytes; ++count1 ) + for( std::size_t count1 = 0; count1 < bytes; ++count1 ) { esc.push_back( static_cast< STD1::uint8_t >( buffer[ count1 ] ) ); + } } if( doOrigin || doSize ) { STD1::uint8_t flag( 0xC0 ); @@ -265,13 +268,15 @@ void AcViewport::buildText( Cell* cell ) esc.push_back( 0 ); if( doOrigin ) { STD1::uint8_t* src = reinterpret_cast< STD1::uint8_t* >( &origin ); - for( std::size_t count1 = 0; count1 < sizeof( PageOrigin ); ++count1, ++src) + for( std::size_t count1 = 0; count1 < sizeof( PageOrigin ); ++count1, ++src ) { esc.push_back( *src ); + } } if( doSize ) { STD1::uint8_t* src = reinterpret_cast< STD1::uint8_t* >( &size ); - for( std::size_t count1 = 0; count1 < sizeof( PageSize ); ++count1, ++src) + for( std::size_t count1 = 0; count1 < sizeof( PageSize ); ++count1, ++src ) { esc.push_back( *src ); + } } } esc[ 1 ] = static_cast< STD1::uint8_t >( esc.size() - 1 ); diff --git a/bld/wipfc/cpp/compiler.cpp b/bld/wipfc/cpp/compiler.cpp index 8c4ccc95f9..a9e6f24d2e 100644 --- a/bld/wipfc/cpp/compiler.cpp +++ b/bld/wipfc/cpp/compiler.cpp @@ -64,7 +64,7 @@ Compiler::~Compiler() void Compiler::setInputFile( std::string& name ) { std::wstring* wname( new std::wstring() ); - mbtowstring( name, *wname ); + mbtow_string( name, *wname ); wname = addFileName( wname ); inFiles.push_back( new IpfFile( wname ) ); } diff --git a/bld/wipfc/cpp/ctrlbtn.cpp b/bld/wipfc/cpp/ctrlbtn.cpp index 6eb2b8e271..174d0f1447 100644 --- a/bld/wipfc/cpp/ctrlbtn.cpp +++ b/bld/wipfc/cpp/ctrlbtn.cpp @@ -41,7 +41,7 @@ STD1::uint32_t ControlButton::write( std::FILE *out ) const if( std::fwrite( &res, sizeof( STD1::uint16_t), 1, out) != 1 ) throw FatalError( ERR_WRITE ); std::string buffer; - wtombstring( txt, buffer ); + wtomb_string( txt, buffer ); std::size_t length( buffer.size() ); if( length > 255 ) { buffer.erase( 255 ); diff --git a/bld/wipfc/cpp/document.cpp b/bld/wipfc/cpp/document.cpp index 2511633603..650bdbf2e5 100644 --- a/bld/wipfc/cpp/document.cpp +++ b/bld/wipfc/cpp/document.cpp @@ -209,7 +209,7 @@ Document::Document( Compiler& c, const char* loc ) : fonts.reset( new FontCollection( codePage() ) ); FontEntry fnt; char buffer[ sizeof( fnt.faceName ) ]; - std::size_t size( std::wcstombs( buffer, cgraphicFontFaceName().c_str(), sizeof( fnt.faceName ) ) ); + std::size_t size( wtomb_cstring( buffer, cgraphicFontFaceName().c_str(), sizeof( buffer ) - 1 ) ); if( size == static_cast< std::size_t >( -1 ) ) throw FatalError( ERR_T_CONV ); std::strncpy( fnt.faceName, buffer, sizeof( fnt.faceName ) ); @@ -604,7 +604,7 @@ void Document::makeBitmaps() try { for( BitmapNameIter itr = bitmapNames.begin(); itr != bitmapNames.end(); ++itr ) { std::string fname; - wtombstring( itr->first, fname ); + wtomb_string( itr->first, fname ); for( std::size_t count = 0; count < paths.size(); ++count ) { std::string fullname( paths[ count ] ); if( !fullname.empty() ) @@ -875,13 +875,13 @@ Lexer::Token Document::processCommand( Lexer* lexer, Tag* parent ) std::string::size_type idx1( 0 ); std::string::size_type idx2( env.find_first_of( separators, idx1 ) ); std::wstring fbuffer; - mbtowstring( env.substr( idx1, idx2 - idx1 ), fbuffer ); + mbtow_string( env.substr( idx1, idx2 - idx1 ), fbuffer ); paths.push_back( fbuffer ); while( idx2 != std::string::npos ) { idx1 = idx2 + 1; idx2 = env.find_first_of( separators, idx1 ); fbuffer.clear(); - mbtowstring( env.substr( idx1, idx2 - idx1 ), fbuffer ); + mbtow_string( env.substr( idx1, idx2 - idx1 ), fbuffer ); paths.push_back( fbuffer ); } for( std::size_t count = 0; count < paths.size(); ++count ) { diff --git a/bld/wipfc/cpp/extfiles.cpp b/bld/wipfc/cpp/extfiles.cpp index 6309de157d..c102cd8236 100644 --- a/bld/wipfc/cpp/extfiles.cpp +++ b/bld/wipfc/cpp/extfiles.cpp @@ -57,7 +57,7 @@ STD1::uint32_t ExternalFiles::write( std::FILE *out ) STD1::uint32_t start( std::ftell( out ) ); for( ConstTableIter itr = table.begin(); itr != table.end(); ++itr ) { std::string buffer; - wtombstring( itr->first, buffer ); + wtomb_string( itr->first, buffer ); std::size_t length( buffer.size() ); if( length > 255 ) { buffer.erase( 255 ); diff --git a/bld/wipfc/cpp/font.cpp b/bld/wipfc/cpp/font.cpp index 64c7f13b11..d4af0dcd87 100644 --- a/bld/wipfc/cpp/font.cpp +++ b/bld/wipfc/cpp/font.cpp @@ -63,7 +63,7 @@ Lexer::Token Font::parse( Lexer* lexer ) fnt.height = 0; fnt.width = 0; isDefault = true; - } else if( std::wcstombs( &fnt.faceName[0], value.c_str(), sizeof( fnt.faceName ) / sizeof( char ) ) == static_cast< std::size_t >( -1 ) ) { + } else if( wtomb_cstring( fnt.faceName, value.c_str(), sizeof( fnt.faceName ) - 1 ) == static_cast< std::size_t >( -1 ) ) { throw( ERR_T_CONV ); } } else if( key == L"size" ) { diff --git a/bld/wipfc/cpp/gdword.cpp b/bld/wipfc/cpp/gdword.cpp index 710cd64b96..ce6a3c7b8d 100644 --- a/bld/wipfc/cpp/gdword.cpp +++ b/bld/wipfc/cpp/gdword.cpp @@ -38,6 +38,7 @@ #include #include "gdword.hpp" #include "errors.hpp" +#include "util.hpp" void GlobalDictionaryWord::toUpper() { @@ -52,7 +53,7 @@ std::size_t GlobalDictionaryWord::writeWord( std::FILE* out ) const { char buffer[ 256 ]; std::size_t written; - std::size_t length( std::wcstombs( buffer, text.c_str(), sizeof( buffer ) / sizeof( char ) ) ); + std::size_t length( wtomb_cstring( buffer, text.c_str(), sizeof( buffer ) - 1 ) ); if( length == static_cast< std::size_t >( -1 ) ) throw FatalError( ERR_T_CONV ); if( length > 254 ) diff --git a/bld/wipfc/cpp/hide.cpp b/bld/wipfc/cpp/hide.cpp index 24ae2fe033..9bf053700b 100644 --- a/bld/wipfc/cpp/hide.cpp +++ b/bld/wipfc/cpp/hide.cpp @@ -90,7 +90,7 @@ Lexer::Token Hide::parse( Lexer* lexer ) void Hide::buildText( Cell* cell ) { std::string tmp; - wtombstring( keyPhrase, tmp ); + wtomb_string( keyPhrase, tmp ); std::size_t size( tmp.size() ); if( size > 253 ) { tmp.erase( 253 ); diff --git a/bld/wipfc/cpp/hn.cpp b/bld/wipfc/cpp/hn.cpp index dc049d90b9..8a28638ce8 100644 --- a/bld/wipfc/cpp/hn.cpp +++ b/bld/wipfc/cpp/hn.cpp @@ -106,7 +106,7 @@ Lexer::Token Hn::parse( Lexer* lexer ) tok = document->getNextToken(); } //convert to mbs, max 255 char - wtombstring( tmp, title ); + wtomb_string( tmp, title ); if( title.size() > 255 ) title.erase( 255 ); tok = document->getNextToken(); @@ -613,7 +613,7 @@ void Hn::buildText( Cell* cell ) { if( etoc.setTutor ) { std::string tmp; - wtombstring( tutorial, tmp ); + wtomb_string( tutorial, tmp ); std::size_t size1( tmp.size() ); if( size1 > 253 ) { tmp.erase( 253 ); diff --git a/bld/wipfc/cpp/index.cpp b/bld/wipfc/cpp/index.cpp index afc2dc7e96..7320589c6f 100644 --- a/bld/wipfc/cpp/index.cpp +++ b/bld/wipfc/cpp/index.cpp @@ -109,10 +109,10 @@ std::size_t IndexItem::write( std::FILE* out ) std::size_t length1( 0 ); std::size_t length2( 0 ); if( hdr.sortKey ) { - wtombstring( sortKey, buffer1 ); + wtomb_string( sortKey, buffer1 ); length1 = buffer1.size(); } - wtombstring( text, buffer2 ); + wtomb_string( text, buffer2 ); length2 = buffer2.size(); if( length1 + length2 > 254 ) { length2 = length1 > 254 ? 0 : 254 - length1; diff --git a/bld/wipfc/cpp/ipffile.cpp b/bld/wipfc/cpp/ipffile.cpp index 2bc3f3ed7e..93ae157c2c 100644 --- a/bld/wipfc/cpp/ipffile.cpp +++ b/bld/wipfc/cpp/ipffile.cpp @@ -35,11 +35,11 @@ #include #endif -IpfFile::IpfFile( const std::wstring* fname ) : IpfData(), fileName ( fname ), +IpfFile::IpfFile( const std::wstring* fname ) : IpfData(), fileName ( fname ), ungottenChar( WEOF ), ungotten( false ) { std::string buffer; - wtombstring( *fname, buffer ); + wtomb_string( *fname, buffer ); if(( stream = std::fopen( buffer.c_str(), "rb" ) ) == 0) throw FatalIOError( ERR_OPEN, *fileName ); } @@ -94,17 +94,18 @@ std::wint_t IpfFile::readMBChar() if( ungotten ) { ch = ungottenChar; ungotten = false; - } - else { + } else { char mbc[ MB_LEN_MAX ]; if( std::fread( &mbc[0], sizeof( char ), 1, stream ) != 1 ) return WEOF; - else if( _ismbblead( mbc[0] ) ) { - if( std::fread( &mbc[1], sizeof( char ), 1, stream ) != 1 ) + if( _ismbblead( mbc[0] ) ) { + if( std::fread( &mbc[1], sizeof( char ), 1, stream ) != 1 ) { return WEOF; + } } - if( std::mbtowc( &ch, mbc, MB_CUR_MAX ) < 0 ) + if( mbtow_char( &ch, mbc, MB_CUR_MAX ) < 0 ) { throw FatalError( ERR_T_CONV ); + } } return ch; } diff --git a/bld/wipfc/cpp/isyn.cpp b/bld/wipfc/cpp/isyn.cpp index 319591668b..96b3284d83 100644 --- a/bld/wipfc/cpp/isyn.cpp +++ b/bld/wipfc/cpp/isyn.cpp @@ -69,7 +69,7 @@ Lexer::Token ISyn::parse( Lexer* lexer ) while( tok != Lexer::END && !( tok == Lexer::TAG && lexer->tagId() == Lexer::EUSERDOC)) { if( tok == Lexer::WORD ) { char buffer[ 256 ]; - std::size_t length( std::wcstombs( buffer, lexer->text().c_str(), sizeof(buffer) / sizeof(char) ) ); + std::size_t length( wtomb_cstring( buffer, lexer->text().c_str(), sizeof( buffer ) - 1 ) ); if( length == static_cast< std::size_t >( -1 ) ) throw FatalError( ERR_T_CONV ); std::string txt( buffer ); diff --git a/bld/wipfc/cpp/link.cpp b/bld/wipfc/cpp/link.cpp index e5e88a2f8b..44c23b636a 100644 --- a/bld/wipfc/cpp/link.cpp +++ b/bld/wipfc/cpp/link.cpp @@ -508,7 +508,7 @@ void Link::doTopic( Cell* cell ) esc.push_back( static_cast< STD1::uint8_t >( index ) ); //esc.push_back( static_cast< STD1::uint8_t >( index >> 8 ) ); std::string tmp; - wtombstring( refid->getText(), tmp ); + wtomb_string( refid->getText(), tmp ); std::size_t tmpsize( tmp.size() ); esc.push_back( static_cast< STD1::uint8_t >( tmpsize ) ); if( hypergraphic && ( x || y || cx || cy ) ) { @@ -617,9 +617,9 @@ void Link::doLaunch( Cell* cell ) esc.push_back( static_cast< STD1::uint8_t >( cy >> 8 ) ); } std::string buffer; - wtombstring( object, buffer ); + wtomb_string( object, buffer ); buffer += ' '; - wtombstring( data, buffer ); + wtomb_string( data, buffer ); std::size_t buffersize( buffer.size() ); if( buffersize > 255 - esc.size() + 1 ) { buffersize = 255 - esc.size() + 1; diff --git a/bld/wipfc/cpp/nls.cpp b/bld/wipfc/cpp/nls.cpp index 00096d91ce..131b0d8f9a 100644 --- a/bld/wipfc/cpp/nls.cpp +++ b/bld/wipfc/cpp/nls.cpp @@ -151,12 +151,12 @@ void Nls::readEntityFile( std::FILE *entty ) while( std::fgets( buffer, sizeof( buffer ) / sizeof( char ), entty ) ) { std::size_t len = std::strlen( buffer ); killEOL( buffer + len - 1 ); - offset = std::mbtowc( &c, buffer, len ); + offset = mbtow_char( &c, buffer, len ); if( offset == -1 ) throw FatalError( ERR_T_CONV ); if( offset > 1 ) useDBCS = true; - len = std::mbstowcs( text, buffer + offset, sizeof( text ) / sizeof( wchar_t ) ); + len = mbtow_cstring( text, buffer + offset, sizeof( text ) / sizeof( wchar_t ) - 1 ); if( len == static_cast< std::size_t >( -1 )) throw FatalError( ERR_T_CONV ); text[len] = L'\0'; diff --git a/bld/wipfc/cpp/strings.cpp b/bld/wipfc/cpp/strings.cpp index 71b34768db..df6b92afd0 100644 --- a/bld/wipfc/cpp/strings.cpp +++ b/bld/wipfc/cpp/strings.cpp @@ -31,6 +31,7 @@ #include #include "strings.hpp" #include "errors.hpp" +#include "util.hpp" STD1::uint32_t StringTable::write( std::FILE *out ) { @@ -40,7 +41,7 @@ STD1::uint32_t StringTable::write( std::FILE *out ) for( ConstTableIter itr = table.begin(); itr != table.end(); ++itr ) { char buffer[ 256 ]; std::size_t written; - std::size_t length( std::wcstombs( buffer, itr->c_str(), sizeof( buffer ) / sizeof( char ) ) ); + std::size_t length( wtomb_cstring( buffer, itr->c_str(), sizeof( buffer ) - 1 ) ); if( length == static_cast< std::size_t >( -1 ) ) throw FatalError( ERR_T_CONV ); if( std::fputc( static_cast< STD1::uint8_t >( length + 1 ), out ) == EOF || diff --git a/bld/wipfc/cpp/title.cpp b/bld/wipfc/cpp/title.cpp index efea1165e6..e6e4e6159a 100644 --- a/bld/wipfc/cpp/title.cpp +++ b/bld/wipfc/cpp/title.cpp @@ -35,6 +35,7 @@ #include "title.hpp" #include "lexer.hpp" #include "document.hpp" +#include "util.hpp" Lexer::Token Title::parse( Lexer* lexer, IpfHeader* hdr ) { @@ -58,12 +59,11 @@ Lexer::Token Title::parse( Lexer* lexer, IpfHeader* hdr ) tok == Lexer::WORD || tok == Lexer::PUNCTUATION ) { txt += lexer->text(); - } - else if( tok == Lexer::ENTITY ) { + } else if( tok == Lexer::ENTITY ) { const std::wstring* exp( document->nameit( lexer->text() ) ); - if( exp ) + if( exp ) { txt += *exp; - else { + } else { try { wchar_t ch( document->entity( lexer->text() ) ); txt += ch; @@ -72,22 +72,16 @@ Lexer::Token Title::parse( Lexer* lexer, IpfHeader* hdr ) document->printError( e.code ); } } - } - else if( tok == Lexer::END ) + } else if( tok == Lexer::END ) { throw FatalError( ERR_EOF ); - else + } else { break; + } tok = document->getNextToken(); } if( txt.size() > 47 ) document->printError( ERR2_TEXTTOOLONG ); - std::size_t index1 = 0; - std::size_t index2 = 0; - char *title( hdr->title ); - while( index1 < txt.size() && index2 < 47 ) { - index2 += std::wctomb( title + index2, txt[ index1 ] ); - ++index1 ; - } + wtomb_cstring( hdr->title, txt.c_str(), sizeof( hdr->title ) - 1 ); return tok; } diff --git a/bld/wipfc/cpp/util.cpp b/bld/wipfc/cpp/util.cpp index 7957d32f88..fd2dfc4756 100644 --- a/bld/wipfc/cpp/util.cpp +++ b/bld/wipfc/cpp/util.cpp @@ -166,12 +166,61 @@ std::string canonicalPath( char* arg ) #endif return fullpath; } + +int wtomb_char( char *mbc, wchar_t wc ) +{ + return( std::wctomb( mbc, wc ) ); +} + +int mbtow_char( wchar_t *wc, const char *mbc, std::size_t len ) +{ + return( std::mbtowc( wc, mbc, len ) ); +} + +std::size_t wtomb_cstring( char *dst_mbc, const wchar_t *src_wc, std::size_t len ) +{ + std::size_t dst_len = 0; + char mbc[MB_LEN_MAX + 1]; + int bytes; + + while( len > 0 && *src_wc != L'\0' ) { + bytes = wtomb_char( mbc, *src_wc ); + if( bytes == -1 || bytes > len ) + return( static_cast( -1 ) ); + std::memcpy( dst_mbc, mbc, bytes ); + dst_mbc += bytes; + dst_len += bytes; + len -= bytes; + src_wc++; + } + *dst_mbc = '\0'; + return( dst_len ); +} + +std::size_t mbtow_cstring( wchar_t *dst_wc, const char *src_mbc, std::size_t len ) +{ + std::size_t dst_len = 0; + int bytes; + + while( len > 0 && *src_mbc != '\0' ) { + bytes = mbtow_char( dst_wc, src_mbc, MB_LEN_MAX ); + if( bytes == -1 ) + return( static_cast( -1 ) ); + dst_wc++; + dst_len++; + len--; + src_mbc += bytes; + } + *dst_wc = L'\0'; + return( dst_len ); +} + /*****************************************************************************/ -void wtombstring( const std::wstring& input, std::string& output ) +void wtomb_string( const std::wstring& input, std::string& output ) { for( std::size_t index = 0; index < input.size(); ++index ) { char ch[ MB_LEN_MAX + 1 ]; - int bytes( std::wctomb( &ch[ 0 ], input[ index ] ) ); + int bytes( wtomb_char( &ch[ 0 ], input[ index ] ) ); if( bytes == -1 ) throw FatalError( ERR_T_CONV ); ch[ bytes ] = '\0'; @@ -179,13 +228,13 @@ void wtombstring( const std::wstring& input, std::string& output ) } } /*****************************************************************************/ -void mbtowstring( const std::string& input, std::wstring& output ) +void mbtow_string( const std::string& input, std::wstring& output ) { int consumed; for( std::size_t index = 0; index < input.size(); index += consumed ) { wchar_t wch; - consumed = std::mbtowc( &wch, input.data() + index, MB_CUR_MAX ); + consumed = mbtow_char( &wch, input.data() + index, MB_CUR_MAX ); if( consumed == -1 ) throw FatalError( ERR_T_CONV ); output += wch; diff --git a/bld/wipfc/cpp/util.hpp b/bld/wipfc/cpp/util.hpp index 08809b465e..fba095222c 100644 --- a/bld/wipfc/cpp/util.hpp +++ b/bld/wipfc/cpp/util.hpp @@ -41,8 +41,12 @@ void splitAttribute( const std::wstring& text, std::wstring& key, std::wstring& void killEOL( char * text ); void killEOL( wchar_t * text ); std::string canonicalPath( char* arg ); -void wtombstring( const std::wstring& input, std::string& output ); -void mbtowstring( const std::string& input, std::wstring& output ); +int wtomb_char( char *mbc, wchar_t wc ); +int mbtow_char( wchar_t *wc, const char *mbc, std::size_t len ); +std::size_t wtomb_cstring( char *mbc, const wchar_t *wc, std::size_t len ); +std::size_t mbtow_cstring( wchar_t *wc, const char *mbc, std::size_t len ); +void wtomb_string( const std::wstring& input, std::string& output ); +void mbtow_string( const std::string& input, std::wstring& output ); char *skipWS( char *text ); wchar_t *skipWS( wchar_t *text );