diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2017-01-06 03:26:03 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2017-01-09 21:31:14 +0300 |
commit | 9a81c308f2d4217592630ef41a18a8998bd66f5c (patch) | |
tree | e5ab252f90d1b3aa2a2f2775f0f36e569d48b4a5 /butl/utility.cxx | |
parent | 39101a4383d38c1217c44b999a6e3bd199727c60 (diff) |
Add operator<<(ostream, exception)
Diffstat (limited to 'butl/utility.cxx')
-rw-r--r-- | butl/utility.cxx | 68 |
1 files changed, 68 insertions, 0 deletions
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 <ostream> + #include <butl/utility> 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; + } +} |