summaryrefslogtreecommitdiff
path: root/sbuild
diff options
context:
space:
mode:
authorRoger Leigh <rleigh@debian.org>2006-06-24 18:23:24 +0000
committerRoger Leigh <rleigh@debian.org>2006-06-24 18:23:24 +0000
commite62d95e0dc28f5218f1993096091af367a6bdab8 (patch)
treedc8d70fe948386ab67f078a57ec7b594dd4eab13 /sbuild
parent89bae29a6d45262a08f4e6cf5e97c040aba18297 (diff)
downloadschroot-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.h11
-rw-r--r--sbuild/sbuild-util.cc90
-rw-r--r--sbuild/sbuild-util.h26
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.