summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/account.cc10
-rw-r--r--src/account.h3
-rw-r--r--src/csv.cc2
-rw-r--r--src/journal.h22
-rw-r--r--src/option.h2
-rw-r--r--src/pstream.h3
-rw-r--r--src/pyutils.h2
-rw-r--r--src/report.h11
-rw-r--r--src/textual.cc8
-rw-r--r--src/timelog.cc2
-rw-r--r--src/timelog.h15
-rw-r--r--src/times.cc8
-rw-r--r--src/token.cc16
-rw-r--r--src/utils.cc4
-rw-r--r--src/utils.h8
15 files changed, 67 insertions, 49 deletions
diff --git a/src/account.cc b/src/account.cc
index 206e2350..1ea13330 100644
--- a/src/account.cc
+++ b/src/account.cc
@@ -309,6 +309,10 @@ namespace {
return (! account.self_details().latest_checkout.is_not_a_date_time() ?
value_t(account.self_details().latest_checkout) : NULL_VALUE);
}
+ value_t get_latest_checkout_cleared(account_t& account)
+ {
+ return account.self_details().latest_checkout_cleared;
+ }
template <value_t (*Func)(account_t&)>
value_t get_wrapper(call_scope_t& args) {
@@ -405,6 +409,8 @@ expr_t::ptr_op_t account_t::lookup(const symbol_t::kind_t kind,
return WRAP_FUNCTOR(get_wrapper<&get_latest>);
else if (fn_name == "latest_checkout")
return WRAP_FUNCTOR(get_wrapper<&get_latest_checkout>);
+ else if (fn_name == "latest_checkout_cleared")
+ return WRAP_FUNCTOR(get_wrapper<&get_latest_checkout_cleared>);
break;
case 'n':
@@ -662,8 +668,10 @@ void account_t::xdata_t::details_t::update(post_t& post,
earliest_checkin = *post.checkin;
if (post.checkout && (latest_checkout.is_not_a_date_time() ||
- *post.checkout > latest_checkout))
+ *post.checkout > latest_checkout)) {
latest_checkout = *post.checkout;
+ latest_checkout_cleared = post.state() == item_t::CLEARED;
+ }
if (post.state() == item_t::CLEARED) {
posts_cleared_count++;
diff --git a/src/account.h b/src/account.h
index c0e3e1f7..b751cb0b 100644
--- a/src/account.h
+++ b/src/account.h
@@ -51,7 +51,7 @@ class xact_t;
class post_t;
typedef std::list<post_t *> posts_list;
-typedef std::map<const string, account_t *> accounts_map;
+typedef std::map<string, account_t *> accounts_map;
class account_t : public supports_flags<>, public scope_t
{
@@ -183,6 +183,7 @@ public:
datetime_t earliest_checkin;
datetime_t latest_checkout;
+ bool latest_checkout_cleared;
std::set<path> filenames;
std::set<string> accounts_referenced;
diff --git a/src/csv.cc b/src/csv.cc
index 1e55129e..71b6516a 100644
--- a/src/csv.cc
+++ b/src/csv.cc
@@ -87,7 +87,7 @@ char * csv_reader::next_line(std::istream& in)
while (in.good() && ! in.eof() && in.peek() == '#')
in.getline(context.linebuf, parse_context_t::MAX_LINE);
- if (! in.good() || in.eof())
+ if (! in.good() || in.eof() || in.peek() == -1)
return NULL;
in.getline(context.linebuf, parse_context_t::MAX_LINE);
diff --git a/src/journal.h b/src/journal.h
index a7a84447..1f9cf3af 100644
--- a/src/journal.h
+++ b/src/journal.h
@@ -58,17 +58,17 @@ class account_t;
class parse_context_t;
class parse_context_stack_t;
-typedef std::list<xact_t *> xacts_list;
-typedef std::list<auto_xact_t *> auto_xacts_list;
-typedef std::list<period_xact_t *> period_xacts_list;
-typedef std::pair<mask_t, string> payee_mapping_t;
-typedef std::list<payee_mapping_t> payee_mappings_t;
-typedef std::pair<mask_t, account_t *> account_mapping_t;
-typedef std::list<account_mapping_t> account_mappings_t;
-typedef std::map<const string, account_t *> accounts_map;
-typedef std::map<string, xact_t *> checksum_map_t;
-typedef std::multimap<string,
- expr_t::check_expr_pair> tag_check_exprs_map;
+typedef std::list<xact_t *> xacts_list;
+typedef std::list<auto_xact_t *> auto_xacts_list;
+typedef std::list<period_xact_t *> period_xacts_list;
+typedef std::pair<mask_t, string> payee_mapping_t;
+typedef std::list<payee_mapping_t> payee_mappings_t;
+typedef std::pair<mask_t, account_t *> account_mapping_t;
+typedef std::list<account_mapping_t> account_mappings_t;
+typedef std::map<string, account_t *> accounts_map;
+typedef std::map<string, xact_t *> checksum_map_t;
+
+typedef std::multimap<string, expr_t::check_expr_pair> tag_check_exprs_map;
class journal_t : public noncopyable
{
diff --git a/src/option.h b/src/option.h
index 772f2b01..b0d4e0f0 100644
--- a/src/option.h
+++ b/src/option.h
@@ -68,7 +68,7 @@ public:
option_t(const char * _name, const char _ch = '\0')
: name(_name), name_len(std::strlen(name)), ch(_ch),
handled(false), parent(NULL), value(),
- wants_arg(name[name_len - 1] == '_') {
+ wants_arg(name_len > 0 ? name[name_len - 1] == '_' : false) {
DEBUG("option.names", "Option: " << name);
TRACE_CTOR(option_t, "const char *, const char");
}
diff --git a/src/pstream.h b/src/pstream.h
index 6e38158a..e9cddb4c 100644
--- a/src/pstream.h
+++ b/src/pstream.h
@@ -93,9 +93,6 @@ class ptristream : public std::istream
case std::ios::end:
setg(ptr, egptr()+off, ptr+len);
break;
-
- default:
- return pos_type(off_type(-1));
}
return pos_type(gptr() - ptr);
}
diff --git a/src/pyutils.h b/src/pyutils.h
index 44bb6d90..2c7dfaeb 100644
--- a/src/pyutils.h
+++ b/src/pyutils.h
@@ -180,7 +180,9 @@ namespace boost { namespace python {
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr, pytype) \
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
+#if !defined(HAVE_CPP11) && (defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(ledger::string, ::PyUnicode_FromEncodedObject(::PyString_FromString(x.c_str()), "UTF-8", NULL), &PyUnicode_Type)
+#endif
} } // namespace boost::python
diff --git a/src/report.h b/src/report.h
index e7d68dda..d04b3e15 100644
--- a/src/report.h
+++ b/src/report.h
@@ -965,10 +965,13 @@ public:
OPTION_(report_t, time_report, DO() {
OTHER(balance_format_)
.on(none,
- "%(justify(earliest_checkin ? "
- " format_datetime(earliest_checkin) : \"\", 19, -1, true)) "
- "%(justify(latest_checkout ? "
- " format_datetime(latest_checkout) : \"\", 19, -1, true)) "
+ "%(ansify_if(justify(earliest_checkin ? "
+ " format_datetime(earliest_checkin) : \"\", 19, -1, true),"
+ " bold if latest_checkout_cleared)) "
+ "%(ansify_if(justify(latest_checkout ? "
+ " format_datetime(latest_checkout) : \"\", 19, -1, true), "
+ " bold if latest_checkout_cleared)) "
+ "%(latest_checkout_cleared ? \"*\" : \" \") "
"%(ansify_if("
" justify(scrub(display_total), 8,"
" 8 + 4 + 19 * 2, true, color), bold if should_bold))"
diff --git a/src/textual.cc b/src/textual.cc
index d0e4dad2..011e45b7 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -431,7 +431,7 @@ void instance_t::read_next_directive(bool& error_flag)
#if defined(TIMELOG_SUPPORT)
-void instance_t::clock_in_directive(char * line, bool /*capitalized*/)
+void instance_t::clock_in_directive(char * line, bool capitalized)
{
string datetime(line, 2, 19);
@@ -452,7 +452,7 @@ void instance_t::clock_in_directive(char * line, bool /*capitalized*/)
position.end_line = context.linenum;
position.sequence = context.sequence++;
- time_xact_t event(position, parse_datetime(datetime),
+ time_xact_t event(position, parse_datetime(datetime), capitalized,
p ? top_account()->find_account(p) : NULL,
n ? n : "",
end ? end : "");
@@ -460,7 +460,7 @@ void instance_t::clock_in_directive(char * line, bool /*capitalized*/)
timelog.clock_in(event);
}
-void instance_t::clock_out_directive(char * line, bool /*capitalized*/)
+void instance_t::clock_out_directive(char * line, bool capitalized)
{
string datetime(line, 2, 19);
@@ -481,7 +481,7 @@ void instance_t::clock_out_directive(char * line, bool /*capitalized*/)
position.end_line = context.linenum;
position.sequence = context.sequence++;
- time_xact_t event(position, parse_datetime(datetime),
+ time_xact_t event(position, parse_datetime(datetime), capitalized,
p ? top_account()->find_account(p) : NULL,
n ? n : "",
end ? end : "");
diff --git a/src/timelog.cc b/src/timelog.cc
index e84e4188..9516ba17 100644
--- a/src/timelog.cc
+++ b/src/timelog.cc
@@ -62,7 +62,7 @@ namespace {
VERIFY(amt.valid());
post_t * post = new post_t(in_event.account, amt, POST_VIRTUAL);
- post->set_state(item_t::CLEARED);
+ post->set_state(out_event.completed ? item_t::CLEARED : item_t::UNCLEARED);
post->pos = in_event.position;
post->checkin = in_event.checkin;
post->checkout = out_event.checkin;
diff --git a/src/timelog.h b/src/timelog.h
index 857952ff..a902c084 100644
--- a/src/timelog.h
+++ b/src/timelog.h
@@ -56,6 +56,7 @@ class time_xact_t
{
public:
datetime_t checkin;
+ bool completed;
account_t * account;
string desc;
string note;
@@ -66,16 +67,18 @@ public:
}
time_xact_t(const optional<position_t>& _position,
const datetime_t& _checkin,
- account_t * _account = NULL,
- const string& _desc = "",
- const string& _note = "")
- : checkin(_checkin), account(_account), desc(_desc), note(_note),
+ const bool _completed = false,
+ account_t * _account = NULL,
+ const string& _desc = "",
+ const string& _note = "")
+ : checkin(_checkin), completed(_completed), account(_account),
+ desc(_desc), note(_note),
position(_position ? *_position : position_t()) {
TRACE_CTOR(time_xact_t,
- "position_t, datetime_t, account_t *, string, string");
+ "position_t, datetime_t, bool, account_t *, string, string");
}
time_xact_t(const time_xact_t& xact)
- : checkin(xact.checkin), account(xact.account),
+ : checkin(xact.checkin), completed(xact.completed), account(xact.account),
desc(xact.desc), note(xact.note), position(xact.position) {
TRACE_CTOR(time_xact_t, "copy");
}
diff --git a/src/times.cc b/src/times.cc
index 3c556a47..30da301f 100644
--- a/src/times.cc
+++ b/src/times.cc
@@ -48,7 +48,7 @@ namespace {
template <typename T, typename InputFacetType, typename OutputFacetType>
class temporal_io_t : public noncopyable
{
- const char * fmt_str;
+ string fmt_str;
#if defined(USE_BOOST_FACETS)
std::istringstream input_stream;
std::ostringstream output_stream;
@@ -104,7 +104,7 @@ namespace {
#else // USE_BOOST_FACETS
std::tm data(to_tm(when));
char buf[128];
- std::strftime(buf, 127, fmt_str, &data);
+ std::strftime(buf, 127, fmt_str.c_str(), &data);
return buf;
#endif // USE_BOOST_FACETS
}
@@ -138,7 +138,7 @@ namespace {
#else // USE_BOOST_FACETS
std::tm data;
std::memset(&data, 0, sizeof(std::tm));
- if (strptime(str, fmt_str, &data))
+ if (strptime(str, fmt_str.c_str(), &data))
return posix_time::ptime_from_tm(data);
else
return datetime_t();
@@ -175,7 +175,7 @@ namespace {
std::memset(&data, 0, sizeof(std::tm));
data.tm_year = CURRENT_DATE().year() - 1900;
data.tm_mday = 1; // some formats have no day
- if (strptime(str, fmt_str, &data))
+ if (strptime(str, fmt_str.c_str(), &data))
return gregorian::date_from_tm(data);
else
return date_t();
diff --git a/src/token.cc b/src/token.cc
index e5d6b218..1392c29f 100644
--- a/src/token.cc
+++ b/src/token.cc
@@ -148,7 +148,7 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags)
char c = peek_next_nonws(in);
- if (in.eof()) {
+ if (in.eof() || c == -1) {
kind = TOK_EOF;
return;
}
@@ -417,16 +417,20 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags)
if (! temp.parse(in, parse_flags.plus_flags(PARSE_SOFT_FAIL))) {
in.clear();
in.seekg(pos, std::ios::beg);
- if (in.fail())
+ if (in.fail() || ! in.good())
throw_(parse_error, _("Failed to reset input stream"));
c = static_cast<char>(in.peek());
- if (! std::isalpha(c) && c != '_')
- expected('\0', c);
+ if (c != -1) {
+ if (! std::isalpha(c) && c != '_')
+ expected('\0', c);
- parse_ident(in);
+ parse_ident(in);
+ } else {
+ throw_(parse_error, _("Unexpected EOF"));
+ }
- if (value.as_string().length() == 0) {
+ if (! value.is_string() || value.as_string().empty()) {
kind = ERROR;
symbol[0] = c;
symbol[1] = '\0';
diff --git a/src/utils.cc b/src/utils.cc
index 17118904..ada6b600 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -489,7 +489,7 @@ void report_memory(std::ostream& out, bool report_all)
namespace ledger {
-#if defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON)
+#if !defined(HAVE_CPP11) && (defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON))
string::string() : std::string() {
TRACE_CTOR(string, "");
@@ -527,7 +527,7 @@ string::~string() throw() {
TRACE_DTOR(string);
}
-#endif // defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON)
+#endif // !defined(HAVE_CPP11) && (defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON))
string empty_string("");
diff --git a/src/utils.h b/src/utils.h
index 8f11f75a..34011e3f 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -72,7 +72,7 @@
namespace ledger {
using namespace boost;
-#if defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON)
+#if !defined(HAVE_CPP11) && (defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON))
class string;
#else
typedef std::string string;
@@ -93,7 +93,7 @@ namespace ledger {
}
#if BOOST_FILESYSTEM_VERSION == 3
-#if defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON)
+#if !defined(HAVE_CPP11) && (defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON))
namespace boost { namespace filesystem3 { namespace path_traits {
template<> struct is_pathable<ledger::string> { static const bool value = true; };
}}}
@@ -193,7 +193,7 @@ void report_memory(std::ostream& out, bool report_all = false);
namespace ledger {
-#if defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON)
+#if !defined(HAVE_CPP11) && (defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON))
class string : public std::string
{
@@ -272,7 +272,7 @@ inline bool operator!=(const char* __lhs, const string& __rhs)
inline bool operator!=(const string& __lhs, const char* __rhs)
{ return __lhs.compare(__rhs) != 0; }
-#endif // defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON)
+#endif // !defined(HAVE_CPP11) && (defined(VERIFY_ON) || defined(HAVE_BOOST_PYTHON))
extern string empty_string;