diff options
-rw-r--r-- | format.cc | 208 | ||||
-rw-r--r-- | format.h | 18 | ||||
-rw-r--r-- | xml.cc | 210 | ||||
-rw-r--r-- | xml.h | 20 |
4 files changed, 229 insertions, 227 deletions
@@ -555,203 +555,6 @@ void format_entries::operator()(transaction_t& xact) last_entry = xact.entry; } -void xml_write_amount(std::ostream& out, const amount_t& amount, - const int depth = 0) -{ - for (int i = 0; i < depth; i++) out << ' '; - out << "<amount>\n"; - - commodity_t& c = amount.commodity(); - for (int i = 0; i < depth + 2; i++) out << ' '; - out << "<commodity flags=\""; - if (! (c.flags & COMMODITY_STYLE_SUFFIXED)) out << 'P'; - if (c.flags & COMMODITY_STYLE_SEPARATED) out << 'S'; - if (c.flags & COMMODITY_STYLE_THOUSANDS) out << 'T'; - if (c.flags & COMMODITY_STYLE_EUROPEAN) out << 'E'; - out << "\">" << c.symbol << "</commodity>\n"; - - for (int i = 0; i < depth + 2; i++) out << ' '; - out << "<quantity>"; - out << amount.quantity_string() << "</quantity>\n"; - - for (int i = 0; i < depth; i++) out << ' '; - out << "</amount>\n"; -} - -void xml_write_value(std::ostream& out, const value_t& value, - const int depth = 0) -{ - balance_t * bal = NULL; - - for (int i = 0; i < depth; i++) out << ' '; - out << "<value type=\""; - switch (value.type) { - case value_t::BOOLEAN: out << "boolean"; break; - case value_t::INTEGER: out << "integer"; break; - case value_t::AMOUNT: out << "amount"; break; - case value_t::BALANCE: - case value_t::BALANCE_PAIR: out << "balance"; break; - } - out << "\">\n"; - - switch (value.type) { - case value_t::BOOLEAN: - for (int i = 0; i < depth + 2; i++) out << ' '; - out << "<boolean>" << *((bool *) value.data) << "</boolean>\n"; - break; - - case value_t::INTEGER: - for (int i = 0; i < depth + 2; i++) out << ' '; - out << "<integer>" << *((long *) value.data) << "</integer>\n"; - break; - - case value_t::AMOUNT: - xml_write_amount(out, *((amount_t *) value.data), depth + 2); - break; - - case value_t::BALANCE: - bal = (balance_t *) value.data; - // fall through... - - case value_t::BALANCE_PAIR: - if (! bal) - bal = &((balance_pair_t *) value.data)->quantity; - - for (int i = 0; i < depth + 2; i++) out << ' '; - out << "<balance>\n"; - - for (amounts_map::const_iterator i = bal->amounts.begin(); - i != bal->amounts.end(); - i++) - xml_write_amount(out, (*i).second, depth + 4); - - for (int i = 0; i < depth + 2; i++) out << ' '; - out << "</balance>\n"; - break; - - default: - assert(0); - break; - } - - for (int i = 0; i < depth; i++) out << ' '; - out << "</value>\n"; -} - -void output_xml_string(std::ostream& out, const std::string& str) -{ - for (const char * s = str.c_str(); *s; s++) { - switch (*s) { - case '<': - out << "<"; - break; - case '>': - out << "&rt;"; - break; - case '&': - out << "&"; - break; - default: - out << *s; - break; - } - } -} - -void format_xml_entries::format_last_entry() -{ - char buf[256]; - std::strftime(buf, 255, format_t::date_format.c_str(), - std::localtime(&last_entry->date)); - - output_stream << " <entry>\n" - << " <en:date>" << buf << "</en:date>\n"; - - if (last_entry->state == entry_t::CLEARED) - output_stream << " <en:cleared/>\n"; - else if (last_entry->state == entry_t::PENDING) - output_stream << " <en:pending/>\n"; - - if (! last_entry->code.empty()) { - output_stream << " <en:code>"; - output_xml_string(output_stream, last_entry->code); - output_stream << "</en:code>\n"; - } - - if (! last_entry->payee.empty()) { - output_stream << " <en:payee>"; - output_xml_string(output_stream, last_entry->payee); - output_stream << "</en:payee>\n"; - } - - bool first = true; - for (transactions_list::const_iterator i = last_entry->transactions.begin(); - i != last_entry->transactions.end(); - i++) { - if (transaction_has_xdata(**i) && - transaction_xdata_(**i).dflags & TRANSACTION_TO_DISPLAY) { - if (first) { - output_stream << " <en:transactions>\n"; - first = false; - } - - output_stream << " <transaction>\n"; - - if ((*i)->flags & TRANSACTION_VIRTUAL) - output_stream << " <tr:virtual/>\n"; - if ((*i)->flags & TRANSACTION_AUTO) - output_stream << " <tr:generated/>\n"; - - if ((*i)->account) { - std::string name = (*i)->account->fullname(); - if (name == "<Total>") - name = "[TOTAL]"; - else if (name == "<Unknown>") - name = "[UNKNOWN]"; - - output_stream << " <tr:account>"; - output_xml_string(output_stream, name); - output_stream << "</tr:account>\n"; - } - - output_stream << " <tr:amount>\n"; - if (transaction_xdata_(**i).dflags & TRANSACTION_COMPOSITE) - xml_write_value(output_stream, - transaction_xdata_(**i).composite_amount, 10); - else - xml_write_value(output_stream, value_t((*i)->amount), 10); - output_stream << " </tr:amount>\n"; - - if ((*i)->cost) { - output_stream << " <tr:cost>\n"; - xml_write_value(output_stream, value_t(*(*i)->cost), 10); - output_stream << " </tr:cost>\n"; - } - - if (! (*i)->note.empty()) { - output_stream << " <tr:note>"; - output_xml_string(output_stream, (*i)->note); - output_stream << "</tr:note>\n"; - } - - if (show_totals) { - output_stream << " <total>\n"; - xml_write_value(output_stream, transaction_xdata_(**i).total, 10); - output_stream << " </total>\n"; - } - - output_stream << " </transaction>\n"; - - transaction_xdata_(**i).dflags |= TRANSACTION_DISPLAYED; - } - } - - if (! first) - output_stream << " </en:transactions>\n"; - - output_stream << " </entry>\n"; -} - void print_entry(std::ostream& out, const entry_t& entry) { const std::string print_format @@ -965,17 +768,6 @@ void export_format() ; typedef - pystream_handler_wrap<format_xml_entries, transaction_t, bool> - format_xml_entries_wrap; - - class_< format_xml_entries_wrap, bases<item_handler<transaction_t> > > - ("FormatXmlEntries", - init<PyObject *, bool>()[with_custodian_and_ward<1, 2>()]) - .def("flush", &format_xml_entries_wrap::flush) - .def("__call__", &format_xml_entries_wrap::operator()) - ; - - typedef pystream_handler_wrap<format_account, account_t, std::string, std::string> format_account_wrap; @@ -126,24 +126,6 @@ class format_entries : public format_transactions virtual void operator()(transaction_t& xact); }; -class format_xml_entries : public format_entries -{ - bool show_totals; - public: - format_xml_entries(std::ostream& output_stream, - const bool _show_totals = false) - : format_entries(output_stream, ""), show_totals(_show_totals) { - output_stream << "<?xml version=\"1.0\"?>\n<ledger>\n"; - } - - virtual void flush() { - format_entries::flush(); - output_stream << "</ledger>" << std::endl; - } - - virtual void format_last_entry(); -}; - void print_entry(std::ostream& out, const entry_t& entry); bool disp_subaccounts_p(const account_t& account, @@ -143,7 +143,7 @@ bool xml_parser_t::test(std::istream& in) const } in.getline(buf, 255); - if (! std::strstr(buf, "<ledger>")) { + if (! std::strstr(buf, "<ledger")) { in.seekg(0, std::ios::beg); return false; } @@ -207,6 +207,203 @@ unsigned int xml_parser_t::parse(std::istream& in, return count; } +void xml_write_amount(std::ostream& out, const amount_t& amount, + const int depth = 0) +{ + for (int i = 0; i < depth; i++) out << ' '; + out << "<amount>\n"; + + commodity_t& c = amount.commodity(); + for (int i = 0; i < depth + 2; i++) out << ' '; + out << "<commodity flags=\""; + if (! (c.flags & COMMODITY_STYLE_SUFFIXED)) out << 'P'; + if (c.flags & COMMODITY_STYLE_SEPARATED) out << 'S'; + if (c.flags & COMMODITY_STYLE_THOUSANDS) out << 'T'; + if (c.flags & COMMODITY_STYLE_EUROPEAN) out << 'E'; + out << "\">" << c.symbol << "</commodity>\n"; + + for (int i = 0; i < depth + 2; i++) out << ' '; + out << "<quantity>"; + out << amount.quantity_string() << "</quantity>\n"; + + for (int i = 0; i < depth; i++) out << ' '; + out << "</amount>\n"; +} + +void xml_write_value(std::ostream& out, const value_t& value, + const int depth = 0) +{ + balance_t * bal = NULL; + + for (int i = 0; i < depth; i++) out << ' '; + out << "<value type=\""; + switch (value.type) { + case value_t::BOOLEAN: out << "boolean"; break; + case value_t::INTEGER: out << "integer"; break; + case value_t::AMOUNT: out << "amount"; break; + case value_t::BALANCE: + case value_t::BALANCE_PAIR: out << "balance"; break; + } + out << "\">\n"; + + switch (value.type) { + case value_t::BOOLEAN: + for (int i = 0; i < depth + 2; i++) out << ' '; + out << "<boolean>" << *((bool *) value.data) << "</boolean>\n"; + break; + + case value_t::INTEGER: + for (int i = 0; i < depth + 2; i++) out << ' '; + out << "<integer>" << *((long *) value.data) << "</integer>\n"; + break; + + case value_t::AMOUNT: + xml_write_amount(out, *((amount_t *) value.data), depth + 2); + break; + + case value_t::BALANCE: + bal = (balance_t *) value.data; + // fall through... + + case value_t::BALANCE_PAIR: + if (! bal) + bal = &((balance_pair_t *) value.data)->quantity; + + for (int i = 0; i < depth + 2; i++) out << ' '; + out << "<balance>\n"; + + for (amounts_map::const_iterator i = bal->amounts.begin(); + i != bal->amounts.end(); + i++) + xml_write_amount(out, (*i).second, depth + 4); + + for (int i = 0; i < depth + 2; i++) out << ' '; + out << "</balance>\n"; + break; + + default: + assert(0); + break; + } + + for (int i = 0; i < depth; i++) out << ' '; + out << "</value>\n"; +} + +void output_xml_string(std::ostream& out, const std::string& str) +{ + for (const char * s = str.c_str(); *s; s++) { + switch (*s) { + case '<': + out << "<"; + break; + case '>': + out << "&rt;"; + break; + case '&': + out << "&"; + break; + default: + out << *s; + break; + } + } +} + +void format_xml_entries::format_last_entry() +{ + char buf[256]; + std::strftime(buf, 255, format_t::date_format.c_str(), + std::localtime(&last_entry->date)); + + output_stream << " <entry>\n" + << " <en:date>" << buf << "</en:date>\n"; + + if (last_entry->state == entry_t::CLEARED) + output_stream << " <en:cleared/>\n"; + else if (last_entry->state == entry_t::PENDING) + output_stream << " <en:pending/>\n"; + + if (! last_entry->code.empty()) { + output_stream << " <en:code>"; + output_xml_string(output_stream, last_entry->code); + output_stream << "</en:code>\n"; + } + + if (! last_entry->payee.empty()) { + output_stream << " <en:payee>"; + output_xml_string(output_stream, last_entry->payee); + output_stream << "</en:payee>\n"; + } + + bool first = true; + for (transactions_list::const_iterator i = last_entry->transactions.begin(); + i != last_entry->transactions.end(); + i++) { + if (transaction_has_xdata(**i) && + transaction_xdata_(**i).dflags & TRANSACTION_TO_DISPLAY) { + if (first) { + output_stream << " <en:transactions>\n"; + first = false; + } + + output_stream << " <transaction>\n"; + + if ((*i)->flags & TRANSACTION_VIRTUAL) + output_stream << " <tr:virtual/>\n"; + if ((*i)->flags & TRANSACTION_AUTO) + output_stream << " <tr:generated/>\n"; + + if ((*i)->account) { + std::string name = (*i)->account->fullname(); + if (name == "<Total>") + name = "[TOTAL]"; + else if (name == "<Unknown>") + name = "[UNKNOWN]"; + + output_stream << " <tr:account>"; + output_xml_string(output_stream, name); + output_stream << "</tr:account>\n"; + } + + output_stream << " <tr:amount>\n"; + if (transaction_xdata_(**i).dflags & TRANSACTION_COMPOSITE) + xml_write_value(output_stream, + transaction_xdata_(**i).composite_amount, 10); + else + xml_write_value(output_stream, value_t((*i)->amount), 10); + output_stream << " </tr:amount>\n"; + + if ((*i)->cost) { + output_stream << " <tr:cost>\n"; + xml_write_value(output_stream, value_t(*(*i)->cost), 10); + output_stream << " </tr:cost>\n"; + } + + if (! (*i)->note.empty()) { + output_stream << " <tr:note>"; + output_xml_string(output_stream, (*i)->note); + output_stream << "</tr:note>\n"; + } + + if (show_totals) { + output_stream << " <total>\n"; + xml_write_value(output_stream, transaction_xdata_(**i).total, 10); + output_stream << " </total>\n"; + } + + output_stream << " </transaction>\n"; + + transaction_xdata_(**i).dflags |= TRANSACTION_DISPLAYED; + } + } + + if (! first) + output_stream << " </en:transactions>\n"; + + output_stream << " </entry>\n"; +} + } // namespace ledger #ifdef USE_BOOST_PYTHON @@ -224,6 +421,17 @@ void export_xml() { .def("test", &xml_parser_t::test) .def("parse", &xml_parser_t::parse, xml_parse_overloads()) ; + + typedef + pystream_handler_wrap<format_xml_entries, transaction_t, bool> + format_xml_entries_wrap; + + class_< format_xml_entries_wrap, bases<item_handler<transaction_t> > > + ("FormatXmlEntries", + init<PyObject *, bool>()[with_custodian_and_ward<1, 2>()]) + .def("flush", &format_xml_entries_wrap::flush) + .def("__call__", &format_xml_entries_wrap::operator()) + ; } #endif // USE_BOOST_PYTHON @@ -2,6 +2,7 @@ #define _XML_H #include "parser.h" +#include "format.h" namespace ledger { @@ -16,6 +17,25 @@ class xml_parser_t : public parser_t const std::string * original_file = NULL); }; +class format_xml_entries : public format_entries +{ + bool show_totals; + public: + format_xml_entries(std::ostream& output_stream, + const bool _show_totals = false) + : format_entries(output_stream, ""), show_totals(_show_totals) { + output_stream << "<?xml version=\"1.0\"?>\n" + << "<ledger version=\"2.0\">\n"; + } + + virtual void flush() { + format_entries::flush(); + output_stream << "</ledger>" << std::endl; + } + + virtual void format_last_entry(); +}; + } // namespace ledger #endif // _XML_H |