From a38ed141c1f33ecdad99b322acb1ae07b30a5da2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 18 May 2012 01:31:01 -0600 Subject: Switched to Boost.PropertyTree for XML generation --- src/account.cc | 32 ++++++++++++++ src/account.h | 3 ++ src/amount.cc | 12 +++--- src/amount.h | 4 +- src/annotate.cc | 21 ++++++++++ src/annotate.h | 29 +------------ src/balance.cc | 6 +-- src/balance.h | 2 +- src/commodity.cc | 31 ++++++-------- src/commodity.h | 4 +- src/item.cc | 14 +++++++ src/item.h | 1 + src/mask.h | 6 +-- src/post.cc | 93 +++++++++++++++-------------------------- src/post.h | 3 +- src/ptree.cc | 93 +++++++++++++++++++++++++++++++++++++++++ src/ptree.h | 98 +++++++++++++++++++++++++++++++++++++++++++ src/report.cc | 4 +- src/system.hh.in | 4 ++ src/times.h | 30 ++++++------- src/utils.h | 45 -------------------- src/value.cc | 38 +++++++---------- src/value.h | 2 +- src/views.h | 10 ++--- src/xact.cc | 58 +++++++------------------- src/xact.h | 2 +- src/xml.cc | 125 ------------------------------------------------------- src/xml.h | 98 ------------------------------------------- 28 files changed, 381 insertions(+), 487 deletions(-) create mode 100644 src/ptree.cc create mode 100644 src/ptree.h delete mode 100644 src/xml.cc delete mode 100644 src/xml.h (limited to 'src') diff --git a/src/account.cc b/src/account.cc index 1ea13330..11b918fa 100644 --- a/src/account.cc +++ b/src/account.cc @@ -690,4 +690,36 @@ void account_t::xdata_t::details_t::update(post_t& post, } } +void put_account(property_tree::ptree& pt, const account_t& acct, + function pred) +{ + if (pred(acct)) { + property_tree::ptree& st(pt.put("account", "")); + + std::ostringstream buf; + buf.width(sizeof(unsigned long) * 2); + buf.fill('0'); + buf << std::hex << reinterpret_cast(&acct); + + st.put(".id", buf.str()); + + st.put("name", acct.name); + st.put("fullname", acct.fullname()); + + value_t total = acct.amount(); + if (! total.is_null()) { + property_tree::ptree& t(st.put("account-amount", "")); + put_value(t, total); + } + total = acct.total(); + if (! total.is_null()) { + property_tree::ptree& t(st.put("account-total", "")); + put_value(t, total); + } + + foreach (const accounts_map::value_type& pair, acct.accounts) + put_account(st, *pair.second, pred); + } +} + } // namespace ledger diff --git a/src/account.h b/src/account.h index b751cb0b..1716102f 100644 --- a/src/account.h +++ b/src/account.h @@ -305,6 +305,9 @@ private: std::ostream& operator<<(std::ostream& out, const account_t& account); +void put_account(property_tree::ptree& pt, const account_t& acct, + function pred); + } // namespace ledger #endif // _ACCOUNT_H diff --git a/src/amount.cc b/src/amount.cc index 803787e8..645b244b 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -1283,17 +1283,15 @@ bool amount_t::valid() const return true; } -void to_xml(std::ostream& out, const amount_t& amt, bool commodity_details) +void put_amount(property_tree::ptree& pt, const amount_t& amt, + bool wrap, bool commodity_details) { - push_xml x(out, "amount"); + property_tree::ptree& st(wrap ? pt.put("amount", "") : pt); if (amt.has_commodity()) - to_xml(out, amt.commodity(), commodity_details); + put_commodity(st, amt.commodity(), commodity_details); - { - push_xml y(out, "quantity"); - out << y.guard(amt.quantity_string()); - } + st.put("quantity", amt.quantity_string()); } #if defined(HAVE_BOOST_SERIALIZATION) diff --git a/src/amount.h b/src/amount.h index cd77a79a..5863381b 100644 --- a/src/amount.h +++ b/src/amount.h @@ -776,8 +776,8 @@ inline std::istream& operator>>(std::istream& in, amount_t& amt) { return in; } -void to_xml(std::ostream& out, const amount_t& amt, - bool commodity_details = false); +void put_amount(property_tree::ptree& pt, const amount_t& amt, + bool wrap = true, bool commodity_details = false); } // namespace ledger diff --git a/src/annotate.cc b/src/annotate.cc index 41e7a752..b2df0d34 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -216,6 +216,27 @@ void annotation_t::print(std::ostream& out, bool keep_base, out << " ((" << *value_expr << "))"; } +void put_annotation(property_tree::ptree& pt, const annotation_t& details) +{ + property_tree::ptree& st(pt.put("annotation", "")); + + if (details.price) { + property_tree::ptree& t(st.put("price", "")); + put_amount(t, *details.price, false); + } + + if (details.date) { + property_tree::ptree& t(st.put("date", "")); + put_date(t, *details.date, false); + } + + if (details.tag) + st.put("tag", *details.tag); + + if (details.value_expr) + st.put("value_expr", details.value_expr->text()); +} + bool keep_details_t::keep_all(const commodity_t& comm) const { return (! comm.has_annotation() || diff --git a/src/annotate.h b/src/annotate.h index 37ee0685..1e62e2fa 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -124,34 +124,7 @@ private: #endif // HAVE_BOOST_SERIALIZATION }; -inline void to_xml(std::ostream& out, const annotation_t& details) -{ - push_xml x(out, "annotation"); - - if (details.price) - { - push_xml y(out, "price"); - to_xml(out, *details.price); - } - - if (details.date) - { - push_xml y(out, "date"); - to_xml(out, *details.date, false); - } - - if (details.tag) - { - push_xml y(out, "tag"); - out << y.guard(*details.tag); - } - - if (details.value_expr) - { - push_xml y(out, "value-expr"); - out << y.guard(details.value_expr->text()); - } -} +void put_annotation(property_tree::ptree& pt, const annotation_t& details); struct keep_details_t { diff --git a/src/balance.cc b/src/balance.cc index 42034ff8..d9551670 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -336,12 +336,12 @@ void balance_t::print(std::ostream& out, amount_printer.close(); } -void to_xml(std::ostream& out, const balance_t& bal) +void put_balance(property_tree::ptree& pt, const balance_t& bal) { - push_xml x(out, "balance"); + property_tree::ptree& st(pt.put("balance", "")); foreach (const balance_t::amounts_map::value_type& pair, bal.amounts) - to_xml(out, pair.second); + put_amount(st, pair.second); } } // namespace ledger diff --git a/src/balance.h b/src/balance.h index 704b4072..9a07084d 100644 --- a/src/balance.h +++ b/src/balance.h @@ -591,7 +591,7 @@ inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) { return out; } -void to_xml(std::ostream& out, const balance_t& amt); +void put_balance(property_tree::ptree& pt, const balance_t& bal); } // namespace ledger diff --git a/src/commodity.cc b/src/commodity.cc index a72d85c8..54459155 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -496,29 +496,22 @@ bool commodity_t::compare_by_commodity::operator()(const amount_t * left, } } -void to_xml(std::ostream& out, const commodity_t& comm, - bool commodity_details) +void put_commodity(property_tree::ptree& pt, const commodity_t& comm, + bool commodity_details) { - push_xml x(out, "commodity", true); + property_tree::ptree& st(pt.put("commodity", "")); - out << " flags=\""; - if (! (comm.has_flags(COMMODITY_STYLE_SUFFIXED))) out << 'P'; - if (comm.has_flags(COMMODITY_STYLE_SEPARATED)) out << 'S'; - if (comm.has_flags(COMMODITY_STYLE_THOUSANDS)) out << 'T'; - if (comm.has_flags(COMMODITY_STYLE_DECIMAL_COMMA)) out << 'D'; - out << '"'; + std::string flags; + if (! (comm.has_flags(COMMODITY_STYLE_SUFFIXED))) flags += 'P'; + if (comm.has_flags(COMMODITY_STYLE_SEPARATED)) flags += 'S'; + if (comm.has_flags(COMMODITY_STYLE_THOUSANDS)) flags += 'T'; + if (comm.has_flags(COMMODITY_STYLE_DECIMAL_COMMA)) flags += 'D'; + st.put(".flags", flags); - x.close_attrs(); + st.put("symbol", comm.symbol()); - { - push_xml y(out, "symbol"); - out << y.guard(comm.symbol()); - } - - if (commodity_details) { - if (comm.has_annotation()) - to_xml(out, as_annotated_commodity(comm).details); - } + if (commodity_details && comm.has_annotation()) + put_annotation(st, as_annotated_commodity(comm).details); } } // namespace ledger diff --git a/src/commodity.h b/src/commodity.h index bfbabe6b..82be0ee8 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -346,8 +346,8 @@ inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) { return out; } -void to_xml(std::ostream& out, const commodity_t& comm, - bool commodity_details = false); +void put_commodity(property_tree::ptree& pt, const commodity_t& comm, + bool commodity_details = false); } // namespace ledger diff --git a/src/item.cc b/src/item.cc index de5ffef2..5dc62096 100644 --- a/src/item.cc +++ b/src/item.cc @@ -581,4 +581,18 @@ string item_context(const item_t& item, const string& desc) return out.str(); } +void put_metadata(property_tree::ptree& pt, const item_t::string_map& metadata) +{ + property_tree::ptree& st(pt.put("metadata", "")); + foreach (const item_t::string_map::value_type& pair, metadata) { + if (pair.second.first) { + property_tree::ptree& vt(st.put("pair", "")); + vt.put("key", pair.first); + put_value(vt, *pair.second.first); + } else { + st.put("tag", pair.first); + } + } +} + } // namespace ledger diff --git a/src/item.h b/src/item.h index 8d9a79ee..582abc46 100644 --- a/src/item.h +++ b/src/item.h @@ -247,6 +247,7 @@ value_t get_comment(item_t& item); void print_item(std::ostream& out, const item_t& item, const string& prefix = ""); string item_context(const item_t& item, const string& desc); +void put_metadata(property_tree::ptree& pt, const item_t::string_map& metadata); } // namespace ledger diff --git a/src/mask.h b/src/mask.h index 15929b2e..78124d06 100644 --- a/src/mask.h +++ b/src/mask.h @@ -150,10 +150,8 @@ inline std::ostream& operator<<(std::ostream& out, const mask_t& mask) { return out; } -inline void to_xml(std::ostream& out, const mask_t& mask) -{ - push_xml x(out, "mask"); - out << x.guard(mask.str()); +inline void put_mask(property_tree::ptree& pt, const mask_t& mask) { + pt.put("mask", mask.str()); } } // namespace ledger diff --git a/src/post.cc b/src/post.cc index e89c0e7c..f23b81cb 100644 --- a/src/post.cc +++ b/src/post.cc @@ -696,98 +696,73 @@ void extend_post(post_t& post, journal_t& journal) } } -void to_xml(std::ostream& out, const post_t& post) +void put_post(property_tree::ptree& pt, const post_t& post) { - push_xml x(out, "posting", true); + property_tree::ptree& st(pt.put("posting", "")); if (post.state() == item_t::CLEARED) - out << " state=\"cleared\""; + st.put(".state", "cleared"); else if (post.state() == item_t::PENDING) - out << " state=\"pending\""; + st.put(".state", "pending"); if (post.has_flags(POST_VIRTUAL)) - out << " virtual=\"true\""; + st.put(".virtual", "true"); if (post.has_flags(ITEM_GENERATED)) - out << " generated=\"true\""; - - x.close_attrs(); + st.put(".generated", "true"); if (post._date) { - push_xml y(out, "date"); - to_xml(out, *post._date, false); + property_tree::ptree& t(st.put("date", "")); + put_date(t, *post._date, false); } if (post._date_aux) { - push_xml y(out, "aux-date"); - to_xml(out, *post._date_aux, false); + property_tree::ptree& t(st.put("aux-date", "")); + put_date(t, *post._date_aux, false); } if (post.account) { - push_xml y(out, "account", true); - - out << " ref=\""; - out.width(sizeof(unsigned long) * 2); - out.fill('0'); - out << std::hex << reinterpret_cast(post.account); - out << '"'; - y.close_attrs(); - - { - push_xml z(out, "name"); - out << z.guard(post.account->fullname()); - } + property_tree::ptree& t(st.put("account", "")); + + std::ostringstream buf; + buf.width(sizeof(unsigned long) * 2); + buf.fill('0'); + buf << std::hex << reinterpret_cast(post.account); + + t.put(".ref", buf.str()); + t.put("name", post.account->fullname()); } { - push_xml y(out, "post-amount"); + property_tree::ptree& t(st.put("post-amount", "")); if (post.has_xdata() && post.xdata().has_flags(POST_EXT_COMPOUND)) - to_xml(out, post.xdata().compound_value); + put_value(t, post.xdata().compound_value); else - to_xml(out, post.amount); + put_amount(t, post.amount); } if (post.cost) { - push_xml y(out, "cost"); - to_xml(out, *post.cost); + property_tree::ptree& t(st.put("cost", "")); + put_amount(t, *post.cost, false); } if (post.assigned_amount) { if (post.has_flags(POST_CALCULATED)) { - push_xml y(out, "balance-assertion"); - to_xml(out, *post.assigned_amount); + property_tree::ptree& t(st.put("balance-assertion", "")); + put_amount(t, *post.assigned_amount, false); } else { - push_xml y(out, "balance-assignment"); - to_xml(out, *post.assigned_amount); + property_tree::ptree& t(st.put("balance-assignment", "")); + put_amount(t, *post.assigned_amount, false); } } - if (post.note) { - push_xml y(out, "note"); - out << y.guard(*post.note); - } + if (post.note) + st.put("note", *post.note); - if (post.metadata) { - push_xml y(out, "metadata"); - foreach (const item_t::string_map::value_type& pair, *post.metadata) { - if (pair.second.first) { - push_xml z(out, "variable"); - { - push_xml w(out, "key"); - out << y.guard(pair.first); - } - { - push_xml w(out, "value"); - to_xml(out, *pair.second.first); - } - } else { - push_xml z(out, "tag"); - out << y.guard(pair.first); - } - } - } + if (post.metadata) + put_metadata(st, *post.metadata); if (post.xdata_ && ! post.xdata_->total.is_null()) { - push_xml y(out, "total"); - to_xml(out, post.xdata_->total); + property_tree::ptree& t(st.put("total", "")); + put_value(t, post.xdata_->total); } } diff --git a/src/post.h b/src/post.h index f4bff01f..efdd63ab 100644 --- a/src/post.h +++ b/src/post.h @@ -271,8 +271,7 @@ private: class journal_t; void extend_post(post_t& post, journal_t& journal); - -void to_xml(std::ostream& out, const post_t& post); +void put_post(property_tree::ptree& pt, const post_t& post); } // namespace ledger diff --git a/src/ptree.cc b/src/ptree.cc new file mode 100644 index 00000000..5f7b5766 --- /dev/null +++ b/src/ptree.cc @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "ptree.h" +#include "xact.h" +#include "post.h" +#include "account.h" +#include "session.h" +#include "report.h" + +namespace ledger { + +namespace { + bool account_visited_p(const account_t& acct) { + return ((acct.has_xdata() && + acct.xdata().has_flags(ACCOUNT_EXT_VISITED)) || + acct.children_with_flags(ACCOUNT_EXT_VISITED)); + } +} + +void format_ptree::flush() +{ + std::ostream& out(report.output_stream); + + property_tree::ptree pt; + + pt.put("ledger..version", VERSION); + + property_tree::ptree& ct(pt.put("ledger.commodities", "")); + foreach (const commodities_pair& pair, commodities) + put_commodity(ct, *pair.second, true); + + property_tree::ptree& at(pt.put("ledger.accounts", "")); + put_account(at, *report.session.journal->master, account_visited_p); + + property_tree::ptree& tt(pt.put("ledger.transactions", "")); + foreach (const xact_t * xact, transactions) { + put_xact(tt, *xact); + + property_tree::ptree& pt(tt.put("postings", "")); + foreach (const post_t * post, xact->posts) + if (post->has_xdata() && + post->xdata().has_flags(POST_EXT_VISITED)) + put_post(pt, *post); + } + + property_tree::write_xml(out, pt); +} + +void format_ptree::operator()(post_t& post) +{ + assert(post.xdata().has_flags(POST_EXT_VISITED)); + + commodities.insert(commodities_pair(post.amount.commodity().symbol(), + &post.amount.commodity())); + + std::pair::iterator, bool> result = + transactions_set.insert(post.xact); + if (result.second) // we haven't seen this transaction before + transactions.push_back(post.xact); +} + +} // namespace ledger diff --git a/src/ptree.h b/src/ptree.h new file mode 100644 index 00000000..d3fecc88 --- /dev/null +++ b/src/ptree.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @addtogroup report + */ + +/** + * @file ptree.h + * @author John Wiegley + * + * @ingroup report + * + * @brief Brief + * + * Long. + */ +#ifndef _PTREE_H +#define _PTREE_H + +#include "chain.h" + +namespace ledger { + +class xact_t; +class account_t; +class commodity_t; +class post_t; +class report_t; + +/** + * @brief Brief + * + * Long. + */ +class format_ptree : public item_handler +{ +protected: + report_t& report; + + typedef std::map commodities_map; + typedef std::pair commodities_pair; + + commodities_map commodities; + std::set transactions_set; + std::deque transactions; + +public: + format_ptree(report_t& _report) : report(_report) { + TRACE_CTOR(format_ptree, "report&"); + } + virtual ~format_ptree() { + TRACE_DTOR(format_ptree); + } + + virtual void flush(); + virtual void operator()(post_t& post); + + virtual void clear() { + commodities.clear(); + transactions_set.clear(); + transactions.clear(); + + item_handler::clear(); + } +}; + +} // namespace ledger + +#endif // _PTREE_H diff --git a/src/report.cc b/src/report.cc index c80a2f0f..9d417b93 100644 --- a/src/report.cc +++ b/src/report.cc @@ -46,7 +46,7 @@ #include "generate.h" #include "draft.h" #include "convert.h" -#include "xml.h" +#include "ptree.h" #include "emacs.h" #include "org.h" @@ -1649,7 +1649,7 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, if (is_eq(p, "xact")) return WRAP_FUNCTOR(xact_command); else if (is_eq(p, "xml")) - return POSTS_REPORTER(new format_xml(*this)); + return POSTS_REPORTER(new format_ptree(*this)); break; } break; diff --git a/src/system.hh.in b/src/system.hh.in index 8b8fef7f..fd019ba7 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -170,6 +170,10 @@ typedef std::ostream::pos_type ostream_pos_type; #include #include +#include +#include +#include + #include #include #include diff --git a/src/times.h b/src/times.h index 3bb95903..d6ab542d 100644 --- a/src/times.h +++ b/src/times.h @@ -111,26 +111,20 @@ std::string format_date(const date_t& when, void set_date_format(const char * format); void set_input_date_format(const char * format); -inline void to_xml(std::ostream& out, const datetime_t& when, - bool wrap = true) -{ - if (wrap) { - push_xml x(out, "datetime"); - out << format_datetime(when, FMT_WRITTEN); - } else { - out << format_datetime(when, FMT_WRITTEN); - } +inline void put_datetime(property_tree::ptree& pt, const datetime_t& when, + bool wrap = true) { + if (wrap) + pt.put("datetime", format_datetime(when, FMT_WRITTEN)); + else + pt.put_value(format_datetime(when, FMT_WRITTEN)); } -inline void to_xml(std::ostream& out, const date_t& when, - bool wrap = true) -{ - if (wrap) { - push_xml x(out, "date"); - out << format_date(when, FMT_WRITTEN); - } else { - out << format_date(when, FMT_WRITTEN); - } +inline void put_date(property_tree::ptree& pt, const date_t& when, + bool wrap = true) { + if (wrap) + pt.put("date", format_date(when, FMT_WRITTEN)); + else + pt.put_value(format_date(when, FMT_WRITTEN)); } struct date_traits_t diff --git a/src/utils.h b/src/utils.h index 34011e3f..7f5242d9 100644 --- a/src/utils.h +++ b/src/utils.h @@ -727,51 +727,6 @@ inline string sha1sum(const string& str) return to_hex(message_digest, 5); } -class push_xml -{ - std::ostream& out; - string tag; - bool leave_open; - -public: - push_xml(std::ostream& _out, const string& _tag, bool has_attrs = false, - bool _leave_open = false) - : out(_out), tag(_tag), leave_open(_leave_open) { - out << '<' << tag; - if (! has_attrs) - out << '>'; - } - ~push_xml() { - if (! leave_open) - out << "'; - } - - void close_attrs() { - out << '>'; - } - - static string guard(const string& str) { - std::ostringstream buf; - foreach (const char& ch, str) { - switch (ch) { - case '<': - buf << "<"; - break; - case '>': - buf << ">"; - break; - case '&': - buf << "&"; - break; - default: - buf << ch; - break; - } - } - return buf.str(); - } -}; - extern const string version; } // namespace ledger diff --git a/src/value.cc b/src/value.cc index b475b6a2..832460ce 100644 --- a/src/value.cc +++ b/src/value.cc @@ -2014,49 +2014,41 @@ bool sort_value_is_less_than(const std::list& left_values, return false; } -void to_xml(std::ostream& out, const value_t& value) +void put_value(property_tree::ptree& pt, const value_t& value) { switch (value.type()) { case value_t::VOID: - out << ""; + pt.put("void", ""); break; - case value_t::BOOLEAN: { - push_xml y(out, "boolean"); - out << (value.as_boolean() ? "true" : "false"); + case value_t::BOOLEAN: + pt.put("bool", value.as_boolean() ? "true" : "false"); break; - } - case value_t::INTEGER: { - push_xml y(out, "integer"); - out << value.as_long(); + case value_t::INTEGER: + pt.put("int", value.to_string()); break; - } - case value_t::AMOUNT: - to_xml(out, value.as_amount()); + put_amount(pt, value.as_amount()); break; case value_t::BALANCE: - to_xml(out, value.as_balance()); + put_balance(pt, value.as_balance()); break; - case value_t::DATETIME: - to_xml(out, value.as_datetime()); + put_datetime(pt, value.as_datetime()); break; case value_t::DATE: - to_xml(out, value.as_date()); + put_date(pt, value.as_date()); break; - case value_t::STRING: { - push_xml y(out, "string"); - out << y.guard(value.as_string()); + case value_t::STRING: + pt.put("string", value.as_string()); break; - } case value_t::MASK: - to_xml(out, value.as_mask()); + put_mask(pt, value.as_mask()); break; case value_t::SEQUENCE: { - push_xml y(out, "sequence"); + property_tree::ptree& st(pt.put("sequence", "")); foreach (const value_t& member, value.as_sequence()) - to_xml(out, member); + put_value(st, member); break; } diff --git a/src/value.h b/src/value.h index d128bb89..74c015ec 100644 --- a/src/value.h +++ b/src/value.h @@ -1016,7 +1016,7 @@ struct sort_value_t bool sort_value_is_less_than(const std::list& left_values, const std::list& right_values); -void to_xml(std::ostream& out, const value_t& value); +void put_value(property_tree::ptree& pt, const value_t& value); } // namespace ledger diff --git a/src/views.h b/src/views.h index f9a007b7..22bc1dd5 100644 --- a/src/views.h +++ b/src/views.h @@ -182,7 +182,7 @@ public: r_account_ptr create_account(account_t * account = NULL); r_account_ptr create_account(const std::string& name); - friend void to_xml(std::ostream& out, r_journal_ptr journal); + friend void put_journal(property_tree::ptree& pt, r_journal_ptr journal); }; class r_item_t : public r_base_t @@ -267,7 +267,7 @@ public: const string& name); friend class r_journal_t; - friend void to_xml(std::ostream& out, r_item_ptr item); + friend void put_item(property_tree::ptree& pt, r_item_ptr journal); }; class r_xact_t : public r_item_t @@ -315,7 +315,7 @@ public: string payee() const; friend class r_journal_t; - friend void to_xml(std::ostream& out, r_xact_ptr xact); + friend void put_xact(property_tree::ptree& pt, r_xact_ptr journal); }; class r_post_t : public r_item_t @@ -371,7 +371,7 @@ public: optional checkout() const; friend class r_journal_t; - friend void to_xml(std::ostream& out, r_post_ptr post); + friend void put_post(property_tree::ptree& pt, r_post_ptr journal); }; typedef std::map r_accounts_map; @@ -434,7 +434,7 @@ public: } friend class r_journal_t; - friend void to_xml(std::ostream& out, r_account_ptr account); + friend void put_account(property_tree::ptree& pt, r_account_ptr journal); }; template diff --git a/src/xact.cc b/src/xact.cc index 07ca7911..0e7e7e00 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -813,63 +813,37 @@ void auto_xact_t::extend_xact(xact_base_t& xact, parse_context_t& context) } } -void to_xml(std::ostream& out, const xact_t& xact) +void put_xact(property_tree::ptree& pt, const xact_t& xact) { - push_xml x(out, "transaction", true, true); + property_tree::ptree& st(pt.put("transaction", "")); if (xact.state() == item_t::CLEARED) - out << " state=\"cleared\""; + st.put(".state", "cleared"); else if (xact.state() == item_t::PENDING) - out << " state=\"pending\""; + st.put(".state", "pending"); if (xact.has_flags(ITEM_GENERATED)) - out << " generated=\"true\""; - - x.close_attrs(); + st.put(".generated", "true"); if (xact._date) { - push_xml y(out, "date"); - to_xml(out, *xact._date, false); + property_tree::ptree& t(st.put("date", "")); + put_date(t, *xact._date, false); } if (xact._date_aux) { - push_xml y(out, "aux-date"); - to_xml(out, *xact._date_aux, false); + property_tree::ptree& t(st.put("aux-date", "")); + put_date(t, *xact._date_aux, false); } - if (xact.code) { - push_xml y(out, "code"); - out << y.guard(*xact.code); - } + if (xact.code) + st.put("code", *xact.code); - { - push_xml y(out, "payee"); - out << y.guard(xact.payee); - } + st.put("payee", xact.payee); - if (xact.note) { - push_xml y(out, "note"); - out << y.guard(*xact.note); - } + if (xact.note) + st.put("note", *xact.note); - if (xact.metadata) { - push_xml y(out, "metadata"); - foreach (const item_t::string_map::value_type& pair, *xact.metadata) { - if (pair.second.first) { - push_xml z(out, "variable"); - { - push_xml w(out, "key"); - out << y.guard(pair.first); - } - { - push_xml w(out, "value"); - to_xml(out, *pair.second.first); - } - } else { - push_xml z(out, "tag"); - out << y.guard(pair.first); - } - } - } + if (xact.metadata) + put_metadata(st, *xact.metadata); } } // namespace ledger diff --git a/src/xact.h b/src/xact.h index 873c1a9e..52e434e0 100644 --- a/src/xact.h +++ b/src/xact.h @@ -304,7 +304,7 @@ typedef std::list xacts_list; typedef std::list auto_xacts_list; typedef std::list period_xacts_list; -void to_xml(std::ostream& out, const xact_t& xact); +void put_xact(property_tree::ptree& pt, const xact_t& xact); } // namespace ledger diff --git a/src/xml.cc b/src/xml.cc deleted file mode 100644 index 560db805..00000000 --- a/src/xml.cc +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2003-2012, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "xml.h" -#include "xact.h" -#include "post.h" -#include "account.h" -#include "session.h" -#include "report.h" - -namespace ledger { - -namespace { - void xml_account(std::ostream& out, const account_t * acct) { - if ((acct->has_xdata() && - acct->xdata().has_flags(ACCOUNT_EXT_VISITED)) || - acct->children_with_flags(ACCOUNT_EXT_VISITED)) { - out << "(acct); - out << "\">\n"; - - out << "" << acct->name << "\n"; - out << "" << acct->fullname() << "\n"; - value_t total = acct->amount(); - if (! total.is_null()) { - out << "\n"; - to_xml(out, total); - out << "\n"; - } - total = acct->total(); - if (! total.is_null()) { - out << "\n"; - to_xml(out, total); - out << "\n"; - } - out << "\n"; - } - - foreach (const accounts_map::value_type& pair, acct->accounts) - xml_account(out, pair.second); - } - - void xml_transaction(std::ostream& out, const xact_t * xact) { - to_xml(out, *xact); - - foreach (const post_t * post, xact->posts) - if (post->has_xdata() && - post->xdata().has_flags(POST_EXT_VISITED)) - to_xml(out, *post); - - out << "\n"; - } -} - -void format_xml::flush() -{ - std::ostream& out(report.output_stream); - - out << "\n"; - out << "\n"; - - out << "\n"; - foreach (const commodities_pair& pair, commodities) { - to_xml(out, *pair.second, true); - out << '\n'; - } - out << "\n"; - - out << "\n"; - xml_account(out, report.session.journal->master); - out << "\n"; - - out << "\n"; - foreach (const xact_t * xact, transactions) - xml_transaction(out, xact); - out << "\n"; - - out << "\n"; - out.flush(); -} - -void format_xml::operator()(post_t& post) -{ - assert(post.xdata().has_flags(POST_EXT_VISITED)); - - commodities.insert(commodities_pair(post.amount.commodity().symbol(), - &post.amount.commodity())); - - if (transactions_set.find(post.xact) == transactions_set.end()) - transactions.push_back(post.xact); -} - -} // namespace ledger diff --git a/src/xml.h b/src/xml.h deleted file mode 100644 index 871fd120..00000000 --- a/src/xml.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2003-2012, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @addtogroup report - */ - -/** - * @file xml.h - * @author John Wiegley - * - * @ingroup report - * - * @brief Brief - * - * Long. - */ -#ifndef _XML_H -#define _XML_H - -#include "chain.h" - -namespace ledger { - -class xact_t; -class account_t; -class commodity_t; -class post_t; -class report_t; - -/** - * @brief Brief - * - * Long. - */ -class format_xml : public item_handler -{ -protected: - report_t& report; - - typedef std::map commodities_map; - typedef std::pair commodities_pair; - - commodities_map commodities; - std::set transactions_set; - std::deque transactions; - -public: - format_xml(report_t& _report) : report(_report) { - TRACE_CTOR(format_xml, "report&"); - } - virtual ~format_xml() { - TRACE_DTOR(format_xml); - } - - virtual void flush(); - virtual void operator()(post_t& post); - - virtual void clear() { - commodities.clear(); - transactions_set.clear(); - transactions.clear(); - - item_handler::clear(); - } -}; - -} // namespace ledger - -#endif // _XML_H -- cgit v1.2.3