diff options
author | Roger Leigh <rleigh@debian.org> | 2006-06-24 18:23:24 +0000 |
---|---|---|
committer | Roger Leigh <rleigh@debian.org> | 2006-06-24 18:23:24 +0000 |
commit | e62d95e0dc28f5218f1993096091af367a6bdab8 (patch) | |
tree | dc8d70fe948386ab67f078a57ec7b594dd4eab13 /sbuild | |
parent | 89bae29a6d45262a08f4e6cf5e97c040aba18297 (diff) | |
download | schroot-e62d95e0dc28f5218f1993096091af367a6bdab8.tar.gz |
* sbuild/sbuild-format-detail.h: Use a wide string to get
consistent alignment when using a UTF-8 locale.
* sbuild/sbuild-util.cc
(widen_string): New function. Convert a narrow string to a wide
string.
(narrow_string): New function. Convert a wide string to a narrow
string.
Diffstat (limited to 'sbuild')
-rw-r--r-- | sbuild/sbuild-format-detail.h | 11 | ||||
-rw-r--r-- | sbuild/sbuild-util.cc | 90 | ||||
-rw-r--r-- | sbuild/sbuild-util.h | 26 |
3 files changed, 125 insertions, 2 deletions
diff --git a/sbuild/sbuild-format-detail.h b/sbuild/sbuild-format-detail.h index 7239624d..1c0c78f0 100644 --- a/sbuild/sbuild-format-detail.h +++ b/sbuild/sbuild-format-detail.h @@ -26,6 +26,7 @@ #include <iomanip> #include <ostream> +#include <sstream> #include <string> namespace sbuild @@ -107,9 +108,15 @@ namespace sbuild operator << (std::ostream& stream, format_detail<T> const& rhs) { - return stream << " " - << std::setw(21) << std::left << rhs.name + std::locale loc = stream.getloc(); + std::wostringstream ws; + ws.imbue(loc); + ws << L" " << + std::setw(21) << std::left << widen_string(rhs.name, loc); + + return stream << narrow_string(ws.str(), loc) << ' ' << rhs.value << '\n'; + } template<> diff --git a/sbuild/sbuild-util.cc b/sbuild/sbuild-util.cc index 58aeff51..3a4200b8 100644 --- a/sbuild/sbuild-util.cc +++ b/sbuild/sbuild-util.cc @@ -163,6 +163,96 @@ sbuild::split_string (std::string const& value, return ret; } +std::wstring +sbuild::widen_string (std::string const& str, + std::locale locale) +{ + typedef std::codecvt<wchar_t, char, mbstate_t> codecvt_type; + codecvt_type const& cvt = std::use_facet<codecvt_type>(locale); + mbstate_t state; + const char *cbegin = str.data(), *cend = str.data() + str.size(), *cnext; + wchar_t *wcnext; + wchar_t wcbuf[80]; + std::wstring ret; + + std::memset(&state, 0, sizeof(mbstate_t)); + + while (1) + { + std::codecvt_base::result res = + cvt.in(state, + cbegin, cend, cnext, + wcbuf, wcbuf + (sizeof(wcbuf) / sizeof(wcbuf[0])), wcnext); + + if (res == std::codecvt_base::ok || std::codecvt_base::partial) + { + ret += std::wstring(wcbuf, wcnext); + if (cend == cnext) + break; + } + else if (res == std::codecvt_base::noconv) + { + ret += std::wstring(cbegin, cend); + break; + } + else if (res == std::codecvt_base::error) + { + break; + } + else + break; + + cbegin = cnext; + } + + return ret; +} + +std::string +sbuild::narrow_string (std::wstring const& str, + std::locale locale) +{ + typedef std::codecvt<wchar_t, char, mbstate_t> codecvt_type; + codecvt_type const& cvt = std::use_facet<codecvt_type>(locale); + mbstate_t state; + const wchar_t *wcbegin = str.data(), *wcend = str.data() + str.size(), *wcnext; + char *cnext; + char cbuf[80]; + std::string ret; + + std::memset(&state, 0, sizeof(mbstate_t)); + + while (1) + { + std::codecvt_base::result res = + cvt.out(state, + wcbegin, wcend, wcnext, + cbuf, cbuf + (sizeof(cbuf) / sizeof(cbuf[0])), cnext); + + if (res == std::codecvt_base::ok || std::codecvt_base::partial) + { + ret += std::string(cbuf, cnext); + if (wcend == wcnext) + break; + } + else if (res == std::codecvt_base::noconv) + { + ret += std::string(wcbegin, wcend); + break; + } + else if (res == std::codecvt_base::error) + { + break; + } + else + break; + + wcbegin = wcnext; + } + + return ret; +} + std::string sbuild::find_program_in_path (std::string const& program, std::string const& path, diff --git a/sbuild/sbuild-util.h b/sbuild/sbuild-util.h index caaac966..46522aa2 100644 --- a/sbuild/sbuild-util.h +++ b/sbuild/sbuild-util.h @@ -88,6 +88,32 @@ namespace sbuild std::string const& separator); /** + * Widen a string. The narrow string is converted into a wide + * string. Note that any conversion error will cause the string to + * be clipped at the point of error. + * + * @param str the string to widen. + * @param locale the locale to use for the conversion. + * @returns a wide string. + */ + std::wstring + widen_string (std::string const& str, + std::locale locale); + + /** + * Narrow a string. The wide string is converted into a narrow + * string. Note that any conversion error will cause the string to + * be clipped at the point of error. + * + * @param str the string to narrow. + * @param locale the locale to use for the conversion. + * @returns a narrow string. + */ + std::string + narrow_string (std::wstring const& str, + std::locale locale); + + /** * Find a program in the PATH search path. * * @param program the program to search for. |