From 08aa0104ef3f439b0bc9a9708d97440b4bf8b221 Mon Sep 17 00:00:00 2001 From: lmat Date: Thu, 19 Oct 2017 15:23:16 -0400 Subject: [PATCH] Change kvp string representation The nested representation was very noisy. Now, the string representation shows one line per value with the full prefix which is also more expressive than the old version. --- libgnucash/engine/kvp-frame.cpp | 27 +++++++----- libgnucash/engine/kvp-frame.hpp | 6 +++ libgnucash/engine/kvp-value.cpp | 45 ++++++++++++-------- libgnucash/engine/kvp-value.hpp | 1 + libgnucash/engine/test/utest-Transaction.cpp | 2 +- 5 files changed, 53 insertions(+), 28 deletions(-) diff --git a/libgnucash/engine/kvp-frame.cpp b/libgnucash/engine/kvp-frame.cpp index 06101352d0..13a0e4e604 100644 --- a/libgnucash/engine/kvp-frame.cpp +++ b/libgnucash/engine/kvp-frame.cpp @@ -181,23 +181,30 @@ KvpFrameImpl::set_path(Path path, KvpValue* value) noexcept std::string KvpFrameImpl::to_string() const noexcept { - std::ostringstream ret; - ret << "{\n"; + return to_string(""); +} +std::string +KvpFrameImpl::to_string(std::string const & prefix) const noexcept +{ + if (!m_valuemap.size()) + return prefix; + std::ostringstream ret; std::for_each(m_valuemap.begin(), m_valuemap.end(), - [this,&ret](const map_type::value_type &a) + [this,&ret,&prefix](const map_type::value_type &a) { - ret << " "; + std::string new_prefix {prefix}; if (a.first) - ret << a.first; - ret << " => "; + { + new_prefix += a.first; + new_prefix += "/"; + } if (a.second) - ret << a.second->to_string(); - ret << ",\n"; + ret << a.second->to_string(new_prefix) << "\n"; + else + ret << new_prefix << "(null)\n"; } ); - - ret << "}\n"; return ret.str(); } diff --git a/libgnucash/engine/kvp-frame.hpp b/libgnucash/engine/kvp-frame.hpp index e5308ec208..1af4217bf5 100644 --- a/libgnucash/engine/kvp-frame.hpp +++ b/libgnucash/engine/kvp-frame.hpp @@ -187,6 +187,12 @@ struct KvpFrameImpl * @return A std::string representing the frame and all its children. */ std::string to_string() const noexcept; + /** + * Make a string representation of the frame with the specified string + * prefixed to every item in the frame. + * @return A std::string representing all the children of the frame. + */ + std::string to_string(std::string const & prefix) const noexcept; /** * Report the keys in the immediate frame. Be sensible about using this, it * isn't a very efficient way to iterate. diff --git a/libgnucash/engine/kvp-value.cpp b/libgnucash/engine/kvp-value.cpp index 55e0e6e08f..a0329d2112 100644 --- a/libgnucash/engine/kvp-value.cpp +++ b/libgnucash/engine/kvp-value.cpp @@ -125,34 +125,32 @@ struct to_string_visitor : boost::static_visitor void operator()(int64_t val) { - output << "KVP_VALUE_GINT64(" << val << ")"; + output << val << " (64-bit int)"; } - void operator()(KvpFrame * val) + void operator()(KvpFrame* val) { - output << "KVP_VALUE_FRAME(" << val->to_string() << ")"; + output << val->to_string(); } void operator()(GDate val) { - output << "KVP_VALUE_GDATE("; output << std::setw(4) << g_date_get_year(&val) << '-'; output << std::setw(2) << g_date_get_month(&val) << '-'; - output << std::setw(2) << g_date_get_day(&val) << ')'; + output << std::setw(2) << g_date_get_day(&val); + output << " (gdate)"; } void operator()(GList * val) { output << "KVP_VALUE_GLIST("; output << "[ "; - /*Since val is passed by value, we can modify it*/ for (;val; val = val->next) { auto realvalue = static_cast(val->data); output << ' ' << realvalue->to_string() << ','; } - output << " ]"; output << ")"; } @@ -161,53 +159,66 @@ struct to_string_visitor : boost::static_visitor { char tmp1[40] {}; gnc_timespec_to_iso8601_buff (val, tmp1); - output << "KVP_VALUE_TIMESPEC(" << tmp1 << ")"; + output << tmp1 << " (timespec)"; } void operator()(gnc_numeric val) { auto tmp1 = gnc_numeric_to_string(val); - output << "KVP_VALUE_NUMERIC("; if (tmp1) { output << tmp1; g_free(tmp1); } - output << ")"; + else + { + output << "(null)"; + } + output << " (timespec)"; } void operator()(GncGUID * val) { char guidstr[GUID_ENCODING_LENGTH+1]; - output << "KVP_VALUE_GUID("; if (val) { guid_to_string_buff(val,guidstr); output << guidstr; } - output << ")"; + else + { + output << "(null)"; + } + output << " (guid)"; } void operator()(const char * val) { - output << "KVP_VALUE_STRING(" << val << ")"; + output << val << " (char *)"; } void operator()(double val) { - output << "KVP_VALUE_DOUBLE(" << val << ")"; + output << val << " (double)"; } }; std::string -KvpValueImpl::to_string() const noexcept +KvpValueImpl::to_string(std::string const & prefix) const noexcept { + if (this->datastore.type() == typeid(KvpFrame*)) + return this->get()->to_string(prefix); std::ostringstream ret; to_string_visitor visitor {ret}; boost::apply_visitor(visitor, datastore); - /*We still use g_strdup since the return value will be freed by g_free*/ - return ret.str(); + return prefix + ret.str(); +} + +std::string +KvpValueImpl::to_string() const noexcept +{ + return to_string(""); } static int diff --git a/libgnucash/engine/kvp-value.hpp b/libgnucash/engine/kvp-value.hpp index 003ee7d702..78a8eb7fa7 100644 --- a/libgnucash/engine/kvp-value.hpp +++ b/libgnucash/engine/kvp-value.hpp @@ -138,6 +138,7 @@ struct KvpValueImpl KvpValueImpl::Type get_type() const noexcept; std::string to_string() const noexcept; + std::string to_string(std::string const & prefix) const noexcept; template T get() const noexcept; diff --git a/libgnucash/engine/test/utest-Transaction.cpp b/libgnucash/engine/test/utest-Transaction.cpp index dde0a48582..a95a5acaff 100644 --- a/libgnucash/engine/test/utest-Transaction.cpp +++ b/libgnucash/engine/test/utest-Transaction.cpp @@ -885,7 +885,7 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData) xaccTransCommitEdit (clone); g_free (cleanup->msg); g_free (check->msg); - check->msg = g_strdup ("[xaccTransEqual] kvp frames differ:\n{\n notes => KVP_VALUE_STRING(Salt pork sausage),\n qux => KVP_VALUE_FRAME({\n quux => KVP_VALUE_FRAME({\n corge => KVP_VALUE_DOUBLE(654.321),\n}\n),\n}\n),\n}\n\n\nvs\n\n{\n notes => KVP_VALUE_STRING(Salt pork sausage),\n qux => KVP_VALUE_FRAME({\n quux => KVP_VALUE_FRAME({\n corge => KVP_VALUE_DOUBLE(123.456),\n}\n),\n}\n),\n}\n"); + check->msg = g_strdup ("[xaccTransEqual] kvp frames differ:\nnotes/Salt pork sausage (char *)\nqux/quux/corge/654.321 (double)\n\n\n\n\nvs\n\nnotes/Salt pork sausage (char *)\nqux/quux/corge/123.456 (double)\n\n\n"); g_assert (!xaccTransEqual (clone, txn0, TRUE, FALSE, TRUE, TRUE));