29 #define YUILogComponent "ncurses"
30 #include <yui/YUILog.h>
37 std::string NCstring::termEncoding(
"UTF-8" );
42 , hotp( std::wstring::npos )
49 NCstring::NCstring(
const NCstring & nstr )
57 NCstring::NCstring(
const std::wstring & widestr )
59 , hotp( std::wstring::npos )
65 NCstring::NCstring(
const std::string & str )
67 , hotp( std::wstring::npos )
69 bool ok = RecodeToWchar( str,
"UTF-8", &wstr );
73 yuiError() <<
"ERROR: RecodeToWchar() failed" << std::endl;
78 NCstring::NCstring(
const char * cstr )
80 , hotp( std::wstring::npos )
82 bool ok = RecodeToWchar( cstr,
"UTF-8", &wstr );
86 yuiError() <<
"ERROR: RecodeToWchar() failed" << std::endl;
91 std::ostream & operator<<( std::ostream & str,
const NCstring & obj )
93 return str << obj.
Str() ;
112 wstr.append( nstr.wstr );
116 static iconv_t fromwchar_cd = ( iconv_t )( -1 );
117 static std::string to_name =
"";
121 bool NCstring::RecodeFromWchar(
const std::wstring & in,
const std::string & to_encoding, std::string* out )
123 iconv_t cd = ( iconv_t )( -1 );
124 static bool complained =
false;
127 if ( in.length() == 0 )
131 if ( fromwchar_cd == ( iconv_t )( -1 )
132 || to_name != to_encoding )
134 if ( fromwchar_cd != ( iconv_t )( -1 ) )
136 iconv_close( fromwchar_cd );
139 fromwchar_cd = iconv_open( to_encoding.c_str(),
"WCHAR_T" );
143 if ( fromwchar_cd == ( iconv_t )( -1 ) )
147 yuiError() <<
"ERROR: iconv_open failed" << std::endl;
155 to_name = to_encoding;
161 size_t in_len = in.length() *
sizeof( std::wstring::value_type );
162 char* in_ptr = (
char *) in.data();
164 size_t tmp_size = ( in_len *
sizeof( char ) ) * 2;
168 char* tmp = (
char *) malloc( tmp_size +
sizeof(
char ) );
174 size_t tmp_len = tmp_size;
175 *( (
char *) tmp_ptr ) =
'\0';
177 size_t iconv_ret = iconv( cd, &in_ptr, &in_len, &tmp_ptr, &tmp_len );
179 *( (
char *) tmp_ptr ) =
'\0';
180 *out += std::string( tmp );
182 if ( iconv_ret == (
size_t )( -1 ) )
186 yuiError() <<
"ERROR iconv: " << errno << std::endl;
190 if ( errno == EINVAL || errno == EILSEQ )
195 in_ptr +=
sizeof( std::wstring::value_type );
197 in_len -=
sizeof( std::wstring::value_type );
201 while ( in_len != 0 );
208 static iconv_t towchar_cd = ( iconv_t )( -1 );
209 static std::string from_name =
"";
213 bool NCstring::RecodeToWchar(
const std::string& in,
const std::string &from_encoding, std::wstring* out )
215 iconv_t cd = ( iconv_t )( -1 );
216 static bool complained =
false;
219 if ( in.length() == 0 )
223 if ( towchar_cd == ( iconv_t )( -1 )
224 || from_name != from_encoding )
226 if ( towchar_cd != ( iconv_t )( -1 ) )
228 iconv_close( towchar_cd );
231 towchar_cd = iconv_open(
"WCHAR_T", from_encoding.c_str() );
235 if ( towchar_cd == ( iconv_t )( -1 ) )
239 yuiError() <<
"Error: RecodeToWchar iconv_open() failed" << std::endl;
247 from_name = from_encoding;
253 size_t in_len = in.length();
254 char* in_ptr =
const_cast <char*
>( in.c_str() );
256 size_t tmp_size = in_len *
sizeof( wchar_t );
257 char* tmp = (
char*) malloc( tmp_size +
sizeof(
wchar_t ) );
262 size_t tmp_len = tmp_size;
265 size_t iconv_ret = iconv( cd, &in_ptr, &in_len, &tmp_ptr, &tmp_len );
267 *( (
wchar_t *) tmp_ptr ) = L
'\0';
269 *out += std::wstring( (
wchar_t *) tmp );
271 if ( iconv_ret == (
size_t )( -1 ) )
278 yuiError() <<
"ERROR iconv: " << errno << std::endl;
282 if ( errno == EINVAL || errno == EILSEQ )
293 while ( in_len != 0 );
304 RecodeFromWchar( wstr,
"UTF-8", &utf8str );
314 hotp = std::wstring::npos;
315 const wchar_t shortcutMarker = L
'&';
316 const wchar_t replacementShortcutMarker = L
'_';
326 bool have_shortcut =
false;
327 std::wstring::size_type len = wstr.length();
329 newstr.reserve( len );
331 for (std::wstring::iterator it = wstr.begin(); it != wstr.end(); it++) {
332 if ( *it == shortcutMarker &&
333 (it + 1 != wstr.end()) ) {
337 if ( *(it+1) == shortcutMarker) {
338 newstr += shortcutMarker;
345 if ( !have_shortcut) {
346 newstr += replacementShortcutMarker;
347 have_shortcut =
true;
357 std::wstring::size_type tpos = wstr.find_first_of( replacementShortcutMarker );
359 if ( tpos != std::wstring::npos && tpos != wstr.size() - 1 )
361 size_t realpos = 0, t;
363 for ( t = 0; t < tpos; t++ )
364 realpos += wcwidth( wstr[t] );
366 wstr.erase( tpos, 1 );
377 bool NCstring::setTerminalEncoding(
const std::string & encoding )
379 if ( termEncoding != encoding )
381 yuiMilestone() <<
"Terminal encoding set to: " << encoding << std::endl;
382 termEncoding = encoding;