summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commodity.cc4
-rw-r--r--src/derive.cc6
-rw-r--r--src/global.cc10
-rw-r--r--src/journal.cc2
-rw-r--r--src/journal.h4
-rw-r--r--src/mask.cc6
-rw-r--r--src/mask.h43
-rw-r--r--src/post.cc2
-rw-r--r--src/py_journal.cc13
-rw-r--r--src/pyinterp.cc24
-rw-r--r--src/report.cc2
-rw-r--r--src/report.h36
-rw-r--r--src/system.hh.in4
-rw-r--r--src/textual.cc17
-rw-r--r--src/unistring.h7
-rw-r--r--src/xact.cc4
16 files changed, 100 insertions, 84 deletions
diff --git a/src/commodity.cc b/src/commodity.cc
index a0827e7a..0d6c11c6 100644
--- a/src/commodity.cc
+++ b/src/commodity.cc
@@ -512,7 +512,7 @@ void commodity_t::parse_symbol(std::istream& in, string& symbol)
for (std::size_t i = 0; i < bytes; i++) {
in.get(c);
if (in.bad() || in.eof())
- break;
+ throw_(amount_error, _("Invalid UTF-8 encoding for commodity name"));
*_p++ = c;
}
}
@@ -526,7 +526,7 @@ void commodity_t::parse_symbol(std::istream& in, string& symbol)
if (c == '\\') {
in.get(c);
if (in.eof())
- break;
+ throw_(amount_error, _("Backslash at end of commodity name"));
}
*_p++ = c;
}
diff --git a/src/derive.cc b/src/derive.cc
index d3a7a37d..081b96b2 100644
--- a/src/derive.cc
+++ b/src/derive.cc
@@ -307,7 +307,7 @@ namespace {
DEBUG("derive.xact", "Setting note from match: " << *added->note);
#endif
} else {
- added->payee = tmpl.payee_mask.expr.str();
+ added->payee = tmpl.payee_mask.str();
DEBUG("derive.xact", "Setting payee from template: " << added->payee);
}
@@ -403,14 +403,14 @@ namespace {
account_t * acct = NULL;
if (! acct) {
- acct = journal.find_account_re(post.account_mask->expr.str());
+ acct = journal.find_account_re(post.account_mask->str());
#if defined(DEBUG_ON)
if (acct)
DEBUG("derive.xact", "Found account as a regular expression");
#endif
}
if (! acct) {
- acct = journal.find_account(post.account_mask->expr.str());
+ acct = journal.find_account(post.account_mask->str());
#if defined(DEBUG_ON)
if (acct)
DEBUG("derive.xact", "Found (or created) account by name");
diff --git a/src/global.cc b/src/global.cc
index 2383dd84..afc63eb0 100644
--- a/src/global.cc
+++ b/src/global.cc
@@ -469,14 +469,6 @@ void global_scope_t::normalize_report_options(const string& verb)
else if (verb == "equity") {
rep.HANDLER(equity).on_only(string("?normalize"));
}
- else if (rep.HANDLED(related)) {
- if (verb[0] == 'r') {
- rep.HANDLER(invert).on_only(string("?normalize"));
- } else {
- rep.HANDLER(subtotal).on_only(string("?normalize"));
- rep.HANDLER(related_all).on_only(string("?normalize"));
- }
- }
if (verb == "print")
rep.HANDLER(limit_).on(string("?normalize"), "actual");
@@ -538,6 +530,8 @@ void global_scope_t::normalize_report_options(const string& verb)
cols = rep.HANDLER(columns_).value.to_long();
else if (const char * columns = std::getenv("COLUMNS"))
cols = lexical_cast<long>(columns);
+ else
+ cols = 80L;
if (cols > 0) {
DEBUG("auto.columns", "cols = " << cols);
diff --git a/src/journal.cc b/src/journal.cc
index 3a4ada47..550b4f4c 100644
--- a/src/journal.cc
+++ b/src/journal.cc
@@ -83,7 +83,7 @@ journal_t::~journal_t()
void journal_t::initialize()
{
master = new account_t;
- basket = NULL;
+ bucket = NULL;
was_loaded = false;
commodity_pool.reset(new commodity_pool_t);
diff --git a/src/journal.h b/src/journal.h
index e2af0dde..ff2b5f84 100644
--- a/src/journal.h
+++ b/src/journal.h
@@ -115,7 +115,7 @@ public:
};
account_t * master;
- account_t * basket;
+ account_t * bucket;
xacts_list xacts;
auto_xacts_list auto_xacts;
period_xacts_list period_xacts;
@@ -202,7 +202,7 @@ private:
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & master;
- ar & basket;
+ ar & bucket;
ar & xacts;
ar & auto_xacts;
ar & period_xacts;
diff --git a/src/mask.cc b/src/mask.cc
index 135f6669..c1e66ced 100644
--- a/src/mask.cc
+++ b/src/mask.cc
@@ -43,7 +43,11 @@ mask_t::mask_t(const string& pat) : expr()
mask_t& mask_t::operator=(const string& pat)
{
- expr.assign(pat.c_str(), regex::perl | regex::icase);
+#if defined(HAVE_BOOST_REGEX_UNICODE)
+ expr = boost::make_u32regex(pat.c_str(), boost::regex::perl | boost::regex::icase);
+#else
+ expr.assign(pat.c_str(), boost::regex::perl | boost::regex::icase);
+#endif
VERIFY(valid());
return *this;
}
diff --git a/src/mask.h b/src/mask.h
index 32d27f42..62df9b63 100644
--- a/src/mask.h
+++ b/src/mask.h
@@ -45,6 +45,9 @@
#define _MASK_H
#include "utils.h"
+#if defined(HAVE_BOOST_REGEX_UNICODE)
+#include "unistring.h"
+#endif
namespace ledger {
@@ -56,7 +59,11 @@ namespace ledger {
class mask_t
{
public:
+#if defined(HAVE_BOOST_REGEX_UNICODE)
+ boost::u32regex expr;
+#else
boost::regex expr;
+#endif
explicit mask_t(const string& pattern);
@@ -76,17 +83,41 @@ public:
return expr == other.expr;
}
- bool match(const string& str) const {
+ bool match(const string& text) const {
+#if defined(HAVE_BOOST_REGEX_UNICODE)
DEBUG("mask.match",
- "Matching: \"" << str << "\" =~ /" << expr.str() << "/ = "
- << (boost::regex_search(str, expr) ? "true" : "false"));
- return boost::regex_search(str, expr);
+ "Matching: \"" << text << "\" =~ /" << str() << "/ = "
+ << (boost::u32regex_search(text, expr) ? "true" : "false"));
+ return boost::u32regex_search(text, expr);
+#else
+ DEBUG("mask.match",
+ "Matching: \"" << text << "\" =~ /" << str() << "/ = "
+ << (boost::regex_search(text, expr) ? "true" : "false"));
+ return boost::regex_search(text, expr);
+#endif
}
bool empty() const {
return expr.empty();
}
+ string str() const {
+ if (! empty()) {
+#if defined(HAVE_BOOST_REGEX_UNICODE)
+ assert(sizeof(boost::uint32_t) == sizeof(UChar32));
+ unistring ustr;
+ std::basic_string<UChar32> expr_str = expr.str();
+ std::copy(expr_str.begin(), expr_str.end(),
+ std::back_inserter(ustr.utf32chars));
+ return ustr.extract();
+#else
+ return expr.str();
+#endif
+ } else {
+ return empty_string;
+ }
+ }
+
bool valid() const {
if (expr.status() != 0) {
DEBUG("ledger.validate", "mask_t: expr.status() != 0");
@@ -108,7 +139,7 @@ private:
ar & temp;
*this = temp;
} else {
- temp = expr.str();
+ temp = str();
ar & temp;
}
}
@@ -116,7 +147,7 @@ private:
};
inline std::ostream& operator<<(std::ostream& out, const mask_t& mask) {
- out << mask.expr.str();
+ out << mask.str();
return out;
}
diff --git a/src/post.cc b/src/post.cc
index 4f45592f..0fd763a9 100644
--- a/src/post.cc
+++ b/src/post.cc
@@ -246,7 +246,7 @@ namespace {
if (env.value_at(0).is_string())
account = master->find_account(env.get<string>(0), false);
else if (env.value_at(0).is_mask())
- account = master->find_account_re(env.get<mask_t>(0).expr.str());
+ account = master->find_account_re(env.get<mask_t>(0).str());
} else {
account = env->reported_account();
}
diff --git a/src/py_journal.cc b/src/py_journal.cc
index 9b3e7513..17c42c21 100644
--- a/src/py_journal.cc
+++ b/src/py_journal.cc
@@ -166,6 +166,11 @@ namespace {
journal.xact_finalize_hooks.run_hooks(xact, post);
}
+ std::size_t py_read(journal_t& journal, const string& pathname)
+ {
+ return journal.read(pathname);
+ }
+
} // unnamed namespace
void export_journal()
@@ -193,10 +198,10 @@ void export_journal()
.add_property("master", make_getter(&journal_t::master,
return_internal_reference<>()))
- .add_property("basket",
- make_getter(&journal_t::basket,
+ .add_property("bucket",
+ make_getter(&journal_t::bucket,
return_internal_reference<>()),
- make_setter(&journal_t::basket))
+ make_setter(&journal_t::bucket))
.add_property("was_loaded", make_getter(&journal_t::was_loaded))
.add_property("commodity_pool",
make_getter(&journal_t::commodity_pool,
@@ -236,6 +241,8 @@ void export_journal()
.def("sources", range<return_internal_reference<> >
(&journal_t::sources_begin, &journal_t::sources_end))
+ .def("read", py_read)
+
.def("clear_xdata", &journal_t::clear_xdata)
.def("valid", &journal_t::valid)
diff --git a/src/pyinterp.cc b/src/pyinterp.cc
index 3c86ed4b..6a2dea03 100644
--- a/src/pyinterp.cc
+++ b/src/pyinterp.cc
@@ -255,12 +255,22 @@ value_t python_interpreter_t::python_command(call_scope_t& args)
std::strcpy(argv[i + 1], arg.c_str());
}
- int status = Py_Main(static_cast<int>(args.size()) + 1, argv);
+ int status;
+ try {
+ status = Py_Main(static_cast<int>(args.size()) + 1, argv);
+ }
+ catch (...) {
+ for (std::size_t i = 0; i < args.size() + 1; i++)
+ delete[] argv[i];
+ delete[] argv;
+ throw;
+ }
+
for (std::size_t i = 0; i < args.size() + 1; i++)
delete[] argv[i];
delete[] argv;
-
+
if (status != 0)
throw status;
@@ -287,6 +297,9 @@ expr_t::ptr_op_t python_interpreter_t::lookup(const symbol_t::kind_t kind,
switch (kind) {
case symbol_t::FUNCTION:
+ if (option_t<python_interpreter_t> * handler = lookup_option(name.c_str()))
+ return MAKE_OPT_FUNCTOR(python_interpreter_t, handler);
+
if (is_initialized && main_nspace.has_key(name.c_str())) {
DEBUG("python.interp", "Python lookup: " << name);
@@ -354,14 +367,7 @@ value_t python_interpreter_t::functor_t::operator()(call_scope_t& args)
std::signal(SIGINT, sigint_handler);
if (val.check())
return val();
-#if 1
- // jww (2009-02-24): Distinguish between "no return" and values with
- // unconvertable type
return NULL_VALUE;
-#else
- throw_(calc_error,
- _("Could not evaluate Python variable '%1'") << name);
-#endif
}
else if (args.size() > 0) {
list arglist;
diff --git a/src/report.cc b/src/report.cc
index 77548cce..fbe8d37c 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -322,7 +322,7 @@ value_t report_t::fn_account_total(call_scope_t& args)
acct = session.journal->find_account(name, false);
}
else if (args[0].is_mask()) {
- name = args[0].as_mask().expr.str();
+ name = args[0].as_mask().str();
acct = session.journal->find_account_re(name);
}
else {
diff --git a/src/report.h b/src/report.h
index a489ed48..08582075 100644
--- a/src/report.h
+++ b/src/report.h
@@ -869,16 +869,7 @@ public:
});
OPTION_(report_t, wide, DO() { // -w
- parent->HANDLER(date_width_).on_with(string("--wide"), 9L);
- parent->HANDLER(date_width_).specified = true;
- parent->HANDLER(payee_width_).on_with(string("--wide"), 35L);
- parent->HANDLER(payee_width_).specified = true;
- parent->HANDLER(account_width_).on_with(string("--wide"), 39L);
- parent->HANDLER(account_width_).specified = true;
- parent->HANDLER(amount_width_).on_with(string("--wide"), 22L);
- parent->HANDLER(amount_width_).specified = true;
- parent->HANDLER(total_width_).on_with(string("--wide"), 22L);
- parent->HANDLER(total_width_).specified = true;
+ parent->HANDLER(columns_).on_with(string("--wide"), 132L);
});
OPTION_(report_t, yearly, DO() { // -Y
@@ -887,38 +878,23 @@ public:
OPTION__(report_t, date_width_,
bool specified;
- CTOR(report_t, date_width_) {
- on_with(none, 9L);
- specified = false;
- }
+ CTOR(report_t, date_width_) { specified = false; }
DO_(args) { value = args[1].to_long(); specified = true; });
OPTION__(report_t, payee_width_,
bool specified;
- CTOR(report_t, payee_width_) {
- on_with(none, 20L);
- specified = false;
- }
+ CTOR(report_t, payee_width_) { specified = false; }
DO_(args) { value = args[1].to_long(); specified = true; });
OPTION__(report_t, account_width_,
bool specified;
- CTOR(report_t, account_width_) {
- on_with(none, 23L);
- specified = false;
- }
+ CTOR(report_t, account_width_) { specified = false; }
DO_(args) { value = args[1].to_long(); specified = true; });
OPTION__(report_t, amount_width_,
bool specified;
- CTOR(report_t, amount_width_) {
- on_with(none, 12L);
- specified = false;
- }
+ CTOR(report_t, amount_width_) { specified = false; }
DO_(args) { value = args[1].to_long(); specified = true; });
OPTION__(report_t, total_width_,
bool specified;
- CTOR(report_t, total_width_) {
- on_with(none, 12L);
- specified = false;
- }
+ CTOR(report_t, total_width_) { specified = false; }
DO_(args) { value = args[1].to_long(); specified = true; });
};
diff --git a/src/system.hh.in b/src/system.hh.in
index b0b8f1eb..12f257eb 100644
--- a/src/system.hh.in
+++ b/src/system.hh.in
@@ -164,7 +164,11 @@ typedef std::ostream::pos_type ostream_pos_type;
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
+#if defined(HAVE_BOOST_REGEX_UNICODE)
+#include <boost/regex/icu.hpp>
+#else
#include <boost/regex.hpp>
+#endif // HAVE_BOOST_REGEX_UNICODE
#include <boost/variant.hpp>
#include <boost/version.hpp>
diff --git a/src/textual.cc b/src/textual.cc
index 6e2c919f..8d4294a6 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -442,8 +442,8 @@ void instance_t::default_commodity_directive(char * line)
void instance_t::default_account_directive(char * line)
{
- journal.basket = account_stack.front()->find_account(skip_ws(line + 1));
- journal.basket->add_flags(ACCOUNT_KNOWN);
+ journal.bucket = account_stack.front()->find_account(skip_ws(line + 1));
+ journal.bucket->add_flags(ACCOUNT_KNOWN);
}
void instance_t::price_conversion_directive(char * line)
@@ -487,17 +487,8 @@ void instance_t::option_directive(char * line)
*p++ = '\0';
}
-#if 0
- if (! process_option(pathname.string(), line + 2, scope, p, line) &&
- ! dynamic_cast<session_t *>(&scope)) {
- if (std::strlen(line + 2) == 1)
- throw_(option_error, _("Illegal option -%1") << line + 2);
- else
- throw_(option_error, _("Illegal option --%1") << line + 2);
- }
-#else
- process_option(pathname.string(), line + 2, scope, p, line);
-#endif
+ if (! process_option(pathname.string(), line + 2, scope, p, line))
+ throw_(option_error, _("Illegal option --%1") << line + 2);
}
void instance_t::automated_xact_directive(char * line)
diff --git a/src/unistring.h b/src/unistring.h
index 268f60e3..bc55b016 100644
--- a/src/unistring.h
+++ b/src/unistring.h
@@ -59,12 +59,15 @@ namespace ledger {
*/
class unistring
{
+public:
std::vector<boost::uint32_t> utf32chars;
-public:
+ unistring() {
+ TRACE_CTOR(unistring, "");
+ }
unistring(const std::string& input)
{
- TRACE_CTOR(unistring, "");
+ TRACE_CTOR(unistring, "std::string");
const char * p = input.c_str();
std::size_t len = input.length();
diff --git a/src/xact.cc b/src/xact.cc
index 67dad155..68b607f4 100644
--- a/src/xact.cc
+++ b/src/xact.cc
@@ -156,8 +156,8 @@ bool xact_base_t::finalize()
// If there is only one post, balance against the default account if one has
// been set.
- if (journal && journal->basket && posts.size() == 1 && ! balance.is_null()) {
- null_post = new post_t(journal->basket, ITEM_GENERATED);
+ if (journal && journal->bucket && posts.size() == 1 && ! balance.is_null()) {
+ null_post = new post_t(journal->bucket, ITEM_GENERATED);
null_post->_state = (*posts.begin())->_state;
add_post(null_post);
}