Merge branch 'next'
This commit is contained in:
commit
58fb654218
19 changed files with 174 additions and 137 deletions
|
|
@ -34589,18 +34589,17 @@
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1960</integer>
|
<integer>1971</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1959</integer>
|
<integer>1971</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
<string>ParseFootnotes</string>
|
|
||||||
<string>MetaData</string>
|
<string>MetaData</string>
|
||||||
<string>ParseAnnotations</string>
|
<string>ParseAnnotations</string>
|
||||||
<true/>
|
<string>ParseFootnotes</string>
|
||||||
<dict>
|
<dict>
|
||||||
<key>$class</key>
|
<key>$class</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
|
@ -34611,15 +34610,15 @@
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1961</integer>
|
<integer>1960</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1966</integer>
|
<integer>1965</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1969</integer>
|
<integer>1968</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
@ -34633,22 +34632,22 @@
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1962</integer>
|
<integer>1961</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1963</integer>
|
<integer>1962</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>NS.objects</key>
|
<key>NS.objects</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1964</integer>
|
<integer>1963</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1965</integer>
|
<integer>1964</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
@ -34666,22 +34665,22 @@
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1962</integer>
|
<integer>1961</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1963</integer>
|
<integer>1962</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>NS.objects</key>
|
<key>NS.objects</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1967</integer>
|
<integer>1966</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1968</integer>
|
<integer>1967</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
@ -34697,27 +34696,28 @@
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1962</integer>
|
<integer>1961</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1963</integer>
|
<integer>1962</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>NS.objects</key>
|
<key>NS.objects</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1970</integer>
|
<integer>1969</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CF$UID</key>
|
<key>CF$UID</key>
|
||||||
<integer>1971</integer>
|
<integer>1970</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
<string>Base Header Level</string>
|
<string>Base Header Level</string>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
|
<true/>
|
||||||
</array>
|
</array>
|
||||||
<key>$top</key>
|
<key>$top</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,8 @@
|
||||||
<true/>
|
<true/>
|
||||||
<key>inspectorIsCollapsed</key>
|
<key>inspectorIsCollapsed</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>inspectorNotesMode</key>
|
||||||
|
<integer>1</integer>
|
||||||
<key>inspectorReferencesColumns</key>
|
<key>inspectorReferencesColumns</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>order</key>
|
<key>order</key>
|
||||||
|
|
@ -160,7 +162,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>inspectorSelectedDataTab</key>
|
<key>inspectorSelectedDataTab</key>
|
||||||
<integer>0</integer>
|
<integer>2</integer>
|
||||||
<key>inspectorSplitFrames</key>
|
<key>inspectorSplitFrames</key>
|
||||||
<array>
|
<array>
|
||||||
<string>{{0, 0}, {785, 852}}</string>
|
<string>{{0, 0}, {785, 852}}</string>
|
||||||
|
|
|
||||||
|
|
@ -179,11 +179,11 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_amount(account_t& account) {
|
value_t get_amount(account_t& account) {
|
||||||
return VALUE_OR_ZERO(account.self_total());
|
return VALUE_OR_ZERO(account.amount());
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_total(account_t& account) {
|
value_t get_total(account_t& account) {
|
||||||
return VALUE_OR_ZERO(account.family_total());
|
return VALUE_OR_ZERO(account.total());
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_subcount(account_t& account) {
|
value_t get_subcount(account_t& account) {
|
||||||
|
|
@ -377,7 +377,7 @@ account_t::xdata_t::details_t::operator+=(const details_t& other)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t account_t::self_total(const optional<expr_t&>& expr) const
|
value_t account_t::amount(const optional<expr_t&>& expr) const
|
||||||
{
|
{
|
||||||
if (xdata_ && xdata_->has_flags(ACCOUNT_EXT_VISITED)) {
|
if (xdata_ && xdata_->has_flags(ACCOUNT_EXT_VISITED)) {
|
||||||
posts_list::const_iterator i;
|
posts_list::const_iterator i;
|
||||||
|
|
@ -402,19 +402,19 @@ value_t account_t::self_total(const optional<expr_t&>& expr) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t account_t::family_total(const optional<expr_t&>& expr) const
|
value_t account_t::total(const optional<expr_t&>& expr) const
|
||||||
{
|
{
|
||||||
if (! (xdata_ && xdata_->family_details.calculated)) {
|
if (! (xdata_ && xdata_->family_details.calculated)) {
|
||||||
const_cast<account_t&>(*this).xdata().family_details.calculated = true;
|
const_cast<account_t&>(*this).xdata().family_details.calculated = true;
|
||||||
|
|
||||||
value_t temp;
|
value_t temp;
|
||||||
foreach (const accounts_map::value_type& pair, accounts) {
|
foreach (const accounts_map::value_type& pair, accounts) {
|
||||||
temp = pair.second->family_total(expr);
|
temp = pair.second->total(expr);
|
||||||
if (! temp.is_null())
|
if (! temp.is_null())
|
||||||
add_or_set_value(xdata_->family_details.total, temp);
|
add_or_set_value(xdata_->family_details.total, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = self_total(expr);
|
temp = amount(expr);
|
||||||
if (! temp.is_null())
|
if (! temp.is_null())
|
||||||
add_or_set_value(xdata_->family_details.total, temp);
|
add_or_set_value(xdata_->family_details.total, temp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -222,8 +222,8 @@ public:
|
||||||
return *xdata_;
|
return *xdata_;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t self_total(const optional<expr_t&>& expr = none) const;
|
value_t amount(const optional<expr_t&>& expr = none) const;
|
||||||
value_t family_total(const optional<expr_t&>& expr = none) const;
|
value_t total(const optional<expr_t&>& expr = none) const;
|
||||||
|
|
||||||
const xdata_t::details_t& self_details(bool gather_all = true) const;
|
const xdata_t::details_t& self_details(bool gather_all = true) const;
|
||||||
const xdata_t::details_t& family_details(bool gather_all = true) const;
|
const xdata_t::details_t& family_details(bool gather_all = true) const;
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,11 @@ void balance_t::print(std::ostream& out,
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
out.width(first_width);
|
out.width(first_width);
|
||||||
out << (right_justify ? std::right : std::left) << 0;
|
if (right_justify)
|
||||||
|
out << std::right;
|
||||||
|
else
|
||||||
|
out << std::left;
|
||||||
|
out << 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,11 @@ public:
|
||||||
TRACE_DTOR(supports_flags);
|
TRACE_DTOR(supports_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supports_flags& operator=(const supports_flags& other) {
|
||||||
|
_flags = other._flags;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
flags_t flags() const {
|
flags_t flags() const {
|
||||||
return _flags;
|
return _flags;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,8 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format_t::element_t * format_t::parse_elements(const string& fmt)
|
format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
|
const optional<format_t&>& tmpl)
|
||||||
{
|
{
|
||||||
std::auto_ptr<element_t> result;
|
std::auto_ptr<element_t> result;
|
||||||
|
|
||||||
|
|
@ -101,34 +102,6 @@ format_t::element_t * format_t::parse_elements(const string& fmt)
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char * q = buf;
|
char * q = buf;
|
||||||
|
|
||||||
// The following format codes need to be implemented as functions:
|
|
||||||
//
|
|
||||||
// d: COMPLETE_DATE_STRING
|
|
||||||
// D: DATE_STRING
|
|
||||||
// S: SOURCE; break
|
|
||||||
// B: XACT_BEG_POS
|
|
||||||
// b: XACT_BEG_LINE
|
|
||||||
// E: XACT_END_POS
|
|
||||||
// e: XACT_END_LINE
|
|
||||||
// X: CLEARED
|
|
||||||
// Y: XACT_CLEARED
|
|
||||||
// C: CODE
|
|
||||||
// P: PAYEE
|
|
||||||
// W: OPT_ACCOUNT
|
|
||||||
// a: ACCOUNT_NAME
|
|
||||||
// A: ACCOUNT_FULLNAME
|
|
||||||
// t: AMOUNT
|
|
||||||
// o: OPT_AMOUNT
|
|
||||||
// T: TOTAL
|
|
||||||
// N: NOTE
|
|
||||||
// n: OPT_NOTE
|
|
||||||
// _: DEPTH_SPACER
|
|
||||||
//
|
|
||||||
// xB: POST_BEG_POS
|
|
||||||
// xb: POST_BEG_LINE
|
|
||||||
// xE: POST_END_POS
|
|
||||||
// xe: POST_END_LINE
|
|
||||||
|
|
||||||
for (const char * p = fmt.c_str(); *p; p++) {
|
for (const char * p = fmt.c_str(); *p; p++) {
|
||||||
if (*p != '%' && *p != '\\') {
|
if (*p != '%' && *p != '\\') {
|
||||||
*q++ = *p;
|
*q++ = *p;
|
||||||
|
|
@ -203,6 +176,32 @@ format_t::element_t * format_t::parse_elements(const string& fmt)
|
||||||
current->chars = "%";
|
current->chars = "%";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '$': {
|
||||||
|
if (! tmpl)
|
||||||
|
throw_(format_error, _("Prior field reference, but no template"));
|
||||||
|
|
||||||
|
p++;
|
||||||
|
if (*p == '0' || (! std::isdigit(*p) &&
|
||||||
|
*p != 'A' && *p != 'B' && *p != 'C' &&
|
||||||
|
*p != 'D' && *p != 'E' && *p != 'F'))
|
||||||
|
throw_(format_error, _("%$ field reference must be a digit from 1-9"));
|
||||||
|
|
||||||
|
unsigned int index = std::isdigit(*p) ? *p - '0' : (*p - 'A' + 10);
|
||||||
|
element_t * tmpl_elem = tmpl->elements.get();
|
||||||
|
|
||||||
|
for (unsigned int i = 1; i < index && tmpl_elem; i++) {
|
||||||
|
tmpl_elem = tmpl_elem->next.get();
|
||||||
|
while (tmpl_elem && tmpl_elem->type != element_t::EXPR)
|
||||||
|
tmpl_elem = tmpl_elem->next.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! tmpl_elem)
|
||||||
|
throw_(format_error, _("%$ reference to a non-existent prior field"));
|
||||||
|
|
||||||
|
*current = *tmpl_elem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
case '{': {
|
case '{': {
|
||||||
bool format_amount = *p == '{';
|
bool format_amount = *p == '{';
|
||||||
|
|
|
||||||
24
src/format.h
24
src/format.h
|
|
@ -61,7 +61,7 @@ DECLARE_EXCEPTION(format_error, std::runtime_error);
|
||||||
*/
|
*/
|
||||||
class format_t : public noncopyable
|
class format_t : public noncopyable
|
||||||
{
|
{
|
||||||
struct element_t : public supports_flags<>, public noncopyable
|
struct element_t : public supports_flags<>
|
||||||
{
|
{
|
||||||
#define ELEMENT_ALIGN_LEFT 0x01
|
#define ELEMENT_ALIGN_LEFT 0x01
|
||||||
|
|
||||||
|
|
@ -82,6 +82,21 @@ class format_t : public noncopyable
|
||||||
~element_t() throw() {
|
~element_t() throw() {
|
||||||
TRACE_DTOR(element_t);
|
TRACE_DTOR(element_t);
|
||||||
}
|
}
|
||||||
|
element_t(const element_t& elem) : supports_flags<>() {
|
||||||
|
*this = elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
element_t& operator=(const element_t& elem) {
|
||||||
|
if (this != &elem) {
|
||||||
|
supports_flags<>::operator=(elem);
|
||||||
|
type = elem.type;
|
||||||
|
min_width = elem.min_width;
|
||||||
|
max_width = elem.max_width;
|
||||||
|
chars = elem.chars;
|
||||||
|
expr = elem.expr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
friend inline void mark_red(std::ostream& out, const element_t * elem) {
|
friend inline void mark_red(std::ostream& out, const element_t * elem) {
|
||||||
out.setf(std::ios::left);
|
out.setf(std::ios::left);
|
||||||
|
|
@ -114,7 +129,8 @@ public:
|
||||||
static bool default_style_changed;
|
static bool default_style_changed;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static element_t * parse_elements(const string& fmt);
|
static element_t * parse_elements(const string& fmt,
|
||||||
|
const optional<format_t&>& tmpl);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
format_t() {
|
format_t() {
|
||||||
|
|
@ -128,8 +144,8 @@ public:
|
||||||
TRACE_DTOR(format_t);
|
TRACE_DTOR(format_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse(const string& _format) {
|
void parse(const string& _format, const optional<format_t&>& tmpl = none) {
|
||||||
elements.reset(parse_elements(_format));
|
elements.reset(parse_elements(_format, tmpl));
|
||||||
format_string = _format;
|
format_string = _format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -419,7 +419,9 @@ void global_scope_t::normalize_report_options(const string& verb)
|
||||||
report_t& rep(report());
|
report_t& rep(report());
|
||||||
|
|
||||||
// jww (2009-02-09): These globals are a hack, but hard to avoid.
|
// jww (2009-02-09): These globals are a hack, but hard to avoid.
|
||||||
item_t::use_effective_date = rep.HANDLED(effective);
|
item_t::use_effective_date = (rep.HANDLED(effective) &&
|
||||||
|
! rep.HANDLED(actual_dates));
|
||||||
|
|
||||||
rep.session.commodity_pool->keep_base = rep.HANDLED(base);
|
rep.session.commodity_pool->keep_base = rep.HANDLED(base);
|
||||||
rep.session.commodity_pool->get_quotes = rep.session.HANDLED(download);
|
rep.session.commodity_pool->get_quotes = rep.session.HANDLED(download);
|
||||||
|
|
||||||
|
|
@ -432,12 +434,10 @@ void global_scope_t::normalize_report_options(const string& verb)
|
||||||
else
|
else
|
||||||
rep.session.commodity_pool->price_db = none;
|
rep.session.commodity_pool->price_db = none;
|
||||||
|
|
||||||
if (rep.HANDLED(date_format_)) {
|
if (rep.HANDLED(date_format_))
|
||||||
set_date_format(rep.HANDLER(date_format_).str().c_str());
|
set_date_format(rep.HANDLER(date_format_).str().c_str());
|
||||||
}
|
if (rep.HANDLED(datetime_format_))
|
||||||
if (rep.HANDLED(datetime_format_)) {
|
|
||||||
set_datetime_format(rep.HANDLER(datetime_format_).str().c_str());
|
set_datetime_format(rep.HANDLER(datetime_format_).str().c_str());
|
||||||
}
|
|
||||||
if (rep.HANDLED(start_of_week_)) {
|
if (rep.HANDLED(start_of_week_)) {
|
||||||
if (optional<date_time::weekdays> weekday =
|
if (optional<date_time::weekdays> weekday =
|
||||||
string_to_day_of_week(rep.HANDLER(start_of_week_).str()))
|
string_to_day_of_week(rep.HANDLER(start_of_week_).str()))
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,10 @@ format_posts::format_posts(report_t& _report,
|
||||||
first_line_format.parse(string(f, 0, p - f));
|
first_line_format.parse(string(f, 0, p - f));
|
||||||
const char * n = p + 2;
|
const char * n = p + 2;
|
||||||
if (const char * p = std::strstr(n, "%/")) {
|
if (const char * p = std::strstr(n, "%/")) {
|
||||||
next_lines_format.parse(string(n, 0, p - n));
|
next_lines_format.parse(string(n, 0, p - n), first_line_format);
|
||||||
between_format.parse(string(p + 2));
|
between_format.parse(string(p + 2), first_line_format);
|
||||||
} else {
|
} else {
|
||||||
next_lines_format.parse(n);
|
next_lines_format.parse(n, first_line_format);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
first_line_format.parse(format);
|
first_line_format.parse(format);
|
||||||
|
|
@ -125,14 +125,14 @@ format_accounts::format_accounts(report_t& _report,
|
||||||
account_line_format.parse(string(f, 0, p - f));
|
account_line_format.parse(string(f, 0, p - f));
|
||||||
const char * n = p + 2;
|
const char * n = p + 2;
|
||||||
if (const char * p = std::strstr(n, "%/")) {
|
if (const char * p = std::strstr(n, "%/")) {
|
||||||
total_line_format.parse(string(n, 0, p - n));
|
total_line_format.parse(string(n, 0, p - n), account_line_format);
|
||||||
separator_format.parse(string(p + 2));
|
separator_format.parse(string(p + 2), account_line_format);
|
||||||
} else {
|
} else {
|
||||||
total_line_format.parse(n);
|
total_line_format.parse(n, account_line_format);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
account_line_format.parse(format);
|
account_line_format.parse(format);
|
||||||
total_line_format.parse(format);
|
total_line_format.parse(format, account_line_format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,7 @@ namespace {
|
||||||
|
|
||||||
DEBUG("post.account_amount", "Found account: " << account->fullname());
|
DEBUG("post.account_amount", "Found account: " << account->fullname());
|
||||||
|
|
||||||
value_t total = account->self_total();
|
value_t total = account->amount();
|
||||||
if (total.is_null())
|
if (total.is_null())
|
||||||
return 0L;
|
return 0L;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -225,16 +225,13 @@ value_t report_t::fn_truncated(call_scope_t& scope)
|
||||||
|
|
||||||
value_t report_t::fn_justify(call_scope_t& scope)
|
value_t report_t::fn_justify(call_scope_t& scope)
|
||||||
{
|
{
|
||||||
interactive_t args(scope, "vl&lbbs");
|
interactive_t args(scope, "vl&lbb");
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
args.value_at(0)
|
args.value_at(0)
|
||||||
.print(out, args.get<int>(1),
|
.print(out, args.get<int>(1),
|
||||||
args.has(2) ? args.get<int>(2) : -1,
|
args.has(2) ? args.get<int>(2) : -1,
|
||||||
args.has(3) ? args.get<bool>(3) : false,
|
args.has(3) ? args.get<bool>(3) : false,
|
||||||
args.has(4) ? args.get<bool>(4) : false,
|
args.has(4) ? args.get<bool>(4) : false);
|
||||||
args.has(5) ? args.get<string>(5) :
|
|
||||||
(HANDLED(date_format_) ?
|
|
||||||
HANDLER(date_format_).str() : optional<string>()));
|
|
||||||
return string_value(out.str());
|
return string_value(out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -506,6 +503,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
|
||||||
OPT(abbrev_len_);
|
OPT(abbrev_len_);
|
||||||
else OPT(account_);
|
else OPT(account_);
|
||||||
else OPT(actual);
|
else OPT(actual);
|
||||||
|
else OPT(actual_dates);
|
||||||
else OPT(add_budget);
|
else OPT(add_budget);
|
||||||
else OPT(amount_);
|
else OPT(amount_);
|
||||||
else OPT(amount_data);
|
else OPT(amount_data);
|
||||||
|
|
@ -592,6 +590,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
|
||||||
OPT_CH(collapse);
|
OPT_CH(collapse);
|
||||||
else OPT(no_color);
|
else OPT(no_color);
|
||||||
else OPT(no_total);
|
else OPT(no_total);
|
||||||
|
else OPT(now_);
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
OPT(only_);
|
OPT(only_);
|
||||||
|
|
|
||||||
59
src/report.h
59
src/report.h
|
|
@ -196,6 +196,7 @@ public:
|
||||||
HANDLER(abbrev_len_).report(out);
|
HANDLER(abbrev_len_).report(out);
|
||||||
HANDLER(account_).report(out);
|
HANDLER(account_).report(out);
|
||||||
HANDLER(actual).report(out);
|
HANDLER(actual).report(out);
|
||||||
|
HANDLER(actual_dates).report(out);
|
||||||
HANDLER(add_budget).report(out);
|
HANDLER(add_budget).report(out);
|
||||||
HANDLER(amount_).report(out);
|
HANDLER(amount_).report(out);
|
||||||
HANDLER(amount_data).report(out);
|
HANDLER(amount_data).report(out);
|
||||||
|
|
@ -250,6 +251,7 @@ public:
|
||||||
HANDLER(market).report(out);
|
HANDLER(market).report(out);
|
||||||
HANDLER(monthly).report(out);
|
HANDLER(monthly).report(out);
|
||||||
HANDLER(no_total).report(out);
|
HANDLER(no_total).report(out);
|
||||||
|
HANDLER(now_).report(out);
|
||||||
HANDLER(only_).report(out);
|
HANDLER(only_).report(out);
|
||||||
HANDLER(output_).report(out);
|
HANDLER(output_).report(out);
|
||||||
HANDLER(pager_).report(out);
|
HANDLER(pager_).report(out);
|
||||||
|
|
@ -316,6 +318,8 @@ public:
|
||||||
parent->HANDLER(limit_).on(string("--actual"), "actual");
|
parent->HANDLER(limit_).on(string("--actual"), "actual");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
OPTION(report_t, actual_dates);
|
||||||
|
|
||||||
OPTION_(report_t, add_budget, DO() {
|
OPTION_(report_t, add_budget, DO() {
|
||||||
parent->budget_flags |= BUDGET_BUDGETED | BUDGET_UNBUDGETED;
|
parent->budget_flags |= BUDGET_BUDGETED | BUDGET_UNBUDGETED;
|
||||||
});
|
});
|
||||||
|
|
@ -347,7 +351,7 @@ public:
|
||||||
"%(justify(scrub(display_total), 20, -1, true, color))"
|
"%(justify(scrub(display_total), 20, -1, true, color))"
|
||||||
" %(!options.flat ? depth_spacer : \"\")"
|
" %(!options.flat ? depth_spacer : \"\")"
|
||||||
"%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
|
"%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
|
||||||
"%(justify(scrub(display_total), 20, -1, true, color))\n%/"
|
"%$1\n%/"
|
||||||
"--------------------\n");
|
"--------------------\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -377,16 +381,22 @@ public:
|
||||||
OPTION__(report_t, budget_format_, CTOR(report_t, budget_format_) {
|
OPTION__(report_t, budget_format_, CTOR(report_t, budget_format_) {
|
||||||
on(none,
|
on(none,
|
||||||
"%(justify(scrub(get_at(total_expr, 0)), 12, -1, true, color))"
|
"%(justify(scrub(get_at(total_expr, 0)), 12, -1, true, color))"
|
||||||
" %(justify(scrub(- get_at(total_expr, 1)), 12, -1, true, color))"
|
" %(justify(scrub(- get_at(total_expr, 1)), 12, "
|
||||||
" %(justify(scrub(get_at(total_expr, 1) + get_at(total_expr, 0)), 12, -1, true, color))"
|
" 12 + 1 + 12, true, color))"
|
||||||
" %(justify(scrub((100% * get_at(total_expr, 0)) / - get_at(total_expr, 1)), 5, -1, true, color))"
|
" %(justify(scrub(get_at(total_expr, 1) + "
|
||||||
|
" get_at(total_expr, 0)), 12, "
|
||||||
|
" 12 + 1 + 12 + 1 + 12, true, color))"
|
||||||
|
" %(ansify_if("
|
||||||
|
" justify((get_at(total_expr, 1) ? "
|
||||||
|
" scrub((100% * get_at(total_expr, 0)) / "
|
||||||
|
" - get_at(total_expr, 1)) : 0), "
|
||||||
|
" 5, -1, true, false),"
|
||||||
|
" magenta if (color and get_at(total_expr, 1) and "
|
||||||
|
" (abs(quantity(get_at(total_expr, 0)) / "
|
||||||
|
" quantity(get_at(total_expr, 1))) >= 1))))"
|
||||||
" %(!options.flat ? depth_spacer : \"\")"
|
" %(!options.flat ? depth_spacer : \"\")"
|
||||||
"%-(ansify_if(partial_account(options.flat), blue if color))\n"
|
"%-(ansify_if(partial_account(options.flat), blue if color))\n"
|
||||||
"%/"
|
"%/%$1 %$2 %$3 %$4\n%/"
|
||||||
"%(justify(scrub(get_at(total_expr, 0)), 12, -1, true, color))"
|
|
||||||
" %(justify(scrub(- get_at(total_expr, 1)), 12, -1, true, color))"
|
|
||||||
" %(justify(scrub(get_at(total_expr, 1) + get_at(total_expr, 0)), 12, -1, true, color))"
|
|
||||||
" %(justify(scrub((100% * get_at(total_expr, 0)) / - get_at(total_expr, 1)), 5, -1, true, color))\n%/"
|
|
||||||
"------------ ------------ ------------ -----\n");
|
"------------ ------------ ------------ -----\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -403,9 +413,7 @@ public:
|
||||||
" %(latest_cleared ? format_date(latest_cleared) : \" \")"
|
" %(latest_cleared ? format_date(latest_cleared) : \" \")"
|
||||||
" %(!options.flat ? depth_spacer : \"\")"
|
" %(!options.flat ? depth_spacer : \"\")"
|
||||||
"%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
|
"%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
|
||||||
"%(justify(scrub(get_at(total_expr, 0)), 16, -1, true, color))"
|
"%$1 %$2 %$3\n%/"
|
||||||
" %(justify(scrub(get_at(total_expr, 1)), 16, -1, true, color))"
|
|
||||||
" %(latest_cleared ? format_date(latest_cleared) : \" \")\n%/"
|
|
||||||
"---------------- ---------------- ---------\n");
|
"---------------- ---------------- ---------\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -598,6 +606,15 @@ public:
|
||||||
|
|
||||||
OPTION(report_t, no_total);
|
OPTION(report_t, no_total);
|
||||||
|
|
||||||
|
OPTION_(report_t, now_, DO_(args) {
|
||||||
|
date_interval_t interval(args[1].to_string());
|
||||||
|
if (! interval.start)
|
||||||
|
throw_(std::invalid_argument,
|
||||||
|
_("Could not determine beginning of period '%1'")
|
||||||
|
<< args[1].to_string());
|
||||||
|
ledger::epoch = datetime_t(*interval.start);
|
||||||
|
});
|
||||||
|
|
||||||
OPTION__
|
OPTION__
|
||||||
(report_t, only_,
|
(report_t, only_,
|
||||||
CTOR(report_t, only_) {}
|
CTOR(report_t, only_) {}
|
||||||
|
|
@ -678,13 +695,7 @@ public:
|
||||||
"%(has_cost & !cost_calculated ?"
|
"%(has_cost & !cost_calculated ?"
|
||||||
" \" @ \" + justify(scrub(abs(cost / amount)), 0) : \"\")"
|
" \" @ \" + justify(scrub(abs(cost / amount)), 0) : \"\")"
|
||||||
"%(comment)\n%/"
|
"%(comment)\n%/"
|
||||||
" %(xact.uncleared ?"
|
" %$7%$8 %$9%$A%$B\n%/\n");
|
||||||
" (cleared ? \"* \" : (pending ? \"! \" : \"\")) : \"\")"
|
|
||||||
"%-34(account)"
|
|
||||||
" %12(calculated ? \"\" : justify(scrub(amount), 12, -1, true))"
|
|
||||||
"%(has_cost & !cost_calculated ?"
|
|
||||||
" \" @ \" + justify(scrub(abs(cost / amount)), 0) : \"\")"
|
|
||||||
"%(comment)\n%/\n");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, quantity, DO() { // -O
|
OPTION_(report_t, quantity, DO() { // -O
|
||||||
|
|
@ -717,15 +728,7 @@ public:
|
||||||
" %(justify(scrub(display_total), total_width, "
|
" %(justify(scrub(display_total), total_width, "
|
||||||
" 4 + date_width + payee_width + account_width + amount_width "
|
" 4 + date_width + payee_width + account_width + amount_width "
|
||||||
" + total_width, true, color))\n%/"
|
" + total_width, true, color))\n%/"
|
||||||
"%(justify(\" \", 2 + date_width + payee_width))"
|
"%(justify(\" \", 2 + date_width + payee_width))%$3 %$4 %$5\n");
|
||||||
"%(ansify_if(justify(truncated(account, account_width, abbrev_len), "
|
|
||||||
" account_width), blue if color))"
|
|
||||||
" %(justify(scrub(display_amount), amount_width, "
|
|
||||||
" 3 + date_width + payee_width + account_width + amount_width, "
|
|
||||||
" true, color))"
|
|
||||||
" %(justify(scrub(display_total), total_width, "
|
|
||||||
" 4 + date_width + payee_width + account_width + amount_width "
|
|
||||||
" + total_width, true, color))\n");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, related); // -r
|
OPTION(report_t, related); // -r
|
||||||
|
|
|
||||||
|
|
@ -981,7 +981,7 @@ post_t * instance_t::parse_post(char * line,
|
||||||
<< "POST assign: parsed amt = " << *post->assigned_amount);
|
<< "POST assign: parsed amt = " << *post->assigned_amount);
|
||||||
|
|
||||||
amount_t& amt(*post->assigned_amount);
|
amount_t& amt(*post->assigned_amount);
|
||||||
value_t account_total(post->account->self_total(false)
|
value_t account_total(post->account->amount(false)
|
||||||
.strip_annotations(keep_details_t()));
|
.strip_annotations(keep_details_t()));
|
||||||
|
|
||||||
DEBUG("post.assign",
|
DEBUG("post.assign",
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
optional<datetime_t> epoch;
|
||||||
|
|
||||||
date_time::weekdays start_of_week = gregorian::Sunday;
|
date_time::weekdays start_of_week = gregorian::Sunday;
|
||||||
|
|
||||||
//#define USE_BOOST_FACETS 1
|
//#define USE_BOOST_FACETS 1
|
||||||
|
|
|
||||||
11
src/times.h
11
src/times.h
|
|
@ -66,12 +66,17 @@ inline bool is_valid(const date_t& moment) {
|
||||||
return ! moment.is_not_a_date();
|
return ! moment.is_not_a_date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern optional<datetime_t> epoch;
|
||||||
|
|
||||||
#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
|
#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
|
||||||
#define CURRENT_TIME() boost::posix_time::microsec_clock::universal_time()
|
#define CURRENT_TIME() \
|
||||||
|
(epoch ? *epoch : boost::posix_time::microsec_clock::universal_time())
|
||||||
#else
|
#else
|
||||||
#define CURRENT_TIME() boost::posix_time::second_clock::universal_time()
|
#define CURRENT_TIME() \
|
||||||
|
(epoch ? *epoch : boost::posix_time::second_clock::universal_time())
|
||||||
#endif
|
#endif
|
||||||
#define CURRENT_DATE() boost::gregorian::day_clock::universal_day()
|
#define CURRENT_DATE() \
|
||||||
|
(epoch ? epoch->date() : boost::gregorian::day_clock::universal_day())
|
||||||
|
|
||||||
extern date_time::weekdays start_of_week;
|
extern date_time::weekdays start_of_week;
|
||||||
|
|
||||||
|
|
|
||||||
35
src/value.cc
35
src/value.cc
|
|
@ -658,7 +658,18 @@ value_t& value_t::operator/=(const value_t& val)
|
||||||
return *this;
|
return *this;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
if (val.as_balance().single_amount()) {
|
if (val.as_balance().single_amount()) {
|
||||||
as_amount_lval() /= val.simplified().as_amount();
|
value_t simpler(val.simplified());
|
||||||
|
switch (simpler.type()) {
|
||||||
|
case INTEGER:
|
||||||
|
as_amount_lval() /= simpler.as_long();
|
||||||
|
break;
|
||||||
|
case AMOUNT:
|
||||||
|
as_amount_lval() /= simpler.as_amount();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -1490,8 +1501,7 @@ void value_t::print(std::ostream& out,
|
||||||
const int first_width,
|
const int first_width,
|
||||||
const int latter_width,
|
const int latter_width,
|
||||||
const bool right_justify,
|
const bool right_justify,
|
||||||
const bool colorize,
|
const bool colorize) const
|
||||||
const optional<string>& date_format) const
|
|
||||||
{
|
{
|
||||||
if (first_width > 0 &&
|
if (first_width > 0 &&
|
||||||
(! is_amount() || as_amount().is_zero()) &&
|
(! is_amount() || as_amount().is_zero()) &&
|
||||||
|
|
@ -1514,17 +1524,10 @@ void value_t::print(std::ostream& out,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DATETIME:
|
case DATETIME:
|
||||||
if (date_format)
|
|
||||||
out << format_datetime(as_datetime(), FMT_CUSTOM,
|
|
||||||
date_format->c_str());
|
|
||||||
else
|
|
||||||
out << format_datetime(as_datetime(), FMT_WRITTEN);
|
out << format_datetime(as_datetime(), FMT_WRITTEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DATE:
|
case DATE:
|
||||||
if (date_format)
|
|
||||||
out << format_date(as_date(), FMT_CUSTOM, date_format->c_str());
|
|
||||||
else
|
|
||||||
out << format_date(as_date(), FMT_WRITTEN);
|
out << format_date(as_date(), FMT_WRITTEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1547,6 +1550,11 @@ void value_t::print(std::ostream& out,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case BALANCE:
|
||||||
|
as_balance().print(out, first_width, latter_width, right_justify,
|
||||||
|
colorize);
|
||||||
|
break;
|
||||||
|
|
||||||
case STRING:
|
case STRING:
|
||||||
justify(out, as_string(), first_width, right_justify);
|
justify(out, as_string(), first_width, right_justify);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1565,17 +1573,12 @@ void value_t::print(std::ostream& out,
|
||||||
out << ", ";
|
out << ", ";
|
||||||
|
|
||||||
value.print(out, first_width, latter_width, right_justify,
|
value.print(out, first_width, latter_width, right_justify,
|
||||||
colorize, date_format);
|
colorize);
|
||||||
}
|
}
|
||||||
out << ')';
|
out << ')';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BALANCE:
|
|
||||||
as_balance().print(out, first_width, latter_width, right_justify,
|
|
||||||
colorize);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case POINTER:
|
case POINTER:
|
||||||
out << "<POINTER>";
|
out << "<POINTER>";
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -927,8 +927,7 @@ public:
|
||||||
const int first_width = -1,
|
const int first_width = -1,
|
||||||
const int latter_width = -1,
|
const int latter_width = -1,
|
||||||
const bool right_justify = false,
|
const bool right_justify = false,
|
||||||
const bool colorize = false,
|
const bool colorize = false) const;
|
||||||
const optional<string>& date_format = none) const;
|
|
||||||
void dump(std::ostream& out, const bool relaxed = true) const;
|
void dump(std::ostream& out, const bool relaxed = true) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
reg --forecast-while='total < $3500' books
|
reg --now=2009/03/21 --forecast-while='total < $3500' books
|
||||||
<<<
|
<<<
|
||||||
~ monthly
|
~ monthly
|
||||||
Expenses:Books $10.00
|
Expenses:Books $10.00
|
||||||
Loading…
Add table
Reference in a new issue