# # patch "ChangeLog" # from [2948976d62b58c83f588a94d16e33f9653c9e10a] # to [c7896a6483ac1de6792a5d294401e4e9d03eaac1] # # patch "sanity.cc" # from [2396edeaed987d915d9ad8665d1c3e24534043b6] # to [941be97694585d71216f0d16c0ca6750f7101b19] # # patch "sanity.hh" # from [61c096ade1e05ddc33e77708aad6d6d74e1e2f1e] # to [41ccd55d17d0e3068dcb95388058de1b0e9e0fee] # =============================================== --- ChangeLog 2948976d62b58c83f588a94d16e33f9653c9e10a +++ ChangeLog c7896a6483ac1de6792a5d294401e4e9d03eaac1 @@ -1,5 +1,13 @@ 2005-07-24 Nathaniel Smith + * sanity.cc (log, progress, warning): Append '\n' to strings when + necessary. + (gasp): Save string properly. + (M): Apply black magic. Now works correctly. + (dump): Write newline. + +2005-07-24 Nathaniel Smith + * sanity.hh (dump): Add a default 'dump' implementation for all < #include #include +#include #include @@ -119,6 +120,8 @@ str.at(str.size() - 1) = '\n'; } copy(str.begin(), str.end(), back_inserter(logbuf)); + if (str[str.size() - 1] != '\n') + logbuf.push_back('\n'); if (debug) ui.inform(str); } @@ -147,6 +150,8 @@ str.at(str.size() - 1) = '\n'; } copy(str.begin(), str.end(), back_inserter(logbuf)); + if (str[str.size() - 1] != '\n') + logbuf.push_back('\n'); if (! quiet) ui.inform(str); } @@ -176,6 +181,8 @@ } string str2 = "warning: " + str; copy(str2.begin(), str2.end(), back_inserter(logbuf)); + if (str[str.size() - 1] != '\n') + logbuf.push_back('\n'); if (! quiet) ui.warn(str); } @@ -235,11 +242,12 @@ sanity::gasp() { L(F("saving current work set: %i items") % musings.size()); - std::ostringstream out(gasp_dump); + std::ostringstream out; out << F("Current work set: %i items\n") % musings.size(); for (std::vector::const_iterator i = musings.begin(); i != musings.end(); ++i) (*i)->gasp(out); + gasp_dump = out.str(); L(F("finished saving work set")); if (debug) { =============================================== --- sanity.hh 61c096ade1e05ddc33e77708aad6d6d74e1e2f1e +++ sanity.hh 41ccd55d17d0e3068dcb95388058de1b0e9e0fee @@ -227,17 +227,27 @@ template void Musing::gasp(std::ostream & out) const { - out << F("----------------- begin '%s' (in %s, at %s:%d) -----------------\n") % name % func % file % line; + out << F("----- begin '%s' (in %s, at %s:%d)\n") % name % func % file % line; dump(obj, out); - out << F("------------------- end '%s' (in %s, at %s:%d) -----------------\n") % name % func % file % line; + out << F("----- end '%s' (in %s, at %s:%d)\n") % name % func % file % line; } -#define M(obj) Musing(obj, #obj, __FILE__, __LINE__, __PRETTY_FUNCTION__); +// Yes, this is insane. No, it doesn't work if you do something more sane. +// ## explicitly skips macro argument expansion on the things passed to it. +// Therefore, if we simply did foo ## __LINE__, we would get foo__LINE__ in +// the output. In fact, even if we did real_M(obj, __LINE__), we would get +// foo__LINE__ in the output. (## substitutes arguments, but does not expand +// them.) However, while fake_M does nothing directly, it doesn't pass its +// line argument to ##; therefore, its line argument is fully expanded before +// being passed to real_M. +#define real_M(obj, line) Musing this_is_a_musing_fnord_object_ ## line (obj, #obj, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define fake_M(obj, line) real_M(obj, line) +#define M(obj) fake_M(obj, __LINE__) template void dump(T const & obj, std::ostream & out) { - out << obj; + out << obj << "\n"; } #endif // __SANITY_HH__