From 9a81c308f2d4217592630ef41a18a8998bd66f5c Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 6 Jan 2017 03:26:03 +0300 Subject: Add operator<<(ostream, exception) --- butl/utility.cxx | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'butl/utility.cxx') diff --git a/butl/utility.cxx b/butl/utility.cxx index d684553..d971a3f 100644 --- a/butl/utility.cxx +++ b/butl/utility.cxx @@ -2,6 +2,8 @@ // copyright : Copyright (c) 2014-2017 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file +#include + #include namespace butl @@ -22,3 +24,69 @@ namespace butl #endif } + +namespace std +{ + using namespace butl; + + ostream& + operator<< (ostream& o, const exception& e) + { + const char* d (e.what ()); + const char* s (d); + + // Strip the leading junk (colons and spaces). + // + // Note that error descriptions for ios_base::failure exceptions thrown by + // fdstream can have the ': ' prefix for libstdc++ (read more in comment + // for throw_ios_failure()). + // + for (; *s == ' ' || *s == ':'; ++s) ; + + // Strip the trailing junk (periods, spaces, newlines). + // + // Note that msvcrt adds some junk like this: + // + // Invalid data.\r\n + // + size_t n (string::traits_type::length (s)); + for (; n > 0; --n) + { + switch (s[n-1]) + { + case '\r': + case '\n': + case '.': + case ' ': continue; + } + + break; + } + + // Lower-case the first letter if the beginning looks like a word (the + // second character is the lower-case letter or space). + // + char c; + bool lc (n > 0 && alpha (c = s[0]) && c == ucase (c) && + (n == 1 || (alpha (c = s[1]) && c == lcase (c)) || c == ' ')); + + // Print the description as is if no adjustment is required. + // + if (!lc && s == d && s[n] == '\0') + o << d; + else + { + // We need to produce the resulting description and then write it + // with a single formatted output operation. + // + string r (s, n); + + if (lc) + r[0] = lcase (r[0]); + + o << r; + } + + return o; + } +} -- cgit v1.1